• 【ROS】机械人开发五--ROS基本概念的程序实现



    一、开发工具

    • ubuntu18.04
    • RoboWare Studio

    关于RoboWare Studio的下载,这里给出安装包的下载链接:
    链接:https://pan.baidu.com/s/1ypCs18v26PW8Of3aOunDow
    提取码:v2se

    安装前提:

    • 操作系统为ubuntu
    • 已完成ROS系统的安装配置(前面的文章已经讲了)
    • 安装 python-pip: sudo apt-get install python-pip

    下载后将其移动到虚拟机内,打开文件系统,双击安装包就行了,遇到提示就按 Esc 就行了,CSDN上安装教程有很多,这里就不多赘述了。

    至于我问什么要安装这个IDE呢?最最主要的原因就是,他可以自动修改CMakeList.txt与其他配置文件的设置,非常方便。


    二、RoboWare Studio的基本使用

    2.1 软件启动

    下载完成后在命令行输入:

    roboware-studio

    启动软件
    在这里插入图片描述


    2.2 修改界面语言

    ① 根据如下图所示,打开对应语言设置文件。
    在这里插入图片描述

    ② 将 "locale":"en" ,修改为 "locale":"zh-CN"
    在这里插入图片描述
    保存并重启系统,可以看到语言已经修改为中文了。


    2.3 使用

    ① 点击 文件,可新建工作区。
    在这里插入图片描述
    我这边已经有工作区了,就是上几节创建的 catkin_ws,选择打开工作区就行了。

    ② 右击工作区下的 src,可以选择 新建ROS包
    在这里插入图片描述
    ③ 右击 新建的ROS包,可以为其添加依赖。
    在这里插入图片描述
    在这里插入图片描述
    ④ 右击新建包ROS 目录下 src 目录,可以新建CPP文件
    在这里插入图片描述
    新建的文件后,会弹出列表,选择 加入新的可执行文件中,IDE工具则会根据CPP文件名创建一个与之同名的可执行文件(ROS节点),此时CMakeList.txt文件会自动更新。
    在这里插入图片描述


    2.4 编译文件

    ① 修改上面的编译设置为 Debug。
    在这里插入图片描述
    ② 点击小锤子,进行编译,效果与catkin_make一样。


    2.5 卸载

    命令行输入:

    sudo apt-get remove roboware-studio

    可以卸载软件


    三、话题通信

    话题通信是ROS节点通信方式的一种,它是一对多、异步的通信,方式在上一节的内容讲过了。
    这里不过赘述。
    这里讲一下一些话题命令。

    • rostopic echo :打印话题信息
    • rostopic hz : 话题频率
    • rostopic info :话题信息
    • rostopic list :列举话题
    • rostopic pub :往话题输入信息
    • rostopic bw : 话题带宽
    • rostopic find :从数据类型寻找话题
    • rostopic type :查看话题的数据类型

    四、话题的代码编写

    上几节讲了节点的概念,在ROS中,最小的进程单位称为节点(Node)。每个节点都是一个可执行文件,可以是C++或Python文件,下面这里用C++代码来实现节点。

    4.1 发布端

    打开编辑器,右击ROS包目录下的src,创建 PubForBeginner.cpp,内容如下:

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    
    int main(int argc, char **argv)
    {
        //initial and name node
        ros::init(argc, argv, "publisher");
        //create nodehandle
        ros::NodeHandle nh;
        //create publisher
        ros::Publisher simplepub = nh.advertise<std_msgs::String>("string_topic",100);
        ros::Rate rate(10);
        //message for publish
        std_msgs::String pubinfo;
        pubinfo.data = "Hello, I'm Publisher!";
        while(ros::ok())
        {
            simplepub.publish(pubinfo);
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • ros::init :创建 ros 节点,并命名为 publisher。
    • ros::NodeHandle :创建 节点的句柄。
    • ros::Publisher simplepub:创建发布者,并在主题名为 string_topic 的主题上发布类型为的消息。
    • std_msgs::String pubinfo; 定义的消息类型。
    • simplepub.publish(pubinfo); 发布数据

    4.2 接收端

    打开编辑器,右击ROS包目录下的src,创建 SubForBeginner.cpp,内容如下:

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    
    using namespace std;
    
    void subCallback(const std_msgs::String& submsg)
    {
        string subinfo;
        subinfo = submsg.data;
        ROS_INFO("The message subscribed is: %s",subinfo.c_str());
    }
    int main(int argc,char** argv)
    {
        //initial and name node
        ros::init(argc,argv,"subscriber");
        //create nodehandle
        ros::NodeHandle nh;
        //create subscriber
        ros::Subscriber sub = nh.subscribe("string_topic",1000,&subCallback);
        ros::spin();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • subCallback:订阅节点的回调函数,对接收的消息进行打印处理。
    • ros::Subscriber sub :订阅 主题名为 string_topic 上的消息,接收到消息后调用回调函数处理。
    • ros::spin(); :ROS消息的回调处理函数,程序运行到这里后不再往下处理。

    4.3 测试

    ① 首先点击编译。
    在这里插入图片描述
    编译失败,可以在 ②位置处寻找问题,如果是语法问题,编译器里会使用 红线 勾出。

    ② 打开一个终端输入:

    roscore
    在这里插入图片描述

    ③ 再分别打开两个终端,在两个终端分别输入下面的命令:
    格式:rosrun 包名 cpp文件名(节点名)

    rosrun pub_dis_02 SubForBeginner
    在这里插入图片描述
    rosrun pub_dis_02 PubForBeginner
    在这里插入图片描述

    ④ 在 接收端可以看到实验结果:
    在这里插入图片描述
    ⑤ 新建一个终端输入命令 rosrun rqt_graph rqt_graph,可以查看节点间通信的通信关系。
    在这里插入图片描述


    五、自定义消息

    根据上面的代码我们知道,发布与接收的消息需要遵循同一种类型,ROS系统已经帮我们定义了一些常用的数据类型。例如上面代码我们使用的。

    当有些时候,当系统的消息类型无法满足我们的使用时,我们就需要自定义消息类型来使用。

    这里重新建一个ROS包,来演示自定义消息类型。

    5.1 自定义消息类型

    ① 我们又新建了一个ROS包,使用和上面相同的ROS包依赖。在 RoboWare Studio 中,右击ROS包,就可以创建 msg 文件夹,在msg创建自定义消息文件,格式为.msg。或者可以直接敲命令进行创建。但自定义消息文件必须储存在msg文件夹内。
    在这里插入图片描述
    ② 在msg 文件夹内创建 Student.msg。文件名可以自定义。内容包含如下:
    在这里插入图片描述

    string name
    float64 height
    float64 weight
    
    • 1
    • 2
    • 3

    内容是:

    • 字符串类型 ,保存学生姓名
    • 64位的数据类型,保存学生的身高
    • 64位的数据类型,保存学生的体重

    ③ 在创建了自定义类型后,需要在ROS包目录下修改以下内容(如果文件中已经修改了,就不管)
    package.xml文件修改:

    • 添加:message_generation
    • 添加:message_runtime

    CMakeLists.txt文件修改:

    • 修改:find_package (catkin REQUIRED COMPONENTS roscpp std_msgs message_generation),就是添加message_generation
    • 打开注释,且有以下内容:add_message_files( FILES Message1.msg ),Message1为你自己自定义msg文件名
    • 打开注释,且有以下内容:generate_messages( DEPENDENCIES std_msgs )
    • 打开注释,且有以下内容:catkin_package( CATKIN_DEPENDS message_runtime … )

    ④ 点击编译,就可以在工作空间目录下,的devel目录下找到Student.h。我们使用自定义类型时,包含这个头文件就行了。
    在这里插入图片描述


    5.2 自定义消息发布端

    #include "ros/ros.h"
    #include "book_msg_03/Student.h"
    #include 
    
    using namespace std;
    
    int main(int argc, char **argv)
    {
        //initial and name node
        ros::init(argc, argv, "node_MsgPub");
    
        if(argc != 4)
        {
            cout << "Error command parameter!\n"\
            << "Please run command eg:\n"\
            << "rosrun book_msg_03 Book_MsgPub name height weight" << endl;
            return -1;
        }
    
        //create node handle
        ros::NodeHandle nh;
    
        //create messge publisher
        ros::Publisher MsgPub = nh.advertise<book_msg_03::Student>("MyMsg", 100);
        book_msg_03::Student stdmsg;
        stdmsg.name = argv[1];
        stdmsg.height = atof(argv[2]);
        stdmsg.weight = atof(argv[3]);
    
        ros::Rate rate(10);
        while(ros::ok())
        {
            MsgPub.publish(stdmsg);
            rate.sleep();
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • if(argc != 4) :提醒用户如何使用该节点。
    • ros::Publisher MsgPub = nh.advertise(“MyMsg”, 100); 这里我们使用了自定义消息类型,格式为ROS包名::自定义消息类型。
    • rate.sleep(); 固定发送消息的频率。

    5.3 自定义消息接收端

    #include "ros/ros.h"
    #include "book_msg_03/Student.h"
    
    // custom defined message callback function
    void MsgCallback(const book_msg_03::Student &stdInfo)
    {
        ROS_INFO("The student information is:\n name:%s--height:%f--weight:%f",
            stdInfo.name.c_str(),
            stdInfo.height,
            stdInfo.weight);
    
    }
    
    int main(int argc, char *argv[])
    {
        //initial and name node
        ros::init(argc, argv, "node_MsgSub");
        //create node handle
        ros::NodeHandle nh;
        //create subscriber
        ros::Subscriber MsgPub = nh.subscribe("MyMsg" ,100, &MsgCallback);
        ros::spin();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    类似之前的接收端程序,不过这里使用的是自定义的学生消息数据类型。


    5.4 测试

    ① 首先点击编译。
    在这里插入图片描述
    编译失败,可以在 ②位置处寻找问题,如果是语法问题,编译器里会使用 红线 勾出。

    ② 打开一个终端输入:

    roscore
    在这里插入图片描述

    ③ 再分别打开两个终端,在两个终端分别输入下面的命令:
    格式:rosrun 包名 cpp文件名(节点名)

    rosrun book_msg_03 Book_MsgSub
    在这里插入图片描述
    rosrun book_msg_03 Book_MsgPub xiaoming 180 74
    在这里插入图片描述

    ④ 在 接收端可以看到实验结果:
    在这里插入图片描述

    ⑤ 新建一个终端输入命令 rosrun rqt_graph rqt_graph,可以查看节点间通信的通信关系。
    在这里插入图片描述


    到这里就结束啦!
    在这里插入图片描述

  • 相关阅读:
    吐血整理,Jmeter服务端性能测试-线程阻塞问题案例分析(超细)
    ASEMI整流桥GBU610参数,GBU610规格
    Linux - lsof显示 tcp,udp 的端口和进程
    学姐想学SpringBoot?连夜整理了一份SpringBoot高阶笔记,涵盖六大核心专题
    Linux基础概要
    智能资产时代:探索Web3对数字资产的变革
    k8s 新版本 部署 Ingress-nginx controller
    创造者设计模式
    HTTP与TCP的特点
    【C++杂货铺】继承由浅入深详细总结
  • 原文地址:https://blog.csdn.net/qq_51447215/article/details/127964411