3.6 ROS 2 JointState 브리지
3.6.1 토픽 계약
이 장의 예제 토픽은 다음과 같다.
| 토픽 | 타입 | 발행자 | 구독자 | 의미 |
|---|---|---|---|---|
/leader/joint_states | sensor_msgs/msg/JointState | Leader 드라이버 | 안전 브리지 | 측정 관절 상태 |
/follower/joint_command | sensor_msgs/msg/JointState | 안전 브리지 | 교육용 드라이버 어댑터 | 제한된 목표 위치 |
/follower/joint_states | sensor_msgs/msg/JointState | Follower 드라이버 | 시각화/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에 적용하는 기본 흐름은 다음과 같다.
/follower/joint_states를 구독한다.- 이름 배열을 USD articulation의 DoF 이름으로 매핑한다.
- radian/degree와 그리퍼 단위를 변환한다.
- 시뮬레이션 시간에 맞춰 최신 상태를 적용한다.
- 측정값을 시각화할 때는 물리 드라이브 목표와 순간 상태 설정의 차이를 구분한다.
센서 기반 디지털 트윈은 “완벽한 동시성”이 아니라 타임스탬프가 있는 두 상태의 정렬 문제다. 네트워크 지연을 숨기기 위해 미래를 추정하면 모니터링 화면은 부드러워지지만 실제 측정과 달라질 수 있으므로 추정 상태를 별도 색상/프레임으로 표시한다.