본문으로 건너뛰기

Launch 시스템

개요

PLEM은 RT(실시간) 스레드 분리 아키텍처를 사용합니다.

  1. RT 드라이버 - 단일 프로세스 내 RT 스레드들 (EtherCAT 1kHz, Controller, IPC Bridge)
  2. ROS2 노드들 - 여러 독립 노드가 composable하게 실행 (ros2_control, MoveIt, bridge 등)

RT 스레드와 ROS2 노드 간 통신은 POSIX 공유 메모리를 통해 이루어집니다.

런치 파일 위치: 모든 런치 파일은 plem_bringup/launch/ 디렉토리에 위치하며, 모듈식(composable) 구조로 설계되어 개별 실행 및 조합이 가능합니다.

Composable Launch 구조

런치 파일역할의존성
plem_launch.py메인 통합 런치 - 모든 컴포넌트 자동 조합모든 하위 런치 포함
rt_driver.launch.pyRT 드라이버 (내장/사용자 공용)없음 (독립 실행 가능)
ros2_control.launch.pyROS2 Control 스택 (하드웨어 인터페이스 + 컨트롤러)RT 드라이버 필요
moveit.launch.pyMoveIt 모션 플래너ROS2 Control 필요
moveit_only_launch.py단일 로봇 MoveIt + ROS2 Control (namespace 격리)RT 드라이버 필요
multi_robot.launch.pyN대 로봇 동시 실행 (각각 독립 namespace)RT 드라이버 필요

설계 원칙:

  • 각 런치 파일은 독립적으로 실행 가능 (의존성 충족 시)
  • plem_launch.py는 하위 런치들을 IncludeLaunchDescription으로 조합
  • 개발 시 개별 컴포넌트만 재시작 가능

시스템 실행

전체 시스템 실행

# 프로덕션 런치 (RT 드라이버 + ROS2 스택 + Python bridge 자동 시작)
ros2 launch plem_bringup plem_launch.py

# 로봇 ID 지정 (namespace 격리)
ros2 launch plem_bringup plem_launch.py robot_id:=indy

# 기록 활성화
ros2 launch plem_bringup plem_launch.py record:=true

# 외부 description 패키지 사용
ros2 launch plem_bringup plem_launch.py description_package:=ur_description

# 내장 로봇 타입 선택 (wim_description 사용 시)
ros2 launch plem_bringup plem_launch.py robot_type:=indy7

주요 런치 인수

인수타입기본값설명
robot_idstringindy로봇 인스턴스 ID (ROS2 namespace, IPC prefix)
description_packagestringwim_description로봇 URDF/xacro 패키지 이름
robot_typestringindy7_v2내장 로봇 타입 (wim_description일 때만)
eth_interfacestringeth0EtherCAT 네트워크 인터페이스
master_indexint0EtherCAT 마스터 인덱스 (0=eth0, 1=eth1 등)
recordbooltruerosbag2 기록 활성화
bag_dirstring~/bags/rt_monitoringrosbag2 저장 디렉토리
retention_minutesint60bag 파일 보관 기간 (분)
disk_thresholdint70디스크 정리 임계값 (%)
urdf_filestring''URDF 경로 오버라이드 (외부 패키지용)
srdf_filestring''SRDF 경로 오버라이드 (외부 패키지용)
robot_namestring''로봇 이름 오버라이드 (외부 패키지용)
외부 description 패키지 사용

패키지는 convention 기반 구조를 따라야 합니다 (상세: Description Protocol 참조). config/, urdf/, meshes/ 디렉토리 구조 필수이며, 자동 검증 및 fallback을 지원합니다.

개별 컴포넌트 실행 (개발용)

# 터미널 1: RT 드라이버만 (내장 드라이버)
ros2 launch plem_bringup rt_driver.launch.py

# 터미널 1: RT 드라이버만 (사용자 정의 드라이버)
ros2 launch plem_bringup rt_driver.launch.py rt_package:=my_robot rt_executable:=my_robot_node

# 터미널 2: ROS2 Control만 (2초 대기 후)
ros2 launch plem_bringup ros2_control.launch.py

# 터미널 3: MoveIt만 (추가 4초 대기 후)
ros2 launch plem_bringup moveit.launch.py

rt_driver.launch.py의 추가 인수:

인수기본값설명
rt_packagebootstrapRT 드라이버 실행 파일이 포함된 패키지
rt_executablebootstrap_node실행 파일 이름
robot_idindyIPC namespace용 로봇 ID
eth_interfaceeth0EtherCAT 네트워크 인터페이스
master_index0EtherCAT 마스터 인덱스
고급 파라미터

rt_priority(기본 98), cycle_time_us(기본 1000) 등 고급 파라미터도 지원됩니다. 전체 목록은 ros2 launch plem_bringup rt_driver.launch.py --show-args 명령으로 확인하세요.

