今天学到了,使用了ros::spin()就是让程序一直在subscriber里面死循环.

更新需求,要把按键设置成控制速度按钮,摇杆作为前进后退的控制.

首先需要测试手柄上所有的按键对应的buttons[]的哪一位:

sudo jstest /dev0/input/js0

全部测试后,发现了以下对应信息:

Buttons[]:
A:     0
B:     1
X:     2
Y:     3
L1:    4
R1:    5
select:6
start: 7
mode:  8
//9,10没有分配

控制的逻辑还是在按下L1下开始,只有按下L1其他按键按动才会启动,现在的设想是:

Y和A分别控制线速度的增加和减少,X和B分别控制角速度的增加和减少;

每个设置4档:0,1,2,3

SELECT设置为最低速度, START设置为最高速度,其它按键暂时不设置.

设置比较简单,但最后的逻辑需要思考一下,先实现:

首先在launch里面更改:

<launch>
    <node pkg="turtlesim" type="turtlesim_node" name="turtle1" output="screen" />
   
    <node pkg="ros_handle_control" type="teleop_turtle4" name="teleop4" output="screen" />
    <node pkg="ros_handle_control" type="teleop_turtle5" name="teleop5" output="screen" />

<!-- 方向按键控制 -->
    <param name="axis_linear" value="7" type="int" />
    <param name="axis_angular" value="6" type="int" />
<!-- 摇杆控制 -->
    <param name="sticks_left" value="1" type="int" />
    <param name="sticks_right" value="3" type="int" />

<!-- 线速度系数设置 -->
    <param name="linear_ratio" value="0.5" type="double" />
<!-- 角速度系数设置 -->
    <param name="angular_ratio" value="0.5" type="double" />

<!-- 线速度换档 -->
    <param name="linear_up" value="3" type=int />
    <param name="linear_down" value="0" type=int />

<!-- 角速度换挡  -->
    <param name="angular_up" value="1" type=int />
    <param name="angular_down" value="2" type=int />

<!-- 设置最低速度和最高速度 -->
    <param name="min_speed" value="6" type=int />
    <param name="max_speed" value="7" type=int />

    <param name="ton" value="4" type="int" />
    <node respawn="true" pkg="joy" type="joy_node" name="joystick" />

</launch>

然后现在teleop_turtle4.cpp里面先修改:

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/Joy.h>

int axis_linear, axis_angular;
int sticks_left, sticks_right;
int ton;

double linear_ratio, angular_ratio;
int linear_up, linear_down, angular_up, angular_down;
int max_speed, min_speed;
double vel_x, vel_z;

bool L1_press = false;
void linear_speed_updown(const sensor_msgs::Joy::ConstPtr &joy)
{
    if(joy->buttons[linear_up])
    {
        vel_x += linear_ratio;
    }
    else if(joy->buttons[linear_down])
    {
        vel_x -= linear_ratio;
    }
}

void angular_speed_updown(const sensor_msgs::Joy::ConstPtr &joy)
{
    if(joy->buttons[angular_up])
    {
        vel_z += angular_ratio;
    }
    else if(joy->buttons[angular_down])
    {
        vel_z -= angular_ratio;
    }
}

void max_min_charge(double& v)
{
    if(v > 0)
        v > 4 ? v = 4 : v;
    else if(v < 0)
        v < -4 ? v = -4 : v;
}
void callback(const sensor_msgs::Joy::ConstPtr &joy)
{

    ROS_INFO("6546546546546");
    if(joy->buttons[ton])
    {
        if(joy->axes[axis_linear] || joy->axes[axis_angular])
        {
            vel_x = joy->axes[axis_linear];
            vel_z = joy->axes[axis_angular];
            linear_speed_updown(joy);
        }
        else if(joy->axes[sticks_left] ||  joy->axes[sticks_right])
        {
            vel_x = joy->axes[sticks_left];
            vel_z = joy->axes[sticks_right];
            angular_speed_updown(joy);
        }
        linear_speed_updown(joy);
        angular_speed_updown(joy);
        if(joy->buttons[min_speed])
        {
            vel_x = 0.5;
            vel_z = 0.5;
        }
        else if(joy->buttons[max_speed])
        {
            vel_x = 4;
            vel_z = 4;
        }
        max_min_charge(vel_x);
        max_min_charge(vel_z);
        ROS_INFO("当前线速度为:%.3lf ; 角速度为:%.3lf", vel_x, vel_z);            
    }
    else
    {
        vel_x = 0;
        vel_z = 0;
    }


}

int main(int argc, char** argv)
{
    setlocale(LC_ALL, "");
    
    ros::init(argc, argv, "sub_joy_pub_msgs");
    ros::NodeHandle nh;
    ros::Rate r(20);

    ros::Subscriber sub;
    ros::Publisher pub;
    nh.param<int>("linear_up", linear_up, 3);
    nh.param<int>("linear_down", linear_down, 0);
    nh.param<int>("angular_up", angular_up, 1);
    nh.param<int>("angular_down", angular_down, 2);
    
    nh.param<double>("linear_ratio", linear_ratio, 0.5);
    nh.param<double>("angular_ratio", angular_ratio, 0.5);

    nh.param<int>("max_speed", max_speed, 6);
    nh.param<int>("min_speed", min_speed, 7);
    nh.param<int>("ton", ton, 4);
    // 按手柄摇杆分配
    nh.param<int>("sticks_left", sticks_left, 7);
    nh.param<int>("sticks_right", sticks_right, 6);
    // 按键分配
    nh.param<int>("axis_linear", axis_linear, 1);
    nh.param<int>("axis_angular", axis_angular, 2);
    
    sub = nh.subscribe<sensor_msgs::Joy>("/joy", 10, callback);



    ros::spin();
    
    return 0;
}

