AEGLOSLAB ROS 2 Jazzy 대전

제9부 매니퓰레이션

9.1 MoveIt 2 아키텍처

9.1.1 이 장에서 배우는 것 / 선수 지식

MoveIt 2는 ROS 2에서 매니퓰레이터를 다루는 표준 프레임워크다. 역기구학, 충돌 검사, 경로 계획, 궤적 실행, 그리퍼 제어 — 팔을 움직이는 데 필요한 것을 모아 놓았다.

Nav2(8.1)와 비슷한 위치에 있지만 성격이 다르다. Nav2는 2D 평면에서 움직이는 로봇을, MoveIt 2는 고차원 관절 공간에서 움직이는 팔을 다룬다. 자유도가 6~7이면 계획 공간이 6~7차원이고, 여기서는 격자 탐색이 불가능하다 — 이것이 MoveIt 2가 표본 기반 계획(9.2)에 의존하는 이유다.

배우는 것:

  • 구성 요소 — move_group과 그 주변.
  • SRDF — URDF가 담지 못하는 의미 정보.
  • 설정 패키지 구조 — Setup Assistant가 만드는 것.
  • 인터페이스 — 코드에서 팔을 움직이는 방법.
  • ros2_control과의 연결 — 계획이 실제 동작이 되는 경로.
  • MTC — 복잡한 작업을 단계로.
  • MoveIt 2가 하지 않는 것 — 경계.
  • 2.12.4 실물 대조(9.1.12) — MoveItCpp의 위치·설정 키·헤더 확장자 전환.

선수 지식: 5.3(URDF), 5.5(관절 상태), 6.5.5(joint_trajectory_controller), 1.8(액션), 1.12(라이프사이클), 8.1(Nav2 — 대조하며 읽으면 좋다).

정직: MoveIt 2는 API·패키지 구성이 활발히 변해 왔다. 특히 MoveItCpp·MoveGroupInterface의 관계, MTC의 성숙도, Setup Assistant의 출력 형식이 배포판마다 다르다. 정확한 API는 MoveIt 2 문서의 Jazzy 버전이 정본이다(확인 필요). 2026-08-16에 MoveIt 2.12.4를 설치해 헤더 경로·인터페이스 타입·패키지 실재를 확인했다(아래 함정과 9.2.1 참조) — 다만 API 호출의 실제 동작은 검증하지 않았다(목차 3). 기구학 이론은 자매서 robotics 제2부(RB-44~RB-62), 계획 알고리즘은 제11부(RB-277~RB-300)가 다룬다(BK-04) — 집필 상태는 A.5.9를 보라(2026-11 기준 새 번호로 작성이 끝난 장은 RB-01뿐이다).

검증 상태(추가): 이 장의 서술 가운데 3곳은 이후 회차에서 Jazzy 실물과 대조해 확인했다 — 본문의 (실행 확인) 표기가 그것이다. 표기가 없는 서술은 위 고지가 그대로 적용된다(목차 3의 검증 범위 표).

9.1.2 구성 요소

MoveGroup 액션 FollowJointTrajectory /joint_states 사용자 코드 · RViz2 move_group 노드 계획 파이프라인 9.2 Planning Scene 9.3 기구학 플러그인 IK · FK 충돌 검사 Octomap (깊이 센서) ros2_control 6.5 로봇
구성 요소역할관련 장
move_group중심 노드 — 모든 기능을 액션·서비스로 노출이 장
계획 파이프라인계획 요청 → 궤적9.2
Planning Scene로봇 상태 + 환경(충돌 물체)9.3
기구학 플러그인IK·FK 계산이 장
충돌 검사자기 충돌·환경 충돌9.3
시간 파라미터화경로 → 시간 궤적9.2
Servo실시간 속도 제어9.4
MTC다단계 작업 계획9.5

move_group이 중심이라는 점이 Nav2와 다르다. Nav2는 여러 서버로 나뉘어 있지만(8.1.2), MoveIt 2는 하나의 큰 노드가 대부분을 담당한다(확인 필요: MoveItCpp를 쓰면 노드 없이 라이브러리로 사용 가능).

견해: move_group이 단일 노드라는 점이 장단이 있다. 설정이 단순하고 상태 공유가 쉽지만, 크래시하면 전부 멈추고 계획·실행이 같은 프로세스에서 경쟁한다. 고성능·저지연이 필요하면 MoveItCpp로 라이브러리처럼 쓰거나 Servo(9.4)를 쓰는 경로가 있다.

