로봇/ROS

ROS2 Transformation System (TF2)

with-RL 2023. 7. 19. 16:28

이 포스트는 로봇의 위치와 방향을 표현하고 계산하는 데 사용되는 ROS2의 transformation에 대한 내용입니다.

이 포스트는 다음 영상의 내용을 기반으로 개발하고자 하는 로봇에 적합하게 수정했습니다.

이 포스트는 다음 과정을 완료한 후에 참고하시길 바랍니다.

1. ChatGPT가 응답한 TF2

  • 아래 내용은 ChatGPT에게 물어본 질문에 대한 답변입니다.
Question: ROS2의 tf2에 대해서 설명해줘

Answer: ROS2의 tf2는 Transformation Library for ROS 2의 약어로, 로봇의 위치와 방향 변환 정보를 관리하기 위한 핵심 라이브러리입니다. tf2는 ROS2에서 좌표 프레임 변환과 관련된 작업을 단순화하고, 로봇 시스템의 여러 구성 요소 간의 좌표계 변환을 추적하는 데 사용됩니다.

tf2는 변환 정보를 관리하기 위해 트리 구조를 사용합니다. 이 트리 구조는 프레임(frame)이라고 불리는 좌표계를 포함하며, 각 프레임은 로봇 시스템 내의 특정 위치나 부분을 나타냅니다. 프레임 간의 변환 정보는 로봇 시스템에서 발생하는 모션과 관련된 변환을 나타냅니다.

tf2의 핵심 구성 요소는 다음과 같습니다:

Broadcaster(브로드캐스터): tf2의 브로드캐스터는 변환 정보를 발행(publish)합니다. 로봇 시스템의 다양한 요소(예: 로봇 팔, 센서 등)의 변환 정보를 브로드캐스터를 통해 전달할 수 있습니다.

Listener(리스너): tf2의 리스너는 변환 정보를 구독(subscribe)합니다. 리스너는 원하는 변환 정보를 구독하여 로봇 시스템의 다른 요소들 간의 변환 관계를 추적하고 사용할 수 있습니다.

Transformer(트랜스포머): tf2의 트랜스포머는 프레임 간의 변환 관계를 계산하고 변환을 수행하는 기능을 제공합니다. 트랜스포머는 변환 트리를 통해 로봇 시스템의 다른 프레임 간의 상대적인 위치와 방향을 추적하고, 좌표계 간의 변환을 수행합니다.

tf2를 사용하면 로봇 시스템 내의 다양한 구성 요소들 간의 변환 관계를 쉽게 추적하고, 로봇의 위치와 방향을 변환하고, 센서 데이터를 변환할 수 있습니다. 또한, tf2는 시각화 도구와 통합하여 로봇의 변환 정보를 시각적으로 확인하고 디버깅할 수 있습니다.

2. 로봇 좌표계에서 고려할 점

  • 3차원 공간에서 물체의 위치와 자세를 표현하기 위해서는 $(x, y, z, \theta_x, \theta_y, \theta_z)$ 6개의 값으로 표현할 수 있습니다.
    $x$: x 축 방향으로 이동 거리입니다.
    $y$: y 축 방향으로 이동 거리입니다.
    $z$: z 축 방향으로 이동 거리입니다.
    $\theta_x$: x 축을 기준으로 반 시계 방향으로 회전한 각도입니다.
    $\theta_y$: y 축을 기준으로 반 시계 방향으로 회전한 각도입니다.
    $\theta_z$: z 축을 기준으로 반 시계 방향으로 회전한 각도입니다.
  • 2차원 공간에서는 물체의 위치와 자세를 표현하기 위해서는 $(x, y, \theta)$ 3개의 값으로 표현할 수 있습니다.
    $x$: x축 방향으로 이동 거리입니다.
    $y$: y축 방향으로 이동 거리입니다.
    $\theta$: 반 시계 방향으로 회전한 각도입니다.
  • 3차원 공간에서 물체의 위치와 자세를 표현하는 것은 매우 복잡한 내용이므로 이번 포스팅에서는 2차원 공간에서 물체의 위치와 자세를 표현하는 것으로 설명하겠습니다.
  • 아래 그림과 같은 임의로 지정한 원점 $C_0$에서 로봇이 출발해서 $C_1$으로 이동하도록 명령하고 다시 $C_1$에서 로봇이 출발해서 $C_2$로 이동하는 과정은 아래 그림과 같습니다.

  • $C_0$에서 $C_1$으로 이동하기 위해서는 로봇에게 $(x_w^{c_1}), y_w^{c_1}), \theta_w^{c_1})$으로 이동하라고 명령하면 됩니다. 이유는 로봇이 사용하는 좌표와 우리가 사용하는 좌표 (world)가 같이 때문입니다.
  • 로봇이 $C_1$ 위치에 있을 때 로봇을 $C_2$로 이동시키기 위해서는 어떤 위치로 이동하라고 명령을 주면 될까요? 로봇이 위치와 자세가 변경되었기 때문에 우리가 사용하는 좌표 (world)와 로봇이 사용하는 좌표는 다르기 때문에 $(x_w^{c_2}), y_w^{c_2}), \theta_w^{c_2})$로 이동하라고 하면 로봇은 엉뚱한 곳으로 이동할 것입니다. 로봇이 바라보는 좌표를 기준으로 $C_2$의 위치를 변환해서 로봇에게 알려줘야 로봇이 $C_2$ 위치로 이동할 것입니다.
  • 이와 같이 좌표 변환을 쉽게 해주는 라이브러리가 TF2입니다.
  • 아래 그림과 같이 $(x_1, y_1)$ 좌표를 $\theta$ 만큼 회전한 점의 좌표를 구하는 회전 변환 행렬은 다음과 같습니다.

