일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Slam
- Gazebo
- Subscriber
- C++
- launch
- 판단
- Publisher
- TinySLAM
- turtlebot3
- 데브코스
- Localization
- 입문
- sudo
- catkin빌드
- Ros
- turtlesim
- XML
- 노트
- navgation
- 튜토리얼
- udacity
- 어렵네
- 가재보
- 공부
- CNN
- 패키지만들기
- 자율주행
- Robotics program 교육
- 기초
- Python
- Today
- Total
Tnote
ROS, turtlesim 활용해 python 기초 코딩 본문
#0 기본 설정
Ubuntu에 ROS, vscode 다운 받은 상태라 가정
새로 만든 폴더에 catkin 빌드 한 상태라 가정 (참고 : https://jfl2dh.tistory.com/8)
#1 turtlesim 실행 (참고 : https://jfl2dh.tistory.com/7)
1) 새 터미널 열고 roscore 입력 후 실행
2) 1번과 다른 터미널 열고 rosrun turtlesim turtlesim_node 입력 후 실행
#2 원하는 데이터(topic) 찾기
1) 새 터미널 열고 rostopic list 입력 후 실행
- /turtle1으로 시작 것이 turtlesim과 관련된 topic
2) rostopic info 토픽이름
- ex) rostopic info /turtle1/cmd_vel
* [명령어] rostopic info 토픽이름 : 해당 토픽 정보 확인
3개의 topic 정보를 살펴보면 '/turtle1/cmd_vel' 이름의 topic만 Subscribers에 "/turtlesim" 노드(프로그램)이 연결 되어있고, 나머지 '/turtle1/color_sensor', '/turtle1/pose' 는 Publishers에 "/turtlesim" 노드가 연결되어 있다.
즉, "/turtlesim" 이라는 노드(프로그램)는 '/turtle1/cmd_vel' 토픽을 받고(Subscribers), '/turtle1/color_sensor'과 '/turtle1/pose' 토픽을 준다(Publishers).
*더 자세한 사항은 #1의 링크 참고
우리는 '/turtle1/pose' 토픽을 받아서 '/turtle1/cmd_vel' 토픽을 "/turtlesim" 노드(프로그램)에 준다.
Subscriber : /turtle1/pose
Publisher : /turtle1/cmd_vel
- 전체코드 미리보기
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
|
#! /usr/bin/env python
import rospy
from turtlesim.msg import Pose
from geometry_msgs.msg import Twist
class turtle_study:
def __init__(self):
self.turtle_sub = rospy.Subscriber('/turtle1/pose', Pose, self.callback)
self.turtle_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)
def callback(self, data):
velocity = Twist()
global count, x0
#print(count)
if count == 0:
x0 = data.x
if abs(data.x - x0) >= 2: velocity.linear.x = 0
else: velocity.linear.x = 2
self.turtle_pub.publish(velocity)
count += 1
def run():
rospy.init_node('turtle_study1', anonymous=True)
turtle1 = turtle_study()
rospy.spin()
if __name__ == "__main__":
count = 0
switch = 0
run()
|
cs |
=> 실행해 보면 거북이가 2의 거리만큼 이동하면 멈춘다.
#3 topic의 정보 확인
2번에서 원하는 데이터를 찾았다면 rostopic info 에서 Type을 기억한다.
- '/turtle1/pose' 토픽의 msg(메시지) 이름 : geometry_msgs/Twist
- '/turtle1/cmd_vel' 토픽의 msg 이름 : turtlesim/Pose
=>이것이 나중에 코딩할 때 사용됨. (아래 예시)
1
2
3
4
|
#! /usr/bin/env python
import rospy
from turtlesim.msg import Pose
from geometry_msgs.msg import Twist
|
cs |
#4 code 노드와 "/turtlesim" 노드(프로그램)을 연결하기
* rqt_graph : 노드, 토픽의 관계를 시각화 해준다.
위 그림처럼 연결해주기 위해서 rospy의 Subscriber, Publisher 코드를 사용한다.
rospy.Subscriber('토픽이름', 메시지이름, 객체(변수))
rospy.Publisher('토픽이름', 메시지이름, queue_size)
- 객체 : 포인터 개념은 생략하고, 일단은 Subscriber로 받은 데이터를 어디로 줄 것인가? 정도로 이해
- queue_size : 발행할 때 얼만큼의 사이즈로 보낼 것인지. 적정한 queue 사이즈를 정하는게 문제
- 코드 예시
6
7
8
9
|
class turtle_study:
def __init__(self):
self.turtle_sub = rospy.Subscriber('/turtle1/pose', Pose, self.callback)
self.turtle_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)
|
cs |
python 문법 설명은 생략,
8 : "/turtlesim" 노드가 주는, "Pose" 메시지의 '/turtle1/pose' 토픽을 self.callback 객체로 주겠다. ( 거북 -> 나 )
9 : 우리가 "Twist" 메시지의 '/turtle1/cmd_vel' 토픽을 10의 큐 사이즈로 "/turtlesim" 노드에게 주겠다. ( 나 -> 거북 )
#5 노드 설정 및 코드 구성 마무리
29
30
31
32
33
34
35
36
37
|
def run():
rospy.init_node('turtle_study1', anonymous=True)
turtle1 = turtle_study()
rospy.spin()
if __name__ == "__main__":
count = 0
switch = 0
run()
|
cs |
- 실행 순서대로 코드 설명
34 : 이 이름공간의 이름이 메인이 된다면 .... -> 이 코드가 실행된다면 35, 36, 37번째 코드 실행
실질적으로 import 말고는 가장 먼저 실행되는 코드
35 : count 변수(객체)에 0 저장(할당)
36 : switch 변수에 0 저장
37 : 29번에 있는 run 함수 실행(호출)
29 : 함수 이름 run 이다. (양식)
30 : 노드의 이름 선언
31 : turtle_study 클래스 실행(호출)
32 : 터미널에 ctrl+c 입력 전 까지 callback 반복
#6 코딩 (상세한 설명은 생략)
- 이 포스팅에는 callback 함수안에서 이루어 지지만 다양한 방법이 있다.
- Subscriber해서 오는 데이터는 data변수로 온다. ex) data.x -> '/turtle1/pose' 토픽의 x값 = 거북이 x좌표
토픽에 어떤 데이터가 오는지 알기 위해선, 위 #3 에서의 msg를 통해 알 수 있는데,
'/turtle1/pose'의 정보는 아래와 같다.
* [명령어] rosmsg show 메시지타입 : 해당 메시지 정보 확인
* 여기서 주의할 점은 pose(위치) 데이터는 어디에 소속되어 있지 않지만, '/turtle1/cmd_vel' 토픽을 보면,
위 그림처럼 linear의 x, y, z angular의 x, y, z 이런 식으로 되어있으니 확인해 볼 것.
- 코드의 개략적인 흐름은
1. 변수에 메시지 호출 : 지금은 Publisher를 하기위해서 변수와 메시지를 연결한다 정도만 이해.(그래서 수정이 가능)
2. 제어(멈추거나, 직진하거나)
3. 제어로 결정된 최종적인 값 전달(여기서는 속력)
* 여기서 가장 햇갈렸던 부분이 13~22번에서 아무리 지지고 볶아봤자 가장 마지막에 결정된 값이 23번을 통해 한번 전달되는 점이었다.
- 1, 3번은 양식으로 무조건 있어야 하고, 2번을 수정하여 거북이를 제어하는 것.
#마무리
간단하게 설명하면, 로봇(위 거북이)의 현재 상태(데이터)를 받아서 제어(속도, 방향 등 조종)한 값(데이터)를 다시 로봇으로 전달해주는 과정을 해본 것이다.
기존에 있는 것 : rosrun turtlesim turtle_teleop_key 명령어를 입력하면, 거북이를 방향키로 조종할 수 있다.
우리가 만든 것 : rosrun 패키지 우리가만든파이썬파일 명령어를 입력하면, 거북이를 한방향으로 2만큼 움직일 수 있다.
=> 기존에 있는 걸 구글링이나 다른 매체를 통해 검색해보면서 우리가 직접 만들어 보면 금방 익숙해 진다고 믿는다.
감사합니다.
'ROS' 카테고리의 다른 글
ROS, hector_slam (0) | 2022.02.21 |
---|---|
ROS, launch 파일(.xml) (0) | 2022.02.20 |
ROS, 패키지 만들기, catkin 빌드하기 (0) | 2022.02.05 |
ROS, turtlesim을 활용한 데이터 이동 확인 (0) | 2022.02.04 |
ROS 설치 확인법 (0) | 2022.02.04 |