개발자와 함께하는 ROS2 Humble Action 이해하기, ROS2 명령어-6

IROBOU·2023년 9월 30일
1

인공지능_로봇개발

목록 보기
7/17

ROS2로 개발할 때 topic과 service 만큼 자주 쓰이지 않지만, 특정 기능 을 구현 할 때 사용하면 깔끔하게 구현을 도와주는 개념이 있다.
바로 action이라는 개념인데, ROS2 Navigation stack에서도 자주 사용되는 개념이므로 나중에 직접 구현하여 사용하지 않더라도, 한번 어떤거지 배워 놓으면 도움 된다.

그렇다면 Let's go!


목표
ROS2 action 에 대해

예상 소요시간
15분


배경지식

topic과 service처럼 action은 ROS2에서 사용되는 통신 방법중 하나다.
action은 goal(목표로 하는 행위), feedback(행위가 이루어지는 동안 피드백), result(결과)로 구성돼있다.

하단에 첨부된 그림과 같이 action은 service(goal에 대한 Goal Service, result에 대한 Result Service)와 topic(feedback을 주는 Feedback Topic)을 갖추고 있다. 그렇기 때문에 service와 유사하다. 그렇지만 service와 다르게 action은 중간에 취소가능하고 goal을 위해 어떤 행위를 취하는 동안 그에 따른 진행사항(피드백)을 말해준다.

Action은 client-server 구조를 사용한다.
즉, "Action Client" node는 "Action Server" node로 goal을 보내고 Action Server는 이를 받아 행동을 수행하면서 피드백을 그림과 같이 보내고 결과 적으로 행위가 잘 이루어졌는지에 대한 결과를 반환한다.


준비물


1. 환경 설정하기

항상 그랬듯이 다음 명령어들로 /turtlesim과 /teleop_turtle을 실행해주자!

ros2 run turtlesim turtlesim_node
ros2 run turtlesim turtle_teleop_key

2. Action 실습

/teleop_turtle node를 실행 했다면 터미널에 다음과 같은 메세지가 떴을 것이다.

Use arrow keys to move the turtle.
Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation.

이때 두번째 줄에 있는 메세지는 action과 긴밀하게 연관 되어있다. (첫번째 방향키 움직이는 것은 topic과 관련 되어있으니 지금은 신경쓰지 않아도 된다.)

"G|B|V|C|D|E|R|T"는 각각 미리 설정된 방향을 의미한다. 예를 들어 "E" 같은 경우 turtle이 왼쪽 위를 바라보는 방향을 의미한다.

8개의 알파벳 중 하나를 누르면 /turtlesim node에 있는 action server에 goal을 보내는 것과 같다.
/teleop_turlte node에서 즉 E를 누르면 turtle을 왼쪽 위를 보도록 돌리라는 goal을 action client가 /turtlesim node에 있는 action server에 보낸다.

그러면 action server는 turtle을 goal(e.g. 왼쪽 위)을 향하도록 돌리기 시작한다. 특정 방향에 도달하게 되면 다음과 같이 골에 도달 했다는 메세지를 출력하게 된다.

[INFO] [turtlesim]: Rotation goal completed successfully

"F" 키를 누르게 되면 goal을 향해 움직이다가 행위를 취소한다.

예를 들어 "C" 키를 누르고 goal에 도달하기 전에 "F"를 누르게 되면 /turtlesim node를 실행한 터미널에서는 다음과 같이 goal에 도달하기 위한 행위가 취소 됐다는 메세지를 출력할 것이다.

[INFO] [turtlesim]: Rotation goal canceled

action의 특징 중 하나는 action client(요청자), action server(제공자) 양측에서 행위를 취소할 수 있다는 것이다. 방금 위에서 "F" 키를 통해서 취소한 것은 action client 측에서 취소한 것에 해당한다.

action server에서 취소하는 행위는 "abort"라고 불리는데 이를 실습해보자.
먼저 "D" key를 누르고 "D" goal에 도달하기 전에 "G" key를 빠르게 누른다.
그러면 다음과 같이 abort되었다는 message를 볼 수 있을 것이다.

