Priceless

[ROS1] ROS 커스텀 메시지 본문

ROS1 & ROS2

[ROS1] ROS 커스텀 메시지

Hyun__ 2023. 10. 11. 00:41

ROS 커스텀 메시지를 통한 통신

msg 파일 추가

메시지를 구성하는 폴더를 추가하여 

cd <path to workspace/src>
roscd <pkg name>
mkdir msg # 메시지 폴더 생성
cd msg

 

메시지를 구성하는 타입을 저장하는 msg 파일을 추가한다

my_msg.msg

string first_name
string last_name 
int32 age 
int32 score 
string phone_number 
int32 id_number

 

커스텀 메시지 선언

패키지 파일 내에 있는 package.xml 파일을 수정한다

태그를 추가할 수 있는 영역 가장 아래에 다음 코드를 추가한다

<build_depend>message_generation</build_depend> 
<exec_depend>message_runtime</exec_depend>

 

이후 CMakeLists.txt를 수정한다

CMakeLists 파일은 패키지 파일 내에 존재하며, 공백은 2칸씩이다

CMakeLists.txt

find_package(catkin REQUIRED COMPONENTS
  rospy
  std_msgs
  message_generation # 1줄 추가
)

add_message_files( # 코멘트 제거
  FILES
  my_msg.msg # 1줄 추가
  # Message1.msg
  # Message2. msg
)

# 코멘트 제거
generate_messages (
  DEPENDENCIES
  std_msgs
)

catkin_package(
  CATKIN_DEPENDS message_runtime # 1줄 추가
  # INCLUDE_DIRS include
  # LIBRARIES my_pkg1
  # CATKIN_DEPENDS rospy std_msgs
  #  DEPENDS system_lib
)

이후 커스텀 메시지가 잘 구성되어 있는지 확인한다

cm
rosmsg show my_msg

혹은 파이썬 폴더 내의 패키지 파일에서도 확인할 수 있다

$ python/<workspace>/devel/lib/python<version>/dist_packages/msg_send/msg

코드 내에서 커스텀  메시지 사용

my_msg를 사용한 publisher 노드를 발행한다

msg_sender.py

#!/usr/bin/env python3

import rospy
from msg_send.msg import my_msg # 커스텀 메시지 호출

rospy.init_node('msg_sender', anonymous=True)
pub = rospy.Publisher('msg_to_xycar', my_msg)

# my_msg 안에 데이터 채우기
msg = my.msg()
msg.first_name = "janghyun"
msg.last_name = "Cho"
msg.id_number = 20201234
msg.phone_number = "010-1234-1234"

# my_msg 토픽 발행
rate = rospy.Rate(1)
while not rospy.is_shutdown():
	pub.publish(msg)
	print("sending message")
	rate.sleep()

 

my_msg를 받는 subscriber 노드를 발행한다

msg_receiver.py

#!/usr/bin/env python3

import rospy
from msg_send.msg import my_msg # 커스텀 메시지 호출

# my_msg 데이터 꺼내기
def callback(msg):
    print ("1. Name: ", msg.last_name + msg.first_name)
    print ("2. ID: ", msg.id_number)
    print ("3. Phone Number: " , msg.phone_number)
    
rospy.init_node('msg_receiver', anonymous=True)

# my_msg 토픽 구독
sub = rospy.Subscriber('msg_to_xycar', my_msg, callback)

rospy.spin()

 

코드를 추가한 이후 

실행 권한을 추가하는 것을 잊으면 안된다

chmod +x msg_sender.py msg_receiver.py

 

빌드한 후 실행한다

cm
roscore # launch 파일이 아니므로 마스터를 실행한다
rosrun msg_send msg_receiver.py
rosrun msg_send msg_sender.py

 

위 코드를 실행할 수 있는 launch 파일을 작성한다

m_send_sr.launch

‹launch>
    <node pkg="msg_send" type="msg_sender.py" name="sender1"/>
    <node pkg="msg_send" type="msg_sender.py" name="sender2" />
    <node pkg="msg_send" type="msg_receiver.py" name="receiver" output="screen" />
</launch>

 

launch 파일을 생성한 후 실행하고 graph를 확인한다

roslaunch msg_send m_send_sr.launch
rqt_graph

 

이 경우 실행했을 때 한 가지 문제가 발생했다

바로 py 파일에서 import할 때

msg_send 패키지를 읽어오지 못하는 에러가 발생한다

이 부분은 추후에 해결할 예정이다

노트 통신 확인 

누락 없이 모두 잘 도착하는가?

숫자를 보내서 받는 쪽에서 누락된 메시지가 있는지 확인할 수 있다

이 경우 보내는 쪽이 안 보낸 것인지, 받는 쪽이 못 받은 것인지 확인해야한다

데이터 크기에 따른 전송 속도는 어떻게 되는가?

보내는 쪽에서 10분 동안 계속 보내고 얼마나 보냈는지 송신 속도를 확인한다

도착하는 데이터를 미처 처리하지 못하면 어떻게 되는가?

받는 쪽이 버벅되게 만들고 데이터를 많이 보낸다

받는 쪽의 콜백함수 안에 시간이 많이 걸리는 코드를 넣어 토픽 처리 시간이 걸리도록 만든다

주기적 발송에서 타임슬롯을 오버하면 어떻게 되는가?

1초 동안 반복하는 발송에서 타임 슬롯이 1초를 넘길 수 있다

협업해야 하는 노드를 순더대로 기동시킬 수 있을까?

순서대로 작동해야만 하는 노드들을 순서대로 작동시키는 방법

'ROS1 & ROS2' 카테고리의 다른 글

[ROS1] ROS 노드 통신 프로그래밍 실습  (0) 2023.11.07
[ROS1] ROS 원격 노드 통신  (0) 2023.10.15
[ROS1] ROS1 노드 통신 (1대1 ~ N대N)  (1) 2023.10.09
[ROS1] ROS1 launch  (0) 2023.10.08
[ROS1] ROS1 Package(패키지)  (0) 2023.10.08