고정 프레임 추가
저작권: 쿼드(QUAD) 드론연구소 https://smartstore.naver.com/maponarooo / Updated : 2024-10-11
TF2 트리
tf2는 프레임의 트리 구조를 구축하므로 프레임 구조에서 닫힌 루프를 허용하지 않습니다. 즉, 프레임은 하나의 부모만 가지지만 여러 자식을 가질 수 있습니다. 현재 tf2 트리에는 세 개의 프레임, world
, turtle1
및 turtle2
가 있습니다. 두 개의 turtle 프레임은 world
프레임의 자식입니다. tf2에 새 프레임을 추가하려면 기존 프레임 세 개 중 하나가 부모 프레임이어야 하며 새 프레임이 자식 프레임이 됩니다.

1. 고정 프레임 브로드캐스터 작성
거북이 예제에서 우리는 새로운 carrot1
프레임을 추가할 것입니다. 이것은 turtle1
의 자식이 될 것입니다. 이 프레임은 두 번째 거북이의 목표 역할을 할 것입니다.
먼저 소스 파일을 만들어 보겠습니다. 이전 튜토리얼에서 만든 learning_tf2_py
패키지로 이동합니다. src/learning_tf2_py/learning_tf2_py
디렉토리 내부에서 다음 명령을 입력하여 고정 프레임 브로드캐스터 코드를 다운로드합니다.
wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py
이제 fixed_frame_tf2_broadcaster.py
파일을 엽니다.
from geometry_msgs.msg import TransformStamped
import rclpy
from rclpy.node import Node
from tf2_ros import TransformBroadcaster
class FixedFrameBroadcaster(Node):
def __init__(self):
super().__init__('fixed_frame_tf2_broadcaster')
self.tf_broadcaster = TransformBroadcaster(self)
self.timer = self.create_timer(0.1, self.broadcast_timer_callback)
def broadcast_timer_callback(self):
t = TransformStamped()
t.header.stamp = self.get_clock().now().to_msg()
t.header.frame_id = 'turtle1'
t.child_frame_id = 'carrot1'
t.transform.translation.x = 0.0
t.transform.translation.y = 2.0
t.transform.translation.z = 0.0
t.transform.rotation.x = 0.0
t.transform.rotation.y = 0.0
t.transform.rotation.z = 0.0
t.transform.rotation.w = 1.0
self.tf_broadcaster.sendTransform(t)
def main():
rclpy.init()
node = FixedFrameBroadcaster()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
rclpy.shutdown()
이 코드는 tf2 브로드캐스터 튜토리얼 예제와 매우 유사하며 유일한 차이점은 여기의 변환이 시간이 지나도 바뀌지 않는다는 것입니다.
1.1 코드 검토
이 코드의 핵심 줄을 살펴보겠습니다. 여기서 부모에서 turtle1
새 자식으로 새 변환 carrot1
을 만듭니다. carrot1
프레임은 turtle1
프레임을 기준으로 y축으로 2미터 오프셋됩니다.
t = TransformStamped()
t.header.stamp = self.get_clock().now().to_msg()
t.header.frame_id = 'turtle1'
t.child_frame_id = 'carrot1'
t.transform.translation.x = 0.0
t.transform.translation.y = 2.0
t.transform.translation.z = 0.0
1.2 진입점 추가
명령이 노드를 실행하도록 하려면 ( 디렉토리에 있는)에 진입점을 추가해야 합니다.ros2 runsetup.pysrc/learning_tf2_py
다음 줄을 'console_scripts':
괄호 안에 추가하세요.
'fixed_frame_tf2_broadcaster = learning_tf2_py.fixed_frame_tf2_broadcaster:main',
1.3 launch 파일
이제 이 예제에 대한 실행 파일을 만들어 보겠습니다. 텍스트 편집기를 사용하여 src/learning_tf2_py/launch
디렉토리에 새 turtle_tf2_fixed_frame_demo.launch.py
파일을 만들고 다음 줄을 추가합니다.
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
def generate_launch_description():
demo_nodes = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('learning_tf2_py'), 'launch'),
'/turtle_tf2_demo.launch.py']),
)
return LaunchDescription([
demo_nodes,
Node(
package='learning_tf2_py',
executable='fixed_frame_tf2_broadcaster',
name='fixed_broadcaster',
),
])
이 실행 파일은 필요한 패키지를 가져온 다음 이전 튜토리얼의 실행 파일에서 만든 노드를 저장할 demo_nodes
변수를 만듭니다.
코드의 마지막 부분은 fixed_frame_tf2_broadcaster
노드를 사용하여 터틀심 세계에 고정된 carrot1
프레임을 추가합니다.
Node(
package='learning_tf2_py',
executable='fixed_frame_tf2_broadcaster',
name='fixed_broadcaster',
),
1.4 빌드
작업 공간 루트에서 rosdep
실행하여 누락된 종속성을 확인합니다.
cd ~/ros2_ws
rosdep install -i --from-path src --rosdistro humble -y
새 터미널을 열고 작업 공간 루트로 이동한 후 설치 파일을 소싱합니다.
. install/setup.bash
1.5 실행
이제 거북이 방송자 데모를 시작할 수 있습니다.
ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo.launch.py
변형 트리에 새로운 carrot1
프레임이 나타난 것을 확인할 수 있습니다 .

첫 번째 거북이를 운전해 보면, 새로운 프레임을 추가했음에도 불구하고 이전 튜토리얼에서 동작이 바뀌지 않았다는 것을 알 수 있습니다. 그 이유는 추가 프레임을 추가해도 다른 프레임에 영향을 미치지 않고 리스너는 여전히 이전에 정의된 프레임을 사용하고 있기 때문입니다.
따라서 두 번째 거북이가 첫 번째 거북이 대신 당근을 따르게 하려면 target_frame
의 값을 변경해야 합니다 . 이는 두 가지 방법으로 수행할 수 있습니다. 한 가지 방법은 콘솔에서 직접 실행 파일에 target_frame
인수를 전달하는 것입니다.
ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo.launch.py target_frame:=carrot1
두 번째 방법은 실행 파일을 업데이트하는 것입니다. 그러려면 파일을 열고 'target_frame':'carrot1'
인수를 launch_arguments를
통해 매개변수를 turtle_tf2_fixed_frame_demo.launch.py에
추가합니다.
def generate_launch_description():
demo_nodes = IncludeLaunchDescription(
...,
launch_arguments={'target_frame': 'carrot1'}.items(),
)
이제 패키지를 다시 빌드하고, 를 재시작하면 turtle_tf2_fixed_frame_demo.launch.py
첫 번째 거북이 대신 당근 다음에 두 번째 거북이가 나타나는 것을 볼 수 있습니다!
Last updated