使用ROS控制罗技F701游戏手柄

一、前期工作

1.安装joy库

sudo apt install ros-$ROS_DISTRO-joy

在这里插入图片描述

2.查看设备信息

在命令行中,输入如下命令查看当前连接的输入设备。

ls /dev/input/

一般而言,罗技手柄设备的命名都以 js 开头,此处博主的输入即为 js0
在这里插入图片描述
为了确保之后在ROS中使用手柄控制,此处需要将用户所在族添加至该串口的所有者。

sudo chgrp usrname /dev/input/js0
ls -l /dev/input/js0

在这里插入图片描述

3.查看当前按键

安装完joy包后,可以使用jstest命令查看当前按键情况。

sudo jstest /dev/input/js0

在这里插入图片描述

4.启动节点

除了使用jytest指令外,还可以直接运行joy节点进行查看。

roscore
rosrun joy joy_node
rostopic echo /joy

在这里插入图片描述
通过不断改变按键,可以发现对应的数据将进行改变。

二、ROS手柄差速控制(C++版)

1.新建功能包

此处编写代码用到了 geometry_msgs、std_msgs、sensor_msgs三个库,需要在创建功能包时,同时添加依赖。

# 新建功能包
catkin_create_pkg logitech_teleop_key roscpp rospy geometry_msgs std_msgs sensor_msgs

2.编写节点代码

在上一步创建的功能包中继续编写添加节点代码

# 添加控制代码
cd logitech_teleop_key/src/
touch logitech_teleop_key.cpp
vim logitech_teleop_key.cpp

此处用到的代码内容如下所示,主要控制的效果有如下几条:

  • 在使用手柄进行控制时,必须按下手柄的6号键 不放,同时使用摇杆进行调速。
  • 如若不知道手柄上各个建对应的序号,可以通过jstest命令查看。
  • 左侧摇杆控制线速度,右侧摇杆控制角速度
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <std_msgs/String.h> 
#include <sensor_msgs/Joy.h>

using namespace std;
 
class LogTeleop
{
public:
    LogTeleop();
 
private:
    /* data */
    void LogCallback(const sensor_msgs::Joy::ConstPtr& Joy);
    ros::NodeHandle n;
    ros::Subscriber sub ;
    ros::Publisher pub ;
    double vel_linear,vel_angular;
    int axis_angular,axis_linear,ton;
};
 
LogTeleop::LogTeleop()
{
    // 手柄摇杆的转动幅度
    n.param<int>("axis_linear",axis_linear,1);
    n.param<int>("axis_angular",axis_angular,2);
    // 线速度和角速度
    n.param<double>("vel_linear",vel_linear,0.1);
    n.param<double>("vel_angular",vel_angular,0.4);
    n.param<int>("button",ton,6);
    // 发布与订阅
    pub = n.advertise<geometry_msgs::Twist>("cmd_vel", 1, true);;
    sub = n.subscribe<sensor_msgs::Joy>("joy",10,&LogTeleop::LogCallback,this);
}
 
void LogTeleop::LogCallback(const sensor_msgs::Joy::ConstPtr& Joy)
{
	geometry_msgs::Twist twist;

	vel_linear = vel_linear * (1 + (Joy->axes[5] * 0.1));
	if(vel_linear>=0.2)
	   vel_linear = 0.2;
	else if (vel_linear<=0)
	   vel_linear = 0;
	else
	   vel_linear = vel_linear;
	
	vel_angular = vel_angular * (1 +  (Joy->axes[4] * 0.1));
	if(vel_angular>=0.6)
		vel_angular = 0.6;
	else if(vel_angular<=0)
		vel_angular = 0;
	else
		vel_angular = vel_angular;

	// 控制时,需要同时按住6号键
	if(Joy->buttons[ton])
	{
	    twist.linear.x =(Joy->axes[axis_linear])*vel_linear;
	    twist.linear.y = 0;
	    twist.linear.z = 0;
	    
	    twist.angular.x = 0;
	    twist.angular.y = 0;
	    twist.angular.z =(Joy->axes[axis_angular])*vel_angular;
		    
		ROS_INFO("linear:%.3lf angular:%.3lf",twist.linear.x,twist.angular.z);
		pub.publish(twist);
	}
}

int main(int argc,char** argv)
{
    ros::init(argc, argv, "logitech_teleop_key");
    LogTeleop  logteleop;
    ros::spin();
    return 0;
}

3.添加依赖

编写完成节点代码后,还需要在功能包下的CMakeList.txt文件中添加依赖。

add_executable(logitech_teleop_key src/logitech_teleop_key.cpp)
target_link_libraries(logitech_teleop_key ${catkin_LIBRARIES})

4.launch文件

为了快捷启动节点,此处使用launch文件进行配置。

