How to Install ROS2 (Humble or Jassy)
WSL Ubuntu 24에서 Humble의 경우 repo list에서 지원하지 않아 Jassy로 설치하여 진행함
- Humble : link
-
Jazzy : link
- rqt_graph로 현재 실행중인 노드 및 발행된 topic 정보 확인 가능
ROS2 특징
-
setup.sh
- sudo apt install 명령으로 설치한 ros pkg들이 저장된 곳이 /opt/ros/[Version, ex.huble/jassyh]이며, 해당 경로의 setup.bash를 sourc로 읽어 들여야 ros2 개발환경 사용이 가능
-
ROS_DOMAIN_ID
-
DDS(Data Distribution Service, 데이터 분산 서비스)
을 재택하여 시스템의 실시간성/규모가변성/안정성/고성능을 가능케 하도록 Publish/Subscribe 네트워크 커뮤니케이션 구조의 미들웨어를 사용함
- 따라서 다른 네트워크에서 들어오는 정보를 구분 짓기 위해
ROS_DOMAIN_ID
라는 시스템 변수를 사용함
ROS 구조
Node :
- 실행가능한 최소 단위를 말함
- 노드확인 명령어 :
ros2 run <PKG Name> <Node Name>
- ex. ros2 run turtlesim turtlesim_node
- 그외 명령어
ros2 node list
: 실행중인 노드 리스트 확인 가능
ros2 node info turtlesim
: 현재 실행중인 노드의 정보를 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
gyyeon@DESKTOP-A9M7R8S:~$ ros2 node list # 현재 실행중인 노드 리스트 확인
/turtlesim
gyyeon@DESKTOP-A9M7R8S:~$ ros2 node info /turtlesim # 이 노드가 어떤것을 제공하는지 확인 가능
/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/get_type_description: type_description_interfaces/srv/GetTypeDescription
/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:
|
Service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
gyyeon@DESKTOP-A9M7R8S:~$ ros2 service list
/clear
/kill
/reset
/spawn
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/get_type_description
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically
# 서비스 타입 파일 확인
gyyeon@DESKTOP-A9M7R8S:~$ ros2 service type /turtle1/teleport_absolute
turtlesim/srv/TeleportAbsolute
# srv의 서비스 타입 정보 확인(--- 기준 위는 request, 밑은 response)
gyyeon@DESKTOP-A9M7R8S:~$ ros2 interface show turtlesim/srv/TeleportAbsolute
float32 x
float32 y
float32 theta
---
|
ros에서 제공하는 서비스 타입의 경우 단위는 KMS
, radian
을 주로 사용한다
Service Call
- 제공하는 서비스에 대해 사용 요청하는
서비스 콜
명령어에 대해 알아보자
- 서비스 콜 명령어 :
ros2 service call '서비스타입(srv) "data"
-ex.
- ros2 service call /turtle1/teleport_absolute turtlesim/srv/TeleportAbsolute “{x: 2, y: 2, theta: 1.57}”
- ros2 service call /reset std_srvs/srv/Empty {}
Service Call(Name Space)
- 어떤 로봇인지 구분하기 위해 Name Space를 사용하며
ros2 service list
를 쳐보면 확인 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# 임의의 터틀봇 생성
gyyeon@DESKTOP-A9M7R8S:~$ ros2 service call /spawn turtlesim/srv/Spawn "{x: 3, y: 5, theta: 3.14, name: ''}"
requester: making request: turtlesim.srv.Spawn_Request(x=3.0, y=5.0, theta=3.14, name='')
response:
turtlesim.srv.Spawn_Response(name='turtle2')
# 터틀봇 서비스 리스트 정보를 확인해보면 turtle1/2 namespace로 개별 동작 서비스가 나눠져 있음이 확인 가능
gyyeon@DESKTOP-A9M7R8S:~$ ros2 service list
/clear
/kill
/reset
/spawn
/turtle1/set_pen #<------
/turtle1/teleport_absolute #<------
/turtle1/teleport_relative #<------
/turtle2/set_pen #>------
/turtle2/teleport_absolute #>------
/turtle2/teleport_relative #>------
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/get_type_description
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically
|
TOPIC
- Publisher측에서 brodcast로 특정 Topic으로 정보를 제공할때 사용되며,
- Subscriber측은 Topic Name/Message Type을 알면 어느 노드건 해당 메세지를 받아 볼수 있음
- 토픽 리스트 확인 명령어 :
ros2 topic list [-t|-v, 토픽 메시지 타입까지 표여줌| pub,sub 정보를 다보여줌]
- 토픽 확인 명령어 :
ros2 topic echo [토픽]
(ex. ros2 topic echo /turtle1/pose)
- 그외 명령어
-
ros2 topic type [토픽]
: 토픽의 메세지 타입 파일 확인
-ex. ros2 topic type /turtle1/pose
-
ros2 topic info [토픽]
: 토픽 타입 및 pub/sub 갯수 확인 가능(ex. subscription cnt:0이라면 아무도 안듣고 있는 상황)
-
ros2 interface show <토픽 Msg 타입> : 토픽 Msg 타입 정보 확인
-ex. ros2 interface show turtlesim/msg/Pose
-
ros2 topic echo [토픽]
: 특정 토픽을 subscribe 수행
-
rqt_graph
: 실행중인 노드 및 토픽 정보를 확인 가능(debug를 꺼야 cli로 sub중인 상태들까지 확인 가능)
-
ros2 topic pub [토픽] [타입] [데이터]
: 특정 토픽으로 msg pub 수행 (옵션으로 명령어 주기 설정 가능 –once / –rate [Hz])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# [default] 토픽 정보 확인
gyyeon@DESKTOP-A9M7R8S:~$ ros2 topic list
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
/turtle2/cmd_vel
/turtle2/color_sensor
/turtle2/pose
/turtle3/cmd_vel
/turtle3/color_sensor
/turtle3/pose
# [t] 토픽 정보를 토픽 타입 파일과 함께 확인
gyyeon@DESKTOP-A9M7R8S:~$ ros2 topic list -t
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
/turtle1/cmd_vel [geometry_msgs/msg/Twist]
/turtle1/color_sensor [turtlesim/msg/Color]
/turtle1/pose [turtlesim/msg/Pose]
/turtle2/cmd_vel [geometry_msgs/msg/Twist]
/turtle2/color_sensor [turtlesim/msg/Color]
/turtle2/pose [turtlesim/msg/Pose]
/turtle3/cmd_vel [geometry_msgs/msg/Twist]
/turtle3/color_sensor [turtlesim/msg/Color]
/turtle3/pose [turtlesim/msg/Pose]
# [v] 토픽 세부 정보 확인
gyyeon@DESKTOP-A9M7R8S:~$ ros2 topic list -v
Published topics:
* /parameter_events [rcl_interfaces/msg/ParameterEvent] 2 publishers
* /rosout [rcl_interfaces/msg/Log] 2 publishers
* /turtle1/color_sensor [turtlesim/msg/Color] 1 publisher
* /turtle1/pose [turtlesim/msg/Pose] 1 publisher
* /turtle2/color_sensor [turtlesim/msg/Color] 1 publisher
* /turtle2/pose [turtlesim/msg/Pose] 1 publisher
* /turtle3/color_sensor [turtlesim/msg/Color] 1 publisher
* /turtle3/pose [turtlesim/msg/Pose] 1 publisher
Subscribed topics:
* /parameter_events [rcl_interfaces/msg/ParameterEvent] 2 subscribers
* /turtle1/cmd_vel [geometry_msgs/msg/Twist] 1 subscriber
* /turtle2/cmd_vel [geometry_msgs/msg/Twist] 1 subscriber
* /turtle3/cmd_vel [geometry_msgs/msg/Twist] 1 subscriber
# 토픽 타입 파일 정보 확인
gyyeon@DESKTOP-A9M7R8S:~$ ros2 interface show turtlesim/msg/
Pose
float32 x
float32 y
float32 theta
float32 linear_velocity
float32 angular_velocity
gyyeon@DESKTOP-A9M7R8S:~$ ros2 topic echo /turtle1/pose
x: 5.544444561004639
y: 5.544444561004639
theta: 0.0
linear_velocity: 0.0
angular_velocity: 0.0
---
gyyeon@DESKTOP-A9M7R8S:~$ ros2 topic pub /gyu/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2, y: 0, z: 0}, angular: {x: 0, y: 0, z: 2}}"
|
Action
- Action은 Goal/Result service와 그리고 중간 과정을 모니터링을 위한 feedback topic으로 구성됨
- Service + topic = action으로 생각하면 되고 action server를 두고 실행된다고 생각하면 됨 - ex. 로봇한테 10,10 좌표로 이동하라고 골을 주면, 이동하는 동안 피드백으로 좌표를 확인하고, 목표에 도착하면 result를 받는게 action임
- 명령어
- ros2 action list -t : 액션 리스트 타입과 함께 확인
- ros2 interface show [액션타입] : 액션 타입 메시지 확인
-
---
를 기준으로 goal/result/feedback으로 영역이 나눠져 있음 (service의 경우에는 request/response 타입 정보였음)
- ros2 action send_goal [액션] [액션타입] [데이타] : 액션 실행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
gyyeon@gyeon ~ ros2 run turtlesim turtlesim_node
gyyeon@gyeon ~ ros2 run turtlesim turtle_teleop_key => rqt_graph로 확인해보면 /turtle1/rotate_absolute라는 토픽의 액션을 확인 가능
gyyeon@gyeon ~ ros2 action list -t
/gyu/rotate_absolute [turtlesim/action/RotateAbsolute]
/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]
gyyeon@gyeon ~ ros2 interface show turtlesim/action/RotateAbsolute
# 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
gyyeon@gyeon ~
✘ gyyeon@gyeon ~ ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{ theta: 2.11 }"
Waiting for an action server to become available...
Sending goal:
theta: 2.11
Goal accepted with ID: 2717c10c13194056b6d0aabf6007c746
Result:
delta: 1.0399997234344482
Goal finished with status: SUCCEEDED
|
Topic Subscribe/Publish (Python) ROS2 Docs
노드 생성 및 topic 구독
- cnt를 활용해 Topic 받는 횟수를 제한함(cnt를 없애면 계속 구독)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import rclpy as rp #rclp : robot common library python
from turtlesim.msg import Pose # Data Type(Pose)을 import로 받아옴
import time
# ros2 run turtlesim turtlesim_node
# subscription은 토픽이 들어올때마다 실행할 함수를 필수로 지정해야함
cnt = 0
def callback(data):
global cnt
print("--->")
print("/turtle1/pose : ", data)
print("X :", data.x)
print("Y : ", data.y)
print("Theta : ", data.theta)
cnt = cnt + 1
if cnt>3:
raise Exception("Subscription Stop")
def main():
#노드 create
rp.init()
test_node = rp.create_node('sub_test')
# while 1 :
# time.sleep(1)
# print(test_node, "is running")
#subscription 수행
# 생성한 노드에 토픽/메세지 타입/콜백을 등록하여 sub 가능
test_node.create_subscription(Pose, '/turtle1/pose', callback, 10)
#rp.spin_once(test_node) #=> 토픽을 한번만 받음
rp.spin(test_node) #=> 토픽을 계속 받음
if __name__ == "__main__":
main()
|
노드 생성 및 topic 발행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
import rclpy as rp #rclp : robot common library python
from geometry_msgs.msg import Twist # Data Type(Twist)을 import로 받아옴
import time
# ros2 run turtlesim turtlesim_node
# subscription은 토픽이 들어올때마다 실행할 함수를 필수로 지정해야함
cnt = 0
def timer_callback(pub, msg):
global cnt
print(cnt)
cnt += 1
pub.publish(msg)
if cnt>100:
raise Exception("Publisher Stop")
def main():
#노드 create
rp.init()
test_node = rp.create_node('pub_test')
#Twist Class 인스턴스화(instantiation)
msg=Twist()
print(msg) # default값으로 linear/angular로 바뀜
# 아래와 같이 twist 값 설정
# msg.angular.z = 1.8
# msg.linear.x = 2
# ex.
# gyyeon@gyeon ~ ros2 topic list -t
# /parameter_events [rcl_interfaces/msg/ParameterEvent]
# /rosout [rcl_interfaces/msg/Log]
# /turtle1/cmd_vel [geometry_msgs/msg/Twist]
# /turtle1/color_sensor [turtlesim/msg/Color]
# /turtle1/pose [turtlesim/msg/Pose]
# publisher 생성(publish할 토픽과 메세지 타입을 지정)
# 한번만 pub 수행
pub = test_node.create_publisher(Twist, '/turtle1/cmd_vel', 10)
pub.publish(msg)
msg.angular.z = 1.6
msg.linear.x = 4.0
# 여러번 pub 수행을 하고자 할경우 timer_callback() 사용
timer_period=0.1
timer = test_node.create_timer(timer_period, lambda:timer_callback(pub, msg))
rp.spin(test_node)
## 노드 종료
test_node.destroy_node()
if __name__ == "__main__":
main()
|
ROS2 Service Client 다루기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
import rclpy as rp #rclp : robot common library python
from turtlesim.srv import TeleportAbsolute
import time
# ros2 run turtlesim turtlesim_node
# subscription은 토픽이 들어올때마다 실행할 함수를 필수로 지정해야함
cnt = 0
def timer_callback(pub, msg):
global cnt
print(cnt)
cnt += 1
pub.publish(msg)
if cnt>100:
raise Exception("Publisher Stop")
def main():
#노드 create
rp.init()
test_node = rp.create_node('client_test')
service_name = '/turtle1/teleport_absolute'
cli = test_node.create_client(TeleportAbsolute, service_name)
# 서비스 Req Type 인스턴스 생성
req = TeleportAbsolute.Request()
print(req)
req.x = 1.
req.y = 1.
req.theta = 1.
cli.call_async(req)
# 서비스 노드가 기동할때까지 기다리는 함수
while not cli.wait_for_service(timeout_sec=1.0):
print("Waiting for service")
# 서비스콜 한번만 수행
# rp.spin_once(test_node) # spin() will not return until the node is shutdown
# 서비스가 실행되는 결과 받아오기
future = cli.call_async(req)
while not future.done():
rp.spin_once(test_node)
print(future.done(), future.result())
## 노드 종료
test_node.destroy_node()
if __name__ == "__main__":
main()
|