实验现象
1.在操纵结点按下方向键,屏幕中的小海龟作出对应的移动。
2.编译写好的源文件,小海龟开始走圆圈。
键盘操纵小海龟
roscore
打开终端,输入roscore,并保持开启。
海龟图形界面
另开一个终端,输入指令:
rosrun turtlesim turtlesim_node
即可在新弹出的窗口中,看见一只海龟:
海龟按键操纵
另开一个终端,输入指令:
rosrun turtlesim turtle_teleop_key
即可在这个终端中,通过箭头按键控制小乌龟移动。
控制乌龟走圆圈
原理
其实turtlesim_node与turtle_teleop_key这两个都是ROS事先已经写好的文件,可以直接编译执行。从前面的实验可以看到,turtle_teleop_key可以发送键盘按键信息给turtlesim_node,使海龟出现移动。那么两个程序之间,是如何通信的呢?
在命令行输入
rosrun rqt_graph rqt_graph
可以看到这个图:
在ROS中,可执行文件被称作节点。turtle_teleop_key与turtlesim_node都被称作节点。
turtle_teleop_key与turtlesim_node这两个节点之间通过/strong/cmd_vel通信,这个/strong/cmd_vel被叫做话题。turtle_teleop_key将按键信息发布在这个话题上,turtlesim_node从这个话题接收信息控制小海龟移动。
因此,要使小海龟转圆圈,我们也可以写一个源文件,在源文件中向/strong/cmd_vel这个话题发送控制指令即可。
数据类型
现在知道了按键控制节点向话题发送数据,让小海龟结点接受数据。那么到时候我们编写文件的时候,要发送什么数据呢?是int型?还是float型?还是数组呢?
可以用命令行指令来查看。
rostopic type /turtle1/cmd_vel
这个指令用于查看某个话题上的数据类型(一个话题上的数据类型是一样的),/turtle1/cmd_vel这个话题的数据类型是:geometry_msgs/Twist
再看看geometry_msgs/Twist是什么样子的:
rosmsg show 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
linear表示线速度,angular表示角速度,xyz表示坐标(x表示前后,y表示左右,z表示上下)。线速度可以用来让小海龟移动,角速度用来控制转向。
要想小海龟转圆圈,就需要让它向前匀速移动,而且角速度保持一个非0的值即可。如果我们向/turtle1/cmd_vel这个话题不断发送以下数据:
geometry_msgs/Vector3 linear
float64 1
float64 0
float64 0
geometry_msgs/Vector3 angular
float64 0
float64 0
float64 2
那么小海龟就可以一直做曲线运动,由于线速度与角速度保持不变,小海龟的移动轨迹就是一个圆。
创建工作空间
可执行文件的编写与运行都是在软件包中执行的,而要制作软件包,又必须在工作空间中执行。因此,要先制作工作空间。
mkdir -p ~/workspace_name/src
cd ~/workspace_name/
catkin_make
source devel/setup.bash
创建软件包
首先进入工作空间的src目录
cd ~/workspace_name/src
然后执行指令创建软件包
catkin_create_pkg pkg_name roscpp rospy std_msgs geometry_msgs
pkg_name是自定义的软件包名称,后面跟着的是软件包要依赖的包。
编写源文件
到新建的软件包下的src目录中,新建cpp源文件,写入以下内容:
#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"control");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",1000);
geometry_msgs::Twist msg;
msg.linear.x = 1.0;
msg.linear.y = 0.0;
msg.linear.z = 0.0;
msg.angular.x = 0.0;
msg.angular.y = 0.0;
msg.angular.z = 2.0;
ros::Rate r(10);
while (ros::ok())
{
pub.publish(msg);
ros::spinOnce();
}
return 0;
}
修改配置文件
修改软件包下的CMakeList.txt文件,添加以下内容并保存:
catkin_package()
add_executable(步骤3的源文件名
src/上一步的源文件名.cpp
)
target_link_libraries(上一步的源文件名
${catkin_LIBRARIES}
)
编译
cd 自定义空间名称
catkin_make
执行
source ./devel/setup.bash
rosrun 自定义的软件包名 自定义的源文件名
可以看到小海龟开始自己做圆周运动了。
总结
键盘操控小海龟可以使用ROS自带的两个节点来实现,实现原理是控制节点发送数据到话题,图形节点再从话题得到数据做出动作。
而控制海龟移动的话题是/turtle1/cmd_vel,而这个话题上的数据是geometry_msgs::Twist。创建软件包写好源文件来持续发送geometry_msgs::Twist类型的数据,海龟就可以做圆形运动。
参考资料
https://blog.csdn.net/weixin_41869763/article/details/113858698
http://wiki.ros.org/cn
http://www.autolabor.com.cn/book/ROSTutorials/