3.6 ROS 2 JointState 브리지

3.6.1 토픽 계약

이 장의 예제 토픽은 다음과 같다.

토픽타입발행자구독자의미
/leader/joint_statessensor_msgs/msg/JointStateLeader 드라이버안전 브리지측정 관절 상태
/follower/joint_commandsensor_msgs/msg/JointState안전 브리지교육용 드라이버 어댑터제한된 목표 위치
/follower/joint_statessensor_msgs/msg/JointStateFollower 드라이버시각화/Isaac Sim실측 상태

표준 JointState는 상태 표현이다. 실제 제어기에서는 trajectory_msgs/msg/JointTrajectory, control_msgs/action/FollowJointTrajectory, ros2_control command interface 또는 장치 전용 API가 더 적절할 수 있다. 여기서 명령 토픽에 JointState를 쓰는 것은 메시지 정렬과 안전 필터를 학습하기 위한 교육용 계약이며, 생산 시스템의 표준 명령 인터페이스라고 주장하지 않는다.

3.6.2 QoS 선택

관절 상태는 최신 값이 중요하므로 작은 큐 깊이와 best-effort를 고려할 수 있다. 반면 명령 손실이 위험한 시스템은 reliable을 선택하되 지연 증가와 backpressure를 측정한다. 시뮬레이터, DDS 구현, 네트워크에 따라 결과가 다르므로 QoS를 하드코딩된 정답이 아니라 인터페이스 계약으로 문서화한다.

code/ros2_ws/src/so101_training_bridge/는 두 노드를 제공한다.

  • safe_joint_bridge.py: Leader 상태를 이름으로 재정렬하고 위치·속도·timeout을 제한해 교육용 명령 토픽으로 발행
  • joint_state_monitor.cpp: Follower 상태의 관절 누락, 비유한 값, 오래된 타임스탬프를 감시

3.6.3 robot_state_publisher와 TF

robot_state_publisher는 URDF와 joint_states를 사용해 링크 TF를 발행한다. 실물과 시뮬레이터가 같은 TF 트리에 동시에 같은 프레임 이름을 발행하면 충돌하므로 접두사를 둔다.

  • 실물: real/base_link, real/gripper_frame_link
  • 시뮬레이터: sim/base_link, sim/gripper_frame_link

또는 서로 다른 ROS domain/namespace를 사용하고 브리지에서 필요한 토픽만 연결한다. 정적 카메라 외부 파라미터와 동적 관절 TF를 중복 발행하지 않는다.

3.6.4 Isaac Sim 미러링

실물 측정값을 가상 articulation에 적용하는 기본 흐름은 다음과 같다.

  1. /follower/joint_states를 구독한다.
  2. 이름 배열을 USD articulation의 DoF 이름으로 매핑한다.
  3. radian/degree와 그리퍼 단위를 변환한다.
  4. 시뮬레이션 시간에 맞춰 최신 상태를 적용한다.
  5. 측정값을 시각화할 때는 물리 드라이브 목표와 순간 상태 설정의 차이를 구분한다.

센서 기반 디지털 트윈은 “완벽한 동시성”이 아니라 타임스탬프가 있는 두 상태의 정렬 문제다. 네트워크 지연을 숨기기 위해 미래를 추정하면 모니터링 화면은 부드러워지지만 실제 측정과 달라질 수 있으므로 추정 상태를 별도 색상/프레임으로 표시한다.

그림 3-4. ROS 2를 통한 실물-시뮬레이터 상태 동기화

이 장의 예제 코드·설정 파일 (6)

이 장의 자가 점검·가상실습