网站建设制作设计开发网站设计 线框图
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:39
当前位置: 首页 > news >正文
网站建设制作设计开发,网站设计 线框图,专业响应式网站制作,数字媒体艺术全球大学排名1.简单介绍 话题通信是ROS中使用频率最高的一种通信模式#xff0c;话题通信是基于发布订阅模式的#xff0c;也即:一个节点发布消息#xff0c;另一个节点订阅该消息。像雷达、摄像头、GPS… 等等一些传感器数据的采集#xff0c;也都是使用了话题通信#xff0c;换言之…1.简单介绍 话题通信是ROS中使用频率最高的一种通信模式话题通信是基于发布订阅模式的也即:一个节点发布消息另一个节点订阅该消息。像雷达、摄像头、GPS… 等等一些传感器数据的采集也都是使用了话题通信换言之话题通信适用于不断更新的、少逻辑处理的数据传输场景。 2.理论模型 该模型中涉及到三个角色: ROS Master (管理者) Talker (发布者) Listener (订阅者) ROS Master 负责保管 Talker 和 Listener 注册的信息并匹配话题相同的 Talker 与 Listener帮助 Talker 与 Listener 建立连接连接建立后Talker 可以发布消息且发布的消息会被 Listener 订阅。 整个流程由以下步骤实现引用自Autolabor-ROS: 0.Talker注册 Talker启动后会通过RPC在 ROS Master 中注册自身信息其中包含所发布消息的话题名称。ROS Master 会将节点的注册信息加入到注册表中。 1.Listener注册 Listener启动后也会通过RPC在 ROS Master 中注册自身信息包含需要订阅消息的话题名。ROS Master 会将节点的注册信息加入到注册表中。 2.ROS Master实现信息匹配 ROS Master 会根据注册表中的信息匹配Talker 和 Listener并通过 RPC 向 Listener 发送 Talker 的 RPC 地址信息。 3.Listener向Talker发送请求 Listener 根据接收到的 RPC 地址通过 RPC 向 Talker 发送连接请求传输订阅的话题名称、消息类型以及通信协议(TCP/UDP)。 4.Talker确认请求 Talker 接收到 Listener 的请求后也是通过 RPC 向 Listener 确认连接信息并发送自身的 TCP 地址信息。 5.Listener与Talker件里连接 Listener 根据步骤4 返回的消息使用 TCP 与 Talker 建立网络连接。 6.Talker向Listener发送消息 连接建立后Talker 开始向 Listener 发布消息。 注意1:上述实现流程中前五步使用的 RPC协议最后两步使用的是 TCP 协议 注意2: Talker 与 Listener 的启动无先后顺序要求 注意3: Talker 与 Listener 都可以有多个 注意4: Talker 与 Listener 连接建立后不再需要 ROS Master。即便关闭ROS MasterTalker 与 Listern 照常通信。 3.模型实现© 首先创建工作空间并shiftctrlB配置好编译文件然后创建功能包plumbing_pub_sub并添加依赖然后创建cpp源文件 在模型实现中ROS master 不需要实现而连接的建立也已经被封装了所以大体流程如下 1.编写发布方实现 2.编写订阅方实现 3.编辑配置文件 4.编译并执行。 1.发布方实现demo01_pub.cpp /需求: 实现基本的话题通信一方发布数据一方接收数据实现的关键点:1.发送方2.接收方3.数据(此处为普通文本)PS: 二者需要设置相同的话题消息发布方:循环发布信息:HelloWorld 后缀数字编号实现流程:1.包含头文件 2.初始化 ROS 节点:命名(唯一)3.实例化 ROS 句柄4.实例化 发布者 对象5.组织被发布的数据并编写逻辑发布数据/ // 1.包含头文件 #include ros/ros.h #include std_msgs/String.h //普通文本类型的消息 #include sstreamint main(int argc, char *argv[]) { //设置编码避免中文乱码setlocale(LC_ALL,);//2.初始化 ROS 节点:命名(唯一)// 参数1和参数2 后期为节点传值会使用// 参数3 是节点名称是一个标识符需要保证运行后在 ROS 网络拓扑中唯一ros::init(argc,argv,talker);//3.实例化 ROS 句柄ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能//4.实例化 发布者 对象//泛型: 发布的消息类型//参数1: 要发布到的话题//参数2: 队列中最大保存的消息数超出此阀值时先进的先销毁(时间早的先销毁)ros::Publisher pub nh.advertisestd_msgs::String(chatter,10);//5.组织被发布的数据并编写逻辑发布数据//数据(动态组织)std_msgs::String msg;std::string msg_front Hello 你好; //消息前缀int count 0; //消息计数器//逻辑(一秒1次/1HZ)ros::Rate r(1);//节点不死while (ros::ok()){//使用 stringstream 拼接字符串与编号std::stringstream ss;ss msg_front count;msg.data ss.str();//发布消息pub.publish(msg);//加入调试打印发送的消息ROS_INFO(发送的消息是:%s,msg.data.c_str());//根据前面制定的发送频率自动休眠 休眠时间 1/频率r.sleep();count;//循环结束前让 count 自增}return 0; } 2.订阅方实现demo02_sub.cpp /需求: 实现基本的话题通信一方发布数据一方接收数据实现的关键点:1.发送方2.接收方3.数据(此处为普通文本)消息订阅方:订阅话题并打印接收到的消息实现流程:1.包含头文件 2.初始化 ROS 节点:命名(唯一)3.实例化 ROS 句柄4.实例化 订阅者 对象5.处理订阅的消息(回调函数)6.设置循环调用回调函数/ // 1.包含头文件 #include ros/ros.h #include std_msgs/String.h//通过msg_p获取并操作订阅到的数据 void doMsg(const std_msgs::String::ConstPtr msg_p){ROS_INFO(我听见:%s,msg_p-data.c_str());// ROS_INFO(我听见:%s,(*msg_p).data.c_str()); }int main(int argc, char *argv[]) {setlocale(LC_ALL,);//2.初始化 ROS 节点:命名(唯一)ros::init(argc,argv,listener);//3.实例化 ROS 句柄ros::NodeHandle nh;//4.实例化 订阅者 对象//5.处理订阅的消息(回调函数)ros::Subscriber sub nh.subscribestd_msgs::String(chatter,10,doMsg);//6.设置循环调用回调函数ros::spin();//循环读取接收的数据并调用回调函数处理return 0; } 3.编辑配置文件CMakeList add_executable(demo01_pubsrc/demo01_pub.cpp ) add_executable(demo02_subsrc/demo02_sub.cpp )target_link_libraries(demo01_pub\({catkin_LIBRARIES} ) target_link_libraries(demo02_sub\){catkin_LIBRARIES} ) 然后ctrl shift B 编译后再执行编译完成后启动roscore 再启动发布节点再启动订阅节点效果如下。。。 一些注意事项 补充0: vscode 中的 main 函数 声明 int main(int argc, char const argv[]){}默认生成 argv 被 const 修饰需要去除该修饰符 补充1: ros/ros.h No such file or directory … 检查 CMakeList.txt find_package 依赖出现重复,删除多出来的包即可 补充2: 订阅时第一条数据丢失 原因: 发送第一条数据时 publisher 还未在 roscore 注册完毕 解决: 注册后加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送 补充3: 可以新开一个终端输入rqt_graph查看计算图 4.话题通信自定义msg ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是这些数据一般只包含一个 data 字段结构的单一意味着功能上的局限性当传输一些复杂的数据比如: 激光雷达的信息… std_msgs 由于描述性较差而显得力不从心这种场景下可以使用自定义的消息类型 msgs只是简单的文本文件每行具有字段类型和字段名称可以使用的字段类型有 int8, int16, int32, int64 (或者无符号类型: uint) float32, float64 string time, duration other msg files variable-length array[] and fixed-length array[C] ROS中还有一种特殊类型Header标头包含时间戳和ROS中常用的坐标帧信息。会经常看到msg文件的第一行具有Header标头。 现在要自定义消息该消息包含人的信息姓名、身高、年龄等。 1.定义msg文件 功能包下新建 msg 目录添加文件 Person.msg string name uint16 age float64 height2.编辑配置文件 package.xml中添加编译依赖与执行依赖 build_dependmessage_generation/build_dependexec_dependmessage_runtime/exec_depend一条是编译一条是运行 CMakeLists.txt编辑 msg 相关配置 find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation )
需要加入 message_generation,必须有 std_msgs放开后多添加一个编译依赖 ## 配置 msg 源文件
add_message_files(FILESPerson.msg )放开后添加自定义msg文件 # 生成消息时依赖于 std_msgs generate_messages(DEPENDENCIESstd_msgs )直接找到并放开 #执行时依赖 catkin_package(
INCLUDE_DIRS include
LIBRARIES demo02_talker_listenerCATKIN_DEPENDS roscpp rospy std_msgs message_runtime
DEPENDS system_lib
)放开后多添加一个执行依赖 然后编译生成中间文件之后只要调用头文件就可以正常使用了。 5.自定义msg的调用© vscode 配置 为了方便代码提示以及避免误抛异常需要先配置 vscode将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性: 右击头文件所在的包在集成终端中打开并输入pwd 会得到这个头文件的路径 把这个路径复制到这个文件的includePath中把最后的包名改成 * * 可以包括进所有包添加的时候前一条路径最后面的逗号别忘了加 发布方 和之前一样的道理只不过发送的消息不同 /需求: 循环发布人的信息/#include ros/ros.h #include plumbing_pub_sub/Person.hint main(int argc, char *argv[]) {setlocale(LC_ALL,); //避免输出乱码//1.初始化 ROS 节点ros::init(argc,argv,banZhuRen);//2.创建 ROS 句柄ros::NodeHandle nh;//3.创建发布者对象ros::Publisher pub nh.advertiseplumbing_pub_sub::Person(chatter_person,1000);//4.组织被发布的消息编写发布逻辑并发布消息//创建被发布的数据plumbing_pub_sub::Person p;p.name 孙悟空;p.age 2000;p.height 1.45;//发布频率ros::Rate r(1);//循环发布while (ros::ok()){pub.publish(p);p.age 1;ROS_INFO(我叫:%s,今年%d岁,高%.2f米, p.name.c_str(), p.age, p.height);r.sleep();ros::spinOnce();}return 0; }订阅方 /需求: 订阅人的信息/#include ros/ros.h #include plumbing_pub_sub/Person.hvoid doPerson(const plumbing_pub_sub::Person::ConstPtr person_p){ROS_INFO(订阅的人信息:%s, %d, %.2f, person_p-name.c_str(), person_p-age, person_p-height); }int main(int argc, char *argv[]) { setlocale(LC_ALL,);//1.初始化 ROS 节点ros::init(argc,argv,jiaZhang);//2.创建 ROS 句柄ros::NodeHandle nh;//3.创建订阅者对象//4.回调函数中处理 personros::Subscriber sub nh.subscribeplumbing_pub_sub::Person(chatter_person,10,doPerson);//5.转头执行回调函数ros::spin();return 0; }配置CMakeList 需要添加 add_dependencies 用以设置所依赖的消息相关的中间文件。 以保证先编译自定义msg文件再去编译cpp源文件 add_executable(新发布方源文件名 src/源文件名.cpp) add_executable(新订阅方源文件名 src/源文件名.cpp)add_dependencies(新发布方源文件名 \({PROJECT_NAME}_generate_messages_cpp) add_dependencies(新订阅方源文件名 \){PROJECT_NAME}_generate_messages_cpp)target_link_libraries(新发布方源文件名\({catkin_LIBRARIES} ) target_link_libraries(新订阅方源文件名\){catkin_LIBRARIES} )然后编译运行即可。。。。效果和之前差不多不过这次的消息类型是自定义的。 节点关系图
- 上一篇: 网站建设制作设计公司佛山网页设计教程清华大学出版社
- 下一篇: 网站建设制作设计施工者网官网
相关文章
-
网站建设制作设计公司佛山网页设计教程清华大学出版社
网站建设制作设计公司佛山网页设计教程清华大学出版社
- 技术栈
- 2026年03月21日
-
网站建设制作汕头网站换新的空间域名解析怎么做
网站建设制作汕头网站换新的空间域名解析怎么做
- 技术栈
- 2026年03月21日
-
网站建设制作确认单万能搜索引擎
网站建设制作确认单万能搜索引擎
- 技术栈
- 2026年03月21日
-
网站建设制作设计施工者网官网
网站建设制作设计施工者网官网
- 技术栈
- 2026年03月21日
-
网站建设制作设计营销公司杭州秦皇岛信息平台
网站建设制作设计营销公司杭州秦皇岛信息平台
- 技术栈
- 2026年03月21日
-
网站建设制作设计营销公司南宁代理注册公司的风险
网站建设制作设计营销公司南宁代理注册公司的风险
- 技术栈
- 2026年03月21日
