文章借鉴了这边博客https://blog.csdn.net/u014587147/article/details/75673110。
这篇文章记录下自己操作过程中遇到的问题,更加适合新手。
1、使用终端分别运行下面三个命令,启动小乌龟和键盘操控。
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
接下来,查看节点与话题之间的关系
rqt_graph
界面如下
椭圆内的是节点,横线上是话题。通过rqt_graph可以看到,小乌龟turtlesim节点订阅/turtle1/cmd_vel话题.那么,我们可以通过向这个话题发布消息来控制小乌龟。接下来查看话题的类型
rostopic type /turtle1/cmd_vel
结果如下
geometry_msgs/Twist
再查看这个话题发布哪些消息来控制乌龟
rosmsg show geometry_msgs/Twist
结果如下
geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z
由之前的经验,小乌龟的运动主要有线速度和角速度来控制,即通过linear x和angular z控制。这在后面的编程中会用到。
2、下面要查看手柄各个按键的作用。
首先,查看手柄的接入端口
ls /dev/input/
很有可能会出现很多端口,手柄的端口主要是js0或者js1,想要确定到底是哪个,把手柄的蓝牙接收器拔了,看哪个端口没了就能确定了。然后安装手柄测试工具并测试手柄按键
sudo apt-get install jstest-gtk
sudo jstest /dev/input/js0
Joystick (BETOP CONTROLLER) has 6 axes (X, Y, Z, Rz, Hat0X, Hat0Y)
and 12 buttons (BtnX, BtnY, BtnZ, BtnTL, BtnTR, BtnTL2, BtnTR2, BtnSelect, BtnStart, BtnMode, BtnThumbL, BtnThumbR).
Testing ... (interrupt to exit)
Axes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off
终端显示阿修罗手柄有6个轴和12个按键(一个转动轴的上下和左右各算一个轴,由一个Axes显示。手柄实际按键只有11个)。
接下来,要自己动手测试每个按键所对应的点,按下手柄上的按键,终端数据会有相应的变化。
这里,我将用Axes[1]用来控制速度,Axes[2]用来控制角速度。即将Axes[1]赋值给linear x,Axes[2]赋值给angular z。
3、下面查看ROS手柄话题的类型
这里joy功能包可能需要自己下载,如果没有joy_node节点,请自行百度下载,然后编译运行
rosrun joy joy_node
rostopic type /joy
结果:
sensor_msgs/Joy
运行
rosmsg show sensor_msgs/Joy
结果:
std_msgs/Header header
uint32 seq
time stamp
string frame_id
float32[] axes
int32[] buttons
4、接下来,编写代码,运行节点
首先
catkin_create_pkg js_turtle std_msgs roscpp
创建ROS包,进入包的src文件夹,创建js_turtle.cpp文件,写入以下代码,记得根据实际情况更改。
#include
#include
#include
#include
using namespace std;
class Teleop
{
public:
Teleop();
private:
/* data */
void callback(const sensor_msgs::Joy::ConstPtr& Joy);
ros::NodeHandle n; //实例化节点
ros::Subscriber sub ;
ros::Publisher pub ;
double vlinear,vangular;//我们控制乌龟的速度,是通过这两个变量调整
int axis_ang,axis_lin; //axes[]的键
};
Teleop::Teleop()
{
//下面按键的设置,一定要根据自己的实际情况来更改
n.param("axis_linear",axis_lin,1); //默认axes[1]接收速度
n.param("axis_angular",axis_ang,2);//默认axes[2]接收角度
n.param("vel_linear",vlinear,1);//默认线速度1 m/s
n.param("vel_angular",vangular,1);//默认角速度1 单位rad/s
pub = n.advertise("/turtle1/cmd_vel",1);//将速度发给乌龟
sub = n.subscribe("joy",10,&Teleop::callback,this); //订阅游戏手柄发来的数据
}
void Teleop::callback(const sensor_msgs::Joy::ConstPtr& Joy)
{
geometry_msgs::Twist v;
v.linear.x =Joy->axes[axis_lin]*vlinear; //将游戏手柄的数据乘以你想要的速度,然后发给乌龟
v.angular.z =Joy->axes[axis_ang]*vangular;
ROS_INFO("linear:%.3lf angular:%.3lf",v.linear.x,v.angular.z);
pub.publish(v);
}
int main(int argc,char** argv)
{
ros::init(argc, argv, "logteleop");
Teleop telelog;
ros::spin();
return 0;
}
然后,修改包的Cmake文件,找到以下两行代码,将代码前面的注释符删掉。
catkin_create_pkg js_turtle std_msgs roscpp
target_link_libraries(${PROJECT_NAME}_node
${catkin_LIBRARIES}
)
再到包目录下,创建luanch文件夹,进入文件夹,创建js_turtle.launch启动文件,将所有需要用的节点直接集合在一起,launch文件的内容如下,请根据实际情况修改
最后,编译运行,界面如下
github: https://github.com/bingo1766/js_turtle.git
这里仍然存在一个问题,就是没有办法一直按着手柄操控乌龟,大概一两秒就会停下,需要放开按键然后重新按下。
希望有大佬可以帮忙解答这个问题。