ROS上用北通阿修罗手柄控制小乌龟

匿名 (未验证) 提交于 2019-12-02 22:56:40

文章借鉴了这边博客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<ros/ros.h>   #include<geometry_msgs/Twist.h>   #include <sensor_msgs/Joy.h>   #include<iostream>   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<int>("axis_linear",axis_lin,1); //默认axes[1]接收速度    n.param<int>("axis_angular",axis_ang,2);//默认axes[2]接收角度 n.param<double>("vel_linear",vlinear,1);//默认线速度1 m/s n.param<double>("vel_angular",vangular,1);//默认角速度1 单位rad/s pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",1);//将速度发给乌龟 sub = n.subscribe<sensor_msgs::Joy>("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文件的内容如下,请根据实际情况修改

 <launch>    <node pkg="turtlesim" type="turtlesim_node" name="turtlesim" />    <node pkg="joy" type="joy_node" name="joystick">     <param name="dev" type="string" value="/dev/input/js0" />     <param name="deadzone" value="0.12" />    </node>    <node pkg="js_turtle" type="js_turtle_node" name="js_turtle_node" /> </launch>

最后,编译运行,界面如下

https://github.com/bingo1766/js_turtle.git

这里仍然存在一个问题,就是没有办法一直按着手柄操控乌龟,大概一两秒就会停下,需要放开按键然后重新按下。

希望有大佬可以帮忙解答这个问题。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!