3.2 ROS基础
作者:公众号:小白学移动机器人
3.2.1 初见ROS
ROS历史起源是什么?
ROS的总体设计是什么?
ROS的应用框架是怎样的?
总结:ROS就是一个为了提高机器人开发的软件复用率,开发的一款具有独特的通信机制、丰富的开发工具、海量的应用功能、良好的生态系统集的工具。
关于ROS更多细节的东西比较多,可以听课、可以看书,但这里只会讲解一些ROS机器人开发中用到的,以及我认为比较重要的地方。在公众号:小白学移动机器人,发送:ROS,即可获得相关ROS学习资源,以下的文章,希望读者已经具备了最基本的ROS知识。本节下面写的内容,主要是在实际的开发中,需要遇到的最基本问题的解决办法。熟悉的可以直接跳过。
3.2.2 如何新建一个工作空间?
在自己的终端中输入依次执行如下命令
mkdir -p ~/catkin_test_ws/src
cd ~/catkin_test_ws/src #存放功能包的地方
catkin_init_workspace #初始化工作空间
cd ~/catkin_test_ws
catkin_make #编译工作空间
source devel/setup.bash #刷新环境变量,单次有效
echo "source ~/catkin_test_ws/devel/setup.bash" >> ~/.bashrc #刷新环境变量,永久有效
source ~/.bashrc #执行上面一个语句,需要执行这一句,刷新生效
echo $ROS_PACKAGE_PATH #查看环境变量,确定工作空间存在环境变量
可能出现的错误,echo “source ~/catkin_test_ws/devel/setup.bash” > ~/.bashrc,使用了一个箭头,将.bashrc文件覆盖了,注意上面是两个箭头追加模式。
如果不小心将.bashrc文件覆盖了,可以使用系统中的存储的.bashrc备份文件恢复到~/目录下,执行:
cp /etc/skel/.bashrc ~/ #/etc/skel是Ubuntu的各种初始配置文件的存放目录
3.2.3 如何调用一个功能包?
这也是调包侠最常用的方式
首先,就是将你需要使用的功能包,从别人的src文件中,复制到你需要使用工作空间下的src文件下
cd ~/catkin_test_ws
catkin_make #编译工作空间
等待编译完成就可以了
特殊情况:
如果有些功能包需要安装或者需要和库文件一起编译,记得将安装或者将库文件复制到src文件中
3.2.4 如何新建一个功能包?
这也是需要每个人都要会的,连个最基础的功能包都不会写,怎么好意思说学过ROS
cd ~/catkin_test_ws/src #进入存放功能包的地方
catkin_create_pkg test_package std_msgs roscpp rospy #创建名字为test_package的功能包,添加std_msgs roscpp rospy依赖
cd ~/catkin_test_ws
catkin_make #编译
source devel/setup.bash #新建功能包刷新环境变量,才能找到功能包
rospack profile #如果还是找不到功能包,使用该命令刷新功能包路径
这里需要注意一点,同一个工作空间下不能存在同名功能包,不同的工作空间下可以存在同名功能包。但是要注意一个问题,ROS运行时会优先选择最前端工作空间的同名功能包。为了避免出现意想不到的问题,所有工作空间尽量不使用同名功能包。
功能包的名称尽量按照a_b_c的格式书写,否则,编译过程将会出现警告。
3.2.5 如何新建一个ROS节点?
接着上面的测试功能包,我们在功能包的src文件下新建test.cpp文件
cd ~/catkin_test_ws/src/test_package/src/
vim test.cpp
然后就是ROS节点的模板程序了,都是在模板程序之上做的修改。
#include "ros/ros.h" //引入ROS头文件
int main(int argc,char **argv)
{
ros::init(argc,argv,"test"); //初始化ROS节点
ros::NodeHandle nh; //创建ROS句柄
ros::Rate loop_rate(10); //定义循环频率 10HZ
while(ros::ok())
{
std::cout<< "hello ros" <<std::endl;
loop_rate.sleep(); //按照循环速率延时
}
return 0;
}
到这里,然后编译就可以了吗?当然不可以,这个功能包的编译还需要修改对应的CMakeLists.txt文件,一般为三步。
设置需要编译的代码和生成的可执行文件;
设置链接库;
设置依赖;
所以我们修改功能包下的CMakeLists.txt文件,一般功能包会自动生成CMakeLists.txt文件内容,我们进行修改即可。
add_executable(${PROJECT_NAME}_node src/test.cpp) #这里注意自动生成的源文件名字一般不对,一定要修改成对的名字
target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES})
add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
这里因为我们没有自定义的消息或者服务类型,所以其他的地方不做更改,如果使用了自定义的消息或者服务类型注意修改其他的地方。
好了,保存,开始编译。
cd ~/catkin_test_ws
catkin_make #编译
此时~/catkin_test_ws/devel/lib/test_package目录下生成了test_package_node的可执行文件
执行功能包。在使用rosrun 执行功能包之前,使用roscore 启动rosmaster。启动rosmaster是启动一切ros节点的前提。
roscore #启动rosmaster
打开一个新终端启动,test_package 功能包下的 test_package_node 节点。
rosrun test_package test_package_node
终端循环打印hello ros ,一个新的ros节点就创建完成了。
3.2.6 如何在一个ros节点文件中调用其他的源文件?
这个问题很常见,但是他不应该是个问题,但是发现一些小伙伴还是不太会操作。我们在开发的过程中,随着程序的不断扩大,模块化编程肯定必不可少。有时,我们要调用别人写好的特定功能的源文件,这个时候我们应该怎么做呢?
首先,将你需要的源文件复制到你需要编写的功能包的src文件夹下,规范的讲,.hpp文件应该放到include文件下,如果文件比较少,也没有必要,和.cpp文件放在一起也可以。
ros节点源文件只需要添加你复制的文件的头文件就行了,函数自己调用就行了。
CMakeLists.txt文件需要做相应的修改,添加你添加的文件名字,放在ros节点文件后面,如下所示:
add_executable(${PROJECT_NAME}_node src/test.cpp src/test2.cpp src/test3.cpp) #这里注意自动生成的源文件名字一般不对,一定要修改成对的名字
然后,编译就行了。
3.2.7 如何设置两台机器的分布式通信?
ROS是一种分布式软件框架,节点之间通过松耦合的方式进行组合。
如何设置两台机器的分布式通信呢?
首先,确保两台机器在同一局域网下,查看各自的ip地址。
ifconfig
然后,各自安装ssh,确保ssh 服务,开机自启动。
sudo apt-get install openssh-server #安装ssh服务端
sudo service ssh start #开启ssh服务
ssh服务开机不会自动启动,需要设置开机自启动
在开机自启动脚本/etc/rc.local加入下面这条命令,注意加入位置是在exit 0这一句之前,加上service ssh start
然后,在两台机器的/etc/hosts文件中,添加对方的ip地址,通过ping命令,互相测试是否连通。
比如在hosts添加 ,对方机器IP 对方机器名
192.168.1.5 对方机器名
ping 对方机器名或者对方机器ip #ping测试
然后,在从机端的~/.bashrc文件末尾设置ROS_MASTER_URI,确保从机可以找到主机。
export ROS_MASTER_URI=http://主机名称:11311
最后,在从机端 使用ssh 用户名@IP地址,输入密码,连接远程终端。
ssh 主机用户名@主机名
这样从机就也可以启动相关的ros节点,或者使用相关工具获取主机ros节点的数据。
3.2.8 ROS开发常用的工具
launch文件,可以同时启动多个ros节点,可自动启动rosmaster。关于launch的细节,自己学习就好。
TF坐标变换,用来描述机器人系统中繁杂的坐标系。
QT工具箱,用来可视化各个ros节点之间的订阅或者请求关系或者可视化各种话题的数据。常用命令,rqt_graph、rqt_plot,而且还可以动态修改部分参数,
rqt_reconfigure(不常用)。
rviz可视化平台,机器人可视化平台,几乎是最常用的工具。使用rviz命令启动。
Gazebo物理仿真环境,可对机器人进行三维物理仿真。需要仿真的同学常用。
3.2.9 ROS的常用命令
#最常用
roscore #启动rosmaster
rosrun pkg_name node_name #启动ros节点
roslaunch pkg_name launch_files_name #启动launch文件
catkin_make #编译工作空间
rospack profile #刷新功能包路径
#环境变量
echo $ROS_PACKAGE_PATH #打印ros环境变量
export | grep ROS #确认环境变量已经设置正确
source devel/setup.bash #刷新环境变量
echo "source ~/catkin_test_ws/devel/setup.bash" >> ~/.bashrc #刷新环境变量,永久有效
source ~/.bashrc #生效上一句
#功能包
catkin_create_pkg test_package std_msgs roscpp rospy #创建名字为test_package的功能包,添加std_msgs roscpp rospy依赖
rospack list #查看软件包列表
rospack find package-name #定位软件包
roscd package-name #切换到指定功能包目录
#话题
rostopic list #输出当前运行的topic列表
rostopic info topic-name #查看话题信息
rostopic echo topic-name #输出话题数据
rostopic hz topic-name #每秒发布的消息数量
rostopic bw topic-name #每秒发布信息所占的字节量
#工具
rviz #启动rviz
rqt_graph #可视化节点关系
rqt_plot #可视化话题数据
rosrun rqt_tf_tree rqt_tf_tree #查看tf树
#数据记录与播放
rosbag record -a #录制所有topic到bag文件
rosbag play bag_files_name #播放bag文件
3.2.10 总结
本节文章,主要是针对开发中常见的操作步骤的描述,这里只是对开发中的一些问题进行讲解。对于ROS的细节知识,大家还是需要自己看书或者听课自行学习。
下一章,我们就开始设计我们的机器人并通过urdf文件描述机器人模型了。
如果你感觉,我的文章比较适合你,关注我,给你不一样的惊喜。