当前位置: 首页 > news >正文

嘉兴网站制作百度网盘网页版入口官网

嘉兴网站制作,百度网盘网页版入口官网,局域网电脑做网站服务器,郑州网站建设网络推广1.简单介绍 话题通信是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:一个节点发布消息,另一个节点订阅该消息。像雷达、摄像头、GPS… 等等一些传感器数据的采集,也都是使用了话题通信,换言之…

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 Master,Talker 与 Listern 照常通信。




3.模型实现(C++)

首先创建工作空间,并shift+ctrl+B配置好编译文件,然后创建功能包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 <sstream>int 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.advertise<std_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.subscribe<std_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 height

2.编辑配置文件
package.xml中添加编译依赖与执行依赖

  <build_depend>message_generation</build_depend><exec_depend>message_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的调用(C++)

vscode 配置
为了方便代码提示以及避免误抛异常,需要先配置 vscode,将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性:

右击头文件所在的包,在集成终端中打开,并输入pwd
会得到这个头文件的路径
在这里插入图片描述
在这里插入图片描述
把这个路径复制到这个文件的includePath中,把最后的包名改成 * * 可以包括进所有包,添加的时候,前一条路径最后面的逗号别忘了加
在这里插入图片描述


发布方
和之前一样的道理,只不过发送的消息不同

/*需求: 循环发布人的信息*/#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"int 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.advertise<plumbing_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.h"void 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.subscribe<plumbing_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}
)

在这里插入图片描述
在这里插入图片描述


然后编译运行即可。。。。效果和之前差不多,不过这次的消息类型是自定义的。


节点关系图
在这里插入图片描述

http://www.hrbkazy.com/news/8506.html

相关文章:

  • 镇江做网站的公司昆明网站seo优化
  • 查询网站是否做301如何在百度上发表文章
  • 上海外贸网站推广方法让顾客进店的100条方法
  • 做外贸最好的网站建设浙江seo关键词
  • 住房城乡建设门户网站百度一下手机版
  • 如何做网站的关键词排名抚顺优化seo
  • 四川城乡建设厅官方网站seo网络推广优化
  • 新疆建设兵团130团网站美国seo薪酬
  • 宜昌网站设计公司百度官网认证价格
  • 有哪些公司网站建设比较好汽油价格最新调整最新消息
  • wordpress把头像改为QQ头像seo优化与sem推广有什么关系
  • 网站制作呼和浩特枫树seo网
  • 做轻奢品的电商网站网络营销服务外包
  • 青浦网站建设推广西安区seo搜索排名优化
  • 淮安做网站.哪家网络公司好?郑州网络营销推广
  • 建政府网站公司网络推广是做什么工作
  • 阿里巴巴国际网站官网入口互动营销策略
  • 虎门镇仿做网站怎么制作百度网页
  • 网站被人做跳转网站搜索引擎优化案例
  • seo全称铁岭网站seo
  • wordpress 建站简单吗发软文是什么意思
  • 藤虎网络广州网站建设如何在各大网站发布信息
  • 中山建网站网站seo诊断分析和优化方案
  • 广东建设网官网武汉seo推广
  • 沈总网站建设深圳seo推广
  • 泊头那家做网站磁力链
  • 深圳市建设工程交易中心网站seo关键词排名技术
  • 江门北京网站建设推广计划书范文
  • 网络私人定制网站seo建站网络公司
  • 网站制作难吗推广app用什么平台比较好