9.1.3 SRDF — 의미 정보

URDF(5.3)는 기구 구조를 기술하지만, "어느 관절이 팔이고 어디가 손인가"는 담지 못한다. SRDF가 그것을 채운다.

<?xml version="1.0"?>
<robot name="my_arm">

  <!-- ① 계획 그룹 — 함께 움직이는 관절의 묶음 -->
  <group name="arm">
    <chain base_link="base_link" tip_link="tool0"/>
  </group>

  <group name="gripper">
    <joint name="finger_joint"/>
  </group>

  <!-- ② 이름 붙은 자세 -->
  <group_state name="home" group="arm">
    <joint name="joint1" value="0"/>
    <joint name="joint2" value="-1.57"/>
    <joint name="joint3" value="1.57"/>
    <joint name="joint4" value="0"/>
    <joint name="joint5" value="1.57"/>
    <joint name="joint6" value="0"/>
  </group_state>

  <!-- ③ 엔드이펙터 -->
  <end_effector name="gripper_ee" parent_link="tool0"
                group="gripper" parent_group="arm"/>

  <!-- ④ 가상 관절 — 로봇을 세계에 고정 -->
  <virtual_joint name="fixed_base" type="fixed"
                 parent_frame="world" child_link="base_link"/>

  <!-- ⑤ 충돌 검사 제외 -->
  <disable_collisions link1="link1" link2="link2" reason="Adjacent"/>
  <disable_collisions link1="base_link" link2="link1" reason="Adjacent"/>
  <disable_collisions link1="link1" link2="link3" reason="Never"/>

</robot>
요소역할
<group>계획 단위 — 이 관절들을 함께 계획
<group_state>이름 붙은 자세(home·ready)
<end_effector>그리퍼와 팔의 관계
<virtual_joint>로봇 베이스를 세계에 연결
<disable_collisions>충돌 검사에서 제외할 링크 쌍

<disable_collisions>가 가장 많고 가장 중요하다.

reason의미
Adjacent관절로 직접 연결 — 항상 닿아 있음
Never어떤 자세에서도 충돌 불가(샘플링으로 확인)
Default기본 자세에서 충돌 중
Always항상 충돌 중(모델 문제일 수 있음)

견해: disable_collisions가 계획 성능을 크게 좌우한다. 검사할 링크 쌍이 $O(n^2)$인데, 불가능한 조합을 미리 빼면 계산이 크게 준다(9.3.8). Setup Assistant가 무작위 샘플링으로 자동 생성하지만, 샘플 수가 적으면 실제로는 충돌 가능한 쌍을 Never로 잘못 표시할 수 있다.

함정: Always로 표시된 쌍이 있으면 URDF를 의심하라. 충돌 기하가 겹쳐 있다는 뜻이고, 대개 모델 오류다(5.3.4·5.7). 이것을 단순히 비활성화하면 실제 충돌을 놓친다.

virtual_joint의 역할:

타입용도
fixed고정 설치 팔
floating모바일 매니퓰레이터(베이스가 움직임)
planar평면 이동 베이스

함정: 모바일 매니퓰레이터에서 virtual_joint를 fixed로 두면 베이스 이동이 계획에 반영되지 않는다. 팔만 계획하려면 그것이 맞지만, 베이스와 팔을 함께 계획하려면 planar·floating이어야 한다(확인 필요: 지원 범위).

9.1.4 설정 패키지

MoveIt Setup Assistant가 만드는 패키지의 구조다.

