游戏手柄之自定义按钮控制海龟

该文为基础上https://blog.csdn.net/qq_34935373/article/details/87905784

想通过游戏手柄自定义话题,自定义按键实现对海龟的控制。于是有了本文

新建节点/joymsg_pub_node和话题/joycontrol_topic.

在src/目录下新建功能包joy_msg,在joy_msg/src的新建源文件joymsg_pub.cpp。代码如下::

#include "ros/ros.h"

#include<geometry_msgs/Twist.h>

#include <iostream>

#include <sstream>

#include <stdio.h>              //perror()

#include <unistd.h>            //fork()

#include <stdlib.h>

#include <errno.h>            //errno, EINTR

#include <string.h>           //strlen()

#include <fcntl.h>

#include <signal.h>

#include <syspes.h>  

#include <sys/stat.h>  

#include <linux/input.h>  

#include <linux/joystick.h>

#include <errno.h>

#include <pthread.h>

 

 

 

#define AXES0 0x00 //Left_Axis from right to left        

#define AXES1 0x01 //Left_Axis from up to down             

#define AXES2 0x02 //Right_Axis from right to left

#define AXES3 0x03 //Right_Axis from down to up

#define AXES4 0x04 //R&L_Key from Right_Key to Left_Key  

#define AXES5 0x05 //D&U_Key from Down_key to Up_key

 

#define BUTTON0 0x00         //X_Botton           

#define BUTTON1 0x01         //A_Botton                   

#define BUTTON2 0x02            //B_Botton       

#define BUTTON3 0x03            //Y_Botton       

#define BUTTON4 0x04            //LB_Botton

#define BUTTON5 0x05            //RB_Botton  

#define BUTTON6 0x06 //LT_Botton

#define BUTTON7 0x07 //RT_Botton

#define BUTTON8 0x08 //BACK_Botton

#define BUTTON9 0x09 //START_Botton

#define BUTTON10 0x10     //Left_Axis__Botton  

#define BUTTON11 0x11    //Right_Axis_Botton

 

float linear_x,linear_y,linear_z ;

float angular_x,angular_y,angular_z, value ;

 

int len, type, number;

int ret0;

pthread_t id0;  

struct js_event js;  

int js_fd;

void * read_js_data(void *);

using namespace std;

 

int main(int argc, char **argv)

{

//Initializing ROS node with a name of joymsg_pub

ros::init(argc, argv,"joymsg_pub");

//Created a nodehandle object

ros::NodeHandle n1;

//Create a publisher object

ros::Publisher number_publisher = n1.advertise<geometry_msgs::Twist>("/joycontrol_topic",100);

//Create a rate object

ros::Rate loop_rate(100);

//Variable of the number initializing as zero

 

js_fd = open("/dev/input/js0", O_RDONLY);  

    if (js_fd < 0)  

    {  

        perror("open");  

        return -1;  

    }  

 

    pthread_create(&id0,NULL,read_js_data,NULL);  // 成功返回0,错误返回错误编号

 

    if(ret0!=0)

        {

            printf ("Create pthread1 error!\n");

            exit(1);

        }

    ret0=pthread_detach(id0);

 

while (ros::ok())

{

 

//Created geometry_msgs/Twist 这里可以加入你自定义文件,本文控制的是海龟,所以是这个消息格式,自定义文件,头文件记得添加奥

        geometry_msgs::Twist msg;

 

        //Inserted data to message header

msg.linear.x = linear_x;

msg.linear.y = linear_y;

msg.linear.z = linear_z;

 

        msg.angular.x = angular_x ;

        msg.angular.y = angular_y;

        msg.angular.z = angular_z;

        

 

//Publishing the message

number_publisher.publish(msg);

//Spining once for doing the  all operation once

ros::spinOnce();

//Setting the loop rate

loop_rate.sleep();

}

return 0;

}

 

void * read_js_data(void *)

{

while(1)

{

    len = read(js_fd, &js, sizeof(struct js_event));  

    if (len < 0)  

    {  

        perror("read");  

        return 0 ;  

    }  

    value = js.value;

    type = js.type;

    number = js.number;

 

    if (type == JS_EVENT_BUTTON)  

    {  

        /* if( number == BUTTON0  )

            {

               linear_x=value;  

            }

            if( number == BUTTON5  )

            {

                angular_z=value;  

            }

这里是设置按钮为操作单位,本文采用axis轴作为输入*/

     }

 

    else if (type == JS_EVENT_AXIS)  

    {

        if( number == AXES5 )

        {

            linear_x = value;

        }  

 if( number == AXES3 )

       {

            angular_z= value;

        }

//本文中控制海龟只用到了这两个

    }

} }

 

修改package.xml文件,添加依赖

  <buildtool_depend>catkin<ildtool_depend>

  <build_depend>roscpp<ild_depend>

  <build_depend>rospy<ild_depend>

  <build_depend>std_msgs<ild_depend>

  <build_export_depend>roscpp<ild_export_depend>

  <build_export_depend>rospy<ild_export_depend>

  <build_export_depend>std_msgs<ild_export_depend>

  <exec_depend>roscpp</exec_depend>

  <exec_depend>rospy</exec_depend>

  <exec_depend>std_msgs</exec_depend>

  <exec_depend>message_runtime</exec_depend>

 

修改CMakeLists.txt

add_executable(joymsg_pub

  src/joymsg_pub.cpp

)

add_dependencies(joymsg_pub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(joymsg_pub

  ${catkin_LIBRARIES}

)

 

 

本文是基于博客https://blog.csdn.net/qq_34935373/article/details/87905784基础上做的,如果又不懂得,建议看下上文。

进入input_js_control的功能包修改源代码logitech.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 geometry_msgs::Twist::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,0);//默认axes[0]接收角度

   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<geometry_msgs::Twist>("joycontrol_topic",10,&Teleop::callback,this);

} //订阅游戏手柄发来的数据}

 

void Teleop::callback(const geometry_msgs::Twist::ConstPtr& Joy)

 {

   geometry_msgs::Twist v;

   v.linear.x =Joy->linear.x*vlinear*0.001; //之后的参数设置在launch文件中输入你的期望值,将游戏手柄的数据乘以你想要的速度,然后发给乌龟

   v.angular.z =Joy->angular.z*vangular*0.001;

   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, "joy_to_turtle");

  Teleop teleop_turtle;

  ros::spin();

  return 0;

}

 

修改input_js_control.launch文件如下

<launch>

    <node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node">

    <de>

    <node pkg="input_js_control" type="logitech" name="joy_to_turtle" output="screen">

    <de>

    

<!--input percentage of you want to set value -->

       <param name="vel_linear" value="1" type="double"/>

       <param name="vel_angular" value="1" type="double"/>

 

    <node pkg="joymsg_pub" type="joymsg_pub" name="joymsg_pub_node">

    <de>

 

    <!-- node  respawn="true" pkg="joy" type="joy_node" name="joystick" >  

    <de -->

    

</launch>

 

 

回到工作目录执行catkin_make 编译节点

然后执行launch文件,就可以了。

最后自己修改按键和axis的轴,确定对应的数字号。我用的是logitech wireless gamepad F710型号.测试结果如下:

 

说明轴0,1和轴4,5在jstest测试和本文测试中顺序相反.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值