joystick_teleop_node.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (C) 2015, Alexander Gonzales
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the author nor other contributors may be
00018 *     used to endorse or promote products derived from this software
00019 *     without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 #include "ros/ros.h"
00036 #include "geometry_msgs/Twist.h"
00037 #include "sensor_msgs/Joy.h"
00038 
00039 double MAX_SPEED_MULT = .5;
00040 double MAX_TURN_MULT = .25;
00041 
00042 bool firstZeroVel = false;
00043 bool publishAnyway = false;
00044 
00045 //Will hold values of sticks and buttons
00046 int lastButtons[11];
00047 float lastAxes[8];
00048 
00049 // Default axis/button mappings for Xbox controller
00050 int SPEED_AXIS = 1;
00051 int TURN_AXIS = 3;
00052 int MAX_TURN_AXIS = 6;
00053 int MAX_SPEED_AXIS = 7;
00054 int BRAKE_BUTTON = 1;
00055 
00056 //Updates the current values
00057 void joystickCallback(const sensor_msgs::Joy::ConstPtr& msg)
00058 {
00059   //Assign the values in a for loop (for some reason got a seg fault when just assigning vectors, prob
00060   //has to do with the pointer being deleted after the msg is over)
00061   int x;
00062   for(x = 0; x < 11; x++)
00063     lastButtons[x] = msg->buttons[x];
00064   
00065   int y;
00066   for(y = 0; y < 8; y++)
00067     lastAxes[y] = msg->axes[y];
00068   
00069   if(lastAxes[SPEED_AXIS] < 0.2 && lastAxes[SPEED_AXIS] > -0.2) //Dead zone for 0
00070     lastAxes[SPEED_AXIS] = 0;
00071   
00072   if(lastAxes[TURN_AXIS] < 0.2 && lastAxes[TURN_AXIS] > -0.2) //Dead zone for 0
00073      lastAxes[TURN_AXIS] = 0;
00074   
00075   //Make sure we accept the 0 vel commands
00076   if(lastAxes[SPEED_AXIS] == 0 && lastAxes[TURN_AXIS] == 0 && lastAxes[MAX_TURN_AXIS] == 0 && lastAxes[MAX_SPEED_AXIS] == 0)
00077     firstZeroVel = true;
00078   
00079   //Up on D pad
00080   if(lastAxes[MAX_TURN_AXIS] == -1)
00081   {
00082     MAX_TURN_MULT += .05;
00083     ROS_INFO("Turn Multiplier Changed: %f -> %f\n", MAX_TURN_MULT - .05, MAX_TURN_MULT);
00084   }
00085   
00086   //Down on D pad
00087   if(lastAxes[MAX_TURN_AXIS] == 1)
00088   {
00089     MAX_TURN_MULT -= .05;
00090     ROS_INFO("Turn Multiplier Changed: %f -> %f\n", MAX_TURN_MULT + .05, MAX_TURN_MULT);
00091   }
00092   
00093   //Left on D pad
00094   if(lastAxes[MAX_SPEED_AXIS] == -1)
00095   {
00096     MAX_SPEED_MULT -= .1;
00097     ROS_INFO("Speed Multiplier Changed: %f -> %f\n", MAX_SPEED_MULT + .1, MAX_SPEED_MULT);
00098   }
00099   
00100   //Right on D pad
00101   if(lastAxes[MAX_SPEED_AXIS] == 1)
00102   {
00103     MAX_SPEED_MULT += .1;
00104     ROS_INFO("Speed Multiplier Changed: %f -> %f\n", MAX_SPEED_MULT - .1, MAX_SPEED_MULT);
00105   }
00106   
00107   //Emergency stop, sets the system to spam 0 vel commands until let go.
00108   //Red "B" button on xbox controllers
00109   if(lastButtons[BRAKE_BUTTON] == 1)
00110   {
00111     lastAxes[SPEED_AXIS] = 0;
00112     lastAxes[TURN_AXIS] = 0;
00113     publishAnyway = true;
00114   }
00115   else
00116   {
00117     publishAnyway = false;
00118   }
00119 }
00120 
00121 int main(int argc, char **argv)
00122 {
00123   
00124   if(!(argc == 1 || argc == 3))
00125     ROS_INFO("Invalid number of starting parameters, ignoring all of them.");
00126   
00127   //Can start with specific speed mults
00128   if(argc == 3)
00129   {
00130     MAX_SPEED_MULT = atof(argv[1]);
00131     MAX_TURN_MULT = atof(argv[2]);
00132     ROS_INFO("Starting with Speed Mult of %f, and Turn Mult of %f", MAX_SPEED_MULT, MAX_TURN_MULT);
00133   }
00134   
00135   //Set default
00136   if(MAX_SPEED_MULT == 0)
00137   {
00138     MAX_SPEED_MULT = .5;
00139     ROS_INFO("Adjusted Speed Mult to .5");
00140   }
00141   
00142   //Set default
00143   if(MAX_TURN_MULT == 0)
00144   {
00145     MAX_TURN_MULT = .25;
00146     ROS_INFO("Adjusted Turn Mult to .25");
00147   }
00148   
00149   ros::init(argc, argv, "joystick_teleop");
00150 
00151   ros::NodeHandle n;
00152   ros::NodeHandle pn("~");
00153 
00154   std::string mapping;
00155   pn.param<std::string>("mapping", mapping, "xbox");
00156   ROS_INFO_STREAM("Using mappings for " << mapping);
00157   if("xbox" == mapping)
00158   {
00159     // no-op: defaults already set
00160   }
00161   else if("ps4" == mapping)
00162   {
00163     SPEED_AXIS = 1;        // left stick up/down
00164     TURN_AXIS = 0;         // left stick left/right
00165     MAX_TURN_AXIS = 6;     // Dpad left/right
00166     MAX_SPEED_AXIS = 7;    // Dpad up/down
00167     BRAKE_BUTTON = 2;      // O (circle) button
00168   }
00169   else
00170   {
00171     ROS_ERROR_STREAM("Unknown ~mapping \"" << mapping << "\". Keeping default.");
00172   }
00173 
00174   ros::Publisher pub = n.advertise<geometry_msgs::Twist>("cmd_vel", 1000);
00175   
00176   ros::Subscriber sub = n.subscribe("joy", 1000, joystickCallback);
00177   
00178   ros::Rate loop_rate(10);
00179  
00180   while (ros::ok())
00181   {
00182     geometry_msgs::Twist msg;
00183     
00184     //Set forward/back based on left joystick up/down
00185     msg.linear.x = lastAxes[SPEED_AXIS] * MAX_SPEED_MULT;
00186     
00187     //Set left/right based on right joystick left/right
00188     msg.angular.z = lastAxes[TURN_AXIS] * MAX_TURN_MULT;
00189     
00190     //Lets not spam 0 cmd vel messages
00191     if(msg.linear.x == 0 && msg.angular.z == 0)
00192     {
00193       if(firstZeroVel == true || publishAnyway == true) //Check if its the first (or close to) or if we have the e-stop override
00194       {
00195         pub.publish(msg);
00196         firstZeroVel = false;
00197       }
00198     }
00199     else
00200     {
00201       pub.publish(msg);
00202     }
00203     
00204     ros::spinOnce();
00205     
00206     loop_rate.sleep();
00207   }
00208 
00209 
00210   return 0;
00211 }


bwi_joystick_teleop
Author(s): Alex Gonzales
autogenerated on Thu Jun 6 2019 17:57:18