第一版写的很繁琐,需要修改,相关的逻辑也很乱,怎么才能做到在按下L1的时候按方向键控制方向,并且在按动Y和A的时候进行速度的加减,之前尝试了一种方法没有完美实现,只能在按下L1后确定方向按键后松开按键,然后再对速度进行加减.但不太行,想了一下,

准备在设置多个bool来判断按键,然后在进一步处理,这样对于数据的处理更加合理.

想了很久,发现可以根据每一个按键设置对应的速度,最后在把所有的速度全部加起来,这样就可以完美解决按键匹配的功能.

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/Joy.h>

int axis_linear, axis_angular;
int sticks_left, sticks_right;
int ton;

double linear_ratio, angular_ratio;
int linear_up, linear_down, angular_up, angular_down;
int max_speed, min_speed;
double vel_x, vel_z;
double vx_scale = 0, vz_scale = 0;
double vx = 0, vz = 0;
bool min_flag = false, max_flag = false;
bool use_min_max_speed = false;
int cnt = 0;



ros::Subscriber sub;
ros::Publisher pub;
void linear_speed_updown(const sensor_msgs::Joy::ConstPtr &joy)
{

    if(joy->buttons[linear_up])
    {
        min_flag = false;
        max_flag = false;
        vx_scale += linear_ratio;
    }
    else if(joy->buttons[linear_down])
    {
        min_flag = false;
        max_flag = false;
        vx_scale -= linear_ratio;
    }
}
void angular_speed_updown(const sensor_msgs::Joy::ConstPtr &joy)
{
    if(joy->buttons[angular_up])
    {
        min_flag = false;
        max_flag = false;
        vz_scale += angular_ratio;
    }
    else if(joy->buttons[angular_down])
    {
        min_flag = false;
        max_flag = false;
        vz_scale -= angular_ratio;
    }
}
        //这里可以加前进后退方向的判断 
void max_min_speed(const sensor_msgs::Joy::ConstPtr &joy)
{
    if(joy->buttons[min_speed])
    {
        min_flag = true;
        vx = 0;
        vz = 0;
        vel_x = 0;
        vel_z = 0;
        vx_scale = 0;
        vz_scale = 0;
    }
    else if(joy->buttons[max_speed])
    {
        max_flag = true;
        vx = 0;
        vz = 0;
        vel_x = 0;
        vel_z = 0;
        vx_scale = 0;
        vz_scale = 0;
    }    
}
void max_min_charge(double& v)
{
    if(v > 0)
        v > 1 ? v = 1 : v;
    else if(v < 0)
        v < -1 ? v = -1 : v;
}
void callback(const sensor_msgs::Joy::ConstPtr &joy)
{

    if(joy->buttons[ton])
    {
        if(joy->axes[axis_linear]||joy->axes[axis_angular])
        {
            linear_speed_updown(joy);
            angular_speed_updown(joy);
            vel_x = joy->axes[axis_linear] * 0.1;
            vel_z = joy->axes[axis_angular] * 0.1;
            use_min_max_speed = true;
        }
        vx = vel_x + vx_scale;
        vz = vel_z + vz_scale;
        if(min_flag == true)
        {
            vx = 0.1;
        }
        if(max_flag == true)
        {
            vx = 1;
        }
        if((joy->buttons[min_speed] || joy->buttons[max_speed]) && use_min_max_speed)
        {
            if(joy->buttons[min_speed])
            {
                min_flag = true;
            }
            else if(joy->buttons[max_speed])
            {
                max_flag = true;
            }
            use_min_max_speed = false;    
        }

        max_min_charge(vx);
        max_min_charge(vz);
 
    }
    else
    {
        vx = 0;
        vz = 0;
        vel_x = 0;
        vel_z = 0;
        vx_scale = 0;
        vz_scale = 0;
        cnt = 0;
    }


    ROS_INFO("当前线速度为:%.3lf ; 角速度为:%.3lf", vx, vz);          

}

int main(int argc, char** argv)
{
    setlocale(LC_ALL, "");
    
    ros::init(argc, argv, "sub_joy_pub_msgs");
    ros::NodeHandle nh;
    ros::Rate r(10);
    nh.param<int>("linear_up", linear_up, 3);
    nh.param<int>("linear_down", linear_down, 0);
    nh.param<int>("angular_up", angular_up, 1);
    nh.param<int>("angular_down", angular_down, 2);
    
    nh.param<double>("linear_ratio", linear_ratio, 0.5);
    nh.param<double>("angular_ratio", angular_ratio, 0.5);

    nh.param<int>("max_speed", max_speed, 6);
    nh.param<int>("min_speed", min_speed, 7);
    nh.param<int>("ton", ton, 4);
    // 按手柄摇杆分配
    nh.param<int>("sticks_left", sticks_left, 7);
    nh.param<int>("sticks_right", sticks_right, 6);
    // 按键分配
    nh.param<int>("axis_linear", axis_linear, 1);
    nh.param<int>("axis_angular", axis_angular, 2);
    
    sub = nh.subscribe<sensor_msgs::Joy>("/joy", 10, callback);
    pub = nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);    

    while(ros::ok())
    {
        geometry_msgs::Twist v;
        v.linear.x = vx;
        v.angular.z = vz;
        pub.publish(v);
        ros::spinOnce();
    }
    
    return 0;
}

但在设置最低速度和最高速度的时候出了,问题,必须要一直按着selec和start按键,才能设置成相应的速度,按一下就松开就会刷新走,最后请教了师兄,把判断的flag的放置进速度调整里面就行了.还是实际开发能力太弱了,得加强!