[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal

/turtlesim node 에 있는 action server같은 경우 새로운 goal이 들어올 경우 이전의 goal을 abort하게 되어 있다.
그렇지만 이렇게 이전의 goal을 abort하는 것은 필수는 아니며 상황에 맞게 action server가 할 행동을 정의하면된다.(e.g. 현재 goal을 유지하며 새로운 goal을 abort하는 등)


3. ros2 node info

새로운 터미널을 열고 ros2 node info라는 명령어를 사용하게 되면 관심 node의 정보를 알 수 있다.

/turtlesim node에 대한 정보를 얻기 위해 다음을 새로운 터미널을 열어 입력하자.

ros2 node info /turtlesim

다음과 같이 subscriber, publisher, service, action server, action client에 대한 정보를 출력할 것이다.

/turtlesim
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /turtle1/cmd_vel: geometry_msgs/msg/Twist
  Publishers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
    /turtle1/color_sensor: turtlesim/msg/Color
    /turtle1/pose: turtlesim/msg/Pose
  Service Servers:
    /clear: std_srvs/srv/Empty
    /kill: turtlesim/srv/Kill
    /reset: std_srvs/srv/Empty
    /spawn: turtlesim/srv/Spawn
    /turtle1/set_pen: turtlesim/srv/SetPen
    /turtle1/teleport_absolute: turtlesim/srv/TeleportAbsolute
    /turtle1/teleport_relative: turtlesim/srv/TeleportRelative
    /turtlesim/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /turtlesim/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /turtlesim/get_parameters: rcl_interfaces/srv/GetParameters
    /turtlesim/list_parameters: rcl_interfaces/srv/ListParameters
    /turtlesim/set_parameters: rcl_interfaces/srv/SetParameters
    /turtlesim/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:
    /turtle1/rotate_absolute: turtlesim/action/RotateAbsolute
  Action Clients:

Action Servers 부분을 살펴보면 /turtle1/rotate_absolute라는 action이 있는 것을 볼 수 있다.

이는 /turtlesim node는 /turtle1/rotate_absolute라는 action을 제공한다는 것을 의미한다.

반면에, /teleop_turtle의 node info를 살펴보면 다음과 같다.

먼저 ros2 node info를 터미널에 입력하자.

ros2 node info /teleop_turtle

그러면 다음과 같은 메세지가 출력 될 것이다.

/teleop_turtle
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
    /turtle1/cmd_vel: geometry_msgs/msg/Twist
  Service Servers:
    /teleop_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /teleop_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /teleop_turtle/get_parameters: rcl_interfaces/srv/GetParameters
    /teleop_turtle/list_parameters: rcl_interfaces/srv/ListParameters
    /teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters
    /teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:

  Action Clients:
    /turtle1/rotate_absolute: turtlesim/action/RotateAbsolute

Action Clients쪽을 보면 /turtle1/rotate_absolute가 있는 것을 볼 수 있고, 이는 /turtle1/rotate_absolute로 action goal을 보낸 다는 것을 의미한다.


4. ros2 action list

다음으로 살펴 볼 명령어는 ros2 action list이다.
해당 명령어는 현재 ROS graph에 존재하는 모든 action을 알려준다.
백문이 불여일견! 바로 실행해보자.

ros2 action list

다음과 같은 action을 확인 할 수 있다.

/turtle1/rotate_absolute

즉, 현재 존재하는 action은 /turtle1/rotate_absolute임을 의미한다.
이 action은 앞서 2. action 실습에서 살펴봤던 것처럼 turtle을 특정 방향으로 돌리는 행위를 하는 action이다.


4.1 ros2 action list -t

action list 명령어와 함께 사용 할 수 있는 인자가 있는데 "-t" 이다.

이는 현존하는 action의 type을 같이 표시해준다.

ros2 action list -t

을 입력하면 다음과 같이 type이 표시된다.

/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]

이는 /turtle1/rotate_absolute라는 action은 turtlesim/action/RotateAbsolute라는 type을 사용한다는 의미이다.
이 type은 명령어를 통해 action을 요청하거나 code에서 action을 요청하고자 할 때 알아야 된다. 나중에 필요하면 실습할 예정이니 지금은 그런게 있구나 정도로 생각하고 넘어가면 된다.


5. ros2 action info

다음으로 살펴볼 명령어는 ros2 action info이다.
해당 명령어를 사용하면 관심 action에 대한 요약된 정보를 알 수 있다.

거두절미하고 실습해보자. 다음 명령어를 터미널에 복붙!

ros2 action info /turtle1/rotate_absolute

이때 /turtle1/rotate_absolute는 action 이름인 것에 주목하자!

그러면 다음과 같은 메세지를 출력할 것이다.

Action: /turtle1/rotate_absolute
Action clients: 1
    /teleop_turtle
Action servers: 1
    /turtlesim

요약하자면 Action은 /turtle1/rotate_absolute 이고 해당 action의 client와 server 수는 각각 1개씩 그리고 해당 client와 server가 있는 node는 /teleop_turtle, /turtlesim node이다.


6. ros2 interface show

다음으로 살펴볼 명령어는 ros2 interface show이다.
action을 command나 code를 통해 요청하기 전에 정보가 더 필요한데, 이를 알아낼 수 있는 명령어는 ros2 interface show이다.