파일내용
config/<robot>.srdfSRDF(9.1.3)
config/kinematics.yamlIK 플러그인·파라미터
config/joint_limits.yaml속도·가속 한계(계획용)
config/ompl_planning.yaml플래너 설정(9.2)
config/moveit_controllers.yaml컨트롤러 연결(9.1.6)
config/moveit_cpp.yamlMoveItCpp 설정 — 키 구조는 planning_scene_monitor_options.*·planning_pipelines.*(실행 확인, 9.1.12.2)
config/*.rvizRViz2 설정
launch/*.launch.py실행
ros2 launch moveit_setup_assistant setup_assistant.launch.py

Setup Assistant가 하는 일:

단계작업
URDF 로드모델 확인
자기 충돌 행렬 생성무작위 샘플링(9.1.3)
가상 관절베이스 연결
계획 그룹팔·그리퍼 정의
자세home 등
엔드이펙터그리퍼 지정
컨트롤러ros2_control 연결
파일 생성설정 패키지 출력

함정: joint_limits.yaml의 값이 URDF와 다를 수 있다. MoveIt은 이 파일의 값을 계획에 쓰며, URDF의 <limit>(5.3.3)과 별개다. 의도적으로 더 보수적으로 설정할 수 있지만, 불일치를 모르면 혼란스럽다.

joint_limits:
  joint1:
    has_velocity_limits: true
    max_velocity: 2.0          # URDF 값보다 작게 둘 수 있다
    has_acceleration_limits: true
    max_acceleration: 3.0      # ★ URDF에는 없는 정보

견해: 가속 한계는 URDF에 없으므로 여기서만 정해진다(5.3.3). 이 값이 궤적의 부드러움과 소요 시간을 좌우하므로(9.2.7), 실제 로봇 사양에 맞춰 설정해야 한다. 너무 크면 로봇이 못 따라가고, 너무 작으면 느리다.

함정: Setup Assistant를 다시 실행하면 수동으로 수정한 설정이 덮어써질 수 있다. 생성 후 수정한 파일을 버전 관리하고, 재생성 시 diff를 확인하라(8.8.8의 변경 관리와 같은 논리).

9.1.5 인터페이스

팔을 움직이는 세 가지 방법이 있다.

9.1.5.1 MoveGroupInterface (가장 흔함)

#include <moveit/move_group_interface/move_group_interface.hpp>

auto move_group = moveit::planning_interface::MoveGroupInterface(node, "arm");

// 목표: 관절 공간
move_group.setJointValueTarget({0.0, -1.57, 1.57, 0.0, 1.57, 0.0});

// 또는 목표: 자세 공간 (IK 필요)
geometry_msgs::msg::Pose target;
target.position.x = 0.4;
target.position.y = 0.1;
target.position.z = 0.5;
target.orientation.w = 1.0;
move_group.setPoseTarget(target);

// 또는 이름 붙은 자세 (SRDF — 9.1.3)
move_group.setNamedTarget("home");

// 계획
moveit::planning_interface::MoveGroupInterface::Plan plan;
auto result = move_group.plan(plan);
if (result == moveit::core::MoveItErrorCode::SUCCESS) {
  move_group.execute(plan);          // 또는 move_group.move() 로 계획+실행
} else {
  RCLCPP_ERROR(logger, "계획 실패: %d", result.val);
}
from moveit.planning import MoveItPy       # import 정상 확인(Jazzy · moveit_py 2.12.4)

moveit = MoveItPy(node_name="moveit_py")
arm = moveit.get_planning_component("arm")
arm.set_start_state_to_current_state()
arm.set_goal_state(configuration_name="home")
plan_result = arm.plan()
if plan_result:
    moveit.execute(plan_result.trajectory, controllers=[])

정직: Python API는 배포판을 거치며 크게 바뀌었다. 구 moveit_commander에서 moveit_py로 이행했다. 실행 확인(2026-08-16): Jazzy에 ros-jazzy-moveit-py(2.12.4)가 실재하고 from moveit.planning import MoveItPy가 정상 import된다 — 패키지 이름은 moveit_py이지만 파이썬 모듈은 moveit 이다. 다만 아래 코드의 메서드·인자 형태까지 실행해 본 것은 아니다(확인 필요).

함정 — MoveIt 헤더는 이제 .hpp다(실행 확인 2026-08-16). MoveIt 2는 모든 헤더를 .hpp 확장자로 옮겼다. 기존 .h는 자동 생성된 전환용 shim으로 남아 있고, 열어 보면 이렇게 적혀 있다 — "All MoveIt 2 headers have been updated to use the .hpp extension … imports via .h files may be removed in future releases." 실제로 .h로 include해 컴파일하면 #pragma message: .h header is obsolete. Please use the .hpp header instead. 가 출력된다(2.12.4에서 실측). 설치 트리에는 .h shim 697개와 .hpp 770개가 공존한다. 이 책도 .h로 적고 있었고 .hpp로 정정했다 — 인터넷 예제 대부분이 아직 .h이므로 복사할 때 바꿔 쓰라.

함정: MoveGroupInterface는 내부적으로 액션·서비스를 호출한다. 즉 move_group 노드와 통신하며, 1.7의 데드락 규칙이 적용된다. 콜백 안에서 plan()·execute()를 동기 호출하면 멈출 수 있다 — 별도 executor나 스레드가 필요하다(1.7.4).

9.1.5.2 액션 직접 사용

# move_group 액션 (저수준)
ros2 action list | grep move
# /move_action, /execute_trajectory 등

9.1.5.3 MoveItCpp (라이브러리 방식)

move_group 노드 없이 프로세스 안에서 직접 사용한다. 통신 오버헤드가 없어 빠르지만 설정이 복잡하다. Jazzy에서의 위치는 확정했다 — moveit_ros_planning 패키지의 moveit/moveit_cpp/moveit_cpp.hpp(실행 확인, 9.1.12.1).

견해: 시작은 MoveGroupInterface, 성능이 필요하면 MoveItCpp나 Servo(9.4)를 검토한다. 대부분의 응용에서 MoveGroupInterface로 충분하며, 계획에 수백 ms가 걸리는 것이 병목이지 통신이 병목인 경우는 드물다.

9.1.6 ros2_control 연결

MoveIt이 만든 궤적이 실제 동작이 되는 경로다.

move_group: 궤적 생성 FollowJointTrajectory 액션 joint_trajectory_controller 6.5.5 보간 → command_interface 하드웨어 컴포넌트 write() 6.2 로봇
# moveit_controllers.yaml
moveit_controller_manager: moveit_simple_controller_manager/MoveItSimpleControllerManager

moveit_simple_controller_manager:
  controller_names:
    - arm_controller
    - gripper_controller

  arm_controller:
    type: FollowJointTrajectory
    action_ns: follow_joint_trajectory
    default: true
    joints:
      - joint1
      - joint2
      - joint3
      - joint4
      - joint5
      - joint6

  gripper_controller:
    type: GripperCommand
    action_ns: gripper_cmd
    default: true
    joints:
      - finger_joint

핵심: MoveIt은 FollowJointTrajectory 액션 클라이언트다(6.5.5). 이것이 제6부와 제9부가 만나는 지점이며, 6.1.10에서 "MoveIt 2를 쓸 계획이면 ros2_control이 사실상 필수"라고 한 이유다.

함정: joints 목록이 컨트롤러의 관절과 정확히 일치해야 한다. 순서까지 맞아야 하는 경우가 있으며(확인 필요), 불일치하면 실행이 거부되거나 잘못된 관절이 움직인다.

함정: 컨트롤러가 활성 상태여야 한다(6.3.6). joint_trajectory_controller가 inactive면 MoveIt이 액션 서버를 못 찾고 "컨트롤러를 찾을 수 없다"는 오류가 난다.

# 확인
ros2 control list_controllers
ros2 action list | grep follow_joint_trajectory

허용오차 상호작용(6.5.5):

설정영향
컨트롤러의 constraints궤적 추종 중 중단 판정
MoveIt의 trajectory_execution 파라미터실행 감시

함정: 컨트롤러 허용오차가 빡빡하면 MoveIt 궤적이 자주 중단된다. 특히 가속이 큰 궤적이나 하드웨어 지연이 있을 때 그렇다. 6.5.5에서 본 "실측 오차의 3~5배" 원칙을 여기서도 적용한다.

9.1.7 MoveIt Task Constructor

여러 단계로 이루어진 작업을 계획하는 도구다.

작업 정의 Stage 1: 현재 상태 Stage 2: 접근 Stage 3: 파지 Stage 4: 이탈 Stage 5: 이송 Stage 6: 배치 전체 해 탐색

단순 계획과의 차이: 각 단계를 독립적으로 계획하면 앞 단계의 결과가 뒤 단계를 불가능하게 만들 수 있다. MTC는 전체를 함께 탐색해 일관된 해를 찾는다.

개념설명
Stage계획 단계 하나
Generator후보 상태를 만든다(파지 자세 등)
Propagator앞·뒤로 전파(접근·이탈)
Connector두 상태를 잇는다(자유 이동)
Container단계를 묶는다(Serial·Alternatives)

정직: MTC는 Jazzy에 실재한다 — ros-jazzy-moveit-task-constructor-core 0.1.5(실행 확인 2026-08-16). 버전 번호가 말해 주듯 MoveIt 본체(2.12.4)와 성숙도가 다르며, API 안정성은 확인하지 않았다(확인 필요). 강력하지만 학습 곡선이 가파르고, 단순한 픽앤플레이스에는 과할 수 있다. 9.5에서 실제 사용을 다룬다.

견해: 단계가 3~4개 이하면 MoveGroupInterface로 순차 계획하는 것이 단순하다. MTC는 단계 간 의존이 강하고 실패 시 앞으로 되돌아가야 하는 복잡한 작업에서 값을 한다.

9.1.8 MoveIt 2가 하지 않는 것

하지 않음누가 하는가
물체 인식인지 파이프라인(제7부)
파지 자세 결정파지 생성기·학습 모델(9.5)
관절 제어ros2_control(6.5)
힘 제어별도 컨트롤러(6.5.7)
작업 순서·논리상위 시스템(14.2)
캘리브레이션별도 절차(9.6)
안전 인증14.10
실시간 보장계획은 비실시간(9.4)

두 가지를 강조한다:

① 계획은 실시간이 아니다. OMPL 계획에 수백 ms~수 초가 걸릴 수 있고(9.2), 이것은 반응형 제어에 쓸 수 없다. 빠른 반응이 필요하면 Servo(9.4)다.

② 파지 자세는 MoveIt이 정해 주지 않는다. "이 물체를 어떻게 파지할 것인가"는 별개 문제이며, MoveIt은 정해진 자세로 가는 방법만 계산한다(9.5).

견해: MoveIt 2를 "팔을 움직이는 라이브러리"로 이해하는 것이 정확하다. 무엇을 왜 할지는 위에서 정하고, 어떻게 안전하게 갈지를 MoveIt이 답한다. Nav2와 같은 구조의 경계다(8.1.9).

9.1.9 첫 실행 절차

1. URDF 검증 5.7 2. ros2_control 동작 6.3.8 3. Setup Assistant 설정 생성 4. RViz2에서 계획만 (실행 없이) 5. mock 하드웨어로 실행 6.2.8 6. 실기 저속 실행 7. 충돌 환경 추가 9.3 8. 응용 통합 9.5

각 단계 확인:

단계확인
1관절 축·한계·충돌 기하 정확(5.7)
2joint_trajectory_controller 활성·동작(6.5)
3자기 충돌 행렬이 합리적(9.1.3)
4RViz2에서 목표를 끌어 계획이 되는가
5궤적이 실행되는가(6.2.8)
6실제 로봇이 예상대로 움직이는가
7장애물을 피하는가

견해: 4단계(RViz2 계획)가 결정적 단계다. MoveIt의 MotionPlanning 디스플레이에서 목표 자세를 마우스로 끌고 Plan 버튼을 누르면, 계획 가능 여부·궤적 형태·충돌을 즉시 볼 수 있다. 여기서 안 되면 코드에서도 안 된다 — 설정 문제를 코드 문제로 오해하지 않게 해 준다.

함정: 6단계로 넘어갈 때 반드시 속도를 크게 낮추라. MoveIt 궤적은 관절 여러 개가 동시에 움직이며, 예상과 다른 경로로 갈 수 있다. 비상 정지를 손에 들고, max_velocity_scaling_factor를 0.1 정도로 시작한다.

move_group.setMaxVelocityScalingFactor(0.1);      // 사양의 10%
move_group.setMaxAccelerationScalingFactor(0.1);

9.1.12 MoveIt 2.12.4를 설치해 대조했다 — 실측

ros-jazzy-moveit 2.12.4를 설치해 이 장이 남긴 위치·설정 관련 항목을 확인했다.

9.1.12.1 MoveItCpp는 어디에 있나

항목확인된 값
헤더moveit/moveit_cpp/moveit_cpp.hpp
포함 경로/opt/ros/jazzy/include/moveit_ros_planning/
라이브러리libmoveit_cpp.so.2.12.4
제공 패키지ros-jazzy-moveit-ros-planning

moveit_cpp라는 이름의 독립 패키지는 없다 — moveit_ros_planning에 들어 있다. package.xml에 의존을 적을 때 이름을 혼동하기 쉬운 자리다.

함정: .h와 .hpp가 둘 다 있는데 .h는 폐기 예정이다. 헤더 자체가 이렇게 밝힌다 — ".h headers are now autogenerated via create_deprecated_headers.py, and will import the corresponding .hpp with a deprecation warning." MoveIt 2.12부터는 .hpp를 쓰라. 예전 예제를 복사하면 .h를 포함하게 되고 빌드 로그에 폐기 경고가 쌓인다.

9.1.12.2 moveit_cpp.yaml의 키 구조

헤더가 파라미터를 읽는 코드에서 그대로 드러난다.

planning_scene_monitor_options:
  name: "planning_scene_monitor"
  robot_description: "robot_description"
  joint_state_topic: …
  attached_collision_object_topic: …
  monitored_planning_scene_topic: …
  publish_planning_scene_topic: …
  wait_for_initial_state_timeout: …

planning_pipelines:
  pipeline_names: ["ompl", "pilz_industrial_motion_planner", …]

두 최상위 키가 전부다 — planning_scene_monitor_options와 planning_pipelines. MoveItCpp가 move_group과 다른 점이 여기서 드러난다: 계획 파이프라인 목록을 스스로 들고 있고, 장면 감시자도 직접 실행한다. move_group이 해 주던 것을 내 프로세스가 담당하는 구조다(9.1.4).

pipeline_names가 복수형 목록인 점에 주의하라. MoveItCpp는 여러 파이프라인을 동시에 로드해 두고 호출할 때 고를 수 있다(9.2). move_group에서 파이프라인을 바꾸려면 파라미터를 다시 로드해야 하는 것과 대조된다.

9.1.12.3 확인하지 못한 것

  • MoveItCpp와 MoveGroupInterface의 성능 차이는 측정하지 않았다. 통신이 없으니 빠를 것이라는 추론은 합리적이지만 이 책에 숫자는 없다(확인 필요: 실제 차이).
  • moveit_cpp.yaml의 완전한 키 목록은 헤더가 읽는 것만 확인했다 — 하위 파이프라인이 각자 읽는 키는 별개다.

9.1.10 함정 카탈로그

#함정증상대처
1자기 충돌 행렬 부실계획 실패·느림·오탐샘플 수 증가·수동 검토
2Always 충돌 방치실제 충돌 놓침URDF 확인(5.7)
3virtual_joint 타입 오류베이스 이동 미반영용도에 맞게
4joint_limits.yaml과 URDF 불일치예상과 다른 속도의도 확인
5가속 한계 미설정·부적절못 따라가거나 느림실제 사양
6컨트롤러 joints 불일치실행 거부이름·순서 대조
7컨트롤러 비활성액션 서버 없음list_controllers(6.3)
8컨트롤러 허용오차 빡빡궤적 자주 중단실측의 3~5배(6.5.5)
9콜백에서 동기 plan()데드락별도 executor(1.7)
10Setup Assistant 재실행으로 수정 덮어씀설정 손실버전 관리·diff
11계획을 실시간으로 기대지연Servo 사용(9.4)
12실기에서 전속력 첫 실행충돌 위험스케일링 0.1
13파지 자세를 MoveIt이 줄 것으로 기대구현 누락별도 생성(9.5)
14예제를 복사해 .h 헤더 포함폐기 경고 누적2.12부터 .hpp(9.1.12.1)
15moveit_cpp 패키지를 의존에 적음그런 패키지는 없다moveit_ros_planning(9.1.12.1)

9.1.11 체크포인트

  • MoveIt 2의 구성 요소 여덟 가지와 각각의 역할을 말할 수 있는가. move_group이 단일 노드인 것의 장단은?
  • SRDF의 다섯 요소와 각각이 URDF에 없는 이유를 설명할 수 있는가.
  • disable_collisions의 네 가지 reason과, 이것이 계획 성능에 미치는 영향은? Always가 보이면 무엇을 의심하는가.
  • virtual_joint 타입 세 가지와, 모바일 매니퓰레이터에서의 주의점은?
  • 설정 패키지의 주요 파일 여섯 가지를 말할 수 있는가. 가속 한계가 왜 joint_limits.yaml에서만 정해지는가.
  • 팔을 움직이는 세 가지 인터페이스와 각각의 적합 상황은?
  • MoveGroupInterface를 콜백에서 동기 호출하면 안 되는 이유는?
  • MoveIt이 만든 궤적이 실제 동작이 되는 경로를 그릴 수 있는가. 제6부와 만나는 지점은?
  • 컨트롤러 연결에서 흔한 실패 두 가지는?
  • MTC가 단순 순차 계획과 다른 점과, 언제 값을 하는가.
  • MoveIt 2가 하지 않는 것 여덟 가지를 들 수 있는가. 특히 강조되는 두 가지는?
  • 첫 실행 절차에서 결정적 단계는 무엇이며 왜인가. 실기 첫 실행 시 반드시 할 것은?
  • MoveItCpp는 어느 패키지가 제공하며 헤더 확장자는 무엇을 써야 하는가(9.1.12.1).
  • moveit_cpp.yaml의 두 최상위 키는 무엇이며, 그것이 move_group과의 구조 차이를 어떻게 드러내는가(9.1.12.2).

다음 장 9.2는 그 계획이 실제로 어떻게 만들어지는가 — 계획 파이프라인과 플래너 종류를 다룬다.