一. ROS的节点和包
✨Node: ROS的基本单位,实现某个功能的节点。比如实现超声波传感器就是一个节点,雷达传感器就可以是一个节点
✨Package: 多个有联系的节点组成的单位,比如你要控制无人机姿态,可能需要多个节点(也就是多个传感器互相配合),如陀螺仪传感器,雷达,超声波传感器等等。我们就可以把这些联系的节点打包就是package。
✨这里我使用哔哩哔哩机器人工匠阿杰博主的视频例子作为说明。
✨节点通过订阅发布这种模式互相传递消息。可以的对应关系如下:
二,添加发布节点
✨既然我们要发布消息,就需要查看ROS支持的标准消息包类型。输入进入ROS的官网:ROS官网
输入std_msgs,点击搜索
✨ 找到我们ROS对应的版本,Ubuntu18.04的是melodic.没装对可以参考我之前的博客。手把手教Ubuntu18.04安装melodic环境,一个是虚拟机,一个是服务器版本(带有1080显卡)
参考一
参考二
✨ 点击Website
✨就可以查看到消息的信息支持列表
✨在上一篇文章当中我们使用catkin工具新建了节点工具包,具体参考如下。
✨ROS添加节点
- 使用如下命令:
- catkin_create_pkg ssr_pkg rospy roscpp std_msgs
2.1输入我们节点代码
✨我们就可以使用图片指令进行运行
- rosrun ssr_pkg chao_node
#include<ros/ros.h>
#include<std_msgs/String.h>int main(int argc, char *argv[])
{ros::init(argc, argv, "chao_node");printf("小马同学,hello welcome coming Ros world! \n ");// 建立节点句柄ros::NodeHandle nh;//建立发布者ros::Publisher pub=nh.advertise<std_msgs::String>("play_game_topic",10);//控制循环次数,ros系统给我自带了控制语句,不用我们自己写睡眠函数ros::Rate loop_rate(10); // publish 10 times of per secondwhile(ros::ok()){printf("xiaoma will carry !\n");//开始定义标准消息包、std_msgs::String msg;msg.data="please come on!\n";//给发布者发布pub.publish(msg);loop_rate.sleep();//调用loop_rate的sleep函数,让其产生短暂的阻塞}return 0;
}
✨备注:ROS里面while循环要使用ROS::OK(),否则无法效应外界,按CTRL+C都没用。
✨然后,发现我们的主题名称不合法。修改我们的主题名称,26个大小字符和下划线。即可成功运行
✨使用rostopic list工具可以查看我们的话题活跃类型
✨rostopic echo /我们自己的主题(topic名称)可以查看消息内容
2.2小结
✨同理我们可以使用相同方法构建另外一个节点主题,新建yao_node.cpp
#include<ros/ros.h>
#include<std_msgs/String.h>int main(int argc, char *argv[])
{ros::init(argc, argv, "yao_node");printf("小李同学,hello welcome coming Ros world! \n ");// 建立节点句柄ros::NodeHandle nh;//建立发布者ros::Publisher pub=nh.advertise<std_msgs::String>("xiang_he_xiao_ma_wan_you_xi",10);//控制循环次数,ros系统给我自带了控制语句,不用我们自己写睡眠函数ros::Rate loop_rate(10); // publish 10 times of per secondwhile(ros::ok()){printf("xiaoli will follow !\n");//开始定义标准消息包、std_msgs::String msg;msg.data="i am about coming on!,waiting for me\n";//给发布者发布pub.publish(msg);loop_rate.sleep();//调用loop_rate的sleep函数,让其产生短暂的阻塞}return 0;
}
✨新建订阅节点,因为订阅和发布时分开的,我们需要再使用catkin根据新建一个包
在新建的包的src文件夹里面新建ma_node.cpp文件。**
#include<ros/ros.h>
#include<std_msgs/String.h>void xiaoli_callback(std_msgs::String msg)
{ROS_INFO(msg.data.c_str());
}void play_game_callback(std_msgs::String msg)
{ROS_WARN(msg.data.c_str());//这个输出语句只是把输出内容变成还黄色
}int main(int argc, char *argv[])
{ros::init(argc, argv, "ma_node");printf("马同学,我将接受发布者的消息! \n ");// 建立节点句柄ros::NodeHandle nh;//建立订阅者1ros::Subscriber sub=nh.subscribe<std_msgs::String>("xiang_he_xiao_ma_wan_you_xi",10,xiaoli_callback);//建立订阅者2不能和第一个名字一样ros::Subscriber sub2=nh.subscribe<std_msgs::String>("play_game_topic",10,play_game_callback);while(ros::ok()){ros::spinOnce();}return 0;
}
✨同样,别忘了在CMakeLists.txt文件里面末尾添加如下两句。
add_executable(ma_node src/ma_node.cpp) #添加执行文件,我们这里ma_node.cpp
target_link_libraries(ma_node
${catkin_LIBRARIES}
) #详细说明连接库
✨我们都把节点运行起来,使用rosrun指令(参考之前运行的chao_node节点)
三 常用工具使用
- rqt_graph # 查看节点之间的信息传递关系
3.1 XML文件一下子启动全部节点
✨定义:XML(可扩展标记语言)是一种用于存储和传输数据的文本格式。它是一种可扩展的、标签化的数据描述语言,旨在提供一种通用的数据格式,以便不同应用程序和平台之间可以轻松地交换信息。
XML文件由一系列标签和文本内容组成,其中标签用于标识数据的结构和含义。每个标签通常包含一个元素(element),可以有属性(attributes)和子元素(子标签)。XML文本使用标签来描述数据的层次结构,使得数据可以按照树状结构进行组织。
如描述纸盒中有小纸盒
✨描述阵容
✨类比我们可以描述我们的节点
✨直接运行全部代码