주변기기 추가
plem 플랫폼은 2-Layer Description 패턴으로 로봇 본체와 주변기기(그리퍼, 카메라 등)를 독립적으로 관리한다. 새 주변기기를 추가할 때 로봇 URDF나 launch 파일을 수정할 필요 없이, 정해진 디렉터리에 파일을 배치하면 PeripheralScanner가 자동으로 발견한다.
2-Layer Description 패턴
| Layer | 패키지 예시 | 역할 | 수정 여부 |
|---|---|---|---|
| Description | neuromeka_description, onrobot_description, stereolabs_description | 하드웨어 URDF — 기기별 독립 패키지 | 새 주변기기 시 생성 |
| Integration | neuromeka_integrations | 마운팅 + SRDF + 드라이버 매핑 | 새 주변기기 시 항목 추가 |
핵심 원칙:
- 로봇 Description은 수정하지 않는다. 로봇 URDF는 로봇 제조사의 SSoT(Single Source of Truth)이다.
- Description은 주변기기별 독립 패키지로 관리한다. 각 패키지는 자체 URDF와 메시를 포함한다.
- Integration은 Description들을 조합하는 계층이다. 마운팅 위치, 충돌 비활성화, 드라이버 매핑을 정의한다.
Description 패키지 생성 조건
| 상황 | 예시 | 조치 |
|---|---|---|
| 벤더 공식 ROS2 URDF 패키지 없음 | OnRobot, Robotiq | 자체 작성 |
| 벤더 URDF가 무거운 SDK에 묶여 있음 | Stereolabs (ZED SDK) | 공식 매크로 벤더링 |
| 벤더가 가벼운 URDF 패키지 제공 | (해당 시 직접 사용) | Description 불필요 |
새 그리퍼 추가 (예: Robotiq 2F-85)
1단계: Description — robotiq_description 패키지 생성
주변기기의 URDF와 메시를 담는 독립 패키지를 생성한다.
robotiq_description/
├── CMakeLists.txt
├── package.xml
├── urdf/
│ └── 2f85.urdf.xacro # robotiq_2f85 매크로 (prefix 파라미터)
└── meshes/
└── 2f85/
├── visual/ # DAE 또는 STL 시각 메시
└── collision/ # 단순화된 충돌 메시
urdf/2f85.urdf.xacro는 반드시 prefix 파라미터를 지원해야 한다. 모든 link와 joint 이름에 ${prefix}를 붙인다:
<xacro:macro name="robotiq_2f85" params="prefix">
<link name="${prefix}robotiq_2f85_base_link">
<!-- ... -->
</link>
<!-- 나머지 link/joint에도 ${prefix} 적용 -->
</xacro:macro>
2단계: Integration — wrapper 추가
neuromeka_integrations 패키지에 다음 파일들을 추가한다.
2-1. 마운팅 매크로
neuromeka_integrations/urdf/grippers/2f85.xacro:
<xacro:macro name="mount_gripper" params="prefix name parent_link flange_xyz flange_rpy">
<xacro:include filename="$(find robotiq_description)/urdf/2f85.xacro"/>
<joint name="${prefix}${name}_mount" type="fixed">
<parent link="${parent_link}"/>
<child link="${prefix}robotiq_2f85_base_link"/>
<origin xyz="${flange_xyz}" rpy="${flange_rpy}"/>
</joint>
<xacro:robotiq_2f85 prefix="${prefix}"/>
</xacro:macro>
2-2. SRDF 매크로
neuromeka_integrations/srdf/grippers/2f85.srdf.xacro:
그리퍼-로봇 간 충돌 비활성화 쌍을 정의하는 gripper_srdf 매크로를 작성한다.
2-3. 드라이버 매핑
neuromeka_integrations/config/gripper_drivers.yaml에 1줄 추가:
2f85:
package: robotiq_gripper_driver
launch_file: robotiq_gripper.launch.py
2-4. 패키지 의존성
neuromeka_integrations/package.xml에 의존성 추가:
<exec_depend>robotiq_description</exec_depend>
3단계: 빌드 및 테스트
colcon build && colcon test --packages-select neuromeka_integrations
4단계: 실행 확인
ros2 launch neuromeka_robot_driver plem_launch.py gripper:=2f85
새 카메라 추가
카메라도 동일한 2-Layer 패턴을 따른다. 그리퍼의 mount_gripper 대신 mount_sensor 매크로를 사용한다.
mount_sensor 매크로 인터페이스:
<xacro:macro name="mount_sensor" params="prefix name parent_link mount_config_file">
<xacro:property name="cam_name" value="${prefix}${name}_cam"/>
<xacro:property name="mount"
value="${xacro.load_yaml(mount_config_file)['camera_mount']}"/>
<!-- Description 매크로 호출 -->
<xacro:zed_camera name="${cam_name}" model="zedxm"/>
<!-- 마운트 조인트: Hand-Eye 캘리브레이션 결과 -->
<joint name="${cam_name}_mount_joint" type="fixed">
<parent link="${parent_link}"/>
<child link="${cam_name}_camera_link"/>
<origin xyz="${mount['x']} ${mount['y']} ${mount['z']}"
rpy="${mount['roll']} ${mount['pitch']} ${mount['yaw']}"/>
</joint>
</xacro:macro>
자체 작성 시
벤더가 ROS2 URDF를 제공하지 않는 경우:
- Description: 카메라 description 패키지 생성 (예:
realsense_description) - Integration:
neuromeka_integrations/urdf/sensors/디렉터리에 마운팅 매크로 배치
공식 매크로 벤더링 시
벤더의 URDF가 무거운 SDK에 포함된 경우 (예: Stereolabs ZED):
- 공식 매크로 파일을 Description 패키지에 복사
- 메시 경로만 패치 (
$(find vendor_package)→$(find your_description)) VENDOR_SOURCE.md에 출처와 수정 내역 기록- 프레임명은 반드시 공식 드라이버와 동일하게 유지
벤더링 시 프레임명을 절대 변경하지 않는다. 드라이버가 publish하는 frame_id와 URDF의 TF 프레임이 일치해야 RViz에서 센서 데이터가 올바른 위치에 표시된다.
카메라 SRDF 인터페이스
카메라의 SRDF 매크로는 cam_name 파라미터를 받는다:
<xacro:macro name="sensor_collision" params="prefix cam_name">
<disable_collisions link1="${prefix}link6" link2="${cam_name}_camera_center" reason="Adjacent"/>
</xacro:macro>
cam_name은 Integration layer에서 ${prefix}${name}_cam으로 구성된다.
자동 발견
launch 파일, Scanner, macro.xacro는 수정할 필요가 없다. PeripheralScanner가 neuromeka_integrations의 디렉터리 구조를 스캔하여 등록된 주변기기를 자동으로 발견한다. 정해진 디렉터리(urdf/grippers/, urdf/sensors/)에 파일을 배치하고 gripper_drivers.yaml에 드라이버를 등록하면 된다.