ROS2 구독 노드 subscriber 만들고 실행해보기 1
ROS2 패키지 만들기
워크스페이스 만들고 빌드하기학습용 워크스페이스 폴더를 만들고 패키지를 만들어 봄폴더를 하나 만들고 그 안에 src 폴더를 하나 더 만듦mkdir -p ~/ros2_ws/src하위 폴더까지 한 번에 만들 수 있음
studentstory.tistory.com
나는 우선 VS code 를 이용해 편집하려고 한다.
우선 이전 글에 수행했던 내용을 빠르게 보자면
워크스페이스 위치에서 colcon build 후
src 위치에서 패키지를 만든 모습
패키지 빌드
다시 빌드하면
(빌드는 반드시 워크스페이스 폴더 에서 진행해야한다.)
빌드 완료 후 워크스페이스 폴더 내부를 확인하면
아래와 같이 파이썬 노드 파일이 만들어진 것을 볼 수 있다.
워크스페이스 불러오기
하지만 이후 ros2 run 명령어로 노드를 실행하려고 해도 tab이 안될 뿐더러 실행할 수 없다.
그 이유는 워크스페이스에서 install/local_setup.bash 를 불러와야하기 때문
아래 source 명령을 수행해야한다.
source ./install/local_setup.bash
이 과정을 거치기 귀찮으니 alias 단축어를 만들어 보도록 함
~/.bashrc 파일에 다음 코드를 추가함
gedit ~/.bashrc 혹은 vim ~/.bashrc 혹은 본인이 사용하는 텍스트 편집기로 파일을 수정하자.
alias ros2study="humble; source ~/ros2_ws/install/local_setup.bash; echo \"ros2_ws workspace is activated\""
민형기 강사님의 코드처럼 ros2study로 변경된 워크스페이스를 불러오도록 했다.
이후 다음 명령을 실행하면
ros2 run my_first_package my_first_node
노드가 잘 실행되는 것을 볼 수 있다.
노드 만들기
topic subscribe Node
다음으로 아까 생성된 my_first_package의 my_first_node.py 파일을 수정할 것이다.
혹은 새로운 파일을 만들어도 된다.
새로운 코드는 다음과 같다.
import rclpy as rp
from rclpy.node import Node
from turtlesim.msg import Pose
class TurtlesimSubscriber(Node):
def __init__(self):
super().__init__('turtlesim_subscriber') #노드이름을 정해준 것임
self.subscription = self.create_subscription(
Pose,
'/turtle1/pose',
self.callback,
10
)# Pose 타입, turtle1의 'pose' 토픽 발행
def callback(self, msg):
print("X: ", msg.x, ", Y: ",msg.y)
def main():
rp.init()
turtlesim_subscriber = TurtlesimSubscriber()
rp.spin(turtlesim_subscriber)
turtlesim_subscriber.destroy_node()
rp.shutdown()
if __name__ == '__main__':
main()
이후 workspace에서 colcon build를 하고 워크스페이스 환경을 불러준다.
ros2study 단축 명령어를 입력하거나..
source ./install/local_setup.bash
이후 ros2 run my_first_package my_first_node 명령을 실행해준다.
※ 만약 새로운 파일을 만들었다면 해당 파일 명이 tab으로 완성되지 않는다.
- setup.py에 새로운 파일을 알려주어야 한다
- src 폴더에 있는 setup.py 의 entry_points에 추가해주어야 한다.
'my_first_node = my_first_package.my_first_node:main'
#위를 아래처럼 바꿔야 한다.
'my_first_node = my_first_package.my_first_node:main',
'<확장자를 뺀 파일명> = my_first_package.<확장자를 뺀 파일명>:main'
이후엔 다시 빌드해야하고 불러야 함.
※ 혹시나 수정 과정에서 빌드가 꼬인 경우,,,
- src를 제외한 폴더를 지우고 다시 빌드하기
코드 해석
self.create_subscription을 만드는데 turtle1/pose를 구독하는
그리고 callback 함수로 해당 메시지 데이터를 인자로 전달
파이썬에서는 각 파일(모듈)에 __name__ 변수를 정의하는데
- 직접 실행되면 __name__ = '__main__' 으로 해석할 수 있다.
- 파일이 다른 파일에서 import 되면 __name__ = <파일 이름> 이다.
때문에 아래와 같은 코드는
if __name__ == '__main__':
main()
해당 파일이 직접 실행될 때만 if 문의 조건이 True가 되어 실행될 것이다.
즉 1. python3 로 실행하면 if문이 직접 실행되고 main으로 건너간다.
반대로 2. ros2 run 으로 실행하면 바로 main으로 간다. (import 하면 if 실행하지 않음)
만든 노드 실행하려면 setup.py 에서 entry_points 수정해야함
↓ 파이썬에서 super 의 사용 ↓
class 를 상속하여 쓰는 경우가 많은데
def __init__ () 아래에 추가하고 싶을 때 그냥 수정해버리면 over writing이 되어버린다.
때문에 아래에 super().__init__(~~~) 을 사용하면 기존의 init에 더하여 추가하는 코드로 생각하면 된다.