ROS学习记录(二)

本文介绍了如何在Ubuntu上安装ROSnoetic,并使用VSCode作为代码编辑器。通过创建节点和包,演示了如何实现超声波节点。文章详细阐述了ROS中的话题通讯机制,包括Publisher和Subscriber的使用,并提供了C++实现示例。最后,展示了如何使用launch文件启动多个节点。
摘要由CSDN通过智能技术生成

一、环境搭建

在ubuntu安装好ROS后(可以尝试鱼香ROS的方法,终端输入wget http://fishros.com/install -O fishros && . fishros),本人用的是noetic版本,使用的代码编译工具是vscode,并在其中安装了ROS插件,同时安装了超级终端工具,方便ROS的调试。推荐安装教程

二、节点与包

我们在使用ROS时,实际是在使用ROS的一些节点(node),例如建图节点、导航节点、控制底盘节点、控制雷达节点等,ROS机器人所实现的功能,实际是这些节点堆在一起的运行结果。虽然ROS的基础单元时节点(node),但实际上我们所使用的节点都被封装在软件包(package)里了,我们一般都把项目所需的软件包(package)下载下来,进而使用软件包(package)里的节点(node)。所以,可以理解包为节点的容器,节点不能脱离包而存在。

三、实现一个节点

加入我们要实现一个超声波节点,即超声波_node,因为节点不能脱离包而存在,所以我们需要给节点找一个上级组织,命名为ssr_pkg。

  1. 在目录下新建一个catkin_ws文件夹,并在里面再建立一个src文件夹,并在终端执行catkin_init_workspace,之后会生成cmakelist文件,再回到上一级目录执行catkin_make进行编译,会生成build,devel文件夹

  1. 再执行catkin_make install,生成install文件夹

  1. 再进入src文件夹,执行catkin_create_pkg test_pkg roscpp rospy std_msgs,生成文件夹以及相关依赖。意思是catkin_create_pkg <包名> <依赖项列表>

  1. 在返回工程文件夹(catkin文件夹下),执行catkin_make,完成编译

  1. 接着我们进入到src文件夹下,在终端输入

code .

在vscode下打开了项目源码

  1. 接着需要完成环境参数的配置,在桌面的.bashrc文件添加如下代码

source 路径/catkin_ws/devel/setup.bash
  1. 接着修改ssr_pkg文件下的CMakeLists.txt文件,完成配置,在代码最后添加如下代码

add_executable(chao_node src/chao_node.cpp)  #添加可执行文件
target_link_libraries(chao_node              #链接所需要的库
  ${catkin_LIBRARIES}
)

四、使用话题通讯方式完成不同包之间节点通讯

1.介绍

(1)话题Topic是节点间进行持续通讯的一种形式;

(2)话题通讯的两个节点通过话题的名称建立起话题通讯连接;

(3)话题中通讯的数据,叫做消息Message;

(4)消息Message通常会按照一定的频率持续不断的发送,以保证消息数据的实时性;

(5)消息的发送方叫做话题的发布者Publisher;

(6)消息的接收方叫做话题的订阅者Subscriber.

2.同时也可以多个话题(Topic)多个发布者(Publisher),发布相应的消息(Message),通常Message为传感器观测到的数据,对应为多个话题(Topic),订阅者(Subscriber)根据需要订阅需要的话题(Topic)

当然也可以一个话题(Topic)多个发布者(Publisher),例如机器人的底盘节点(底盘_node)需要订阅速度指令_topic,话题里有导航节点和跟踪节点发布的消息。

3.总结

(1).一个ROS节点网络中,可以同时存在多个话题

(2).一个话题可以有多个发布者,也可以有多个订阅者

(3).一个节点可以对多个话题进行订阅,也可以发布多个话题

(4).不同的传感器信息通常会拥有各自独立话题名称,每个话题只有一个发布者

(5).机器人速度指令话题通常会有多个发布者,但是同一时间只能有一个发言人,否则会造成抖动

五、Publisher发布者的C++实现

来完成如下的通讯实现

在src下的chao_node下编写代码如下

#include <ros/ros.h>
#include <std_msgs/String.h>


int main(int argc, char  *argv[])
{
    /* code */
    ros::init(argc, argv, "chao_node");   //节点初始化,节点名称
   
    ros::NodeHandle nh;          //创建节点管理对象nh
    ros::Publisher pub = nh.advertise<std_msgs::String>("kuai_shang_che_kai_hei_qun", 10);//创建话题和缓存长度,pub为消息发布对象


    ros::Rate loop_rate(10);     //延时,1s10次

    while(ros::ok())
    {
        std_msgs::String msg;      //创建消息对象msg
        msg.data = "国服马超,带飞";        //给消息Message赋值
        pub.publish(msg);          //发布消息
        loop_rate.sleep();

    }
    return 0;
}

编译后运行,首先执行roscore,启动ROS;再分出一个终端,执行chao_node.cpp文件,输入代码rosrun ssr_pkg chao_node;执行后发布者便可以把消息发布出来,执行代码rostopic list可以查看当前运行着的topic;

接着执行代码rostopic echo /话题名称,便可以显示发布者发布的消息,

由于编码的缘故,显示与实际输出不一致,再次执行如下代码便可正常显示

执行代码rostopic hz /话题名称,便可以显示消息发布的频率

总结:

(1).确定话题名称和消息类型

(2).在代码文件中include消息类型对应的头文件

(3).在main函数中通过NodeHandle大管家发布一个话题并得到消息发布对象

(4).生成要发送的消息包并进行发布数据的赋值

(5).调用消息发送对象的publish()函数将消息包发送到话题中

/

接着复制一个节点,命名为yao_node;代码如下

#include <ros/ros.h>
#include <std_msgs/String.h>

int main(int argc, char  *argv[])
{
    /* code */
    ros::init(argc, argv, "yao_node");
   
    ros::NodeHandle nh;
    ros::Publisher pub = nh.advertise<std_msgs::String>("gie_gie_dai_wo", 10);

    ros::Rate loop_rate(10);

    while(ros::ok())
    {
        //printf("明天见\n");
        std_msgs::String msg;
        msg.data = "求上车+++";
        pub.publish(msg);
        loop_rate.sleep();

    }
    return 0;
}

同时修改CMakeists文件

测试通过

六、Subscriber订阅者的C++实现

在catkin_ws的src文件下,使用代码catkin_create_pkg atr_pkg roscpp rospy std_msgs创建新的软件包,进入vscode,在对应的src文件下新建ma_node.cpp文件,输入代码

#include <ros/ros.h>
#include <std_msgs/String.h>

void chao_callback(std_msgs::String msg)    //回调函数
{
    ROS_INFO(msg.data.c_str());   //带时间戳显示输出
}

void yao_callback(std_msgs::String msg)
{
    ROS_WARN(msg.data.c_str());   //显示颜色不同
}

int main(int argc, char  *argv[])
{
    /* code */
    setlocale(LC_ALL, "");          //使输出正常显示
    ros::init(argc, argv, "ma_node");

    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("kuai_shang_che_kai_hei_qun",10,chao_callback);
    ros::Subscriber sub_2 = nh.subscribe("gie_gie_dai_wo",10,yao_callback);
    while (ros::ok())
    {
        ros::spinOnce();   //让回调函数能够响应接收到的消息包
    }
    
    return 0;
}

通讯图解为

同时还需配置CMaketists文件

测试通过

执行代码rqt_graph,可以图示通信网络

总结:

(1).确定话题名称和消息类型

(2).在代码文件中include <ros.h>和消息类型对应的头文件

(3).在main函数中通过NodeHandler大管家订阅一个话题并设置消息接收回调函数

(4).定义回调函数,对接受到的消息包进行处理

(5).main函数中需要执行ros::spinOnce(),让回调函数能够相应接收到的消息包

七.使用launch文件启动节点

在atr_pkg文件夹下新建launch文件夹,并在里面新建kaihei.launch文件,按照既定规则编写代码

<launch>

    <node pkg = "ssr_pkg" type = "yao_node" name = "yao_node"/>
    <node pkg = "ssr_pkg" type = "chao_node" name = "chao_node" launch-prefix = "gnome-terminal -e"/>
    <node pkg = "atr_pkg" type = "ma_node" name = "ma_node" output = "screen"/>

</launch>

总结:

(1).使用launch文件,可以通过roslaunch指令一次启动多个节点

(2).在launch文件中,为节点添加output="screen"属性,可以让节点信息输出在终端中(ROS_WARN属性不受影响)

(3).在launch文件中,为节点添加launch-prefix="gnome-terminal -e"属性,可以让节点单独运行在一个独立终端中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值