pr2_teleop_general_joystick.cpp
Go to the documentation of this file.
00001 /*
00002  * pr2_teleop_general_joystick
00003  * Copyright (c) 2010, 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 // Author: E. Gil Jones
00032 
00033 #include <termios.h>
00034 #include <signal.h>
00035 #include <cstdio>
00036 #include <cstdlib>
00037 #include <unistd.h>
00038 #include <math.h>
00039 
00040 #include <ros/ros.h>
00041 
00042 #include <sensor_msgs/Joy.h>
00043 #include "pr2_teleop_general/pr2_teleop_general_commander.h"
00044 
00045 enum JoystickLayoutMode {
00046   LAYOUT_NONE,
00047   LAYOUT_BODY,
00048   LAYOUT_HEAD,
00049   LAYOUT_RIGHT_ARM,
00050   LAYOUT_LEFT_ARM,
00051   LAYOUT_BOTH_ARMS
00052 };
00053 
00054 static const unsigned int BODY_LAYOUT_BUTTON = 10;
00055 static const unsigned int RIGHT_ARM_LAYOUT_BUTTON = 9;
00056 static const unsigned int LEFT_ARM_LAYOUT_BUTTON = 8;
00057 static const unsigned int HEAD_LAYOUT_BUTTON = 11;
00058 
00059 static const unsigned int HEAD_MODE_TOGGLE_BUTTON = 4;
00060 static const unsigned int PROJECTOR_TOGGLE_BUTTON = 5;
00061 static const unsigned int LASER_TOGGLE_BUTTON = 7;
00062 static const unsigned int PROSILICA_POLL_BUTTON = 6;
00063 static const unsigned int OPEN_GRIPPER_BUTTON = 15;
00064 static const unsigned int CLOSE_GRIPPER_BUTTON = 13;
00065 static const unsigned int ARM_MODE_TOGGLE_BUTTON = 4;
00066 static const unsigned int ARM_POSE_BUTTON = 6;
00067 
00068 static const unsigned int LEFT_AXIS_NUMBER = 1;
00069 static const unsigned int RIGHT_AXIS_NUMBER = 1;
00070 
00071 static const unsigned int TORSO_UP_BUTTON = 12;
00072 static const unsigned int TORSO_DOWN_BUTTON = 14;
00073 static const unsigned int SPEED_UP_BUTTON = 11;
00074 
00075 static const unsigned int WRIST_CLOCKWISE_BUTTON = 12;
00076 static const unsigned int WRIST_COUNTER_BUTTON = 14;
00077 
00078 static const unsigned int VX_AXIS = 3;
00079 static const unsigned int VY_AXIS = 2;
00080 static const unsigned int VW_AXIS = 0;
00081 
00082 static const unsigned int HEAD_PAN_AXIS = 0;
00083 static const unsigned int HEAD_TILT_AXIS = 3;
00084 
00085 static const unsigned int ARM_X_AXIS = 3;
00086 static const unsigned int ARM_Y_AXIS = 2;
00087 static const unsigned int ARM_Z_AXIS = 1;
00088 static const unsigned int ARM_YAW_AXIS = 0;
00089 
00090 static const unsigned int ARM_UNTUCK_BUTTON = 7;
00091 static const unsigned int ARM_TUCK_BUTTON = 5;
00092 
00093 static const unsigned int MOVE_TO_WALK_ALONG_BUTTON = 0;
00094 static const unsigned int SET_WALK_ALONG_BUTTON = 3;
00095 
00096 static const ros::Duration DOUBLE_TAP_TIMEOUT(.25);
00097 
00098 class Pr2TeleopGeneralJoystick
00099 {
00100 public:
00101   Pr2TeleopGeneralJoystick(bool deadman_no_publish = false)
00102   { 
00103     gc = NULL;
00104   }
00105 
00106   void init()
00107   {
00108     des_pan_pos_ = des_tilt_pos_ = 0;
00109     vel_val_pan_ = vel_val_tilt_ = 0;
00110     
00111     des_torso_pos_ = 0;
00112 
00113     des_torso_vel_ = 0.0;
00114     
00115     ros::NodeHandle n_local("~");
00116 
00117     // Head pan/tilt parameters
00118     n_local.param("max_pan", max_pan_, 2.7);
00119     n_local.param("max_tilt", max_tilt_, 1.4);
00120     n_local.param("min_tilt", min_tilt_, -0.4);
00121     
00122     n_local.param("tilt_scale", tilt_scale_, .5);
00123     n_local.param("pan_scale", pan_scale_, 1.2);
00124     
00125     n_local.param("torso_step", torso_step_, 0.05);
00126     n_local.param("min_torso", min_torso_, 0.0);
00127     n_local.param("max_torso", max_torso_, 0.3);
00128 
00129     n_local.param("vx_scale", vx_scale_, 0.6);
00130     n_local.param("vy_scale", vy_scale_, 0.6);
00131     n_local.param("vw_scale", vw_scale_, 0.8);
00132     
00133     n_local.param("arm_x_scale", arm_x_scale_, .15);
00134     n_local.param("arm_y_scale", arm_y_scale_, .15);
00135     n_local.param("arm_z_scale", arm_z_scale_, .15);
00136 
00137     n_local.param("arm_roll_scale", arm_roll_scale_, -1.50);
00138     n_local.param("arm_pitch_scale", arm_pitch_scale_, 1.50);
00139     n_local.param("arm_yaw_scale", arm_yaw_scale_, 1.50);
00140 
00141     n_local.param("wrist_velocity",wrist_velocity_, 4.5);
00142 
00143     n_local.param("walk_along_x_speed_scale", walk_along_x_speed_scale_, 9.0);
00144     n_local.param("walk_along_y_speed_scale", walk_along_y_speed_scale_, 9.0);
00145     n_local.param("walk_along_w_speed_scale", walk_along_w_speed_scale_, 9.0);
00146     n_local.param("walk_along_thresh", walk_along_thresh_, .015);
00147     n_local.param("walk_along_x_dist_max", walk_along_x_dist_max_, .5);
00148     n_local.param("walk_along_y_dist_max", walk_along_y_dist_max_, .5);
00149 
00150     n_local.param("prosilica_namespace", prosilica_namespace_, std::string("prosilica_polled"));
00151 
00152     bool control_prosilica;
00153     n_local.param("control_prosilica", control_prosilica, true);
00154     
00155     bool control_body;
00156     n_local.param("control_body", control_body, true);
00157 
00158     bool control_larm;
00159     n_local.param("control_larm", control_larm, true);
00160 
00161     bool control_rarm;
00162     n_local.param("control_rarm", control_rarm, true);
00163 
00164     bool control_head;
00165     n_local.param("control_head", control_head, true);
00166 
00167     std::string arm_controller_name;
00168     n_local.param("arm_controller_name", arm_controller_name,std::string(""));
00169 
00170     ROS_DEBUG("tilt scale: %.3f rad\n", tilt_scale_);
00171     ROS_DEBUG("pan scale: %.3f rad\n", pan_scale_);
00172     
00173     ROS_INFO("Initing general commander");
00174 
00175     if(arm_controller_name.empty()) {
00176       gc = new GeneralCommander(control_body, 
00177                                 control_head, 
00178                                 control_rarm,
00179                                 control_larm,
00180                                 control_prosilica);
00181     } else {
00182       gc = new GeneralCommander(control_body, 
00183                                 control_head, 
00184                                 control_rarm,
00185                                 control_larm,
00186                                 control_prosilica,
00187                                 arm_controller_name);
00188     }
00189     first_callback_ = true;
00190     
00191     head_init_ = false;
00192     torso_init_ = false;
00193     
00194     proj_toggle_com_ = false;
00195     
00196     walk_along_init_waiting_ = false;
00197     set_walk_along_mode_ = false;
00198 
00199     joy_sub_ = n_.subscribe("joy", 10, &Pr2TeleopGeneralJoystick::joy_cb, this);
00200   }
00201 
00202 
00203   ~Pr2TeleopGeneralJoystick() {  
00204     if(gc != NULL) {
00205       delete gc;
00206     }
00207   }
00208 
00209   bool buttonOkAndOn(unsigned int buttonNum, const sensor_msgs::Joy::ConstPtr& joy_msg) const {
00210     if(buttonNum >= joy_msg->buttons.size()) return false;
00211     return(joy_msg->buttons[buttonNum]);
00212   }
00213 
00214   bool axisOk(unsigned int axisNum, const sensor_msgs::Joy::ConstPtr& joy_msg) const {
00215     return (axisNum < joy_msg->axes.size());
00216   }
00217 
00218   bool sameValueAsLast(unsigned int button, 
00219                        const sensor_msgs::Joy::ConstPtr& new_msg,
00220                        const sensor_msgs::Joy::ConstPtr& old_msg) {
00221     return (buttonOkAndOn(button, new_msg) == buttonOkAndOn(button, old_msg));
00222   }
00223                        
00224 
00225   void joy_cb(const sensor_msgs::Joy::ConstPtr& joy_msg)
00226   {
00227     if(first_callback_) {
00228       last_joy_ = joy_msg;
00229       first_callback_ = false;
00230     }
00231 
00232     JoystickLayoutMode layout;
00233     
00234     if(buttonOkAndOn(BODY_LAYOUT_BUTTON, joy_msg)) {
00235       layout = LAYOUT_BODY;
00236     } else if (buttonOkAndOn(RIGHT_ARM_LAYOUT_BUTTON, joy_msg) && buttonOkAndOn(LEFT_ARM_LAYOUT_BUTTON, joy_msg)) {
00237       layout = LAYOUT_BOTH_ARMS;
00238     } else if (buttonOkAndOn(RIGHT_ARM_LAYOUT_BUTTON,joy_msg)) {
00239       layout = LAYOUT_RIGHT_ARM;
00240     } else if (buttonOkAndOn(LEFT_ARM_LAYOUT_BUTTON, joy_msg)) {
00241       layout = LAYOUT_LEFT_ARM;
00242     } else if (buttonOkAndOn(HEAD_LAYOUT_BUTTON, joy_msg)) {
00243       layout = LAYOUT_HEAD;
00244     } else {
00245       layout = LAYOUT_NONE;
00246     }
00247 
00248     bool setting_walk_along_this_cycle_ = false;
00249 
00250     if(layout == LAYOUT_HEAD) {
00251       if(buttonOkAndOn(MOVE_TO_WALK_ALONG_BUTTON, joy_msg) && !sameValueAsLast(MOVE_TO_WALK_ALONG_BUTTON, joy_msg, last_joy_)) {
00252         ros::Time now = ros::Time::now();
00253         if(now-last_walk_along_time_ < DOUBLE_TAP_TIMEOUT) {
00254           //only matters if this is off
00255           if(!gc->isWalkAlongOk()) {
00256             set_walk_along_mode_ = true;
00257             setting_walk_along_this_cycle_ = true;
00258           }
00259         }
00260         if(gc->isWalkAlongOk()) {
00261           gc->turnOffWalkAlong();
00262           ROS_INFO("Turning off walk along");
00263         } else {
00264           last_walk_along_time_ = now;
00265         }
00266       }
00267     }
00268 
00269     bool in_walk_along = false;
00270     if(gc->isWalkAlongOk()) {
00271       if(buttonOkAndOn(MOVE_TO_WALK_ALONG_BUTTON, joy_msg) && !sameValueAsLast(MOVE_TO_WALK_ALONG_BUTTON, joy_msg, last_joy_)) {
00272         gc->turnOffWalkAlong();
00273         ROS_INFO("Turning off walk along");
00274       } else {
00275         vel_val_pan_ = 0.0;
00276         vel_val_tilt_ = 0.0;
00277         des_torso_vel_ = 0.0;
00278         des_vx_ = 0.0;
00279         des_vy_ = 0.0;
00280         des_vw_ = 0.0;
00281         des_right_wrist_vel_ = 0.0;
00282         right_arm_vx_ = 0.0;
00283         right_arm_vy_ = 0.0;
00284         right_arm_vz_ = 0.0;
00285         des_left_wrist_vel_ = 0.0;
00286         left_arm_vx_ = 0.0;
00287         left_arm_vy_ = 0.0;
00288         left_arm_vz_ = 0.0;
00289         right_arm_vel_roll_ = 0.0;
00290         right_arm_vel_pitch_ = 0.0;
00291         right_arm_vel_yaw_ = 0.0;
00292         left_arm_vel_roll_ = 0.0;
00293         left_arm_vel_pitch_ = 0.0;
00294         left_arm_vel_yaw_ = 0.0;
00295         in_walk_along = true;
00296       }
00297     }
00298 
00299     //we must be moving the arms into the mode
00300     if(!in_walk_along && layout == LAYOUT_HEAD && set_walk_along_mode_) {
00301       if(buttonOkAndOn(SET_WALK_ALONG_BUTTON, joy_msg) 
00302          && !sameValueAsLast(SET_WALK_ALONG_BUTTON, joy_msg, last_joy_)) {
00303         gc->sendHeadSequence(GeneralCommander::HEAD_SHAKE);
00304       }
00305       if(!setting_walk_along_this_cycle_ && buttonOkAndOn(MOVE_TO_WALK_ALONG_BUTTON, joy_msg) && !sameValueAsLast(MOVE_TO_WALK_ALONG_BUTTON, joy_msg, last_joy_)) {
00306         set_walk_along_mode_ = false;
00307         ROS_INFO("No longer waiting for set");
00308       }
00309     }
00310 
00311     if(!in_walk_along && layout == LAYOUT_HEAD && walk_along_init_waiting_) {
00312       if(buttonOkAndOn(SET_WALK_ALONG_BUTTON, joy_msg) 
00313          && !sameValueAsLast(SET_WALK_ALONG_BUTTON, joy_msg, last_joy_)) {
00314         bool ok = gc->initWalkAlong();
00315         if(!ok) {
00316           gc->sendHeadSequence(GeneralCommander::HEAD_SHAKE);
00317         } else {
00318           gc->sendHeadSequence(GeneralCommander::HEAD_NOD);
00319           ROS_INFO("Should be in walk along");
00320           walk_along_init_waiting_ = false;
00321         }
00322       }
00323       if(buttonOkAndOn(MOVE_TO_WALK_ALONG_BUTTON, joy_msg) && !sameValueAsLast(MOVE_TO_WALK_ALONG_BUTTON, joy_msg, last_joy_)) {
00324         walk_along_init_waiting_ = false;
00325         ROS_INFO("No longer waiting for init");
00326       }
00327     }
00328     if(layout == LAYOUT_RIGHT_ARM || layout == LAYOUT_LEFT_ARM || layout == LAYOUT_BOTH_ARMS) {
00329       if(buttonOkAndOn(CLOSE_GRIPPER_BUTTON, joy_msg) 
00330          && !sameValueAsLast(CLOSE_GRIPPER_BUTTON, joy_msg, last_joy_)) {
00331         if(layout == LAYOUT_RIGHT_ARM) {
00332           gc->sendGripperCommand(GeneralCommander::ARMS_RIGHT, false);
00333         } else if(layout == LAYOUT_LEFT_ARM) {
00334           gc->sendGripperCommand(GeneralCommander::ARMS_LEFT, false);
00335         } else {
00336           gc->sendGripperCommand(GeneralCommander::ARMS_BOTH, false);
00337         }
00338       }
00339       if(buttonOkAndOn(OPEN_GRIPPER_BUTTON, joy_msg) 
00340          && !sameValueAsLast(OPEN_GRIPPER_BUTTON, joy_msg, last_joy_)) {
00341         if(layout == LAYOUT_RIGHT_ARM) {
00342           gc->sendGripperCommand(GeneralCommander::ARMS_RIGHT, true);
00343         } else if(layout == LAYOUT_LEFT_ARM) {
00344           gc->sendGripperCommand(GeneralCommander::ARMS_LEFT, true);
00345         } else {
00346           gc->sendGripperCommand(GeneralCommander::ARMS_BOTH, true);
00347         }
00348       }
00349     }
00350 
00351     if(!in_walk_along && layout == LAYOUT_HEAD) {
00352 
00353       if(buttonOkAndOn(PROJECTOR_TOGGLE_BUTTON, joy_msg) 
00354          && !sameValueAsLast(PROJECTOR_TOGGLE_BUTTON,joy_msg, last_joy_)) {
00355         proj_toggle_com_ = !proj_toggle_com_;
00356         gc->sendProjectorStartStop(proj_toggle_com_);
00357       }
00358       
00359       if(buttonOkAndOn(PROSILICA_POLL_BUTTON, joy_msg) 
00360          && !sameValueAsLast(PROSILICA_POLL_BUTTON,joy_msg, last_joy_)) {
00361         gc->requestProsilicaImage(prosilica_namespace_);
00362       }
00363 
00364       if(buttonOkAndOn(HEAD_MODE_TOGGLE_BUTTON, joy_msg) 
00365          && !sameValueAsLast(HEAD_MODE_TOGGLE_BUTTON, joy_msg, last_joy_)) {
00366         
00367         if(gc->getHeadMode() == GeneralCommander::HEAD_JOYSTICK) {
00368           ROS_DEBUG("Head mode to left");
00369           gc->setHeadMode(GeneralCommander::HEAD_TRACK_LEFT_HAND);
00370         } else if(gc->getHeadMode() == GeneralCommander::HEAD_TRACK_LEFT_HAND) {
00371           gc->setHeadMode(GeneralCommander::HEAD_TRACK_RIGHT_HAND);
00372           ROS_DEBUG("Head mode to right");
00373         } else if(gc->getHeadMode() == GeneralCommander::HEAD_TRACK_RIGHT_HAND){
00374           gc->setHeadMode(GeneralCommander::HEAD_MANNEQUIN);
00375           ROS_DEBUG("Head mode to mannequin");
00376         } else {
00377           ROS_DEBUG("Head mode to joystick");
00378           head_init_ = false;
00379           gc->setHeadMode(GeneralCommander::HEAD_JOYSTICK);
00380         }
00381       }
00382 
00383       if(buttonOkAndOn(LASER_TOGGLE_BUTTON, joy_msg) 
00384          && !sameValueAsLast(LASER_TOGGLE_BUTTON, joy_msg, last_joy_)) {
00385         if(gc->getLaserMode() == GeneralCommander::LASER_TILT_OFF) {
00386           gc->setLaserMode(GeneralCommander::LASER_TILT_SLOW);
00387         } else if(gc->getLaserMode() == GeneralCommander::LASER_TILT_SLOW) {
00388           gc->setLaserMode(GeneralCommander::LASER_TILT_FAST);
00389         } else {
00390           gc->setLaserMode(GeneralCommander::LASER_TILT_OFF);
00391         }
00392       }
00393 
00394       if(axisOk(HEAD_PAN_AXIS, joy_msg))
00395       {
00396         vel_val_pan_ = joy_msg->axes[HEAD_PAN_AXIS] * pan_scale_;
00397       }
00398       
00399       if(axisOk(HEAD_TILT_AXIS, joy_msg))
00400       {
00401         vel_val_tilt_ = joy_msg->axes[HEAD_TILT_AXIS] * tilt_scale_;
00402       }   
00403     } else {
00404       vel_val_pan_ = 0.0;
00405       vel_val_tilt_ = 0.0;
00406     }
00407 
00408     if(!in_walk_along && layout == LAYOUT_BODY) {
00409       bool down = buttonOkAndOn(TORSO_DOWN_BUTTON, joy_msg);
00410       bool up = buttonOkAndOn(TORSO_UP_BUTTON, joy_msg);
00411       bool speedup = buttonOkAndOn(SPEED_UP_BUTTON, joy_msg);
00412       bool unsafe = buttonOkAndOn(RIGHT_ARM_LAYOUT_BUTTON, joy_msg); // for jsk_pr2_startup
00413       
00414       //ROS_INFO_STREAM("Down is " << down);
00415       //ROS_INFO_STREAM("Up is " << up);
00416       
00417       if(down && !up) {
00418         des_torso_vel_ = -torso_step_;
00419       } else if(!down && up) {
00420         des_torso_vel_ = torso_step_;
00421       } else {
00422         //ROS_INFO_STREAM("Setting des vel to 0.0");
00423         des_torso_vel_ = 0.0;
00424       }
00425       if(axisOk(VX_AXIS, joy_msg)) {
00426         des_vx_ = joy_msg->axes[VX_AXIS]*vx_scale_*(unsafe?0.5:(speedup?2.0:1.0));
00427       } else {
00428         des_vx_ = 0.0;
00429       }
00430       if(axisOk(VY_AXIS, joy_msg)) {
00431         des_vy_ = joy_msg->axes[VY_AXIS]*vy_scale_*(unsafe?0.5:(speedup?2.0:1.0));
00432       } else {
00433         des_vy_ = 0.0;
00434       }
00435       if(axisOk(VW_AXIS, joy_msg)) {
00436         des_vw_ = joy_msg->axes[VW_AXIS]*vw_scale_*(unsafe?0.5:(speedup?2.0:1.0));
00437       } else {
00438         des_vw_ = 0.0;
00439       }
00440     } else {
00441       des_torso_vel_ = 0.0;
00442       des_vx_ = 0.0;
00443       des_vy_ = 0.0;
00444       des_vw_ = 0.0;
00445     }
00446 
00447     if(layout == LAYOUT_RIGHT_ARM) {
00448       if(buttonOkAndOn(ARM_MODE_TOGGLE_BUTTON, joy_msg) && !sameValueAsLast(ARM_MODE_TOGGLE_BUTTON, joy_msg, last_joy_)) {
00449         if(in_walk_along) {
00450           gc->turnOffWalkAlong();
00451           ROS_INFO("Turning off walk along");
00452         }
00453         if(gc->getArmMode(GeneralCommander::ARMS_RIGHT) == GeneralCommander::ARM_POSITION_CONTROL) {
00454           gc->setArmMode(GeneralCommander::ARMS_RIGHT,GeneralCommander::ARM_MANNEQUIN_MODE);
00455         } else if (gc->getArmMode(GeneralCommander::ARMS_RIGHT) == GeneralCommander::ARM_MANNEQUIN_MODE) {
00456           gc->setArmMode(GeneralCommander::ARMS_RIGHT,GeneralCommander::ARM_NO_CONTROLLER);
00457         } else {
00458           gc->setArmMode(GeneralCommander::ARMS_RIGHT,GeneralCommander::ARM_POSITION_CONTROL);
00459         }
00460       }
00461 
00462       if(buttonOkAndOn(ARM_TUCK_BUTTON, joy_msg) && !sameValueAsLast(ARM_TUCK_BUTTON, joy_msg, last_joy_)) {
00463         if(in_walk_along) {
00464           gc->turnOffWalkAlong();
00465           ROS_INFO("Turning off walk along");
00466         }
00467         gc->tuckArms(GeneralCommander::ARMS_RIGHT);        
00468       } else if(buttonOkAndOn(ARM_UNTUCK_BUTTON, joy_msg) && !sameValueAsLast(ARM_UNTUCK_BUTTON, joy_msg, last_joy_)) {
00469         if(in_walk_along) {
00470           gc->turnOffWalkAlong();
00471           ROS_INFO("Turning off walk along");
00472         }
00473         gc->untuckArms(GeneralCommander::ARMS_RIGHT);
00474       } 
00475 
00476       if(!in_walk_along) {
00477 
00478         bool lookAnalog = false;
00479         bool rotClock = buttonOkAndOn(WRIST_CLOCKWISE_BUTTON, joy_msg);
00480         bool rotCounter = buttonOkAndOn(WRIST_COUNTER_BUTTON, joy_msg);
00481         bool rotateArm = buttonOkAndOn(ARM_POSE_BUTTON, joy_msg);
00482         if(rotClock && !rotCounter) {
00483           des_right_wrist_vel_ = wrist_velocity_;
00484         } else if(!rotClock && rotCounter) {
00485           des_right_wrist_vel_ = -wrist_velocity_;
00486         } else {
00487           des_right_wrist_vel_ = 0.0;
00488           lookAnalog = true;
00489         }
00490 
00491         right_arm_vx_ = 0.0;
00492         right_arm_vy_ = 0.0;
00493         right_arm_vz_ = 0.0;
00494         right_arm_vel_roll_ = 0.0;
00495         right_arm_vel_pitch_ = 0.0;
00496         right_arm_vel_yaw_ = 0.0;
00497         
00498         if(lookAnalog) {
00499           //look at analog sticks if we aren't supposed to wrist rotate
00500           if(axisOk(ARM_X_AXIS, joy_msg)) {
00501             if(!rotateArm)
00502               right_arm_vx_ = joy_msg->axes[ARM_X_AXIS]*arm_x_scale_;
00503             else
00504               right_arm_vel_pitch_ = joy_msg->axes[ARM_X_AXIS]*arm_pitch_scale_;
00505           }
00506           if(axisOk(ARM_Y_AXIS, joy_msg)) {
00507             if(!rotateArm)
00508               right_arm_vy_ = joy_msg->axes[ARM_Y_AXIS]*arm_y_scale_;
00509             else
00510               right_arm_vel_roll_ = joy_msg->axes[ARM_Y_AXIS]*arm_roll_scale_;
00511           }
00512           if(axisOk(ARM_Z_AXIS, joy_msg) && (!rotateArm)) {
00513             right_arm_vz_ = joy_msg->axes[ARM_Z_AXIS]*arm_z_scale_;
00514           }
00515           if(axisOk(ARM_YAW_AXIS, joy_msg) && rotateArm) {
00516             right_arm_vel_yaw_ = joy_msg->axes[ARM_YAW_AXIS]*arm_yaw_scale_;
00517           }
00518           //ROS_INFO_STREAM("Setting vx " << right_arm_vx_ << " " << right_arm_vy_ << " " << right_arm_vz_);
00519         }
00520       }
00521     } else if (layout != LAYOUT_BOTH_ARMS) {
00522       des_right_wrist_vel_ = 0.0;
00523       right_arm_vx_ = 0.0;
00524       right_arm_vy_ = 0.0;
00525       right_arm_vz_ = 0.0;
00526       right_arm_vel_roll_ = 0.0;
00527       right_arm_vel_pitch_ = 0.0;
00528       right_arm_vel_yaw_ = 0.0;
00529     }
00530     if(layout == LAYOUT_LEFT_ARM) {
00531       if(buttonOkAndOn(ARM_MODE_TOGGLE_BUTTON, joy_msg) && !sameValueAsLast(ARM_MODE_TOGGLE_BUTTON, joy_msg, last_joy_)) {
00532         if(in_walk_along) {
00533           gc->turnOffWalkAlong();
00534           ROS_INFO("Turning off walk along");
00535         }
00536         if(gc->getArmMode(GeneralCommander::ARMS_LEFT) == GeneralCommander::ARM_POSITION_CONTROL) {
00537           gc->setArmMode(GeneralCommander::ARMS_LEFT,GeneralCommander::ARM_MANNEQUIN_MODE);
00538         } else if (gc->getArmMode(GeneralCommander::ARMS_LEFT) == GeneralCommander::ARM_MANNEQUIN_MODE) {
00539           gc->setArmMode(GeneralCommander::ARMS_LEFT,GeneralCommander::ARM_NO_CONTROLLER);
00540         } else {
00541           gc->setArmMode(GeneralCommander::ARMS_LEFT,GeneralCommander::ARM_POSITION_CONTROL);
00542         }
00543       }
00544 
00545       if(buttonOkAndOn(ARM_TUCK_BUTTON, joy_msg) && !sameValueAsLast(ARM_TUCK_BUTTON, joy_msg, last_joy_)) {
00546         if(in_walk_along) {
00547           gc->turnOffWalkAlong();
00548           ROS_INFO("Turning off walk along");
00549         }
00550         gc->tuckArms(GeneralCommander::ARMS_LEFT);        
00551       } else if(buttonOkAndOn(ARM_UNTUCK_BUTTON, joy_msg) && !sameValueAsLast(ARM_UNTUCK_BUTTON, joy_msg, last_joy_)) {
00552         if(in_walk_along) {
00553           gc->turnOffWalkAlong();
00554           ROS_INFO("Turning off walk along");
00555         }
00556         gc->untuckArms(GeneralCommander::ARMS_LEFT);
00557       } 
00558 
00559       if(!in_walk_along) {
00560         bool lookAnalog = false;
00561         bool rotClock = buttonOkAndOn(WRIST_CLOCKWISE_BUTTON, joy_msg);
00562         bool rotCounter = buttonOkAndOn(WRIST_COUNTER_BUTTON, joy_msg);
00563         bool rotateArm = buttonOkAndOn(ARM_POSE_BUTTON, joy_msg);
00564         if(rotClock && !rotCounter) {
00565           des_left_wrist_vel_ = wrist_velocity_;
00566         } else if(!rotClock && rotCounter) {
00567           des_left_wrist_vel_ = -wrist_velocity_;
00568         } else {
00569           des_left_wrist_vel_ = 0.0;
00570           lookAnalog = true;
00571         }
00572 
00573         left_arm_vx_ = 0.0;
00574         left_arm_vy_ = 0.0;
00575         left_arm_vz_ = 0.0;
00576         left_arm_vel_roll_ = 0.0;
00577         left_arm_vel_pitch_ = 0.0;
00578         left_arm_vel_yaw_ = 0.0;
00579         
00580         if(lookAnalog) {
00581           //look at analog sticks if we aren't supposed to wrist rotate
00582           if(axisOk(ARM_X_AXIS, joy_msg)) {
00583             if(!rotateArm)
00584               left_arm_vx_ = joy_msg->axes[ARM_X_AXIS]*arm_x_scale_;
00585             else
00586               left_arm_vel_pitch_ = joy_msg->axes[ARM_X_AXIS]*arm_pitch_scale_;
00587           }
00588           if(axisOk(ARM_Y_AXIS, joy_msg)) {
00589             if(!rotateArm)
00590               left_arm_vy_ = joy_msg->axes[ARM_Y_AXIS]*arm_y_scale_;
00591             else
00592               left_arm_vel_roll_ = joy_msg->axes[ARM_Y_AXIS]*arm_roll_scale_;
00593           }
00594           if(axisOk(ARM_Z_AXIS, joy_msg) && (!rotateArm)) {
00595             left_arm_vz_ = joy_msg->axes[ARM_Z_AXIS]*arm_z_scale_;
00596           }
00597           if(axisOk(ARM_YAW_AXIS, joy_msg) && rotateArm) {
00598             left_arm_vel_yaw_ = joy_msg->axes[ARM_YAW_AXIS]*arm_yaw_scale_;
00599           }
00600           //ROS_INFO_STREAM("Setting vx " << left_arm_vx_ << " " << left_arm_vy_ << " " << left_arm_vz_);
00601         }
00602       }
00603     } else if (layout != LAYOUT_BOTH_ARMS) {
00604       des_left_wrist_vel_ = 0.0;
00605       left_arm_vx_ = 0.0;
00606       left_arm_vy_ = 0.0;
00607       left_arm_vz_ = 0.0;
00608       left_arm_vel_roll_ = 0.0;
00609       left_arm_vel_pitch_ = 0.0;
00610       left_arm_vel_yaw_ = 0.0;
00611     }
00612     if(layout == LAYOUT_BOTH_ARMS) {
00613       if(buttonOkAndOn(ARM_MODE_TOGGLE_BUTTON, joy_msg) && !sameValueAsLast(ARM_MODE_TOGGLE_BUTTON, joy_msg, last_joy_)) {
00614         GeneralCommander::ArmControlMode toSend;
00615         if(in_walk_along) {
00616           gc->turnOffWalkAlong();
00617           ROS_INFO("Turning off walk along");
00618         }
00619         if(gc->getArmMode(GeneralCommander::ARMS_RIGHT) != gc->getArmMode(GeneralCommander::ARMS_RIGHT)) {
00620           toSend = GeneralCommander::ARM_POSITION_CONTROL;
00621         } else if(gc->getArmMode(GeneralCommander::ARMS_RIGHT) == GeneralCommander::ARM_POSITION_CONTROL) {
00622           toSend = GeneralCommander::ARM_MANNEQUIN_MODE;
00623         } else if (gc->getArmMode(GeneralCommander::ARMS_RIGHT) == GeneralCommander::ARM_MANNEQUIN_MODE) {
00624           toSend = GeneralCommander::ARM_NO_CONTROLLER;
00625         } else {
00626           toSend = GeneralCommander::ARM_POSITION_CONTROL;
00627         }
00628         gc->setArmMode(GeneralCommander::ARMS_BOTH, toSend);
00629       }
00630 
00631       if(buttonOkAndOn(ARM_TUCK_BUTTON, joy_msg) && !sameValueAsLast(ARM_TUCK_BUTTON, joy_msg, last_joy_)) {
00632         if(in_walk_along) {
00633           gc->turnOffWalkAlong();
00634           ROS_INFO("Turning off walk along");
00635         }
00636         gc->tuckArms(GeneralCommander::ARMS_BOTH);        
00637       } else if(buttonOkAndOn(ARM_UNTUCK_BUTTON, joy_msg) && !sameValueAsLast(ARM_UNTUCK_BUTTON, joy_msg, last_joy_)) {
00638         if(in_walk_along) {
00639           gc->turnOffWalkAlong();
00640           ROS_INFO("Turning off walk along");
00641         }
00642         gc->untuckArms(GeneralCommander::ARMS_BOTH);
00643       } 
00644 
00645       if(!in_walk_along) {
00646         bool lookAnalog = false;
00647         bool rotClock = buttonOkAndOn(WRIST_CLOCKWISE_BUTTON, joy_msg);
00648         bool rotCounter = buttonOkAndOn(WRIST_COUNTER_BUTTON, joy_msg);
00649         bool rotateArm = buttonOkAndOn(ARM_POSE_BUTTON, joy_msg);
00650         if(rotClock && !rotCounter) {
00651           des_left_wrist_vel_ = wrist_velocity_;
00652           des_right_wrist_vel_ = wrist_velocity_;
00653         } else if(!rotClock && rotCounter) {
00654           des_left_wrist_vel_ = -wrist_velocity_;
00655           des_right_wrist_vel_ = -wrist_velocity_;
00656         } else {
00657           des_left_wrist_vel_ = 0.0;
00658           des_right_wrist_vel_ = 0.0;
00659           lookAnalog = true;
00660         }
00661 
00662         left_arm_vx_ = 0.0;
00663         left_arm_vy_ = 0.0;
00664         left_arm_vz_ = 0.0;
00665         right_arm_vx_ = 0.0;
00666         right_arm_vy_ = 0.0;
00667         right_arm_vz_ = 0.0;
00668         left_arm_vel_roll_ = 0.0;
00669         left_arm_vel_pitch_ = 0.0;
00670         left_arm_vel_yaw_ = 0.0;
00671         right_arm_vel_roll_ = 0.0;
00672         right_arm_vel_pitch_ = 0.0;
00673         right_arm_vel_yaw_ = 0.0;
00674         
00675         if(lookAnalog) {
00676           //look at analog sticks if we aren't supposed to wrist rotate
00677           if(axisOk(ARM_X_AXIS, joy_msg)) {
00678             if(!rotateArm) {
00679               left_arm_vx_ = joy_msg->axes[ARM_X_AXIS]*arm_x_scale_;
00680               right_arm_vx_ = joy_msg->axes[ARM_X_AXIS]*arm_x_scale_;
00681             } else {
00682               left_arm_vel_pitch_ = joy_msg->axes[ARM_X_AXIS]*arm_pitch_scale_;
00683               right_arm_vel_pitch_ = joy_msg->axes[ARM_X_AXIS]*arm_pitch_scale_;
00684             }
00685           }
00686           if(axisOk(ARM_Y_AXIS, joy_msg)) {
00687             if(!rotateArm) {
00688               left_arm_vy_ = joy_msg->axes[ARM_Y_AXIS]*arm_y_scale_;
00689               right_arm_vy_ = joy_msg->axes[ARM_Y_AXIS]*arm_y_scale_;
00690             } else {
00691               left_arm_vel_roll_ = joy_msg->axes[ARM_Y_AXIS]*arm_roll_scale_;
00692               right_arm_vel_roll_ = joy_msg->axes[ARM_Y_AXIS]*arm_roll_scale_;
00693             }
00694           }
00695           if(axisOk(ARM_Z_AXIS, joy_msg) && (!rotateArm)) {
00696             left_arm_vz_ = joy_msg->axes[ARM_Z_AXIS]*arm_z_scale_;
00697             right_arm_vz_ = joy_msg->axes[ARM_Z_AXIS]*arm_z_scale_;
00698           }
00699           if(axisOk(ARM_YAW_AXIS, joy_msg) && rotateArm) {
00700             left_arm_vel_yaw_ = joy_msg->axes[ARM_YAW_AXIS]*arm_yaw_scale_;
00701             right_arm_vel_yaw_ = joy_msg->axes[ARM_YAW_AXIS]*arm_yaw_scale_;
00702           }
00703         //ROS_INFO_STREAM("Setting vx " << left_arm_vx_ << " " << left_arm_vy_ << " " << left_arm_vz_);
00704         }
00705       }
00706     } else if (layout != LAYOUT_RIGHT_ARM && layout != LAYOUT_LEFT_ARM) {
00707       des_right_wrist_vel_ = 0.0;
00708       des_left_wrist_vel_ = 0.0;
00709       left_arm_vx_ = 0.0;
00710       left_arm_vy_ = 0.0;
00711       left_arm_vz_ = 0.0;
00712       right_arm_vx_ = 0.0;
00713       right_arm_vy_ = 0.0;
00714       right_arm_vz_ = 0.0;
00715       left_arm_vel_roll_ = 0.0;
00716       left_arm_vel_pitch_ = 0.0;
00717       left_arm_vel_yaw_ = 0.0;
00718       right_arm_vel_roll_ = 0.0;
00719       right_arm_vel_pitch_ = 0.0;
00720       right_arm_vel_yaw_ = 0.0;
00721     }
00722 
00723     joy_deadman_ = ros::Time::now();
00724     last_joy_ = joy_msg;
00725   }
00726 
00727   bool convertCurrentVelToDesiredTorsoPos(double hz) {
00728     if(!torso_init_)  {
00729       double cur_torso_pos = 0.0;
00730       bool ok = gc->getJointPosition("torso_lift_joint", cur_torso_pos);
00731       if(!ok) return false;
00732       des_torso_pos_ = cur_torso_pos;
00733       torso_init_ = true;
00734     }
00735     double dt = 1.0/double(hz);
00736     double horizon = dt*5.0;
00737     double cur_torso_pos = 0.0;
00738     gc->getJointPosition("torso_lift_joint", cur_torso_pos);
00739     des_torso_pos_ = cur_torso_pos+des_torso_vel_ * horizon;
00740     des_torso_pos_ = std::min(des_torso_pos_, max_torso_);
00741     des_torso_pos_ = std::max(des_torso_pos_, min_torso_);
00742     return true;
00743   }
00744 
00745   bool convertCurrentVelToDesiredHeadPos(double hz) {
00746    
00747     if(!head_init_)  {
00748       double cur_pan_pos = 0.0;
00749       double cur_tilt_pos = 0.0;
00750       bool ok = gc->getJointPosition("head_pan_joint", cur_pan_pos);
00751       if(!ok) return false;
00752       ok = gc->getJointPosition("head_tilt_joint", cur_tilt_pos);
00753       if(!ok) return false;
00754       des_pan_pos_ = cur_pan_pos;
00755       des_tilt_pos_ = cur_tilt_pos;
00756       head_init_ = true;
00757     }
00758     if(fabs(vel_val_pan_) > .0001) {
00759       des_pan_pos_ = des_pan_pos_ + vel_val_pan_*(1.0/hz);
00760       des_pan_pos_ = std::min(des_pan_pos_, max_pan_);
00761       des_pan_pos_ = std::max(des_pan_pos_, -max_pan_);
00762     }
00763     if(fabs(vel_val_tilt_) > .0001) {
00764       des_tilt_pos_ = des_tilt_pos_ - vel_val_tilt_*(1.0/hz);
00765       des_tilt_pos_ = std::min(des_tilt_pos_, max_tilt_);
00766       des_tilt_pos_ = std::max(des_tilt_pos_, min_tilt_);
00767     }
00768     //ROS_INFO_STREAM("Des pan pos " << des_pan_pos_ << " tilt " << des_tilt_pos_);
00769     return true;
00770   }
00771 
00772 public:
00773   double max_pan_, max_tilt_, min_tilt_;
00774   int axis_pan_, axis_tilt_;
00775   double pan_scale_, tilt_scale_;
00776 
00777   double des_pan_pos_;
00778   double des_tilt_pos_;
00779 
00780   double vel_val_pan_;
00781   double vel_val_tilt_;
00782 
00783   double des_vx_;
00784   double des_vy_;
00785   double des_vw_;
00786 
00787   double vx_scale_;
00788   double vy_scale_;
00789   double vw_scale_;
00790 
00791   double arm_x_scale_;
00792   double arm_y_scale_;
00793   double arm_z_scale_;
00794   double arm_roll_scale_;
00795   double arm_pitch_scale_;
00796   double arm_yaw_scale_;
00797 
00798   double right_arm_vx_;
00799   double right_arm_vy_;
00800   double right_arm_vz_;
00801 
00802   double left_arm_vx_;
00803   double left_arm_vy_;
00804   double left_arm_vz_;
00805 
00806   double right_arm_vel_roll_;
00807   double right_arm_vel_pitch_;
00808   double right_arm_vel_yaw_;
00809 
00810   double left_arm_vel_roll_;
00811   double left_arm_vel_pitch_;
00812   double left_arm_vel_yaw_;
00813 
00814   bool head_init_;
00815   bool torso_init_;
00816 
00817   double req_torso_vel_;
00818   double req_torso_pos_;
00819 
00820   double des_torso_pos_;
00821   double des_torso_vel_;
00822   double torso_step_;
00823   double min_torso_;
00824   double max_torso_;
00825 
00826   double wrist_velocity_;
00827   double des_right_wrist_vel_;  
00828   double des_left_wrist_vel_;
00829 
00830   double walk_along_x_speed_scale_;
00831   double walk_along_y_speed_scale_;
00832   double walk_along_w_speed_scale_;
00833   double walk_along_thresh_;
00834   double walk_along_x_dist_max_;
00835   double walk_along_y_dist_max_;
00836 
00837   bool walk_along_init_waiting_;
00838   bool set_walk_along_mode_;
00839 
00840   std::string prosilica_namespace_;
00841 
00842   bool proj_toggle_com_; 
00843  
00844   int projector_toggle_button_;
00845   int tilt_toggle_button_;
00846   int switch_head_control_mode_button_;
00847 
00848   GeneralCommander* gc;
00849 
00850   ros::Time joy_deadman_;
00851 
00852   sensor_msgs::JoyConstPtr last_joy_;
00853   bool first_callback_;
00854 
00855   ros::NodeHandle n_;
00856   ros::Subscriber joy_sub_;
00857 
00858   ros::Time last_projector_toggle_;
00859   ros::Time last_laser_toggle_;
00860   ros::Time last_head_toggle_;
00861 
00862   ros::Time last_walk_along_time_;
00863 
00864 };
00865 
00866 static const double FastHz = 100;
00867 static const double SlowHz = 20;
00868 
00869 void spin_function() {
00870   ros::spin();
00871 }
00872 
00873 // void quit(int sig)
00874 // {
00875 //   delete generaljoy;
00876 //   ros::shutdown();
00877 //   spin_thread.join();
00878 //   exit(0);
00879 // }
00880 
00881 int main(int argc, char **argv)
00882 {
00883   ros::init(argc, argv, "pr2_telep_general_joystick", ros::init_options::NoSigintHandler);
00884   //signal(SIGINT,quit);
00885 
00886   boost::thread spin_thread(boost::bind(&spin_function));
00887 
00888   Pr2TeleopGeneralJoystick generaljoy;
00889   generaljoy.init();
00890   
00891   ros::Rate pub_rate(FastHz);
00892     
00893   unsigned int counter_limit = (unsigned int)(FastHz/SlowHz);
00894 
00895   unsigned int counter = 0;
00896 
00897   ros::Time beforeCall = ros::Time::now();
00898   ros::Time afterCall = ros::Time::now();
00899   while (ros::ok()) 
00900   {
00901     //ROS_INFO_STREAM("Time since last " << (ros::Time::now()-beforeCall).toSec());
00902     beforeCall = ros::Time::now();
00903 
00904     if(!generaljoy.gc->isWalkAlongOk() && !generaljoy.set_walk_along_mode_ && !generaljoy.walk_along_init_waiting_) {
00905       if(generaljoy.convertCurrentVelToDesiredHeadPos(FastHz)) {
00906         generaljoy.gc->sendHeadCommand(generaljoy.des_pan_pos_, generaljoy.des_tilt_pos_);
00907       } 
00908       generaljoy.gc->sendHeadTrackCommand();
00909       generaljoy.gc->sendBaseCommand(generaljoy.des_vx_, generaljoy.des_vy_, generaljoy.des_vw_);
00910     }
00911       
00912     if((counter % counter_limit) == 0) {
00913       
00914       counter = 0;
00915       
00916       if(generaljoy.set_walk_along_mode_) {
00917         bool ok = generaljoy.gc->moveToWalkAlongArmPose();
00918         //if we didn't get a select while moving the arms
00919         if(ok && generaljoy.set_walk_along_mode_) {
00920           ROS_INFO("Arms in walk position");
00921           generaljoy.walk_along_init_waiting_ = true;
00922         } else {
00923           ROS_INFO("Arms not in walk position");
00924         }
00925         generaljoy.set_walk_along_mode_ = false;
00926       }
00927       
00928       if(generaljoy.gc->isWalkAlongOk()) {
00929         
00930         generaljoy.gc->sendWalkAlongCommand(generaljoy.walk_along_thresh_, 
00931                                             generaljoy.walk_along_x_dist_max_,
00932                                             generaljoy.walk_along_x_speed_scale_,
00933                                             generaljoy.walk_along_y_dist_max_,
00934                                             generaljoy.walk_along_y_speed_scale_,
00935                                             generaljoy.walk_along_w_speed_scale_);
00936       } else {
00937         if(generaljoy.convertCurrentVelToDesiredTorsoPos(SlowHz)) {
00938           generaljoy.gc->sendTorsoCommand(generaljoy.des_torso_pos_, generaljoy.des_torso_vel_);
00939         }
00940         //generaljoy.gc->updateCurrentWristPositions();
00941         generaljoy.gc->sendWristVelCommands(generaljoy.des_right_wrist_vel_, generaljoy.des_left_wrist_vel_, SlowHz);
00942         
00943         generaljoy.gc->sendArmVelCommands(generaljoy.right_arm_vx_, generaljoy.right_arm_vy_, generaljoy.right_arm_vz_, generaljoy.right_arm_vel_roll_, generaljoy.right_arm_vel_pitch_, generaljoy.right_arm_vel_yaw_,
00944                                           generaljoy.left_arm_vx_, generaljoy.left_arm_vy_, generaljoy.left_arm_vz_, generaljoy.left_arm_vel_roll_, generaljoy.left_arm_vel_pitch_, generaljoy.left_arm_vel_yaw_,
00945                                           SlowHz);
00946       }
00947     }
00948     //ROS_INFO_STREAM("Everything took " << (afterCall-beforeCall).toSec());
00949     counter++;
00950     pub_rate.sleep();
00951   }
00952   
00953   ros::shutdown();
00954   spin_thread.join();
00955   return 0;
00956 }


pr2_teleop_general
Author(s): Gil Jones
autogenerated on Fri Aug 28 2015 12:05:50