# 功能包根目录下
mkdir launch
touch launch/logitech_teleop_key.launch
vim launch/logitech_teleop_key.launch

文件内容如下:

<launch>
  <arg name="joy_dev" default="/dev/input/js0" />
 
  <node pkg="joy" type="joy_node" name="joy_node">
    <param name="dev" value="$(arg joy_dev)" />
    <param name="deadzone" value="0.05" />
    <param name="autorepeat_rate" value="10" />  <!--检测到键值时键值发送频率单位Hz,100.1m发送一次-->
  </node>
 
  <node pkg="logitech_teleop_key" type="logitech_teleop_key" name="logitech_teleop_key" output="screen">
    <!--input axis -->
      <param name="axis_linear" value="1" type="int"/>
      <param name="axis_angular" value="4" type="int"/>
    <!--input vel -->
      <param name="vel_linear" value="0.2" type="double"/>
      <param name="vel_angular" value="0.5" type="double"/>
      <param name="button" value="6" type="int"/>
  </node>
</launch>

5.编译并运行

# 工作空间根目录下
catkin_make
source devel/setup.bash
# 运行launch文件
roslaunch logitech_teleop_key logitech_teleop_key.launch

运行效果如下:
在这里插入图片描述
此时,如果按住手柄上的6号键,则将自动发送消息。同时控制摇杆,即可修改速度。
在这里插入图片描述

三、ROS手柄差速控制(Pyhon版)

1.新建功能包

此处编写代码用到了 geometry_msgs、std_msgs、sensor_msgs三个库,需要在创建功能包时,同时添加依赖。

# 新建功能包
catkin_create_pkg logitech_teleop_key roscpp rospy geometry_msgs std_msgs sensor_msgs

2.编写节点代码

博主使用的ROS版本为Noetic版,所以使用的为python3。低于此版本的用户可以将第一行修改为如下内容

# Noetic版本如下:
#! /usr/bin/env python3
# encoding: utf-8

# Melodic版本、Kinetic版本如下:
#! /usr/bin/env python
# encoding: utf-8

全部代码如下:

#! /usr/bin/env python3
# encoding: utf-8

import rospy
from geometry_msgs.msg import Twist
from std_msgs.msg import String
from sensor_msgs.msg import Joy

def joyCallback(msg):
    if not isinstance(msg, Joy): return 0

    # 手柄摇杆的转动幅度
    axis_linear_x = 1
    axis_angular_z = 2

    # 角速度和线速度
    vel_linear_x = 0.1
    vel_angular_z = 0.4

    twist = Twist()

    # linear speed value
    vel_linear_x *= 1 + (msg.axes[5]*0.1)
    if vel_angular_z >= 0.2:
        vel_linear_x = 0.2
    elif vel_linear_x <= 0:
        vel_linear_x = 0
    else:
        vel_linear_x = vel_linear_x

    # angular speed value
    vel_angular_z *= 1 + (msg.axes[4] *0.1)
    if vel_angular_z >= 0.6:
        vel_angular_z = 0.6
    elif vel_angular_z <= 0:
        vel_angular_z = 0
    else:
        vel_angular_z = vel_angular_z

    # control
    if msg.buttons[6]:
        twist.linear.x = msg.axes[axis_linear_x] * vel_linear_x
        twist.linear.y = 0
        twist.linear.z = 0

        twist.angular.x = 0
        twist.angular.y = 0
        twist.angular.z = msg.axes[axis_angular_z] * vel_angular_z

        publisher.publish(twist)
        rospy.loginfo("linear:{} angular:{}".format(twist.linear.x,twist.angular.z))

def onShutdown():
    rospy.loginfo("stop using teleop")
    twist = Twist()
    twist.linear.x = 0
    twist.angular.z = 0
    publisher.publish(twist)

if __name__ == '__main__':
    # ros node
    node_name = "logitech_teleop_key"
    rospy.init_node(node_name)

    rospy.on_shutdown(onShutdown)

    # pubilsher /cmd_vel
    publisher = rospy.Publisher("/cmd_vel", Twist,queue_size=59)
    # subscriber /joy
    rospy.Subscriber("/joy", Joy, joyCallback)

    rospy.spin()

3.编写launch文件

<launch>
  <arg name="joy_dev" default="/dev/input/js0" />
  
  <node pkg="joy" type="joy_node" name="joy_node">
    <param name="dev" value="$(arg joy_dev)" />
    <param name="deadzone" value="0.05" />
    <param name="autorepeat_rate" value="10" />  <!--检测到键值时键值发送频率单位Hz,100.1m发送一次-->
  </node>
 
  <node pkg="logitech_teleop_key" type="logitech_teleop_key.py" name="logitech_teleop_key" output="screen">
  </node>
</launch>
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值