$$\begin{pmatrix} x_2 \\ y_2 \end{pmatrix} = \begin{pmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{pmatrix} \begin{pmatrix} x_1 \\ y_1 \end{pmatrix}$$

3. static_transform_publisher를 이용한 TF2 기능 확인

  • 서로 연결된 두 개의 로봇 중 한 개를 회전했을 때 다른 로봇의 위치에 계산에 대한 기능을 확인해 보는 과정입니다.
  • 첫 번째 터미널에서 아래 명령을 실행해서 world frame과 robot_1을 생성합니다.
    2 1 0: x, y, z 좌표로 x=2, y=1, z=0이라는 의미입니다.
    0.785 0 0: 은 yaw, pitch, roll 값으로 반시계 방향으로 45° $\pi/4$ 만큼 회전하라는 의미입니다.
$ ros2 run tf2_ros static_transform_publisher 2 1 0 0.785 0 0 world robot_1

  • 두 번째 터미널에서 아래 명령을 실행해서 Rviz를 실행합니다.
$ rviz2
  • 실행된 Rviz 창에서 ‘Fixed Frame’에서 ‘world’를 선택합니다.

  • ‘Add’ 버튼을 눌러서 실행되는 팝업창에서 ‘TF’를 선택하고 ‘Ok’ 버튼을 누릅니다.

  • TF의 ‘Show Names’를 선택하면 우측에 ‘world’를 기준으로 ‘robot_1’이 $(x, y, \theta) = (2, 1, \pi/4)$ 위치에 나타난 것을 확인할 수 있습니다.

  • 세 번째 터미널에서 아래 명령을 실행해서 robot_1의 하위에 robot_2 생성합니다.
    1 0 0: x, y, z 좌표로 x=1, y=0, z=0이라는 의미입니다.
    0 0 0: 은 yaw, pitch, roll 값으로 회전이 없다는 의미입니다.
$ ros2 run tf2_ros static_transform_publisher 1 0 0 0 0 0 robot_1 robot_2

  • Rviz에서 확인하면 ‘robot_1’의 좌표를 기준으로 ‘robot_2’가 $(x, y, \theta) = (1, 0, 0)$ 위치에 나타난 것을 확인할 수 있습니다.

  • 네 번째 터미널에서 아래 명령을 실행해서 world 좌표를 기준으로 robot_1의 위치를 변경합니다.
    1 0 0: x, y, z 좌표로 x=1, y=0, z=0이라는 의미입니다.
    1.57 0 0: 은 yaw, pitch, roll 값으로 반시계 방향으로 90° $\pi/2$ 만큼 회전하라는 의미입니다.
$ ros2 run tf2_ros static_transform_publisher 2 1 0 1.57 0 0 world robot_1

  • Rviz에서 확인하면 ‘world’를 기준으로 ‘robot_1’이 $(x, y, \theta) = (2, 1, \pi/2)$ 위치로 이동하고 이에 따라서 robot_2도 이동한 것을 확인할 수 있습니다.

  • 다섯 번째 터미널에서 아래 명령을 실행해서 rqt_graph를 실행합니다. 아래 그림과 같이 3개의 ‘static_transform_publisher’와 1개의 ‘tf_listener’를 확인할 수 있습니다.
$ # wget https://gist.githubusercontent.com/joshnewans/69cb8a049fb4606b0a6bdecd6933164e/raw/0851acb1a78605ce658292e734c83bcb73b515a6/example_robot.urdf.xacro
$ rqt_graph

4. Moving Robot 기능 확인

  • Josh Newans님이 제공하는 robot urdf를 이용해서 TF기능을 확인해 보는 과정입니다. 우선 이전 과정에서 실행했던 모든 프로그램을 종료하고 PowerShell을 모두 종료합니다.
  • 첫 번째 터미널에서 아래 명령을 실행해서 ‘example_robot.urdf.xacro’ 파일을 다운로드합니다.
$ cd
$ wget https://gist.githubusercontent.com/joshnewans/69cb8a049fb4606b0a6bdecd6933164e/raw/0851acb1a78605ce658292e734c83bcb73b515a6/example_robot.urdf.xacro
  • 첫 번째 터미널에서 아래 명령을 실행해서 ‘robot_state_publisher’를 실행합니다. 이때 robot에 대한 정보인 robot_description은 다운로드한 ‘example_robot.urdf.xacro’ 파일을 사용합니다.
$ ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$( xacro ~/example_robot.urdf.xacro )"
  • 두 번째 터미널에서 아래 명령을 실행해서 ‘joint_state_publisher_gui’를 실행합니다. ‘joint_state_publisher_gui’는 로봇의 각 joint를 조절해 볼 수 있는 기능을 제공합니다. 아래 그림과 같이 4개의 joint를 조절할 수 있는 창이 실행됩니다.
$ ros2 run joint_state_publisher_gui joint_state_publisher_gui

  • 세 번째 터미널에서 아래 명령을 실행해서 Rviz를 실행합니다.
$ rviz2
  • Rviz 창에서 ‘Fixed Frame’을 ‘world’를 선택하고 TF를 추가합니다.

  • TF에서 ‘Show Names’를 선택하면 아래와 같이 로봇의 TF 정보를 확인할 수 있습니다.

  • ‘joint_state_publisher_gui’의 항목을 조절하면 Rviz에 보이는 로봇의 joint가 조절되면서 로봇이 동작하는 것을 확인할 수 있습니다.

  • Rviz에 ‘Robot Model’을 추가합니다.

  • Rviz에서 RobotModel에 ‘Description Topic’을 ‘/robot_description’으로 선택하면 아래 그림과 같이 로봇 형상을 확인할 수 있습니다.