ROS通信 9.18 话题通信

ROS通信 == 核心

https://i.niupic.com/images/2022/09/18/a5iZ.png

 

话题通信

发送方基本操作

 

接收方基本操作

 

image-20220918133418620

注意

补充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 出现重复,删除内容少的即可

参考资料:https://answers.ros.org/question/237494/fatal-error-rosrosh-no-such-file-or-directory/

补充2:

find_package 不添加一些包,也可以运行啊, ros.wiki 答案如下

 You may notice that sometimes your project builds fine even if you did not call find_package with all dependencies. This is because catkin combines all your projects into one, so if an earlier project calls find_package, yours is configured with the same values. But forgetting the call means your project can easily break when built in isolation.
 Copy

补充3:

订阅时,第一条数据丢失

原因: 发送第一条数据时, publisher 还未在 roscore 注册完毕

解决: 注册后,加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送


PS:可以使用 rqt_graph 查看节点关系。

话题通信自定义

在 ROS 通信协议中,数据载体是一个较为重要组成部分,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 文件

  2. 编辑配置文件

  3. 编译生成可以被 Python 或 C++ 调用的中间文件

1.定义msg文件

功能包下新建 msg 目录,添加文件 Person.msg

 string name
 uint16 age
 float64 height
 Copy

2.编辑配置文件

package.xml中添加编译依赖与执行依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
  <!-- 
  exce_depend 以前对应的是 run_depend 现在非法
  -->
Copy

CMakeLists.txt编辑 msg 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)   //加上一个依赖的包
# 需要加入 message_generation,必须有 std_msgs
Copy
## 配置 msg 源文件
add_message_files(
  FILES
  Person.msg
)
Copy
# 生成消息时依赖于 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)
Copy
#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listener
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)
Copy

3.编译

编译后的中间文件查看:

C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)

img

Python 需要调用的中间文件(.../工作空间/devel/lib/python3/dist-packages/包名/msg)

img

后续调用相关 msg 时,是从这些中间文件调用的

话题通信自定义msg调用(c++)

需求:

编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布自定义消息,订阅方订阅自定义消息并将消息内容打印输出。

分析:

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

  1. 发布方

  2. 接收方

  3. 数据(此处为自定义消息)

流程:

  1. 编写发布方实现;

  2. 编写订阅方实现;

  3. 编辑配置文件;

  4. 编译并执行。

0.vscode 配置

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

{
    "configurations": [
        {
            "browse": {
                "databaseFilename": "",
                "limitSymbolsToIncludedHeaders": true
            },
            "includePath": [
                "/opt/ros/noetic/include/**",
                "/usr/include/**",
                "/xxx/yyy工作空间/devel/include/**" //配置 head 文件的路径 
            ],
            "name": "ROS",
            "intelliSenseMode": "gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

1.发布方

/*
    需求: 循环发布人的信息

*/

include "ros/ros.h"

include "demo02_talker_listener/Person.h"

int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");

//1.初始化 ROS 节点
ros::init(argc,argv,"talker_person");

//2.创建 ROS 句柄
ros::NodeHandle nh;

//3.创建发布者对象
ros::Publisher pub = nh.advertise&lt;demo02_talker_listener::Person&gt;("chatter_person",1000);

//4.组织被发布的消息,编写发布逻辑并发布消息
demo02_talker_listener::Person p;
p.name = "sunwukong";
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;

}

注:修改配置文件.txt:

修改文件的原因

运行上面文件,依赖与person.cpp文件,如果事前没有编译person文件,直接编译demo文件

add_dependencies(${PROJECT_NAME}node ${${PROJECT_NAME}EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

${PROJECT_NAME}_node 映射文件名字

${${PROJECT_NAME}_EXPORTED_TARGETS} 项目名称,既是功能包的名称

${catkin_EXPORTED_TARGETS})/// 感觉时固定的

出现的问题

在创建发布者对象,输入话题时,不能有空格

nh.advertiseplumbing_pub_sub::Person("student_information",1000) //"student_information这里中间不能加空格

![(https://i.niupic.com/images/2022/09/18/a5jl.png)

 

 

posted @   精通+1  阅读(122)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示