carl_key_teleop.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * * Redistributions of source code must retain the above copyright
00009  * notice, this list of conditions and the following disclaimer.
00010  * * Redistributions in binary form must reproduce the above copyright
00011  * notice, this list of conditions and the following disclaimer in the
00012  * documentation and/or other materials provided with the distribution.
00013  * * Neither the name of the Willow Garage, Inc. nor the names of its
00014  * contributors may be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00043 #include <carl_teleop/carl_key_teleop.h>
00044 
00045 // used for capturing keyboard input
00046 int kfd = 0;
00047 struct termios cooked, raw;
00048 
00049 carl_key_teleop::carl_key_teleop()
00050 {
00051   // a private handle for this ROS node (allows retrieval of relative parameters)
00052   ros::NodeHandle private_nh("~");
00053 
00054   // create the ROS topics
00055   angular_cmd = nh_.advertise<wpi_jaco_msgs::AngularCommand>("jaco_arm/angular_cmd", 10);
00056   cartesian_cmd = nh_.advertise<wpi_jaco_msgs::CartesianCommand>("jaco_arm/cartesian_cmd", 10);
00057   vel_pub_ = nh_.advertise<geometry_msgs::Twist>("cmd_vel", 1);
00058 
00059   // read in throttle values
00060   private_nh.param<double>("linear_throttle_factor_base", linear_throttle_factor_base, 1.0);
00061   private_nh.param<double>("angular_throttle_factor_base", angular_throttle_factor_base, 1.0);
00062   private_nh.param<double>("linear_throttle_factor_arm", linear_throttle_factor_arm, 1.0);
00063   private_nh.param<double>("angular_throttle_factor_arm", angular_throttle_factor_arm, 1.0);
00064   private_nh.param<double>("finger_throttle_factor", finger_throttle_factor, 1.0);
00065 
00066   mode = BASE_CONTROL;
00067 
00068   ROS_INFO("CARL Keyboard Teleop Started");
00069 }
00070 
00071 void carl_key_teleop::watchdog()
00072 {
00073   boost::mutex::scoped_lock lock(publish_mutex_);
00074   if ((ros::Time::now() > last_publish_ + ros::Duration(0.15))
00075       && (ros::Time::now() > first_publish_ + ros::Duration(0.50)))
00076     publish(0, 0);
00077 }
00078 
00079 void carl_key_teleop::loop()
00080 {
00081   // get the console in raw mode
00082   tcgetattr(kfd, &cooked);
00083   memcpy(&raw, &cooked, sizeof(struct termios));
00084   raw.c_lflag &= ~(ICANON | ECHO);
00085   // Setting a new line, then end of file
00086   raw.c_cc[VEOL] = 1;
00087   raw.c_cc[VEOF] = 2;
00088   tcsetattr(kfd, TCSANOW, &raw);
00089 
00090   puts("    Reading from Keyboard    ");
00091   puts("-----------------------------");
00092   puts("   Press the H key for help ");
00093 
00094   while (ros::ok())
00095   {
00096     // get the next event from the keyboard
00097     char c;
00098     if (read(kfd, &c, 1) < 0)
00099     {
00100       ROS_ERROR("Could not read input from keyboard.");
00101       exit(-1);
00102     }
00103 
00104     //Display help message
00105     if (c == KEYCODE_H)
00106     {
00107       displayHelp();
00108     }
00109 
00110     switch (mode)
00111     {
00112       case BASE_CONTROL:
00113       {
00114         // determine the speed
00115         double linear = 0;
00116         double angular = 0;
00117         switch (c)
00118         {
00119           case KEYCODE_LEFT:
00120             angular = MAX_ANG_VEL_BASE * angular_throttle_factor_base;
00121             break;
00122           case KEYCODE_RIGHT:
00123             angular = -MAX_ANG_VEL_BASE * angular_throttle_factor_base;
00124             break;
00125           case KEYCODE_UP:
00126             linear = MAX_TRANS_VEL_BASE * linear_throttle_factor_base;
00127             break;
00128           case KEYCODE_DOWN:
00129             linear = -MAX_TRANS_VEL_BASE * linear_throttle_factor_base;
00130             break;
00131           case KEYCODE_1:
00132             mode = ARM_CONTROL;
00133             ROS_INFO("Activated arm control mode");
00134             break;
00135           case KEYCODE_2:
00136             mode = FINGER_CONTROL;
00137             ROS_INFO("Activated finger control mode");
00138             break;
00139         }
00140 
00141         // attempt to publish the speed
00142         boost::mutex::scoped_lock lock(publish_mutex_);
00143         if (ros::Time::now() > last_publish_ + ros::Duration(1.0))
00144         {
00145           first_publish_ = ros::Time::now();
00146         }
00147         last_publish_ = ros::Time::now();
00148         publish(angular, linear);
00149       }
00150         break;
00151       case ARM_CONTROL:
00152       {
00153         //initialize twist command
00154         wpi_jaco_msgs::CartesianCommand cmd;
00155         cmd.position = false;
00156         cmd.armCommand = true;
00157         cmd.fingerCommand = false;
00158         cmd.repeat = true;
00159         cmd.arm.linear.x = 0.0;
00160         cmd.arm.linear.y = 0.0;
00161         cmd.arm.linear.z = 0.0;
00162         cmd.arm.angular.x = 0.0;
00163         cmd.arm.angular.y = 0.0;
00164         cmd.arm.angular.z = 0.0;
00165 
00166         // w/s control forward/backward translation
00167         // a/d control left/right translation
00168         // r/f control up/down translation
00169         // q/e controls roll
00170         // up/down controls pitch
00171         // left/right controls yaw
00172         switch (c)
00173         {
00174           case KEYCODE_W:
00175             cmd.arm.linear.x = MAX_TRANS_VEL_ARM * linear_throttle_factor_arm;
00176             break;
00177           case KEYCODE_S:
00178             cmd.arm.linear.x = -MAX_TRANS_VEL_ARM * linear_throttle_factor_arm;
00179             break;
00180           case KEYCODE_A:
00181             cmd.arm.linear.y = MAX_TRANS_VEL_ARM * linear_throttle_factor_arm;
00182             break;
00183           case KEYCODE_D:
00184             cmd.arm.linear.y = -MAX_TRANS_VEL_ARM * linear_throttle_factor_arm;
00185             break;
00186           case KEYCODE_R:
00187             cmd.arm.linear.z = MAX_TRANS_VEL_ARM * linear_throttle_factor_arm;
00188             break;
00189           case KEYCODE_F:
00190             cmd.arm.linear.z = -MAX_TRANS_VEL_ARM * linear_throttle_factor_arm;
00191             break;
00192           case KEYCODE_Q:
00193             cmd.arm.angular.z = -MAX_ANG_VEL_ARM * angular_throttle_factor_arm;
00194             break;
00195           case KEYCODE_E:
00196             cmd.arm.angular.z = MAX_ANG_VEL_ARM * angular_throttle_factor_arm;
00197             break;
00198           case KEYCODE_UP:
00199             cmd.arm.angular.x = -MAX_ANG_VEL_ARM * angular_throttle_factor_arm;
00200             break;
00201           case KEYCODE_DOWN:
00202             cmd.arm.angular.x = MAX_ANG_VEL_ARM * angular_throttle_factor_arm;
00203             break;
00204           case KEYCODE_LEFT:
00205             cmd.arm.angular.y = MAX_ANG_VEL_ARM * angular_throttle_factor_arm;
00206             break;
00207           case KEYCODE_RIGHT:
00208             cmd.arm.angular.y = -MAX_ANG_VEL_ARM * angular_throttle_factor_arm;
00209             break;
00210           case KEYCODE_2:
00211             mode = FINGER_CONTROL;
00212             ROS_INFO("Activated finger control mode");
00213             break;
00214           case KEYCODE_3:
00215             mode = BASE_CONTROL;
00216             ROS_INFO("Activate base control mode");
00217             break;
00218         }
00219 
00220         //publish twist to arm controller
00221         boost::mutex::scoped_lock lock(publish_mutex_);
00222         if (ros::Time::now() > last_publish_ + ros::Duration(1.0))
00223         {
00224           first_publish_ = ros::Time::now();
00225         }
00226         last_publish_ = ros::Time::now();
00227         cartesian_cmd.publish(cmd);
00228       }
00229         break;
00230       case FINGER_CONTROL:
00231       {
00232         //initialize finger command
00233         wpi_jaco_msgs::AngularCommand cmd;
00234         cmd.position = false;
00235         cmd.armCommand = false;
00236         cmd.fingerCommand = true;
00237         cmd.repeat = true;
00238         cmd.fingers.resize(3);
00239         cmd.fingers[0] = 0.0;
00240         cmd.fingers[1] = 0.0;
00241         cmd.fingers[2] = 0.0;
00242 
00243         // q/a controls finger 1
00244         // w/s controls finger 2
00245         // e/d controls finger 3
00246         // r/f controls entire hand
00247         switch (c)
00248         {
00249           case KEYCODE_Q:
00250             cmd.fingers[0] = -MAX_FINGER_VEL * finger_throttle_factor;
00251             break;
00252           case KEYCODE_A:
00253             cmd.fingers[0] = MAX_FINGER_VEL * finger_throttle_factor;
00254             break;
00255           case KEYCODE_W:
00256             cmd.fingers[1] = -MAX_FINGER_VEL * finger_throttle_factor;
00257             break;
00258           case KEYCODE_S:
00259             cmd.fingers[1] = MAX_FINGER_VEL * finger_throttle_factor;
00260             break;
00261           case KEYCODE_E:
00262             cmd.fingers[2] = -MAX_FINGER_VEL * finger_throttle_factor;
00263             break;
00264           case KEYCODE_D:
00265             cmd.fingers[2] = MAX_FINGER_VEL * finger_throttle_factor;
00266             break;
00267           case KEYCODE_R:
00268             cmd.fingers[0] = -MAX_FINGER_VEL * finger_throttle_factor;
00269             cmd.fingers[1] = cmd.fingers[0];
00270             cmd.fingers[2] = cmd.fingers[0];
00271             break;
00272           case KEYCODE_F:
00273             cmd.fingers[0] = MAX_FINGER_VEL * finger_throttle_factor;
00274             cmd.fingers[1] = cmd.fingers[0];
00275             cmd.fingers[2] = cmd.fingers[0];
00276             break;
00277           case KEYCODE_1:
00278             mode = ARM_CONTROL;
00279             ROS_INFO("Activated arm control mode");
00280             break;
00281           case KEYCODE_3:
00282             mode = BASE_CONTROL;
00283             ROS_INFO("Activate base control mode");
00284             break;
00285         }
00286 
00287         //publish twist to finger controller
00288         boost::mutex::scoped_lock lock(publish_mutex_);
00289         if (ros::Time::now() > last_publish_ + ros::Duration(1.0))
00290         {
00291           first_publish_ = ros::Time::now();
00292         }
00293         last_publish_ = ros::Time::now();
00294         angular_cmd.publish(cmd);
00295       }
00296         break;
00297     }
00298   }
00299 }
00300 
00301 void carl_key_teleop::publish(double angular, double linear)
00302 {
00303   geometry_msgs::Twist vel;
00304   vel.angular.z = angular;
00305   vel.linear.x = linear;
00306   // send the command
00307   vel_pub_.publish(vel);
00308 }
00309 
00310 void carl_key_teleop::displayHelp()
00311 {
00312   switch (mode)
00313   {
00314     case ARM_CONTROL:
00315       puts(" ------------------------------------");
00316       puts("| CARL Keyboard Teleop Help          |");
00317       puts("|------------------------------------|*");
00318       puts("| Current Mode: Arm Control          |*");
00319       puts("|------------------------------------|*");
00320       puts("| w/s : forward/backward translation |*");
00321       puts("| a/d : left/right translation       |*");
00322       puts("| r/f : up/down translation          |*");
00323       puts("| q/e : roll                         |*");
00324       puts("| up/down : pitch                    |*");
00325       puts("| left/right : yaw                   |*");
00326       puts("| 1 : switch to Arm Control          |*");
00327       puts("| 2 : switch to Finger Control       |*");
00328       puts("| 3 : switch to Base Control         |*");
00329       puts(" ------------------------------------**");
00330       puts("  *************************************");
00331       break;
00332     case FINGER_CONTROL:
00333       puts(" ------------------------------------");
00334       puts("| CARL Keyboard Teleop Help          |");
00335       puts("|------------------------------------|*");
00336       puts("| Current Mode: Finger Control       |*");
00337       puts("|------------------------------------|*");
00338       puts("| q/a : open/close thumb             |*");
00339       puts("| w/s : open/close top finger        |*");
00340       puts("| e/d : open/close bottom finger     |*");
00341       puts("| r/f : open/close entire hand       |*");
00342       puts("| 1 : switch to Arm Control          |*");
00343       puts("| 2 : switch to Finger Control       |*");
00344       puts("| 3 : switch to Base Control         |*");
00345       puts(" ------------------------------------**");
00346       puts("  *************************************");
00347       break;
00348     case BASE_CONTROL:
00349       puts(" ------------------------------------");
00350       puts("| CARL Keyboard Teleop Help          |");
00351       puts("|------------------------------------|*");
00352       puts("| Current Mode: Base Control         |*");
00353       puts("|------------------------------------|*");
00354       puts("| up/down : forward/backward         |*");
00355       puts("| left/right : turn left/right       |*");
00356       puts("| 1 : switch to Arm Control          |*");
00357       puts("| 2 : switch to Finger Control       |*");
00358       puts("| 3 : switch to Base Control         |*");
00359       puts(" ------------------------------------**");
00360       puts("  *************************************");
00361   }
00362 }
00363 
00364 void shutdown(int sig)
00365 {
00366   // shut everything down
00367   tcsetattr(kfd, TCSANOW, &cooked);
00368   ros::shutdown();
00369 }
00370 
00371 int main(int argc, char** argv)
00372 {
00373   // initialize ROS and the node
00374   ros::init(argc, argv, "carl_key_teleop");
00375 
00376   // initialize the keyboard controller
00377   carl_key_teleop key_controller;
00378   ros::NodeHandle n;
00379 
00380   // setup the SIGINT signal for exiting
00381   signal(SIGINT, shutdown);
00382 
00383   // setup the watchdog and key loop in a thread
00384   boost::thread my_thread(boost::bind(&carl_key_teleop::loop, &key_controller));
00385   ros::Timer timer = n.createTimer(ros::Duration(0.1), boost::bind(&carl_key_teleop::watchdog, &key_controller));
00386   ros::spin();
00387 
00388   // wait for everything to end
00389   my_thread.interrupt();
00390   my_thread.join();
00391 
00392   return EXIT_SUCCESS;
00393 }


carl_teleop
Author(s): Steven Kordell , Russell Toris , David Kent
autogenerated on Thu Jun 6 2019 21:09:59