1/自定义消息类型与编译
(1)在功能包里面创建一个msg文件夹,添加文档,文档名字为生成的头文件名和消息类型名,功能包名为消息类型的作用域.
在msg文件夹下创建一个Person.msg文件,将下列代码复制进去:
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
生成的头文件在devel文件夹里面添加方式为#include<package_name/Person.h>
注:前三行是ROS提供的基础数据类型;后三行是定义的常量,发布和订阅数据时可直接使用,相当于C++中的宏定义.
(2)
在功能包清单 package.xml 中添加功能包依赖:编译依赖 + 运行依赖
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
(3)在编译规则 CMakeList.txt 中添加编译选项
在 find_package 中添加 消息生成 依赖的功能包 message_generation,如下:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation //添加消息类型时独有的
)
在 catkin_package 中设置 catkin 依赖的功能包,如下:
catkin_package(
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
)
在 add_message_files 和 generate_messages 中设置需要编译的.msg文件,如下:
add_message_files(
FILES
Person.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
添加要编译的文件
add_executable(pub_msg src/pub_msg.cpp)
add_dependencies(pub_msg KaTeX parse error: Expected '}', got 'EOF' at end of input: {{PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(pub_msg ${catkin_LIBRARIES})
add_executable(sub_msg src/sub_msg.cpp)
add_dependencies(sub_msg KaTeX parse error: Expected '}', got 'EOF' at end of input: {{PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(sub_msg ${catkin_LIBRARIES})
****最后的Cmakelistx.txt****
----------------
```cpp
cmake_minimum_required(VERSION 2.8.3)
project(self_def_msg_pub)
find_package(catkin REQUIRED COMPONENTS
message_generation
roscpp
rospy
std_msgs
)
## Generate messages in the 'msg' folder
add_message_files(
FILES
Score.msg
Person.msg
)
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
CATKIN_DEPENDS
message_runtime
)
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
add_executable(pub_msg src/pub_msg.cpp)
add_dependencies(pub_msg ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(pub_msg ${catkin_LIBRARIES})
add_executable(sub_msg src/sub_msg.cpp)
add_dependencies(sub_msg ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(sub_msg ${catkin_LIBRARIES})
发布消息代码
#include<ros/ros.h>
#include<self_def_msg_pub/Person.h>
int main(int argc ,char **argv)
{
//ros结点初始化
ros::init (argc ,argv,"person_publisher");
//句柄的创建
ros::NodeHandle n;
//创建一个Publishe 发布名为person_info的topic 消息类型为 self_def_msg_pub::Person,队列的长度为10
//self_def_msg_pub::Person 其中self_def_msg_pub为功能包名 Person为自定义的消息文件名 在devel里面生成头文件
ros::Publisher person_info_pub = n.advertise<self_def_msg_pub::Person> ("/person_info",10);
//设置循环频率
ros::Rate loop_rate(100); //设置的越大 发布订阅的频率越大
int count= 0;
while(ros::ok())
{
//初始化self_def_msg_pub::Person类型的消息
self_def_msg_pub::Person person_msg;
person_msg.name ="Tom";
person_msg.age = 18;
person_msg.sex = self_def_msg_pub::Person::male;
//发布消息
person_info_pub.publish(person_msg);
ROS_INFO("publish person info: name:%s age:%d sex:%d",person_msg.name.c_str(),person_msg.age,person_msg.sex );
//按照循环频率延时
loop_rate.sleep();
}
return 0;
}
**订阅消息代码**
```cpp
#include<ros/ros.h>
#include<self_def_msg_pub/Person.h>
void personinfocallback(const self_def_msg_pub::Person::ConstPtr& msg )
{
ROS_INFO("Subcribe Person Info :name:%s age:%d sex:%d", msg->name.c_str() , msg->age ,msg->sex);
}
int main(int argc ,char **argv)
{
//初始化ros结点
ros::init (argc ,argv,"person_subscriber");
//创建结点句柄
ros::NodeHandle n;
//创建一个Subscriber 订阅名为/person_info的topic
ros::Subscriber person_info_sub = n.subscribe ("/person_info",10,personinfocallback);
//循环等待回调函数
ros::spin();
return 0;
}
python发布代码
import rospy
from learning_topic.msg import Person
def velocity_publisher():
# ROS节点初始化
rospy.init_node('person_publisher', anonymous=True)
# 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10
person_info_pub = rospy.Publisher('/person_info', Person, queue_size=10)
#设置循环的频率
rate = rospy.Rate(10)
while not rospy.is_shutdown():
# 初始化learning_topic::Person类型的消息
person_msg = Person()
person_msg.name = "Tom";
person_msg.age = 18;
person_msg.sex = Person.male;
# 发布消息
person_info_pub.publish(person_msg)
rospy.loginfo("Publsh person message[%s, %d, %d]",
person_msg.name, person_msg.age, person_msg.sex)
# 按照循环频率延时
rate.sleep()
if __name__ == '__main__':
try:
velocity_publisher()
except rospy.ROSInterruptException:
pass
python订阅代码
import rospy
from learning_topic.msg import Person
def personInfoCallback(msg):
rospy.loginfo("Subcribe Person Info: name:%s age:%d sex:%d",
msg.name, msg.age, msg.sex)
def person_subscriber():
# ROS节点初始化
rospy.init_node('person_subscriber', anonymous=True)
# 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback
rospy.Subscriber("/person_info", Person, personInfoCallback)
# 循环等待回调函数
rospy.spin()
if __name__ == '__main__':
person_subscriber()```