
ROS入门
机器人操作系统入门
-
liunx系统常见指令
1.1 打开终端快捷键
ctrl+alt+t

1.2,ls 然后回车 显示当前文件夹下的内容

ls是list列出清单的简写
1.3 mkdir 在当前文件夹下新建文件夹
mkdir=make directory 创建新的目录

1.4 cd 改变当前目录
cd =change directory 改变当前目录






1.5 cd .. 返回上一级目录


1.6 cd ~返回主文件夹
~=/home/用户名/当前用户主文件夹

1.7 tab键 可以用于补全指令或者目录名

自动补全:

1.7 gedit 文本编辑器
gedit 我在这里.txt

然后:


1.8 source 指令
source=执行文件中的指令序列
例子:
先用gedit 编写一个command.sh文件

内容:
echo 我来了
echo 我走了
echo 我又来了
echo意思是显示
然后

执行source

总结:在Linux系统中我们通过.sh文件用source来加载运行
1.9 ~/.bashrc文件 ~/.bashrc=终端程序启动脚本
~/.bashrc一般是看不到的,怎么才能看到 ~/.bashrc文件?
ls -a 查看所有文件


终端程序启动脚本=每次进入终端程序的时候都会首先执行这个文件
所有我们其实可以用这个文件完成一些环境变量的赋值工作
例子:通过修改/.bashrc来完成环境变量的赋值与设置的工作
1.gedit ~/.bashrc
文本编辑工作,编辑主文件夹下的.bashrc文件
gedit ~/.bashrc ## ~ 主文件夹


课堂截图:

1.10 sudo 执行管理员
sudo apt install xxx 安装软件命令
2.ROS安装
ROS类似于安卓手机系统
APT类似于软件商城
包类似于软件
包把有联系的节点装在一起,不同的包
3.ROS除了apt中的包还有哪里有ros中的包?
进入ros官网
输入网址:
index.ros.org

官网

基本上常用的ROS软件包官网上都有
然后我们点击PACKAGE LIST 软件包列表

也就是:

PACKAGE LIST有ROS商店中所有的软件包
进入后页面:

排名越上的软件包越新
随便点击一个软件包进入:

如何使用ros官网的软件包,使用步骤?
(假设我们要下载上面截图中的那个软件包MVSIM)
-
打开终端,输入:
sudo apt update ros-Melodic-gtsam

然后启动ROS核心(就像安卓的app要启动·安卓系统一样)
roscore
然后输入
rosrun planner_cspace planner_cspace
注意planner_cspace出现了两遍,一遍是包的名称,一遍是节点的名称
然后用rosrun运行小乌龟
课程截图:

4.开源自由市场 GitHub
打开浏览器,输入GitHub: Let’s build from here · GitHub
GitHub: Let’s build from here · GitHub

由于 GitHub上的ros软件包都是以源码存在
源码需要编译才能运行
所以我们要先建立一个工作空间来进行源代码编译
工作空间怎么建立?
输入 mkdir catkin_ws 建立一个文件夹
mkdir catkin_ws
然后
cd catkin_ws
进入文件夹
然后mkdir src创建子目录

课堂截图:

下载源代码之前还需要安装git这个工具
sudo apt install git

准备工作完成后回到网站,我们试着下载一个wpr_simulation的软件包

找到下面这一项

点击进入
进入之后点击code绿色的

弹出了一个小窗口

我们点击复制网址
https://github.com/6-robot/wpr_simulation.git
然后切换回终端程序,在src文件下输入

git clone https://github.com/6-robot/wpr_simulation.git
正在克隆

我们可以查看文件中具体有些什么

使用脚本安装需要编译的依赖库
终端输入:
./install_for_melodic.sh

所有依赖包安装完成之后,我们就可以回到工作空间的入口位置,准备开始编译
在~/catkin_ws目录下运行catkin_make对src所有源代码进行编译

