当ROS提供的基本消息类型不满足需求的时候,就需要自定义msg了。
下面看笔者定义的一个PersonMsg.msg
文件,这个msg文件要放在功能包目录的msg文件夹下
string name
uint8 sex
uint8 age
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
那么定义这样一个msg文件,需要在package.xml中添加功能依赖:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
在CMakeLists.txt中添加编译选项:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
std_srvs
message_generation
)
add_message_files(FILES PersonMsg.msg)
generate_messages(DEPENDENCIES std_msgs)
catkin_package(
CATKIN_DEPENDS roscpp rospy std_msgs std_srvs message_runtime
)
有了以上配置后,在编译的时候,就可以生成各种语言的相关文件了。
回到工作空间根目录,执行catkin_make
就可以编译msg了。
产生的C++头文件可以在devel/include/learning_communication
文件夹中查看。
产生的Python头文件可以在devel/lib/python2.7/dist-packages/learning_communication/msg
目录中查看。
在scripts
文件夹下编写发布者和订阅者代码。
#!/usr/bin/env python
import rospy
from learning_communication.msg import PersonMsg
def publisher():
pub = rospy.Publisher('/person_info', PersonMsg, queue_size=10)
rospy.init_node('person_publisher', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
person_msg = PersonMsg('tangjz', 28, PersonMsg.male)
pub.publish(person_msg)
rate.sleep()
if __name__ == '__main__':
try:
publisher()
except rospy.ROSInterruptException:
pass
person_publisher.py
#!/usr/bin/env python
import rospy
from learning_communication.msg import PersonMsg
import std_msgs
def callback(person_msg):
rospy.loginfo("%s %s %s" % (person_msg.name, person_msg.age, person_msg.sex))
def subscriber():
rospy.init_node('person_subscriber', anonymous=True)
rospy.Subscriber('/person_info', PersonMsg, callback)
rospy.spin()
if __name__ == '__main__':
subscriber()
person_subscriber.py
回到工作空间根目录,先运行ROS Master
roscore
在启动发布者:
rosrun learning_communication person_publisher.py
最后启动订阅者:
rosrun learning_communication person_subscriber.py
从订阅者打印出来的信息,就可以看到成功的使用了自定义的msg。