Description Package Protocol
외부 로봇 description package를 위한 convention 기반 명세입니다.
개요
Description Package Protocol은 외부 로봇 description을 PLEM과 설정 없이 통합할 수 있게 합니다. 사용자는 URDF와 joint limit이 포함된 ROS2 package를 제공하면, 시스템이 파일을 자동으로 발견하고 누락된 MoveIt 설정을 생성합니다.
Package 구조 Convention
my_robot_description/
├── urdf/
│ ├── my_robot.urdf.xacro # 필수: 정확히 하나의 URDF
│ └── my_robot.ros2_control.xacro # 필수: hardware interface 정의
├── srdf/
│ └── my_robot.srdf.xacro # 선택: MoveIt용 (--with-moveit으로 생성)
├── config/
│ ├── joint_limits.yaml # 필수: 안전 제한값
│ ├── controllers.yaml # 선택: 없으면 자동 생성
│ └── kinematics.yaml # 선택: 없으면 자동 생성
├── launch/ # 선택: 커스텀 launch 파일 (기본 생성)
│ └── bringup.launch.py # (scaffold 도구가 기본 생성)
├── meshes/ # 선택: visual/collision mesh
├── PLEM_COMPAT_VERSION # 필수: PLEM 호환성 버전
├── CMakeLists.txt
└── package.xml
ros2 run plem_bringup create_description --name <name> --dof <n> [--with-moveit]로 전체 구조를 자동 생성할 수 있습니다. --name/--dof 생략 시 대화형 모드가 자동 실행됩니다. Launch 파일은 기본 생성되며, --no-launch로 비활성화할 수 있습니다. 기존 package에 재실행 시 동일한 파일은 건너뛰고, --force로 덮어쓸 수 있습니다.
필수 파일
| 파일 | 목적 | 검증 |
|---|---|---|
urdf/*.urdf.xacro | 로봇 geometry, kinematics | 정확히 하나의 파일, 유효한 XML |
urdf/*.ros2_control.xacro | Hardware interface 정의 | URDF에서 include, prefix parameter |
config/joint_limits.yaml | Position/velocity/acceleration 제한값 | 유효한 YAML, URDF joint와 일치 |
PLEM_COMPAT_VERSION | PLEM 라이브러리 호환성 버전 (예: 1.0.0) | 파일 존재, SemVer 형식 |
선택 파일 (자동 생성 또는 MoveIt 비활성화)
| 파일 | 목적 | 자동 생성 동작 |
|---|---|---|
srdf/*.srdf | MoveIt semantic description | 자동 생성 안 됨. 없으면 MoveIt이 시작되지 않음. |
config/kinematics.yaml | IK solver 설정 | KDL solver, 기본 parameter로 생성 (SRDF 필요) |
config/controllers.yaml | Joint trajectory controller 설정 | joint_limits.yaml에서 생성 |
자동 발견 규칙
URDF 발견
규칙: 시스템은 urdf/ directory에서 .urdf.xacro 파일을 검색합니다.
제약사항:
- 정확히 하나의 URDF 파일이 존재해야 함
- 파일은
.urdf.xacro확장자를 가져야 함 - 파일 이름은 임의 (package 이름과 일치할 필요 없음)
- xacro 파일은 인자 없이 독립 실행 가능해야 함 (아래 섹션 참조)
Override: urdf_file:=/absolute/path/to/file.urdf.xacro 실행 인자를 사용합니다.
URDF/SRDF 독립 실행 요구사항
외부 package의 xacro 파일은 인자 없이 독립 실행 가능해야 합니다.
xacro my_robot.urdf.xacro # 인자 없이 동작
xacro my_robot.urdf.xacro name:=... type:=... # 인자 필수 → 지원 안 됨
인자가 필요한 경우, wrapper xacro에서 기본값을 지정하세요:
<!-- my_robot.urdf.xacro -->
<xacro:include filename="base_robot.urdf.xacro"/>
<xacro:base_robot name="my_robot" prefix="" eye="false"/>
업계 표준(UR, Franka, MoveIt2)과의 일관성을 유지하고 사용자 경험을 단순화하기 위함입니다.
SRDF 발견
규칙: 시스템은 srdf/ directory에서 .srdf 파일을 검색합니다.
제약사항:
- 최대 하나의 SRDF 파일
- 파일 이름은 임의
Override: srdf_file:=/absolute/path/to/file.srdf 실행 인자를 사용합니다.
Config 발견
규칙: 시스템은 config/ directory에서 정확한 파일명을 찾습니다.
예상 파일명:
joint_limits.yamlcontrollers.yamlkinematics.yaml
URDF 요구사항
1. ros2_control Hardware Interface 태그
권장 패턴: 별도 {name}.ros2_control.xacro 파일에 hardware interface를 정의하고 URDF에서 include합니다. Scaffold 도구가 이 패턴으로 자동 생성합니다.
ros2_control.xacro:
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:macro name="my_robot_ros2_control" params="prefix:=''">
<ros2_control name="${prefix}my_robot_hardware" type="system">
<hardware>
<plugin>hardware/HardwareInterface</plugin>
</hardware>
<joint name="${prefix}joint1">
<command_interface name="position"/>
<command_interface name="velocity"/>
<command_interface name="acceleration"/>
<command_interface name="effort"/>
<state_interface name="position"/>
<state_interface name="velocity"/>
<state_interface name="effort"/>
</joint>
<!-- 모든 구동 joint에 대해 반복 -->
</ros2_control>
</xacro:macro>
</robot>
URDF에서 include:
<xacro:include filename="$(find my_robot_description)/urdf/my_robot.ros2_control.xacro"/>
<xacro:my_robot_ros2_control prefix="$(arg prefix)"/>
검증:
<ros2_control>태그가 존재해야 함hardware/HardwareInterfaceplugin을 참조해야 함- 모든 구동 joint가 선언되어야 함
prefixparameter 지원 (multi-robot scenario)
2. Joint 타입
지원됨: revolute, prismatic, continuous (구동 joint)
무시됨: fixed joint는 DOF 개수에서 제외됨
현재 RT driver는 revolute joint에 최적화되어 있습니다. Prismatic과 continuous joint는 추출되지만 추가 테스트가 필요할 수 있습니다.
3. Joint 개수
지원되는 DOF: 6 또는 7
감지: Runtime에 URDF joint 선언에서 계산됨
제약: RT driver compile-time DOF와 일치해야 함 (IPC 호환성 섹션 참조)
DOF=6, 7. 8-DOF 이상의 로봇은 RT driver의 커스텀 빌드가 필요합니다.
Config 파일 형식
joint_limits.yaml (필수)
joint_limits:
joint1:
has_position_limits: true
min_position: -3.14159 # radian
max_position: 3.14159
max_velocity: 3.0 # rad/s
max_acceleration: 5.0 # rad/s^2
max_jerk: 50.0 # rad/s^3
joint2:
# ... 모든 joint에 대해 반복
검증:
- URDF의 모든 joint가 항목을 가져야 함
- 모든 제한값은 양수여야 함 (position min/max 제외)
min_position < max_position
controllers.yaml (선택)
controller_manager:
ros__parameters:
update_rate: 1000
arm_controller:
ros__parameters:
type: joint_trajectory_controller/JointTrajectoryController
joints:
- joint1
- joint2
# ...
command_interfaces:
- position
state_interfaces:
- position
- velocity
constraints:
stopped_velocity_tolerance: 0.01
goal_time: 0.0
자동 생성: joint_limits.yaml에서 기본 tolerance로 생성됩니다.
kinematics.yaml (선택)
arm:
kinematics_solver: kdl_kinematics_plugin/KDLKinematicsPlugin
kinematics_solver_search_resolution: 0.005
kinematics_solver_timeout: 0.05
kinematics_solver_attempts: 3
자동 생성: 보수적인 기본값으로 KDL solver를 사용합니다.
SRDF (선택)
<robot name="my_robot">
<group name="arm">
<chain base_link="base_link" tip_link="link6"/>
</group>
<group_state name="home" group="arm">
<joint name="joint1" value="0"/>
<!-- ... 모든 joint -->
</group_state>
</robot>
SRDF는 자동 생성되지 않습니다. 수동으로 생성해야 합니다. SRDF가 제공되지 않으면 MoveIt이 시작되지 않으며, ros2_control만 활성화됩니다.
실행 인자 참조
| 인자 | 기본값 | 목적 |
|---|---|---|
description_package | wim_description | 로봇 description을 위한 ROS2 package 이름 |
robot_name | (description_package에서) | Topic namespace를 위한 로봇 식별자 |
urdf_file | (자동 발견) | URDF 경로 override |
srdf_file | (자동 발견) | SRDF 경로 override |
robot_type | indy7_v2 | Legacy: 내장 로봇 (indy7_v2, indy12_v2, indyrp2, indyrp2_v2) |
사용 패턴
빠른 테스트: 통합 Launcher
모든 PLEM component를 한 번에 실행합니다:
# Convention 기반 (권장)
ros2 launch plem_bringup plem_launch.py description_package:=my_robot_description
# URDF 경로 override
ros2 launch plem_bringup plem_launch.py \
description_package:=my_robot_description \
urdf_file:=/path/to/custom.urdf.xacro
# Legacy 내장 로봇
ros2 launch plem_bringup plem_launch.py robot_type:=indy7_v2
용도: Prototyping, 기능 검증, 전체 stack 테스트
특징: RT driver, ROS2 Control, MoveIt, Bridge, AI Server 모두 시작
Production: Scaffold Launcher
필요한 component만 선택 가능한 커스텀 launcher:
# 1. Description package 생성 (launch 파일 기본 포함)
ros2 run plem_bringup create_description --name my_robot --dof 6
# 2. 생성된 bringup.launch.py를 편집하여 component 선택
# my_robot_description/launch/bringup.launch.py
# 예: MoveIt과 AI Server를 비활성화하고 RT driver와 ROS2 Control만 실행
# 3. 커스텀 launcher 실행
ros2 launch my_robot_description bringup.launch.py
용도: Production 배포, embedded system, resource 최적화
특징:
- Component별 활성화/비활성화 제어
- 로봇별 초기화 logic 추가 가능
- 설정을 코드와 함께 version 관리
검증 규칙
자동 검증 도구
ros2 run plem_bringup validate_description <package_name>
다음을 자동으로 검증합니다:
- URDF 구조 및 ros2_control 태그
- Joint limit 일관성
- 파일 간 joint 이름 일치
- DOF 개수 확인
- SRDF와 URDF 간 일관성 (SRDF 제공 시)
파일 간 일관성
| 검증 | 확인 사항 |
|---|---|
| URDF ↔ joint_limits.yaml | 모든 URDF joint가 제한값 항목을 가짐, 추가 항목 없음 |
| URDF ↔ SRDF | 모든 SRDF group이 유효한 URDF link/joint 참조 |
| URDF ↔ controllers.yaml | 모든 controller joint가 URDF에 존재 |
| URDF ↔ kinematics.yaml | 모든 kinematic group이 SRDF group과 일치 |
검증 시점
| 단계 | 검증 |
|---|---|
| 빌드 후 | validate_description 도구로 사전 검증 (권장) |
| 실행 시점 | 파일 존재, YAML 문법, URDF XML 문법 |
| Node 시작 | ros2_control 태그, joint 개수, joint 타입 |
| Runtime | IPC DOF 일치, joint limit 적용 |
오류 메시지 형식
모든 오류는 WHAT/WHY/HOW 구조를 따릅니다:
ERROR: No URDF file found in package 'my_robot_description'
WHAT: Auto-discovery expected exactly one .urdf.xacro file in urdf/ directory
WHY: Found 0 matching files
HOW: Create urdf/my_robot.urdf.xacro or use urdf_file:=/path launch argument
일반적인 오류 범주:
- 파일 발견 실패 (누락, 여러 개, 잘못된 확장자)
- 검증 실패 (schema, 파일 간 불일치)
- Runtime 실패 (DOF 불일치, joint 이름 불일치)
자동 생성 동작
Trigger 조건
누락된 config 파일은 실행 중에 자동 생성을 trigger합니다.
로그 출력:
[plem_launch.py] INFO: SRDF not found - MoveIt will not be started
[plem_launch.py] INFO: Auto-generating kinematics.yaml (KDL solver)
SRDF는 자동 생성되지 않습니다. SRDF가 없으면 MoveIt이 비활성화되고 ros2_control만 활성화됩니다.
생성된 파일 위치
자동 생성된 파일은 임시 (package directory에 기록되지 않음)입니다.
위치: /tmp/wim_launch_<timestamp>/
근거: 사용자 package 수정 방지, version 관리 가능
영구 보존
자동 생성된 파일을 영구 보존하려면:
- 파일 생성을 위해 한 번 실행
/tmp/wim_launch_<timestamp>/에서 packageconfig/로 복사- Version 관리에 commit
- 필요에 따라 customize
확장 지점
커스텀 Hardware Interface
hardware/HardwareInterface를 커스텀 plugin으로 교체:
<hardware>
<plugin>my_package/MyHardwareInterface</plugin>
</hardware>
요구사항: 커스텀 plugin은 hardware_interface::SystemInterface를 구현해야 합니다.
커스텀 Kinematics Solver
kinematics.yaml에서 override:
arm:
kinematics_solver: trac_ik_kinematics_plugin/TRAC_IKKinematicsPlugin
# ...
요구사항: Solver plugin이 설치되고 로드 가능해야 합니다.
하위 호환성
Legacy robot_type 인자
ros2 launch plem_bringup plem_launch.py robot_type:=indy7_v2
동작: 내장 description package(indy7_v2_description)로 해석됩니다.
내장 로봇: indy7_v2, indy12_v2, indyrp2, indyrp2_v2
마이그레이션 경로: 외부 description package 생성, description_package:= 인자 사용
구현 노트
DOF 감지
DOF는 runtime에 URDF joint 개수에서 감지됩니다.
DOF=6, 7. 6-DOF 또는 7-DOF URDF 사용 시 IPC 호환성이 보장됩니다.
IPC 호환성
RT driver는 IPC memory layout을 위해 compile-time DOF를 사용합니다.
현재 제약: IPC DOF가 URDF DOF와 일치해야 합니다.
DOF=6, 7. 8-DOF 이상의 로봇은 RT driver의 커스텀 빌드가 필요합니다.
향후: URDF DOF 기반 동적 IPC 크기 조정 지원 예정
참조
- 로봇 통합: Robot Integration Guide
- 빠른 시작: Quickstart