然后我们要运行包里的一些功能
首先我们要catkin_ws的工作空间里的环境参数加载到终端程序中 如果不加载,那就会报错提示找不到里面的软件包
使用source指令载入工作空间的环境设置
在终端里输入:
source ~/catkin_ws/devel/setup.bash
然后使用roslaunch运行编译好的ros程序
roslaunch wpr_simulation wpb_simple.launch

运行成功

把工作空间的source指令添加到终端程序初始化脚本中~/.bashrc文件里,这样每次打开终端就可以马上运行ros程序(以免忘记设置)
在终端程序中输入个gedit ~/.bashrc
gedit ~/.bashrc

来到文件末尾
加上source ~/catkin_ws/devel/setup.bash
source ~/catkin_ws/devel/setup.bash

5.ros官网软件包中的源代码
ros官网软件包中的源代码在github中都开源了,那么我们怎么来找到他呢?
我们再次来到官网,进入


github网址

点击进入

6.世界上最好的代码工具vscode,没有之一
-
安装
鱼香
-
导入工作空间
vscode界面

导入工作空间

点击进入主文件夹,双击catkin_ws进入



选择src

然后点击添加

这时候可以在列表里看见src目录里的内容

3.安装辅助插件
安装ros插件



安装cmake插件



安装括号颜色插件


4.设置编译快捷键
同时按下ctrl+shift+B

选择这一项:



我们还可以:
按下ctrl+shift+B
点击小齿轮




