teleop_keyboard.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Arizona Robotics Research Group, University of Arizona
00003  * Copyright (c) 2008, Willow Garage, Inc.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the <ORGANIZATION> nor the names of its
00015  *       contributors may be used to endorse or promote products derived from
00016  *       this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028  * POSSIBILITY OF SUCH DAMAGE.
00029  */
00030 
00031 #include <termios.h>
00032 #include <signal.h>
00033 #include <math.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <sys/poll.h>
00037 
00038 #include <boost/thread/thread.hpp>
00039 #include <ros/ros.h>
00040 #include <geometry_msgs/Twist.h>
00041 
00042 
00043 
00044 #define KEYCODE_W 0x77
00045 #define KEYCODE_A 0x61
00046 #define KEYCODE_S 0x73
00047 #define KEYCODE_D 0x64
00048 
00049 
00050 
00051 #define KEYCODE_A_CAP 0x41
00052 #define KEYCODE_D_CAP 0x44
00053 #define KEYCODE_S_CAP 0x53
00054 #define KEYCODE_W_CAP 0x57
00055 
00056 
00057 
00058 class ErraticKeyboardTeleopNode
00059 {
00060   private:
00061     double walk_vel_;
00062     double run_vel_;
00063     double yaw_rate_;
00064     double yaw_rate_run_;
00065 
00066     geometry_msgs::Twist cmdvel_;
00067     ros::NodeHandle n_;
00068     ros::Publisher pub_;
00069 
00070   public:
00071     ErraticKeyboardTeleopNode() {
00072       pub_ = n_.advertise<geometry_msgs::Twist> ("cmd_vel", 1);
00073 
00074       ros::NodeHandle n_private ("~");
00075       n_private.param ("walk_vel", walk_vel_, 0.4);
00076       n_private.param ("run_vel", run_vel_, 0.7);
00077       n_private.param ("yaw_rate", yaw_rate_, 0.4);
00078       n_private.param ("yaw_rate_run", yaw_rate_run_, 0.8);
00079     }
00080 
00081     ~ErraticKeyboardTeleopNode() { }
00082     void keyboardLoop();
00083 
00084     void stopRobot() {
00085       cmdvel_.linear.x = 0.0;
00086       cmdvel_.angular.z = 0.0;
00087       pub_.publish (cmdvel_);
00088     }
00089 };
00090 
00091 
00092 
00093 ErraticKeyboardTeleopNode* tbk;
00094 int kfd = 0;
00095 struct termios cooked, raw;
00096 bool done;
00097 
00098 
00099 
00100 int main (int argc, char** argv)
00101 {
00102   ros::init (argc, argv, "teleop_keyboard");
00103   ErraticKeyboardTeleopNode tbk;
00104 
00105   boost::thread t = boost::thread (boost::bind (&ErraticKeyboardTeleopNode::keyboardLoop, &tbk));
00106 
00107   ros::spin();
00108 
00109   t.interrupt();
00110   t.join();
00111   tbk.stopRobot();
00112   tcsetattr (kfd, TCSANOW, &cooked);
00113 
00114   return (0);
00115 }
00116 
00117 
00118 
00119 void ErraticKeyboardTeleopNode::keyboardLoop()
00120 {
00121   char c;
00122   double max_tv = walk_vel_;
00123   double max_rv = yaw_rate_;
00124   bool dirty = false;
00125   int speed = 0;
00126   int turn = 0;
00127 
00128   // get the console in raw mode
00129   tcgetattr (kfd, &cooked);
00130   memcpy (&raw, &cooked, sizeof (struct termios));
00131   raw.c_lflag &= ~ (ICANON | ECHO);
00132   raw.c_cc[VEOL] = 1;
00133   raw.c_cc[VEOF] = 2;
00134   tcsetattr (kfd, TCSANOW, &raw);
00135 
00136   puts ("Reading from keyboard");
00137   puts ("Use WASD keys to control the robot");
00138   puts ("Press Shift to move faster");
00139 
00140   struct pollfd ufd;
00141   ufd.fd = kfd;
00142   ufd.events = POLLIN;
00143 
00144   for (;;) {
00145     boost::this_thread::interruption_point();
00146 
00147     // get the next event from the keyboard
00148     int num;
00149 
00150     if ( (num = poll (&ufd, 1, 250)) < 0) {
00151       perror ("poll():");
00152       return;
00153     }
00154     else if (num > 0) {
00155       if (read (kfd, &c, 1) < 0) {
00156         perror ("read():");
00157         return;
00158       }
00159     }
00160     else {
00161       if (dirty == true) {
00162         stopRobot();
00163         dirty = false;
00164       }
00165 
00166       continue;
00167     }
00168 
00169     switch (c) {
00170       case KEYCODE_W:
00171         max_tv = walk_vel_;
00172         speed = 1;
00173         turn = 0;
00174         dirty = true;
00175         break;
00176       case KEYCODE_S:
00177         max_tv = walk_vel_;
00178         speed = -1;
00179         turn = 0;
00180         dirty = true;
00181         break;
00182       case KEYCODE_A:
00183         max_rv = yaw_rate_;
00184         speed = 0;
00185         turn = 1;
00186         dirty = true;
00187         break;
00188       case KEYCODE_D:
00189         max_rv = yaw_rate_;
00190         speed = 0;
00191         turn = -1;
00192         dirty = true;
00193         break;
00194 
00195       case KEYCODE_W_CAP:
00196         max_tv = run_vel_;
00197         speed = 1;
00198         turn = 0;
00199         dirty = true;
00200         break;
00201       case KEYCODE_S_CAP:
00202         max_tv = run_vel_;
00203         speed = -1;
00204         turn = 0;
00205         dirty = true;
00206         break;
00207       case KEYCODE_A_CAP:
00208         max_rv = yaw_rate_run_;
00209         speed = 0;
00210         turn = 1;
00211         dirty = true;
00212         break;
00213       case KEYCODE_D_CAP:
00214         max_rv = yaw_rate_run_;
00215         speed = 0;
00216         turn = -1;
00217         dirty = true;
00218         break;
00219 
00220       default:
00221         max_tv = walk_vel_;
00222         max_rv = yaw_rate_;
00223         speed = 0;
00224         turn = 0;
00225         dirty = false;
00226     }
00227 
00228     cmdvel_.linear.x = speed * max_tv;
00229     cmdvel_.angular.z = turn * max_rv;
00230     pub_.publish (cmdvel_);
00231   }
00232 }


teleop
Author(s): Raul Perula-Martinez , Jose Carlos Castillo Montoya
autogenerated on Thu Apr 23 2015 22:20:09