659.96 robot_state_publisher를 이용한 TF 자동 발행
1. 개요
robot_state_publisher는 URDF로 정의된 로봇 모델을 기반으로 TF2 변환을 자동으로 발행하는 ROS2 노드이다. 이 노드는 URDF의 고정 관절(fixed joint)에 대한 정적 변환을 /tf_static으로 발행하고, 가동 관절(revolute, continuous, prismatic)에 대한 동적 변환을 /tf로 발행한다. robot_state_publisher는 /joint_states 토픽을 구독하여 관절 상태 데이터를 수신하며, 이를 URDF의 운동학 모델과 결합하여 각 링크의 포즈를 계산한다.
2. 동작 원리
2.1 입력과 출력
| 입력 | 출력 |
|---|---|
robot_description 매개변수 (URDF/Xacro 문자열) | /tf 토픽 (동적 변환) |
/joint_states 토픽 (sensor_msgs/msg/JointState) | /tf_static 토픽 (정적 변환) |
/robot_description 토픽 (URDF 문자열 재발행) |
2.2 처리 흐름
- 초기화:
robot_description매개변수에서 URDF를 파싱하여 운동학 트리를 구성한다. - 정적 변환 발행: 모든
fixed관절의 변환을/tf_static으로 발행한다. 이 변환은 한 번만 발행되며 TF2 버퍼에 영구적으로 유지된다. - 관절 상태 수신:
/joint_states토픽을 구독하여 각 가동 관절의 현재 위치를 수신한다. - 순운동학 계산: 수신된 관절 위치를 URDF의 운동학 모델에 적용하여 각 링크의 포즈를 계산한다.
- 동적 변환 발행: 계산된 포즈를
/tf토픽으로 발행한다.
3. 런치 파일에서의 사용
3.1 기본 사용법
from launch import LaunchDescription
from launch_ros.actions import Node
import xacro
import os
def generate_launch_description():
# URDF 파일 로드
urdf_file = os.path.join(
get_package_share_directory('my_robot'),
'urdf', 'my_robot.urdf.xacro')
robot_description = xacro.process_file(urdf_file).toxml()
return LaunchDescription([
Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher',
parameters=[{
'robot_description': robot_description,
'publish_frequency': 50.0,
'use_tf_static': True,
'ignore_timestamp': False,
}],
output='screen',
),
])
3.2 주요 매개변수
| 매개변수 | 유형 | 기본값 | 설명 |
|---|---|---|---|
robot_description | string | (필수) | URDF 문자열 |
publish_frequency | double | 20.0 | 동적 TF 발행 주파수 (Hz) |
use_tf_static | bool | true | 고정 관절을 /tf_static으로 발행할지 여부 |
ignore_timestamp | bool | false | JointState 메시지의 타임스탬프 무시 여부 |
4. JointState 메시지
4.1 메시지 구조
std_msgs/Header header
builtin_interfaces/Time stamp
string frame_id
string[] name # 관절 이름 배열
float64[] position # 관절 위치 배열 (rad 또는 m)
float64[] velocity # 관절 속도 배열 (rad/s 또는 m/s)
float64[] effort # 관절 힘/토크 배열 (N·m 또는 N)
robot_state_publisher는 name과 position 필드만을 사용하여 TF 변환을 계산한다.
4.2 관절 이름의 일치
JointState 메시지의 name 필드에 포함된 관절 이름은 URDF에서 정의한 관절 이름과 정확히 일치하여야 한다. 불일치 시 해당 관절의 변환이 갱신되지 않는다.
5. 정적 변환과 동적 변환의 분리
5.1 정적 변환 (use_tf_static: true)
고정 관절의 변환을 /tf_static 토픽으로 발행하면 다음과 같은 이점이 있다.
- 네트워크 부하 감소: 정적 변환은 한 번만 발행되므로 주기적 발행에 의한 네트워크 부하가 없다.
- 항상 가용:
/tf_static은 래치(latch) 특성의 QoS를 사용하므로, 나중에 구독하는 노드도 변환을 수신할 수 있다.
5.2 동적 변환
가동 관절의 변환은 /joint_states 갱신 시마다 /tf로 발행된다. 발행 주파수는 publish_frequency 매개변수와 /joint_states 수신 빈도 중 작은 값에 의하여 결정된다.
6. 고정 관절만 있는 경우
센서 프레임만을 정의하는 로봇(예: 고정형 센서 스테이션)이나, 모든 관절이 고정인 경우에도 robot_state_publisher를 사용할 수 있다. 이 경우 /joint_states 토픽이 필요하지 않으며, 정적 변환만 발행된다.
# 고정 관절만 있는 경우 (joint_state_publisher 불필요)
Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'robot_description': robot_description}],
)
7. 검증
7.1 TF2 트리 확인
# 발행되는 프레임 확인
ros2 run tf2_tools view_frames
# 특정 프레임 간 변환 확인
ros2 run tf2_ros tf2_echo base_link laser_link
7.2 URDF 재발행 확인
# robot_description 토픽에서 URDF 확인
ros2 topic echo /robot_description --once
8. 요약
robot_state_publisher는 URDF 기반의 TF2 변환 자동 발행 노드로, 고정 관절의 정적 변환과 가동 관절의 동적 변환을 구분하여 발행한다. /joint_states 토픽에서 관절 상태를 수신하여 순운동학을 계산하고, 결과를 TF2 변환으로 발행함으로써 URDF와 TF2 사이의 자동 연동을 구현한다.
참고 문헌 및 출처
robot_state_publisher패키지, https://github.com/ros/robot_state_publisher (ROS2 Humble 브랜치)- ROS2 공식 문서, “Using Robot State Publisher”, https://docs.ros.org/en/humble/Tutorials/Intermediate/URDF/Using-robot-state-publisher.html (ROS2 Humble Hawksbill)
sensor_msgs/msg/JointStateAPI 문서, https://docs.ros2.org/latest/api/sensor_msgs/msg/JointState.html