인공지능/로봇 시스템 개발

ROS2 Humble + MoveIt2로 Doosan E0509 좌표 시퀀스 이동 만들기 (PyQt5 GUI 포함)

mino28 2026. 2. 23. 14:33

한 줄 요약

ROS2 Humble 환경에서 Doosan E0509 + MoveIt2를 사용해 입력한 목표 좌표들을 순차 이동시키고, /assignment/status 커스텀 메시지로 상태를 통합해 PyQt5 GUI에서 실시간 모니터링/정지까지 구현했다.


1. 요구사항 정리

  • 목표 좌표(x,y,z) 1개 이상 입력
  • ABS/REL 모드 선택
  • vel/acc scaling 반영
  • PyQt5 GUI(코드 UI), 버튼 동작은 별도 스레드
  • 연결 상태 / 동작 상태 / 로그 / joint / EE pose 표시

2. 전체 구성(아키텍처)

  • MoveIt2: /move_action (MoveGroup action)
  • ros2_control: dsr_moveit_controller (FollowJointTrajectory)
  • 내 노드
    • movegroup_sequence: 목표 시퀀스 실행
    • assignment_status_node: 상태 통합 publish
    • assignment_gui: PyQt5 UI


3. 좌표 입력과 ABS/REL 처리

Targets 입력 포맷:

  • "0.35,0.00,0.45;0.30,0.10,0.40"

ABS는 base_link 기준 목표로 사용하고,
REL은 TF로 현재 EE pose를 읽어 offset을 더해 목표를 만든다.


4. MoveIt2 Action으로 이동시키기

핵심은 /move_action에 MoveGroup goal을 보내는 것.

  • 기본 성공률을 위해 position-only constraint를 기본값으로 사용
  • keep_orientation 옵션을 켜면 pos+ori로 1차 시도하고 실패 시 pos-only로 fallback
  • vel/acc scaling을 MotionPlanRequest에 반영


5. 상태관리: /assignment/status 커스텀 메시지

요구사항의 “연결/동작/로그/joint/pose”를 GUI에서 바로 쓰려면 토픽을 분산시키기보다 단일 토픽으로 통합하는 게 편했다.

  • 연결상태: server_is_ready()로 /move_action, follow_joint_trajectory 체크
  • joint: /joint_states
  • EE pose: TF(base_link→link_6)
  • 로그: /assignment/state_event로 이벤트를 받고 recent_logs ring buffer로 유지


6. PyQt5 GUI: 코드 UI + 스레드 분리

  • 좌측: 입력/옵션/RUN/STOP
  • 우측: 상태/조인트/포즈/로그
  • RUN은 QThread에서 subprocess로 실행(ROS spin과 UI freeze 방지)
  • STOP은 /assignment/stop 호출 + SIGINT로 종료


7. 트러블슈팅: CONTROL_FAILED(-4) 해결

가장 큰 삽질 포인트.

  • plan_only=True는 되는데 실행에서 CONTROL_FAILED
  • 원인은 controller action server가 0개(컨트롤러 미활성)
  • spawner로 dsr_moveit_controller 활성화 후 해결

(한 줄 해결 커맨드)

ros2 run controller_manager spawner dsr_moveit_controller --controller-manager /controller_manager
 
 

8. 마무리 / 링크