ros学习笔记(11.14实时更新中)

  • Post author:
  • Post category:其他

0.引言

关于深度学习的学习不能仅仅顾着一个CV领域,也需要很多配套的知识,比如图像学、图像处理、信号处理、图像编码、web、应用端;硬件部分则是ROS、slam、plc、嵌入式
作为一个专硕,没必要太深耕课题,提高知识的广度更有必要,故现在开始学习
大部分内容是基于赵虚左老师的视频和讲义:ros赵虚左

1.安装和配置环境

1.1虚拟机

ros、slam的一些项目大都是基于linux系统的,所以要不双系统要不使用虚拟机,这里建议使用甲骨文的virtualbox,免费开源而且比vm ware轻量化和快捷。然后配置ubuntu的系统,现在主流的Linux系统就是ubuntu。网上有很多现成的教程,记得安装virtualbox tools

1.2ROS安装

首先需要更新 aptapt 是用于从互联网仓库搜索、安装、升级、卸载软件或操作系统的工具。类似于pip和conda

sudo apt update

然后调用,意思是按照官方推荐的配置安装桌面化的ros

sudo apt install ros-noetic-desktop-full

太卡的化记得换源,阿里、豆瓣、中科、清华等等

sudo sh -c ‘. /etc/lsb-release && echo “deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ lsb_release -cs main” > /etc/apt/sources.list.d/ros-latest.list’

1.3测试

在linux里启动三个终端,分别输入:
命令行1键入:roscore 意味着启动ros核心,不管什么ros程序,cpp、py的都需要启用ros

命令行2键入:rosrun turtlesim turtlesim_node(此时会弹出图形化界面)
rosrun xx yy相当于python xx,其中xx代表功能包名或者可以理解为项目名,在这里turtlesim代表我们使用龟龟这个包,yy代表程序名或者可以理解为功能名或者节点名(节点在ros很重要,相当于类,但我感觉ros是面向过程的,结点只相当于一个功能的触发器),在这里turtlesim_node代表召唤乌龟。

命令行3键入:rosrun turtlesim turtle_teleop_key
同上,只是turtle_teleop_key代表键盘输入,可以控制龟龟行走。
三个命令虽然是顺序输入的,但是在terminal中耦合性太强了,所以要三个终端来分别控制。后面学习了launch之后就好了一些,launch就是类似bash。
在这里插入图片描述

2.通信

三种通信模式:话题通信(发布订阅模式),服务通信(请求响应模式),参数服务器(参数共享模式)

2.1 话题通信

在这里插入图片描述
最简单的握手:发布方先发布消息,然后接收方再接受消息,接收方没接受的话,发布的消息放在队列中等待,队列前的先销毁。
发布方:

/*
    需求: 实现基本的话题通信,一方发布数据,一方接收数据,
         实现的关键点:
         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;
    // msg.data = "你好啊!!!";
    std::string msg_front = "Hello 你好!"; //消息前缀
    int count = 0; //消息计数器

    //逻辑(一秒10)
    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 自增
        //暂无应用
        ros::spinOnce();
    }


    return 0;
}

接收方

/*
    需求: 实现基本的话题通信,一方发布数据,一方接收数据,
         实现的关键点:
         1.发送方
         2.接收方
         3.数据(此处为普通文本)


    消息订阅方:
        订阅话题并打印接收到的消息

    实现流程:
        1.包含头文件 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 ROS 句柄
        4.实例化 订阅者 对象
        5.处理订阅的消息(回调函数)
        6.设置循环调用回调函数

*/
// 1.包含头文件 
#include "ros/ros.h"
#include "std_msgs/String.h"

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.实例化 订阅者 对象
    ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
    //5.处理订阅的消息(回调函数)

    //     6.设置循环调用回调函数
    ros::spin();//循环读取接收的数据,并调用回调函数处理

    return 0;
}

在执行cpp的程序时候,一定要先把配置文件给写好,先编译再运行。

2.2msg打包

不打包的话,使用std_msgs只能使用单一数据类型的字段
ros::Subscriber sub = nh.subscribe<std_msgs::String>(“chatter”,10,doMsg);
ros::Publisher pub = nh.advertise<std_msgs::String>(“chatter”,10);


版权声明:本文为qq_41950533原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。