如何使用话题Topic和消息Message来实现控制机器人底盘运动的功能?
对机器人运动控制,目标是驱动机器人进入某种运动状态。
在ROS中对机器人的运动状态的描述有一定的规范。
运动一般分为:
- 矢量运动(向前、向后等平移运动)
- 旋转运动(左转、右转,『左倾、右倾』滚转运动,『前倾、后仰』俯仰运动)
机器人的矢量运动可以看作是如下三个方向的矢量运动的合成:原点为机器人底盘中心点、X-指向机器人正前方向、Y-指向机器人正左方、Z-指向机器人正上方。
![image-20231120213739556](https://img-blog.csdnimg.cn/img_convert/5b41942ab8da66a904cc45c68eef4693.png)
旋转运动
拇指指向X轴正方向,其他四指弯曲方向即机器人滚转运动的正方向。
![image-20231120214429771](https://img-blog.csdnimg.cn/img_convert/495382fb5efee3e14aebfdad64e4a8ba.png)
拇指指向Y轴正方向,四指弯曲方向即机器人俯仰运动的正方向。
![image-20231120221932760](https://img-blog.csdnimg.cn/img_convert/d959b2828d5f5eb2880e69c7424da4d0.png)
拇指指向Z轴正方向,四指弯曲的方向就是机器人自传运动的正方向。
![image-20231120231843240](https://img-blog.csdnimg.cn/img_convert/acbd565e9c4005a074be21c1882d0bff.png)
机器人的基本运动状态由三个矢量运动和三个旋转运动的方向确定:
![image-20231120232049349](https://img-blog.csdnimg.cn/img_convert/83cf0e265a231d76b503b57d1d67d426.png)
- 矢量运动的速度单位统一是 米/秒。
- 旋转运动的速度单位统一是 弧度/秒。比如弧度值=3.14,则代表一秒钟转180度。
根据以上信息,我们可以得出机器人的运动控制可以由矢量速度的X、Y、Z三个轴的速度分量和旋转速度的X、Y、Z三个轴的速度分量来描述。
因此,将这六个速度分量包装到一个包里,就组成了速度消息包。
其中两个数据成员:
- Vector3 linear - 三维的线性变量,矢量速度变量
- Vector3 angular-三维的角度变量,旋转速度变量
通常一个ROS机器人中有一个机器人核心节点,即能够驱动机器人的底层硬件,还会订阅一个速度控制话题(/cmd_vel)。
因此,我们只需编写一个新的节点向/cmd_vel
话题发送消息包即可控制机器人运动。
![image-20231120234237543](https://img-blog.csdnimg.cn/img_convert/433890d9a9ccd8c2411f7cf3b2495822.png)
编写速度发布节点C++
实现思路:
- 构建一个新的软件包,包名叫做
vel_pkg.
- 在软件包中新建一个节点,节点名叫做
vel_node
. - 在节点中,向ROS大管家
NodeHandle
申请发布话题/cmd_vel
,并拿到发布对象vel_pub
. - 构建一个
geometry_msgs/Twist
类型的消息包vel_msg
, 用来承载要发送的速度值。 - 开启一个
while
循环,不停的使用vel_pub
对象发送速度消息包vel_msg
.
程序代码如下:
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
int main(int argc, char *argv[])
{
ros::init(argc, argv, "vel_node");
ros::NodeHandle n;
ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel",10);
geometry_msgs::Twist vel_msg; // 声明一个Twist类型的消息包
//Twist类型的消息包中包含了六个变量,其中三个是线速度,另外三个是角速度。
/*
.linear.x - 机器人正方向的线速度
.linear.y - 机器人正左方的线速度
.linear.z - 机器人正上方的线速度
.angular.x - 机器人绕x轴的角速度
.angular.y - 机器人绕y轴的角速度
.angular.z - 机器人绕z轴的角速度
*/
vel_msg.linear.x = 0; // 设置线速度为0.1m/s
vel_msg.linear.y = 0;
vel_msg.linear.z = 0;
vel_msg.angular.x = 0;
vel_msg.angular.y = 0;
vel_msg.angular.z = 0.5;
ros::Rate loop_rate(30); // 设置循环频率为30次/s
while (ros::ok())
{
vel_pub.publish(vel_msg); // 发布消息
loop_rate.sleep(); // 按前面设置的30次/s频率将程序挂起
}
return 0;
}
编写速度发布节点Python
实现思路和前面C++相同,这里只展示代码:
#!/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)
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()
python文件编写完后不需要编译,可以直接运行,但在运行前需要给可执行权限。
如图
在终端中没有给python文件可执行权限之间,ls
查看是灰白的。chmod +x vel_node.py
之后,ls
文件变为绿色,说明是可执行文件。