중요:

  • RT 드라이버가 공유 메모리를 생성하므로 반드시 먼저 시작해야 합니다.
  • plem_launch.py는 위 컴포넌트들을 자동으로 순차 실행하는 composable launch입니다.
  • Python bridge (plem_ai_server)는 plem_launch.py에 통합되어 자동 시작됩니다.

다중 로봇 실행

PLEM은 namespace 격리를 통해 여러 로봇을 동시에 제어합니다.

다중 로봇 통합 런치:

# 기본 설정
ros2 launch plem_bringup multi_robot.launch.py

# 커스텀 인터페이스 지정
ros2 launch plem_bringup multi_robot.launch.py \
interface_a:=eth0 interface_b:=eth1

단일 로봇 MoveIt 런치 (namespace 격리):

# name 파라미터로 모든 노드를 /{name}/ namespace에 배치
ros2 launch plem_bringup moveit_only_launch.py name:=arm_left
런치 파일별 파라미터 이름
  • plem_launch.py: robot_id 파라미터 사용
  • moveit_only_launch.py: name 파라미터 사용
  • multi_robot.launch.py: robots 파라미터 (comma-separated)

namespace 구조:

리소스단일 로봇다중 로봇 (arm_left)
토픽/indy/joint_states/arm_left/joint_states
액션/indy/wim_rt_driver/set_mode/arm_left/wim_rt_driver/set_mode
IPC/indy_joint_actual_values/arm_left_joint_actual_values

Python Bridge (plem_ai_server)

plem_ai_server는 WebSocket/UDP를 통해 외부 애플리케이션(Android 앱 등)과 통신하는 Python bridge입니다.

주요 기능:

  • WebSocket을 통한 로봇 상태 스트리밍 및 명령 수신
  • UDP를 통한 로봇 자동 발견
  • 연결 끊김 시 자동 브레이크 잠금 (안전 기능)
  • RESET_ERROR WebSocket 메시지로 에러 초기화
  • PLEM_ROBOT_ID 환경 변수로 namespace 설정 (plem_launch.py에서 robot_id 인수로 자동 전달)

plem_launch.py에 통합: bridge는 별도 런치 파일 없이 메인 런치에서 자동 시작됩니다.

RT 드라이버

역할

  • EtherCAT 통신 (1kHz)
  • 토크 계산 (PID + 동역학)
  • 안전 모니터링
  • 공유 메모리 소유자 (생성 및 쓰기)

실행 방식

시나리오RT 드라이버실행 방법
지원 로봇 (Description Package만)PLEM 내장 RT 드라이버ros2 launch plem_bringup plem_launch.py 또는 scaffold bringup.launch.py
새 제조사 로봇 (C++ Extension)create_robot으로 생성한 사용자 애플리케이션ros2 launch <패키지명> bringup.launch.py (상세: 로봇 통합)

상태 확인

# RT 드라이버 생존 확인 (1kHz 토픽 발행 여부)
ros2 topic hz /rt_raw

# 루프 지터 모니터링
ros2 topic echo /rt_raw --field loop_jitter_us

ROS2 노드들

주요 노드

노드역할런치 파일패키지위치
(RT 드라이버)RT EtherCAT 드라이버 (1kHz)rt_driver.launch.py 또는 사용자 애플리케이션--
ros2_control_node하드웨어 인터페이스, 컨트롤러 관리ros2_control.launch.pycontroller_managerROS2 Control 표준
robot_state_publisherURDF 기반 TF 발행 (500Hz)ros2_control.launch.pyrobot_state_publisherROS2 표준
joint_trajectory_controller궤적 실행 액션 서버 (500Hz)ros2_control.launch.pyjoint_trajectory_controllerROS2 Control 표준
mode_control_action_server모드 제어 액션 서버ros2_control.launch.pyPLEM 런타임자동 시작
rt_monitoring_publisherRT 메트릭 ROS2 발행 (10Hz)ros2_control.launch.pyPLEM 런타임자동 시작
move_groupMoveIt 모션 계획moveit.launch.pyMoveIt2 표준자동 시작
plan_trajectory_action_server모션 계획 액션 서버moveit.launch.pyPLEM 런타임자동 시작
plem_ai_serverPython WebSocket/UDP 브리지plem_launch.pyPLEM 런타임자동 시작
런치 파일 위치

모든 런치 파일은 plem_bringup/launch/ 디렉토리에 위치합니다.

실행 중인 노드 확인

# 모든 ROS2 노드 목록
ros2 node list

# 컨트롤러 상태
ros2 control list_controllers

# 하드웨어 인터페이스 상태
ros2 control list_hardware_interfaces

IPC 통신

RT 드라이버와 ROS2 프로세스는 POSIX 공유 메모리로 통신합니다. 사용자가 IPC 채널을 직접 다룰 필요는 없으며, ROS2 토픽(/joint_states, /rt_raw)을 통해 데이터에 접근합니다.

다중 로봇 지원

robot_id가 설정된 경우 IPC 경로에 자동으로 prefix가 적용됩니다.

공유 메모리 정리 (트러블슈팅)

# 공유 메모리 영역 확인 (robot_id에 따라 접두사가 다름)
ls -lh /dev/shm/*joint_actual_values /dev/shm/*joint_target_values /dev/shm/*control_* 2>/dev/null

# 공유 메모리 정리 (RT 드라이버 종료 후)
# 기본(robot_id=indy): /dev/shm/indy_joint_actual_values 등
sudo rm -f /dev/shm/indy_* /dev/shm/joint_* 2>/dev/null

ROS2 토픽

모니터링 토픽

토픽주기내용
/joint_states500Hz조인트 위치, 속도, 노력
/rt_raw1kHzRT 루프 지터, 실행 시간, 타이밍 메트릭
/rt_events이벤트모드 변경, 폴트, 상태 전이
/rt_monitor_stats10Hz큐 통계, 오버플로 카운트
/tf500Hz로봇 기구학 트리
다중 로봇 namespace

모든 토픽에 /{robot_id}/ namespace prefix가 적용됩니다. 예: /{robot_id}/joint_states, /{robot_id}/rt_raw.

토픽 모니터링

# 조인트 상태
ros2 topic echo /joint_states

# RT 지터
ros2 topic echo /rt_raw --field loop_jitter_us

# 모드 변경 이벤트
ros2 topic echo /rt_events

# 토픽 주파수 확인
ros2 topic hz /joint_states

시스템 종료

긴급 종료

긴급 종료 절차

로봇 동작 중 비상 상황에서는 다음 절차를 따르세요.

# 1. 권장: launch 실행 터미널에서 Ctrl+C (SIGINT → 정상 종료)
# 2. 강제 종료가 필요한 경우:
sudo pkill -f plem_launch # launch 프로세스 종료
sudo pkill -f bootstrap_node # RT 드라이버 종료 (내장 드라이버)

# 공유 메모리 정리
sudo rm -f /dev/shm/indy_* /dev/shm/joint_* 2>/dev/null

트러블슈팅

RT 드라이버 크래시

증상:

  • EtherCAT 통신 중지
  • 서보가 SAFE-OP 진입 (브레이크 체결)
  • ROS2 노드가 IPC 읽기 실패

복구:

# 전체 시스템 재시작
ros2 launch plem_bringup plem_launch.py

ROS2 노드 크래시

증상:

  • RT 드라이버 계속 실행
  • IPC 쓰기 성공하지만 reader 없음
  • 100ms 후 보호 정지 (명령 신선도 타임아웃)

복구:

# ROS2 노드만 재시작 (RT 드라이버 유지)
ros2 launch plem_bringup ros2_control.launch.py
# 기존 공유 메모리에 자동 재연결

EtherCAT 통신 손실

진단:

# EtherCAT 상태
sudo ethercat slaves
sudo ethercat master

일반적인 원인:

  • 케이블 연결 해제
  • 서보 전원 손실
  • 네트워크 인터페이스 설정 문제

공유 메모리 손상

증상:

  • 조인트 상태에 NaN/inf 값
  • IPC 읽기 실패 지속

복구:

# 프로세스 종료 (Ctrl+C 권장, 또는 아래 명령)
sudo pkill -f plem_launch
sudo pkill -f bootstrap_node

# 공유 메모리 정리 후 재시작
sudo rm -f /dev/shm/indy_* /dev/shm/joint_* 2>/dev/null
ros2 launch plem_bringup plem_launch.py

요약

핵심 요점:

  1. RT 스레드 분리: RT 드라이버 내 RT 스레드 (1kHz 제어) + 여러 ROS2 노드 (계획/인터페이스)
  2. 통신: POSIX 공유 메모리를 통한 RT↔ROS2 데이터 교환
  3. 실행: ros2 launch plem_bringup plem_launch.py (자동 시퀀싱)
  4. Composable Launch 구조:
    • plem_launch.py: 메인 통합 (모든 컴포넌트 + Python bridge)
    • rt_driver.launch.py: RT 드라이버만
    • ros2_control.launch.py: ROS2 Control 스택
    • moveit.launch.py: MoveIt 플래너
    • moveit_only_launch.py: 단일 로봇 MoveIt (namespace 격리)
    • multi_robot.launch.py: 다중 로봇 동시 실행
  5. 모듈식 설계: 각 컴포넌트를 독립적으로 실행 및 재시작 가능
  6. Python Bridge: plem_ai_server가 메인 런치에 통합되어 WebSocket/UDP 통신 제공
  7. 다중 로봇 지원: robot_id 파라미터로 namespace 및 IPC 경로 격리
  8. 모니터링: /{robot_id}/rt_raw (지터), /{robot_id}/joint_states (상태), /{robot_id}/rt_events (이벤트)
  9. 복구: ROS2 노드는 RT 드라이버를 유지하면서 독립적으로 재시작 가능
  10. 런치 인수:
  • robot_id: 로봇 인스턴스 ID (namespace, IPC prefix)
  • description_package: 외부 URDF/xacro 패키지 지정
  • robot_type: 내장 로봇 타입 선택 (wim_description일 때만)

다음 단계: