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);