一、前言
在下列流程中,Ubuntu环境默认已经安装成功,如安装有问题可以参考鱼香ros一键安装,详细内容可点击链接跳转。
注意:Ubuntu环境安装推荐使用双系统,可以在实际项目的时候避免很多不必要的报错。
二.工作空间创建
注意:root使用CMake(一种构建系统生成工具)和catkin(Catkin 是基于 CMake 的 ROS 特定构建系统)作为编译工具
工作空间在创建的时候理论上是使用以下命令行的:
mkdir -p ~/catkin_ws/src
~ 的意思是主目录下创建
-p的意思是当主目录不存在的时候自动创建
但事实上再创建的时候基本上当时就在主目录下,所以的话其实使用以下命令行即可实现:
mkdir catkin_ws/src
使用命令行之后,工作空间创建完毕!注意:工作空间之所以要起名一个catkin_ws这样的名字,是因为可以快速识别这是一个catkin工作空间,ws的意思是workspace(工作空间)。进入工作空间中的src文件,使用终端打开:
注意:这里的这个子目录src是suorce简写,即装机器人代码的位置
三.节点与包
ros中常用的节点名称:
- GMapping(建图)
- Move_base(导航)
- wpb_core(控制地盘)
- rplidar_ros(驱动雷达)
3.1给节点创建一个软件包
使用cd catkin_ws/src进入之前创建好的工作空间,通过以下命令行创建可以运行python代码后人c++代码的软件包:
catkin_create_pkg ssr_pkg rospy roscpp std_msgs
"""解释:用catkin 工具创建一个package软件包,第二个参数ssr_pkg是包的名字,第三个的意思:
rospy是ros和python的结合,roscpp是ros和c++的结合,std_msgs是标准消息(在生成消息包的时候,通常要指定消息的类型,而这个包中本身包含了很多基础的消息类型,把它作为依赖项,就可以使用他的消息类型来构建消息包)
注意:在执行完上述指令之后,也就意味着当前的软件包ssr_pkg已经支持python,c++两种语言了。
"""
- 上述后面附属的这种通常是通用节点,由于其具有广泛的通用性,所以是不好归纳在任何包中的,所以干脆将这种节点直接单独封装成了独立包,谁用谁就依赖。
- 还有就是在导入的时候要点击src文件进行导入,确保在导入成功之后vs软件中是以src为主目录,这样看起来会整齐一些。
- 创建好包ssr_pkg包之后,包里面会又有一个src文件,这里便是使用代码编写各种节点的地方。
3.2节点的运行
- 启动ros系统核心,终端中执行命令roscore
- 然后运行rosrun ssr_pkg chao_node 节点将被执行
- 注意在while中编写循环使用true的话,节点的程序是不会响应任何外部信号的,也就是说应该使用下列方式编写代码。
while not rospy.is_shutdown():
rospy.loginfo("瑶的消息被订阅成功!")
msg = String()
msg.data = "这是瑶发送的消息!"
pub.publish(msg)
四、ros的主要通讯方式
在ros中,话题相当于是群聊,而message就相当于是在群聊中发送的消息,执行器可以通过在话题(topic)中发送消息(message)来实现和信息获取外设的交互,从而获取到机器人的动作信息。
- topic话题
- message消息
解释:消息的发送方叫做话题的发布者Publisher,消息的接受方叫做话题的订阅者Subsciber
- IMU:是附着在机器人身上,实时发布机器人旋转倾斜这些姿态信息的单元模块
- 在ros中,传感器消息通常会拥有各自独立的话题名称,每个话题只有一个发布者
4.1发布者节点
#!/usr/bin/env python3
#coding=utf-8
import rospy # 这个是ros大管家
from std_msgs.msg import String # 从标准消息包中引入消息的发布类型
if __name__ == "__main__":
rospy.init_node("chao_node")
rospy.logwarn("这个函数是ros中用于记录警告级别的日志信息的")
pub = rospy.Publisher("这里说的是发布的话题名称,注意不能使用汉字",String,queue_size=10)# 后续参数依次是发布内同的格式类型和话题发布端的消息包缓存长度,就是说消息太多堆起来的话就可以开始抛弃
# 现在消息造好了,下一步就应该是发布消息
# 先在这里定义一个发送频率的控制对象rate
rate = rospy.Rate(10)
while not rospy.is_shutdown(): # 这里是循环在向rospy大管家询问节点没有关闭吧,所以只要节点没有关闭就符合代码意思,即为true,可以继续进行下面的循环内容
rospy.loginfo("我要开始刷屏了!") # 这个函数用来记录信息级别的日志,和上述rospy.logwarn函数都是日志记录函数,不过这通常是常用日志,而rospy.logwarn则用来提醒
msg = String() # 构建消息包
msg.data = "国服马超,准备出战!" 然后在消息包的数据段中塞入要发布的消息
pub.publish(msg) # 通过pub对象发布到话题当中,这里塞什么,节点就会发布什么
rate.sleep()# 不理解这里为什么还要再控制以下发送频率
- 上述代码中有话题,有消息,就可以被称为发布者节点
4.2接收者节点
#!/usr/bin/env python3
#coding=utf-8
import rospy
from std_msgs.msg import String
def chao_callback(msg):
rospy.loginfo(msg.data)
if __name__ == "__main__":
rospy.init_node("ma_node")
sub = rospy.Subscriber("kaiheiqun",String,chao_callback,queue_size=10) # 这里拿到消息之后让回调函数用了,实际应用中回调函数应该极为复杂
rospy.spin() # 这里的意思是让这个节点保持运行状态,等待消息包的到来
注意:将新编写的节点文件修改为可执行文件的命令是在节点文件当前目录中执行如下命令行:
- chmod +x 【节点文件名字】
- chmod的意思是改变文件的执行模式 x的意思是可执行权限 即可给文件加上执行权限
终端中执行命令的命令行是(主目录执行即可):
- 第一个终端roscore
- 第二个终rosrun ssr_pkg chao_node.py 意思是运行ssr_pkg包中chao_node.py节点
- 第三个窗口运行rosrun atr_pkg ma_node 代码运行成功,效果如下所示:
4.3 截图工具
可以使用以下这个命令给linux安装一个截图工具
# 先卸载 flameshot
sudo apt --purge remove flameshot -y
# 卸载完之后再安装
sudo apt install flameshot
安装完成之后,使用以下命令即可截图:
flameshot gui
4.4 多个节点同时执行
- launch文件内容:
<launch>
<node pkg="ssr_pkg" type="chao_node.py" name="chao_node"/>
<node pkg="ssr_pkg" type="yao_node.py" name="yao_node"/>
<node pkg="atr_pkg" type="ma_node.py" name="ma_node" launch-prefix="gnome-terminal -e"/>
</launch>
- 可以选择用launch的方式,一次性运行多个节点,运行效果如下:
roslaunch atr_pkg kai_hei.launch
解释:即使用roslaunch命令运行在atr_pkg包中的kai_hei.launch文件
- 运行效果截图:
五.ros仿真
使用网上的开源项目wpr_simulation 进行学习,如果说项目已经下载的话,可以使用git pull 命令,将其更性到最新的版本状态。
开源项目的git如下,可通过命令行cd catkin_ws/src/ 下执行下载:
git clone https://github.com/6-robot/wpr_simulation.git
下载编译完成之后,在著目录执行 :
roslaunch wpr_simulation wpb_simple.launch
即可进入以下仿真环境
此时在主目录使用命令:
rosrun wpr_simulation demo_vel_ctrl.py
即可实现看到机器人向前移动。
机器人向前移动的手动实现:
这里先是创建一个新的软件包,叫做vel_pkg
robot@WP:~$ cd catkin_ws/src/
robot@WP:~/catkin_ws/src$ catkin_create_pkg vel_pkg roscpp rospy geometry_msgs
# 最后这个参数是包含了速度消息类型的消息包
然后通过vs打开刚刚创建的包,在包vel_pkg中,新建文件scripts,在里面新建vel_node节点,节点内容如下:
#!/usr/bin/env python3
# coding=utf-8
import rospy
from geometry_msgs.msg import Twist
if __name__ == "__main__":
rospy.init_node("vel_node")
vel_pub = rospy.Publisher("cmd_vel",Twist,queue_size=10) # 这里是问rospy要一个用来交流消息的群聊
vel_msg = Twist()# 这里作一个消息包
vel_msg.linear.x = 0.1
rate = rospy.Rate(30)
while not rospy.is_shutdown():
vel_pub.publish(vel_msg)
rate.sleep()
节点编写好之后,修改成可执行文件,然后在终端主目录:
- roslaunch wpr_simulation wpb_simple.launch 启动仿真
- rosrun vel_pkg vel_node.py
即可看到机器人正在以0.1米/秒的速度开始前进
代码如果错误,可以在wpr_simulation文件中查看详细应该怎么写,[simulation]的英文意思是仿真
五、RViz软件工具(阿viz)
和传感器数据的查看相关,是一个可视化工具
使用命令rostopic echo /scan 的时候,避免被数据刷屏的话可以使用--noarr将数据折叠起来
六、代码实现获取激光雷达数据
雷达话题包的名字是约定俗成的,叫做/scan
创建包的命令行:robot@WP:~/catkin_ws/src$ catkin_create_pkg lidar_pkg rospy sensor_msgs
lidar_node.py文件内容如下:
#!/usr/bin/env python3
#coding=utf-8
import rospy
from sensor_msgs.msg import LaserScan
def LidarCallback(msg):
dist = msg.ranges[180]
rospy.loginfo("前方距离ranges[180] = %f 米",dist)
if __name__ == "__main__":
rospy.init_node("lidar_node")
lidar_pub = rospy.Subscriber("/scan",LaserScan,LidarCallback,queue_size=10)
rospy.spin()
代码编写完成之后,在终端打开仿真,然后运行节点代码,即可实现以下效果:
七.激光雷达避障的实现
#!/usr/bin/env python3
#coding=utf-8
import rospy
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist
count = 0
def LidarCallback(msg):
global vel_pub
global count
dist = msg.ranges[180]
rospy.loginfo("前方距离ranges[180] = %f 米",dist)
if count > 0:
count = count - 1
return
vel_cmd = Twist()
if dist <1.5:
vel_cmd.angular.z = 0.3
count = 50
else:
vel_cmd.linear.x = 0.05
vel_pub.publish(vel_cmd)
if __name__ == "__main__":
rospy.init_node("lidar_node")
lidar_pub = rospy.Subscriber("/scan",LaserScan,LidarCallback,queue_size=10)
vel_pub = rospy.Publisher("cmd_vel",Twist,queue_size=10)
rospy.spin()
依然是lidar.py文件,添加可执行权限之后运行,在仿真界面中可以看到机器人的避障行为;
八、IMU惯性测量单元包消息
概念:是安装在机器人内部的一种传感模块,用于测量机器人的空间姿态
构建新软件包
IMU数据获取代码
代码执行效果图如下,以欧拉角显示: