话题通讯
- 前言
- 理论模型
- 自定义消息配置与解释
- Package调整
- CmakeLists调整
- 检查生效
- 发布方实现
- C++
- python
- 接收方实现
- C++
- python
- 测试与注意事项
前言
本文主要是跟着audolabor学习ROS笔记,多为操作性质,并从另一种角度对实现的顺序进行调整,想要多学习,可以参考autolabor教程
理论模型
话题通讯包含发布方,实现方和ROS Master,我们在编写程序时,只需要在意发布方和实现方的实现已经两者之间的联系方式。两者之间的联系方式是依靠共同的话题(图中的bar),话题一致,接受方就可以接受发布方的消息
自定义消息配置与解释
ROS自带的消息比较单一,我们有时需要自己定义一下消息的类型,此时需要对Cmakelists等配置进行较大的调整,首先在工作环境新建一个msg文件夹,里面建立msg文件,保存为Person.msg
string name
uint16 age
Package调整
在package.xml中添加以下代码
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
注意,编译时,只需要message_generation,而在运行时,需要message_runtime
CmakeLists调整
打开工作目录src下的CmakeLists,改变以下代码
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
add_message_files(
FILES
Person.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES demo02_talker_listener
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
检查生效
编译后,使用rosmsg命令。一定要source一下,不然会找不到msg
rosmsg show Person
返回person.msg内容说明msg生效
发布方实现
C++
- 配置环境,为了使vscode不误报错误,在c_cpp_properties.json中的includepath中添加编译后生成的Person.h头文件,一般为:工作空间/devel/include/**
- 编写实现,代码如下:
#include "ros/ros.h"
#include "huati/Person.h" //huati为包名
int main( int argc, char *argv[])
{
ros::init(argc,argv,"pub_cpp");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<huati::Person>("huati1",10);//huati1是pub_cpp发布的话题
huati::Person person;
person.name = "zhangsan";
person.age = 18;
ros::Rate rate(1);//发送频率
ros::Duration(2.0).sleep();//防止丢失数据
while(ros::ok())
{
pub.publish(per);
per.age++;
rate.sleep();
ros::spinOnce();
}
return 0;
}
/*
编写完程序后记得对CmakeLists文件做调整,与正常相比还需要添加以下代码:
add_dependencies(person_talker ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(person_listener ${PROJECT_NAME}_generate_messages_cpp)
*/
cpp程序中,逻辑的实现依靠ros名称空间,所需要的函数与变量定义都在ros名称空间里,通过ros::使用。
python
- 配置环境,在setting.json中的python.autoComplete.extraPaths添加编译后自定义消息的库,位置通常在:工作空间/devel/lib/python3/dist-packages
- 代码如下:
#! /usr/bin/env python
import rospy
from huati.msg import Person #huati是包名
if __name__ == "__main__":
rospy.init("pub_py")
pub = rospy.Publisher("huati2",Person,10)
person = Person() #创建发布消息对象
person.name = "Reese"
person.age = 30
rate = rospy.Rate(1) #发送频率1Hz
rospy.sleep(2)
while not rospy.is_shutdown():
pub.publish(person)
person.age += 1
rate.sleep()
接收方实现
C++
代码如下:
#include "ros/ros.h"
#include "huati/Person.h"
void domsg(const huati::Person::Constptr& msg)//回调函数
{
ROS_INFO("姓名是:%s,年龄是:%d",msg->name.c_str(),msg->age);
}
int main( int argc, char *argv[])
{
ros::init(argc,argv,"sub_cpp");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("huati1",10,domsg);
ros::spin();
return 0;
}
python
#! /usr/bin/env python
import rospy
from huati.msg import Person
def domsg(msg):
rospy.info("姓名是%s,年龄是%d"msg.name,msg.age)
if __name__ == "__main__":
rospy.init("sub_py")
sub = rospy.Subscriber("huati2",Person,domsg,queue_size = 10)
rospy.spin()
测试与注意事项
- python与cpp程序编写完成后需要配置cmakeLists文件
- python需要添加可执行权限
- 终端运行时需要source环境变量
更多推荐
1,话题通讯C++与python
发布评论