机器人系列文章目录
第一章 ubuntu16.04系统及相关软件安装
第二章 Linux操作系统入门笔记
第三章 ROS系统架构及程序编写过程
第四章 《probabilistic robotics》学习笔记
本章目录
一、系统架构
三个层次,从小到大依次为计算图层、文件系统层、开源社区层。
1.计算图层
最深层次
(1)节点(rosnode)
指功能或进程,是各自独立的可执行文件。能通过主题、服务或参数服务器与其他节点通信。
名称唯一。
看节点构成(节点之间的发布订阅关系)的计算图:rqt_graph
(2)节点管理器(roscore)
指挥中心。
(3)话题(rostopic)
节点间用了传输数据的总线,进行发布和订阅。发布到话题上的消息必须与话题的ros消息类型匹配。节点要订阅话题,消息类型也要相同。
rostopic (echo、list、type、pub、info topic_name、find message_type )
(4)服务(rosservice)
包含消息源代码的文件存在srv文件夹。
ROS节点之间的主要通讯方式是两种,话题通讯和服务通讯。区别主要是服务调用是一对一通讯,且有响应,信息流是双向的(客户端client给服务端server发送请求request,服务器发送响应response数据给客户端节点)。
(5)消息(rosmsg)
节点通过向特定主题发布消息,将数据发送到另一个节点。消息有类型和数据结构。
/.msg
rosmsg (show、list、package)
(注)launch
版权链接:https://www.jianshu.com/p/63a959bfbb96
ROS采用rosrun命令可以启动一个节点,如果需要同时启动节点管理器(master)和多个节点,就需要采用launch文件来配置。
其中,节点的形式为:
node的三个属性分别为节点名字、程序包名字和 可执行文件的名字。 name属性给节点指派了名称,它将覆盖任何通过调用 ros::init来赋予节点的名称
2.文件系统层
围绕功能包(Package)展开。
所有软件都被组织为功能包形式。不同功能包组织在预期得到功能包集(Stack),也有功能包集清单。
一个功能包有最小的结构和最少的内容,包括可执行文件和其他支持文件。
package.xml是功能包目录
rospack (list、find package-name)
rosls package-name、roscd package-name
(1)功能包清单(package manifest):记录功能包信息,通过manifests.xml文件实现对功能包的管理。相当于节点和节点管理器。
(2)必备:/include、/launch、/src、CMakeLists.txt
(3)其他:
消息类型(msg type):描述ROS采用话题通信的时候的消息的类型的文件;
服务类型(srv type):这描述服务通信的时候的服务类型的文件。
3.开源社区层
ros资源免费开源。
二、常用命令汇总
三、实际运用
善用tab键
1.rosparam
1)查看参数
rosparam list
2)模糊搜索
rosparam list | grep ip
3)获取当前,看配置的参数对不对
rosparam get/ 某地址/scanner_ip
4)改
rosparam set
2.rosnode
1)错误排查
rosnode cleanup
2)节点信息
rosnode info /确定的名字
3.rostopic
1)打印
rostopic echo
具体看什么自己打确切名字+/…/…/…
2)频率
rostopic hz
3)发布
rostopic pub
rostopic pub /cmdvel geometry_msgs/Twist "liner:
x:写
...
z:... -r 20
注:可用于实际topic数据不正常时,自行发布以不影响其他节点运行
4.rosmsg
1)看类型(联系前面3.2)
rostopic type /…
看这个类型打印出来
rosmsgshow /上面得到的
2)看属性
rosmsg show (–help)
5.rosbag
1)准备工作
rostopic list : 看有无发布
rostopic echo /话题名 : 发布话题
rostopic info /话题名/header : 看详细信息,如frame_id
rviz : 数据可视化。调节参数,添加修改topic、轴,以及其中的frame
2)录包
rosbag record -a
其中-a选项表示将当前发布的所有 topic 数据都录制保存到一个 rosbag 文件中。
也可以只记录某些感兴趣的 topic,命令如下:
rosbag record /topic_name1 /topic_name2 /topic_name3
上述命令录制的数据包名字为日期加时间。如果要指定生成数据包的名字,则用-O /-o 参数,如下:
rosbag record -O filename.bag /topic_name1
其中 -O (大写的 O) 后跟录制数据包的名字。如果用 -o (小写的 o),则只是给数据包的名字加前缀。
3)查看
rosbag info 包名
4)播放
rosbag play 包名
rviz
如果想改变消息的发布速率,可以用下面的命令
rosbag play -r 2
这时的轨迹相当于以两倍的速度通过按键发布控制命令时产生的轨迹。 -r 后面的数字对应播放速率。
如果希望 rosbag 循环播放,可以用命令
rosbag play -l # -l == --loop
如果只播放感兴趣的 topic ,则用命令
rosbag play --topic /topic1
5)时间同步
回放数据包时,如果想用 Rviz 可视化数据,可能会遇到时间不匹配的问题
- 启动 ROS master
roscore
- 指定系统以 simulated time 运行(告诉节点以 msg 对应的 simulated time 运行,而不是实际的 wall-clock time)
rosparam set /use_sim_time true
- 回放 rosbag 并发布 simulated time
rosbag play --clock
6)输出到csv、txt:
rostopic echo -b bagfile_name.bag -p /topic_name > csvfile_name.csv
7)裁切重录:一边play一边record
rosbag play 包名
rosbag record
录想录的
8)合并:py脚本
9)修复
版权:https://blog.csdn.net/chongzi865458/article/details/101703250
①切换到xxx.bag.active文件所在的目录下;
②命令行输入rosbag reindex xxx.bag.active;
③输入rosbag fix xxx.bag.active result.bag;
四、综合操作
1.编译过程
- 流程图:
方法一:cmake[…/];make[-j4]
(1)创建工作空间
(2)创建ROS功能包
(3)建立build文件夹,终端输入:
$ cmake../
//cmake到CMakeLists.txt所在目录,若在src,则cmake../src
$ make -j4
$ source devel/setup.bash
(4)删除build文件夹,打开qt进行编译
方法二:catkin_make
(1)创建工作空间
(2)catkin_make得到build、devel文件夹,终端输入:
$ source devel/setup.bash
(3)创建ROS功能包后
终端输入:
$ catkin_make
完成编译
- 示例:Hello ROS
过程包括:
创建工作空间(复制新建CMakeList文档)、创建ROS功能包并编译、使用节点。
cmakelists三件套:
add_executable
add_dependencies
target_link_libraries
2.现场调试
(a)传入并编译节点
步骤:
ssh远程登录
scp传入功能包
建立build文件夹
cmake编译
(b)传入替换节点及参数文件
示例:
step1:修改环境配置
找到自己的库的位置
$ cd ws/build/devel/
复制路径
$ pwd
修改.bashrc
$ vim ~/.bashrc
在source路径位置加上前面复制的+/setup.bash
退出vim界面,cd到所在目录source一下
$ source .bashrc
step1:修改自启的节点名
cd到自启脚本的目录
$ cd 路径/auto...
vim打开,找到要修改的位置,改成自己的节点名,并 在source路径位置加上前面复制的+/setup.bash
注意launch文件是否需要修改相应的节点名。
3.分布式操作
(1)介绍
因为机器人上的工控机没有办法加显卡,所以无法看图形化界面,必须得将图像处理模块,放到笔记本上。通过分布式操作进行可视化。
主机:机器人
从机:笔记本
(2)操作步骤
step1:配ip
找两台机子的IP地址(同一网段),打开两个终端,分别在两台机子上的/etc/hosts文件加入对方的IP地址和对应的计算机名字,并检查能否ping通。
step2:改.bashrc
主机从机两台机子分别设置本机当前名称和主机uri。
如:
z:
export ROS_HOSTNAME=z
export ROS_MASTER_URI=http://zg:11311
zg:
export ROS_HOSTNAME=zg
export ROS_MASTER_URI=http://zg:11311
step3:运行需要的图像处理模块
新终端:
看车内节点
$ rosnode list
运行
$ rosrun rqt_tf_tree rqt_tf_tree
step4:恢复
将bashrc和/etc/hosts文件内容恢复成修改前,可作为注释,并确认无法ping通。
否则其他用户无法进入工控机。
$ gedit .bashrc
$ sudo vim /etc/host
具体参考:
https://blog.csdn.net/hehedadaq/article/details/82898307
4.ros可视化操作----rviz工具使用
分布式操作后,在远程端配置rivz后即可操作。
参考:
https://blog.csdn.net/weixin_44770840/article/details/102533250
五、话题msg
A、发布话题
0、若为自定义消息,则需要生成消息,并include头文件
0.0、创建msg文件夹,添加消息文件名.msg文件
int16 消息1 //【变量名】
int16 消息2
0.1、cmakelists.txt
find_package增加对message_generation的依赖
find_package(catkin REQUIRED COMPONENTS
#一般会有 roscpp
message_generation
)
添加消息文件
add_message_files(
FILES
消息文件名.msg
)
生成消息
generate_messages(
DEPENDENCIES
#std_msgs
)
0.2、package.xml
<build_depend>message_generation</build_depend>
<build_export_depend>message_generation</build_export_depend>
<exec_depend>message_runtime</exec_depend>
0.3、#include <包名/消息文件名.h>
1、初始化ROS节点
#若在main里
#int main(int argc,char* argv[])
#{
ros::init(argc, argv, "节点名");
2、向ROS Master注册节点信息,也就是创建节点句柄,指定发布的话题名、消息类型
ros::NodeHandle nh_;
ros::Publisher 【变量名】group_ = nh_.advertise<消息类型>("话题名", 10);
#或在头文件处声明【ros::Publisher 变量名;】
#main里或类里创建【变量名 = nh_.advertise<消息类型>("话题名", 10);】
3、添加消息数据
#用【发布函数】,或直接【变量名.pub】
# 先定义容纳消息数据的变量【消息类型::变量名】
包名::消息文件名::data;
data.消息1 = 1;
data.消息2 = 2;
group_.publish(data);
4、按照一定频率发消息
#若在main里,循环发布
ros::Rate loop_rate(10);
while(ros::ok())
{
#第三步的发布内容
ros::spinOnce();
loop_rate.sleep();
}
return 0;
#} //结束main
B、订阅话题
参考版权:https://blog.csdn.net/weixin_44692299/article/details/104263552
注:若需控制订阅频率:
#main中
ros::Rate r(1);
ros::Subscriber sub_ = nh_.subscribe(【话题名】"pub", 1, Callback);
while (ros::ok())
{
ros::spinOnce();
r.sleep();
}
六、服务
0. create service file
package中创建srv文件夹(与src同级),添加服务文件名.srv文件
上为req下为res,非全部必要
---
int16 消息1 //【变量名】
int16 消息2
1. compile and include
以下参考:版权:https://www.icode9.com/content-4-815610.html
1、package.xml文件:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
2、CmakeLists.txt文件:
第一块:修改find_package部分,确保编译时找到对应文件
find_package(catkin REQUIRED COMPONENTS
roscpp
message_generation
)
第二块:设置srv文件
add_service_files(
FILES
服务文件名.srv
)
generate_messages(
DEPENDENCIES
#std_msgs
)
第三块:catkin依赖部分
#如果我们编写的ros程序不打算给别人使用,这块就无所谓。
catkin_package(
...
CATKIN_DEPENDS roscpp message_runtime
...
)
3、可在工作空间编译,通过相关命令测试是否已经安装成功:
rossrv show 包名/服务文件名
4、#include <包名/服务文件名.h>
编译成功后,include文件夹中出现
2. generate source code
1、初始化ROS节点
2、向ROS Master注册节点信息,也就是创建节点句柄;建立服务并在ros内发布
ros::NodeHandle n;
ros::ServiceServer 【变量名】service = n.advertiseService("服务名", 回调函数);
#某头文件中声明ros::ServiceServer 【变量名】;
#【变量名】service = n.advertiseService("服务名",&类名:: 回调函数, this);
# ROS_INFO("Ready to....");
3、服务回调函数
//这个回调函数提供两个int值求和的服务,int值从请求request里面获取,而返回数据装入响应response内,这些数据类型都定义在srv文件内部,函数返回一个boolean值。
bool 回调函数(包名::服务文件名::Request &req,
包名::服务文件名::Response &res)
{
res.消息1 = 1;
res.消息2 = 2;
return true;
}
七、tf变换
1.tf与坐标转换
https://blog.csdn.net/baidu_39404323/article/details/117560509
2.transform.h
http://docs.ros.org/en/jade/api/tf/html/c++/classtf_1_1Transform.html
3.tips
手动播放tf
rosrun tf tf_echo /base_link /laser
qrcode
https://blog.csdn.net/weixin_44346182/article/details/122596695
八、节点参数
版权:https://blog.csdn.net/sinat_16643223/article/details/112441563
1.载入参数
1)launch文件
a.通过param标签载入参数:
该方法适用于少量参数的载入,格式为:
<param name="parameter_name" type="double" value="10.0" />
b.通过rosparam标签导入.yam文件载入参数:
该方法适用于大量载入参数,格式为:
<rosparam command="load" file="$(find examle_pkg)/example.yaml" />
重新运行launch文件,参数就会更新。私有参数放在节点中。
2)cpp
a.ros::param::get()
ros::param::get("关键字",变量);
也可获取其他节点参数
ros::param::get("/节点名/参数关键字",变量);
b.ros::NodeHandle::getParam()
ros::NodeHandle nh_priv(~);
nh_priv.getParam("关键字",变量);
c.ros::NodeHandle::param()获取参数失败时,设置默认参数
ros::NodeHandle nh_priv(~);
nh_priv.param("IntParam",IntParam,11);
// be careful when use ros::NodeHandle::param get string param!
nh_priv.param<std::string>("StrParam",StrParam,"stringdemo_default")
ROS_INFO("\nThe IntParam is:%d\nThe StrParam is:%s",IntParam,StrParam.c_str());
2.设置参数
1)ros::param::set()
ros::param::set("StrParam","stringdemo");
2)ros::NodeHandle::setParam();
nh.setParam("IntParam",1);
九、c++
打印字符串
#include
#include
ROS_INFO_STREAM("? " << atoi (变量.c_str()) );
注意
rviz不全
sudo apt-get install ros-kinetic-desktop-full