이 명령어는 action type의 구조를 알려준다.

예를 들어 /turtle1/rotate_absolute의 action type을 다음과 같이 interface show를 통해 알아보면,

ros2 interface show turtlesim/action/RotateAbsolute

다음과 같이 type 구조를 담고 있는 메세지를 보여준다.

# The desired heading in radians
float32 theta
---
# The angular displacement in radians to the starting position
float32 delta
---
# The remaining rotation in radians
float32 remaining

살펴보자면 float32 theta는 goal 방향을 나타낸다.
float32 delta는 시작시점의 방향과 goal 방향까지 차이를 나타낸다.
foat32 remaining은 현재시점의 방향과 goal 방향까지 차이를 나타낸다. feedback으로 사용될 것이다.

그럼 이 구조가 어떻게 사용되는지 다음 명령어를 통해서 살펴보자.


7. ros2 action send_goal

이제 action 이름, type, 구조를 알아냈으니 직접 명령어를 통해서 action을 요청해볼 차례다.

기본적인 문법 구조는 다음과 같다.

ros2 action send_goal <action 이름> <action type> <action 구조에 맞는 >

이때 <action 구조에 맞는 값> 같은 경우에는 YAML format으로 작성되야한다. 뭔지 모르겠지만 실습을 통해 익히면 '아 이렇게 생겼구나' 할 것이니 걱정 안해도 된다.

여태 우리가 살펴왔던 /turtle1/rotate_absolute action에 대한 명령어를 구성해보면 다음과 같다.

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"

명령어를 살펴보자면, "/turtle1/rotate_absolute의 이름을 갖는 action은 turtlesim/action/RoateAbsolute라는 type을 갖고 이때 goal 방향 theta는 1.57 radian으로 하겠다" 라는 의미이다.

이 명령어를 입력하게 되면 turtle이 회전하기 시작하면서 다음과 같은 메세지를 출력할 것이다.

Waiting for an action server to become available...
Sending goal:
   theta: 1.57

Goal accepted with ID: f8db8f44410849eaa93d3feb747dd444

Result:
  delta: -1.568000316619873

Goal finished with status: SUCCEEDED

찬찬히 살펴보자면 action server가 이용가능 한지 대기한 후, goal theta 1.57를 보낸다.
goal은 고유한 ID가 부여된다. (e.g. 여기선 f8db~ 어쩌구 로 부여됐다)
이때 Result delta는 시작시점 방향과 목표 방향간의 차이를 radian으로 나타내고 있다.
그리고 마지막에 goal에 성공적으로 달성했음을 말해주고 있다.

추가적으로 goal방향에 도달하는 동안 feedback을 보고 싶으면 다음과 같이 명령어에 --feedback이라는 인자를 추가해주면 된다.

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback

그러면 다음과 같이 Feedback을 출력할 것이다.

Sending goal:
   theta: -1.57

Goal accepted with ID: e6092c831f994afda92f0086f220da27

Feedback:
  remaining: -3.1268222332000732

Feedback:
  remaining: -3.1108222007751465

…

Result:
  delta: 3.1200008392333984

Goal finished with status: SUCCEEDED

이 feedback은 goal 방향까지 남은 각도를 의미하며, 이는 goal 방향에 도달할 때 까지 출력 될 것이다.


여태까지 ros2에 통신 방법 중 하나인 action에 대해 배웠다.
action이 service와 topic으로 이루어졌기 때문에 엄밀히 말하면 service와 topic로 action 기능과 유사하게 구현 할 수 있다.

그렇지만 있는 것을 편하게 가져다사용하면 통신 방법을 구현하는데 실수를 줄 일 수 있으므로 필요하면 쓰도록 하자!

action은 업무를 할 때 엄청 자주 쓰이진 않는 것 같은게 개인적인 경험이다. 그렇지만 다소 특수한 상황에서 유용하게 사용될 수 있을 것 같다.
대표적인 예시가 Navigation stack에서 move_base이다. (이는 추후에 필요하면 다루도록 하겠다.)

오늘도 여기까지 온 스스로를 칭찬해주도록 하자!

토닥토닥

질문하고 싶거나 인공지능 & 로봇 개발에 대해 다뤄줬으면 하는 주제를 댓글로 남겨주기 바란다~!

문의메일: irobou0915@gmail.com
오픈톡 문의: https://open.kakao.com/o/sXMqcQAf
IRoboU 유튜브 채널: https://www.youtube.com/channel/UC2-d99PrBwJy15MjPa32zYg

참고 문헌: https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Actions/Understanding-ROS2-Actions.html

profile
지식이 현실이 되는 공간

0개의 댓글