这篇文章主要介绍ROS与Gazebo联合仿真下,控制移动机器人运动的三种方式,分别是终端、Python和C++。以上一篇文章中所建立的模型为基础。

1. 终端

通过终端向对应的话题下发送消息实现移动机器人的运动。这个对应话题是建立机器人模型时运动插件的话题。就拿上一篇文章中的模型举个例子吧,所用到的运动插件是Gazebo中自带的轮式差分驱动插件。

false
true
20
left_wheel_hinge
right_wheel_hinge
0.4
0.1
20
mybot/cmd_vel
odom
odom
chassis

上面加粗部分就是这个插件的命令话题,这个话题命令规则没有限制,根据个人喜好。Gazebo中的节点订阅这个命令话题,根据所获得的消息数据去去控制移动机器人相应的运动。

通过终端控制机器人运动,主要是用到了rostopic中的命令,

rostopic pub /命令话题 /话题格式 “依据话题格式给相应变量赋值”

因为笔者所用到的模型是上一篇文章的模型,所以 /命令话题 就是 mycar/cmd_vel,/话题格式 (就是你的消息格式) 就是 geometry_msgs/Twist(差分驱动用到的消息格式),“依据话题格式给相应变量赋值”首先要知道这个消息中有哪些变量。geometry_msgs/Twist消息的数据如下所示:

geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z

如果对某一话题上的消息格式不清楚 ,可以采用下面图片中的方式查询消息格式。

可以看到这个消息格式由三轴的线速度和角速度组成。我们想让小车沿x轴正方向运动,则“依据话题格式给相应变量赋值”就应该是

"linear:
x: 0.1//值的大小代表着速度的快慢
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0"

最终的命令就是:

rostopic pub /mybot/cmd_vel geometry_msgs/Twist "linear:
x: 0.1
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
 z: 0.0"https://www.zhihu.com/video/1241518933146161152
2.Python

主要是通过Python语言实现向话题发送消息。其实它的思想和前一节终端是一样的,只是通过Python语言加以描述。以下是具体代码,在代码中实现移动机器人转圈运动。

import rospy
from geometry_msgs.msg import Twist
class Carcontrol:
def __init__(self):
self.command_pub = rospy.Publisher("/mybot/cmd_vel", Twist, queue_size=1000)
self.rate_10 = rospy.Rate(10)
self.car_cmd_vel = Twist()
def setCommand(self, vel_x, vel_y, vel_z, ang_x, ang_y, ang_z):
self.car_cmd_vel.linear.x = vel_x
self.car_cmd_vel.linear.y = vel_y
self.car_cmd_vel.linear.z = vel_z
self.car_cmd_vel.angular.x = ang_x
self.car_cmd_vel.angular.y = ang_y
self.car_cmd_vel.angular.z = ang_z
self.command_pub.publish(self.car_cmd_vel)
self.rate_10.sleep()
def moveRotation(self, x, z):
self.setCommand(x, 0, 0, 0, 0, z)
def main():
rospy.init_node('carControl')
carcontrol = Carcontrol()
while (not rospy.is_shutdown()):
carcontrol.moveRotation(0.2, 0.1)
if __name__ == '__main__':
 main()

3. C++

这一节主要用到C++语言去写控制节点,代码如下:

#include "ros/ros.h"#include "geometry_msgs/Twist.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "car_control");
ros::NodeHandle n;
ros::Publisher command_pub = n.advertise<:twist>("/mybot/cmd_vel", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
geometry_msgs::Twist car_cmd_vel;
car_cmd_vel.linear.x = 0.2;
car_cmd_vel.linear.y = 0;
car_cmd_vel.linear.z = 0;
car_cmd_vel.angular.x = 0;
car_cmd_vel.angular.y = 0;
car_cmd_vel.angular.z = -0.5;
command_pub.publish(car_cmd_vel);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}

在这里要说一下,运行Python和C++编写的节点方法是不同的。对于Python语言的节点每次修改不需要重新编译工作空间,只需要保存并在对应的文件夹路径下去运行就行了。而对于C++编写的节点必须要进行编译,之后用rosrun中对应的命令去运行节点。

如果有什么问题请多多指教!!!

后面打算结合摄像机图像处理做一些分享。