将"group": "build",改成"group":{"kind":"build",isDefault":true}, 表示这个键为编译的默认操作!

然后ctrl保存,然后关闭。
然后我们按下ctrl+shift+B就自动编译了

7.Terminator简介
超级终端工具terminator,多窗口应用。
例子:打开前面的仿真例子,看看两个终端对比。
系统自带:
打开终端,输入
roscore
启动ros
打开新终端,输入
roslaunch wpr_simulation wpb_simple.launch
打开仿真

然后逐个终端ctrl+c退出
Terminator:
Terminator安装:
打开终端输入
sudo apt install terminator

启动Terminator:
按下ctrl+alt+t启动Terminator

输入
roscore
启动ros系统

鼠标右键弹出菜单,选择水平分割



最后ctrl+c关闭
Terminator快捷键:
E O w
-
CTrl+shift+e 分成左右

-
CTrl+shift+o 分成上下

3alt加方向键,移动终端
4.CTrl+shift+w 撤回窗口

8.节点和包
ros中程序的基本组成单元,节点和包


假设我们要实现一个超声波节点,那么我们要怎么创建这个节点并完成编译勒?

由于节点必须有个上级组织包,因此我们得新建一个包

新建一个ssr_pkg的包
-
工作空间的设置
与上面过程相同,注意vscd也要配置。
-
创建pkg包
catkin_create_pkg<包名><依赖项列表>


那么依赖项又是什么呢?
答: 在ros里面,我们通常要把节点中具有相互具有某种联系的节点放在一个包里面,但是有些包他跟很多很多节点都有联系,即产生了他即与软件包A有联系,又与软件包b有联系,那么那些通用节点我们就称为依赖项,比如roscpp,rospy,这种语言包,std_mags这种标准消息包。
我们在github上面下载的包通常是源码存在,需要编译生成可执行文件使用,但是依赖项的包通常就已经有可执行文件,不需要编译,通常我们在下载ros的时候就下载了这些依赖项,依赖项通常放在ros文件夹下面。


输入:catkin_create_pkg ssr_pkg rospy roscpp std_msgs,创建pkg包

我们可以打开src目录,看到我们创建的包:

打开vscd,查看cmakelists.txt
认识cmakelists.txt文件

最上面是编译器最低版本要求‘

第二排是我们的工程名

中间是寻找依赖包

认识package.xml文件

中间是维护者信息

包的名字,版本号,包的内容描述

开源协议

网址

依赖项

回访依赖项
我们可以通过roscd命令在终端中回访依赖项
比如roscd roscpp访问roscpp


之前一些环境变量配置的原因:

依赖项的package.xml与我们创建包的package.xml对比图:

创建node节点
在文件管理器中找到ssr_pkg
右键里面的src文件夹,选择新建文件

输入文件名chao_node.cpp

编辑代码:
#include<ros/ros.h> //ros头文件
int main(int argc, char *argv[]) //直接输入main,他会自动补其
{
ros::init(argc,argv,"chao_node"); //ros节点初始化,节点与ros建立链接
printf("我的枪去而复返,你的生命有去无回!\n");
while(ros::ok) //用ros::ok代替while里面
{
printf("别投我还能秀!\n");
}
return 0;
}

ctrl+s保存代码
打开cmakelists.txt为新建节点添加编译规则
在注释里找到Build的章节

在这个章节里找到Declare a c++ executable 这一小节

找到这个声明指令

# add_executable(${PROJECT_NAME}_node src/ssr_pkg_node.cpp)
把他粘贴在最末尾

去掉#号,这条指令就是给我们的节点生成可执行文件

指令里这个是可执行文件名字:

我们要把可执行文件和包名一致
chao_node
后面这个表示是从哪个代码文件进行编译

我们就指定是src目录下的chao_node.cpp
结果图:

add_executable(chao_node src/chao_node.cpp)
然后按下ctrl+s保存
ctrl+shift+b进行编译

运行node节点
按下ctrl+alt+t打开终端
输入roscore运行ros系统核心
ctrl+shift+o分开新的终端
运行node节点:输入rosrun<包名><节点文件名>
rosrun ssr_pkg chao_node
结果图:

node节点的完善
首先我们先对节点进行初始化,只有初始化后的节点我们才认为与ros系统产生了链接,才能调用ros核心的各项功能。
在main函数的开头添加ros::init()函数,把main函数的argc和argv 传递过去,然后再加上节点的名称,把main函数里面的const删去。ctrl+s保存
ros::init(argc,argv,"chao_node");

打开cmakelists.txt文件来生成库函数的链接
不然就会报错:

同样我们在注释里面的build章节,找到specify libraries详细描述要链接的库这一项

把后面的#复制下来粘贴到最后面,将#号都去掉
将节点名称改为我们的chao_node,其他不变,然后ctrl+s保存

最后ctrl+shift+b编译哦
编译成功:


9.topic话题通讯
以超声波传感器chao_node节点为例子
topic
只有两个节点的情况
-
话题topic是节点间进行持续通讯的一种形式
-
话题通讯是两个节点通过话题的名称(类似于QQ群)建立起话题的通讯连接。
-
话题中通讯的数据,叫做消息message.
-
消息message通常会按照一定频率持续不断地发送,以保证消息数据的实时性。
-
消息的发送方叫做话题的发布者publisher
-
消息的接收方叫做话题的发布者sublisher
实际任务中,多个节点情况
-
一个话题可以多个发布者,也可以有多个订阅者
有些情况下,我们需要一个话题多个发布者,此时应该注意控制好节点的发言顺序,不然机器人就会面对多个相互冲突的指令。
-
一个Ros节点网络里,可以有多个话题
-
一个节点可以对多个话题进行订阅,也可以发布多个话题
4不同的传感器消息通常会有各自独立话题名称,每个话题只有一个发布者
5.机器人速度指令话题通常有多个发布者,但是同一时间只能有一个发言人
message
(可以粗暴的把消息类型理解为结构体类型)
查看std_mags之前依赖包的标准消息包,进入官网查看

编写publisher发布者节点
先写chao_node节点发布者
在前面的基础上

#include<ros/ros.h>
int main(int argc, char *argv[]) //直接输入main,他会自动补其
{
ros::init(argc,argv,"chao_node");
printf("我的枪去而复返,你的生命有去无回!\n");
while(ros::ok)
{
printf("别投我还能秀!\n");
}
return 0;
}
首先要确定话题名称,齐次在确定chao_node的消息类型
先创建一个NodeHandle对象,名称叫做nh,这个对象是节点和ros通讯的关键,可以把他理解为一位管家,ros就是由这位管家打理的一所豪宅,我们有什么需要直接吩咐管家就行
我们在编写publisher对象,publisher是我们发送消息的工具,可以把他理解为能往QQ群里发送消息的手机
接下来就拜托大管家NodeHandle,我们用泛型函数advertise函数<我们想发送的消息类型>(话题的参数) 话题参数=(“话题名称(qq群名称)”,消息缓存长度) //构建消息发送对象
消息缓存长度过短的话,最先到达的消息如果没来的及处理得话就会被丢企,消息处理周期都要点时间、
#include<ros/ros.h>
#include<std_msgs/String.h>
int main(int argc, char *argv[]) //直接输入main,他会自动补其
{
ros::init(argc,argv,"chao_node");
printf("我的枪去而复返,你的生命有去无回!\n");
ros::NodeHandle nh;
ros::Publisher pub=nh.advertise<std_msgs::String>("快上车开黑群",10);
while(ros::ok)
{
printf("我要刷屏了!\n");
std_msgs::String msg; //生成消息包,std_bmsgs::消息类型 消息包名称(可以随便取个名字)
msg.data="国服马超,代飞"; //消息内容 字符串类型格式 名称.data="内容";
//最后把消息包发给我们的大管家交给我们的手机里面
pub.publish(msg);
}
return 0;
}

设置频率后
#include<ros/ros.h>
#include<std_msgs/String.h>
int main(int argc, char *argv[]) //直接输入main,他会自动补其
{
ros::init(argc,argv,"chao_node");
printf("我的枪去而复返,你的生命有去无回!\n");
ros::NodeHandle nh;
ros::Publisher pub=nh.advertise<std_msgs::String>("快上车开黑群",10);
ros::Rate loop_rate(10); //利用ros生成频率对象,一秒钟十次
// ros::Rate 名称(一秒钟几次
while(ros::ok)
{
printf("我要刷屏了!\n");
std_msgs::String msg; //生成消息包,std_bmsgs::消息类型 消息包名称(可以随便取个名字)
msg.data="国服马超,代飞"; //消息内容 字符串类型格式 名称.data="内容";
//最后把消息包发给我们的大管家交给我们的手机里面
pub.publish(msg);
//接着在while循环里面 loop_rate.sleep():响应前面的频率,给循环造成段时间堵塞
loop_rate.sleep();
}
return 0;
}
运行新节点
启动ros核心。..

出现报错,由于默认的话题名称不能是中文。

启动chao_node节点

查看当前ros活跃话题名称
rostopic list

查看消息内容
rostopic echo /kuai_shang_che_kai_hei_qun

->

由于是中文,都是编码
用echo -e 内容 可以查看
echo -e "\u56FD\u670D\u9A6C\u8D85\uFF0C\u4EE3\u98DE"

查看消息发送的频率
rostopic hz 接话题名称kuai_shang_che_kai_hei_qun
rostopic hz /kuai_shang_che_kai_hei_qun

yao_node


#include<ros/ros.h>
#include<std_msgs/String.h>
int main(int argc, char *argv[]) //直接输入main,他会自动补其
{
ros::init(argc,argv,"yao_node");
printf("过去生于未来!\n");
ros::NodeHandle nh;
ros::Publisher pub=nh.advertise<std_msgs::String>("ye_wang_gei_gei",10);
ros::Rate loop_rate(10); //利用ros生成频率对象,一秒钟十次
// ros::Rate 名称(一秒钟几次
while(ros::ok)
{
printf("我要刷屏了!\n");
std_msgs::String msg; //生成消息包,std_bmsgs::消息类型 消息包名称(可以随便取个名字)
msg.data="骑在你头上"; //消息内容 字符串类型格式 名称.data="内容";
//最后把消息包发给我们的大管家交给我们的手机里面
pub.publish(msg);
//接着在while循环里面 loop_rate.sleep():响应前面的频率,给循环造成段时间堵塞
loop_rate.sleep();
}
return 0;
}

编写Subscriber订阅者节点
创建订阅者节点
新建包
cd catkin/src/
catkin_create_pkg atr_pkg rospy roscpp std_msgs



编辑订阅者节点
#include<ros/ros.h>
#include<std_msgs/String.h>
void chao_callback(std_msgs::String msg) //回调函数,我们可以理解为对消息包到来的一个响应,类似单片机的中断函数,每当一个新的消息包来到节点,ros系统就会在后台调用这个回调函数,系统自动调用,我们不用手动调用,这个函数传过来的消息就是最新获取的消息包对象(std_msgs::String mag
{
//printf(msg.data.c_str());//msg.data.c_str()把string类型装欢成字符📔
ROS_INFO(msg.data.c_str());//显示时间函数
printf("\n");
}
void yao_callback(std_msgs::String msg) //回调函数,我们可以理解为对消息包到来的一个响应,类似单片机的中断函数,每当一个新的消息包来到节点,ros系统就会在后台调用这个回调函数,系统自动调用,我们不用手动调用,这个函数传过来的消息就是最新获取的消息包对象(std_msgs::String mag
{
//printf(msg.data.c_str());//msg.data.c_str()把string类型装欢成字符📔
ROS_WARN(msg.data.c_str());//显示时间函数
printf("\n");
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");//可以后面的显示中文
//初始化节点
ros::init(argc,argv,"ma_node");
ros::NodeHandle nh;
ros::Subscriber sub=nh.subscribe("kaui_shang_che_kai_hei_qun",10,chao_callback); //sub对象理解为一个能够从指定的qq群接收消息的手机
//后面的意思是表示这个手机从大管家这里来
//(“话题名称”,缓存长度,回调函数)
ros::Subscriber sub2=nh.subscribe("ye_wang_gei_gei",10,yao_callback);
//使执行完默认操作后,一直保持运行状态
while(ros::ok)
{
ros::spinOnce();//一定不能少这个函数,这个函数的意思是节点在忙自己的事情时,抽空往其他节点看一眼,看有没有新的消息包接收到
}
return 0;
}
话题是谁的话题?
ros系统共同创建的
使用launch文件启动节点
打开四个终端运行所有节点很繁琐,有没有什么方法能一次性运行所有节点?launch文件

新建文件夹launch

新建文件kai_hei.launch

<launch>
<node pkg="ssr_pkg" type="yao_node" name="yao_node"/>
<node pkg="ssr_pkg" type="chao_node" name="chao_node"/>
<node pkg="atr_pkg" type="ma_node" name="ma_node" output="screen"/>
</launch>
终端输入
roslaunch atr_pkg kai_hei.launch
roslaunch atr_pkg kai_hei.launch
启动launch文件

机器人运动控制
启动之前的仿真包
roscore
roslaunch wpr_simulation wpb_simple.launch

打开终端,创建软件包vel_pkg
cd catkin_ws/src/
catkin_create_pkg vel_pkg roscpp rospy geometry_msgs // geometry_msgs速度消息类型软件包


在src里创建vel_node节点文件
使用rviz观测传感器数据
先打开之前的仿真环境
然后输入rviz
打开rviz

首先把这个fixed frame 修改成base_footprint

然后添加机器人模型
点击add添加


添加激光雷达显示条目

话题添加

为了更明显,把size改为0.03

保存配置:
file-save config -保存文件名lidar.rviz
打开保存的rviz文件?
点击file



roslaunch wpr_simulation wpb_rviz.launch
就会出现一个配置好的rviz界面



ros系统里的激光雷达的消息包格式
我们先启动仿真

将机器人围起来
然后启动配置好的rviz文件

可以看到机器人周围有一圈红色的点阵,这些一连串的点就是激光雷达要描述的数据
用c++实现获取激光雷达数据
我们先打开仿真包
1进入仿真包工作空间
cd catkin_ws/src/wpr_simulation
2将仿真包更新到最新
git pull

先创建软件包
catkin_create_pkg lidar_pkg roscpp rospy sensor_msgs

sensor_msgs为包含雷达消息的软件包
更多推荐
所有评论(0)