jaco_joy_teleop.cpp
Go to the documentation of this file.
00001 
00012 #include <jaco_teleop/jaco_joy_teleop.h>
00013 
00014 using namespace std;
00015 
00016 jaco_joy_teleop::jaco_joy_teleop()
00017 {
00018   // a private handle for this ROS node (allows retrieval of relative parameters)
00019   ros::NodeHandle private_nh("~");
00020 
00021   loadParameters(node);
00022 
00023   // create the ROS topics
00024   angular_cmd = node.advertise<wpi_jaco_msgs::AngularCommand>(topic_prefix_ + "_arm/angular_cmd", 10);
00025   cartesian_cmd = node.advertise<wpi_jaco_msgs::CartesianCommand>(topic_prefix_ + "_arm/cartesian_cmd", 10);
00026   joy_sub = node.subscribe<sensor_msgs::Joy>("joy", 10, &jaco_joy_teleop::joy_cback, this);
00027 
00028   eStopClient = node.serviceClient<wpi_jaco_msgs::EStop>(topic_prefix_ + "_arm/software_estop");
00029 
00030   // read in throttle values
00031   private_nh.param<double>("linear_throttle_factor", linear_throttle_factor, 1.0);
00032   private_nh.param<double>("angular_throttle_factor", angular_throttle_factor, 1.0);
00033   private_nh.param<double>("finger_throttle_factor", finger_throttle_factor, 1.0);
00034   string str;
00035   private_nh.param<string>("controller_type", str, "digital");
00036   if (str.compare("digital") == 0)
00037     controllerType = DIGITAL;
00038   else
00039     controllerType = ANALOG;
00040 
00041   //initialize everything
00042   stopMessageSentArm = true;
00043   stopMessageSentFinger = true;
00044   EStopEnabled = false;
00045   helpDisplayed = false;
00046   mode = ARM_CONTROL;
00047   fingerCmd.position = false;
00048   fingerCmd.armCommand = false;
00049   fingerCmd.fingerCommand = true;
00050   fingerCmd.repeat = true;
00051   fingerCmd.fingers.resize(3);
00052   cartesianCmd.position = false;
00053   cartesianCmd.armCommand = true;
00054   cartesianCmd.fingerCommand = false;
00055   cartesianCmd.repeat = true;
00056 
00057   ROS_INFO("Joystick teleop started for: %s", arm_name_.c_str());
00058 
00059   puts(" ----------------------------------------");
00060   puts("| Joystick Teleop Help                   |");
00061   puts("|----------------------------------------|*");
00062   puts("| Current Mode: Arm Control              |*");
00063   puts("|----------------------------------------|*");
00064   puts("| For help and controls, press:          |*");
00065   puts("|                          _             |*");
00066   puts("|                        _| |_           |*");
00067   puts("|  show finger controls |_   _|          |*");
00068   puts("|                         |_|            |*");
00069   puts("|                  show arm controls     |*");
00070   puts("|                                        |*");
00071   puts(" ----------------------------------------**");
00072   puts("  *****************************************");
00073 
00074   if (controllerType == ANALOG)
00075   {
00076     initLeftTrigger = false;
00077     initRightTrigger = false;
00078     calibrated = false;
00079 
00080     ROS_INFO(
00081         "You specified a controller with analog triggers. This requires calibration before any teleoperation can begin.  Please press and release both triggers before continuing.");
00082   }
00083   else
00084     calibrated = true;
00085 }
00086 
00087 void jaco_joy_teleop::joy_cback(const sensor_msgs::Joy::ConstPtr& joy)
00088 {
00089   // make sure triggers are calibrated before continuint if an analog controller was specified
00090   if (!calibrated)
00091   {
00092     if (!initLeftTrigger && joy->axes.at(2) == 1.0)
00093       initLeftTrigger = true;
00094 
00095     if (!initRightTrigger && joy->axes.at(5) == 1.0)
00096       initRightTrigger = true;
00097 
00098     if (initLeftTrigger && initRightTrigger)
00099     {
00100       calibrated = true;
00101       ROS_INFO("Controller calibration complete!");
00102     }
00103 
00104     return;
00105   }
00106 
00107   //software emergency stop
00108   if (controllerType == DIGITAL)
00109   {
00110     if (joy->buttons.at(8) == 1)
00111     {
00112       EStopEnabled = true;
00113       wpi_jaco_msgs::EStop srv;
00114       srv.request.enableEStop = true;
00115       if (!eStopClient.call(srv))
00116         ROS_INFO("Couldn't call software estop service.");
00117     }
00118     else if (joy->buttons.at(9) == 1)
00119     {
00120       EStopEnabled = false;
00121       wpi_jaco_msgs::EStop srv;
00122       srv.request.enableEStop = false;
00123       if (!eStopClient.call(srv))
00124         ROS_INFO("Couldn't call software estop service.");
00125     }
00126   }
00127   else
00128   {
00129     if (joy->buttons.at(6) == 1)
00130     {
00131       EStopEnabled = true;
00132       wpi_jaco_msgs::EStop srv;
00133       srv.request.enableEStop = true;
00134       if (!eStopClient.call(srv))
00135         ROS_INFO("Couldn't call software estop service.");
00136     }
00137     else if (joy->buttons.at(7) == 1)
00138     {
00139       EStopEnabled = false;
00140       wpi_jaco_msgs::EStop srv;
00141       srv.request.enableEStop = false;
00142       if (!eStopClient.call(srv))
00143         ROS_INFO("Couldn't call software estop service.");
00144     }
00145   }
00146 
00147   //help menu
00148   if ((controllerType == DIGITAL && joy->axes.at(5) == -1.0) || (controllerType == ANALOG && joy->axes.at(7) == -1.0))
00149   {
00150     if (!helpDisplayed)
00151     {
00152       helpDisplayed = true;
00153       puts(" ----------------------------------------");
00154       puts("| Joystick Teleop Help                   |");
00155       puts("|----------------------------------------|*");
00156       if (mode == ARM_CONTROL)
00157         puts("| Current Mode: Arm Control              |*");
00158       else
00159         puts("| Current Mode: Finger Control           |*");
00160       puts("|----------------------------------------|*");
00161       puts("|                Controls                |*");
00162       puts("|   roll/down                 roll/up    |*");
00163       puts("|    ________                ________    |*");
00164       puts("|   /    _   \\______________/        \\   |*");
00165       puts("|  |   _| |_    < >    < >     (4)    |  |*");
00166       puts("|  |  |_   _|  Estop  start (1)   (3) |  |*");
00167       puts("|  |    |_|    ___      ___    (2)    |  |*");
00168       puts("|  |          /   \\    /   \\          |  |*");
00169       puts("|  |          \\___/    \\___/          |  |*");
00170       puts("|  |       x/y trans  pitch/yaw       |  |*");
00171       puts("|  |        _______/--\\_______        |  |*");
00172       puts("|  |       |                  |       |  |*");
00173       puts("|   \\     /                    \\     /   |*");
00174       puts("|    \\___/                      \\___/    |*");
00175       puts("|                                        |*");
00176       puts("| Buttons:                               |*");
00177       puts("|   (1) Switch to finger control mode    |*");
00178       puts("|   (2) Switch to arm control mode       |*");
00179       puts("|   (3) No function                      |*");
00180       puts("|   (4) No function                      |*");
00181       puts(" ----------------------------------------**");
00182       puts("  *****************************************");
00183     }
00184   }
00185   else if ((controllerType == DIGITAL && joy->axes.at(4) == 1.0)
00186       || (controllerType == ANALOG && joy->axes.at(6) == 1.0))
00187   {
00188     if (!helpDisplayed)
00189     {
00190       helpDisplayed = true;
00191       puts(" ----------------------------------------");
00192       puts("| Joystick Teleop Help                   |");
00193       puts("|----------------------------------------|*");
00194       if (mode == ARM_CONTROL)
00195         puts("| Current Mode: Arm Control              |*");
00196       else
00197         puts("| Current Mode: Finger Control           |*");
00198       puts("|----------------------------------------|*");
00199       puts("|                Controls                |*");
00200       puts("| finger1 open/close  finger2 open/close |*");
00201       puts("|    ________                ________    |*");
00202       puts("|   /    _   \\______________/        \\   |*");
00203       puts("|  |   _| |_    < >    < >     (4)    |  |*");
00204       puts("|  |  |_   _|  Estop  start (1)   (3) |  |*");
00205       puts("|  |    |_|    ___      ___    (2)    |  |*");
00206       puts("|  |          /   \\    /   \\          |  |*");
00207       puts("|  |          \\___/    \\___/          |  |*");
00208       puts("|  | hand open/close  thumb open/close|  |*");
00209       puts("|  |        _______/--\\_______        |  |*");
00210       puts("|  |       |                  |       |  |*");
00211       puts("|   \\     /                    \\     /   |*");
00212       puts("|    \\___/                      \\___/    |*");
00213       puts("|                                        |*");
00214       puts("| Buttons:                               |*");
00215       puts("|   (1) Switch to finger control mode    |*");
00216       puts("|   (2) Switch to arm control mode       |*");
00217       puts("|   (3) No function                      |*");
00218       puts("|   (4) No function                      |*");
00219       puts(" ----------------------------------------**");
00220       puts("  *****************************************");
00221     }
00222   }
00223   else
00224     helpDisplayed = false;
00225 
00226   int buttonIndex;
00227 
00228   switch (mode)
00229   {
00230     case ARM_CONTROL:
00231       // left joystick controls the linear x and y movement
00232       cartesianCmd.arm.linear.x = joy->axes.at(0) * MAX_TRANS_VEL * linear_throttle_factor;
00233       cartesianCmd.arm.linear.y = -joy->axes.at(1) * MAX_TRANS_VEL * linear_throttle_factor;
00234 
00235       //triggers control the linear z movement
00236       if (controllerType == DIGITAL)
00237       {
00238         if (joy->buttons.at(7) == 1)
00239           cartesianCmd.arm.linear.z = MAX_TRANS_VEL * linear_throttle_factor;
00240         else if (joy->buttons.at(6) == 1)
00241           cartesianCmd.arm.linear.z = -MAX_TRANS_VEL * linear_throttle_factor;
00242         else
00243           cartesianCmd.arm.linear.z = 0.0;
00244       }
00245       else
00246       {
00247         if (joy->axes.at(5) < 1.0)
00248           cartesianCmd.arm.linear.z = (0.5 - joy->axes.at(5) / 2.0) * MAX_ANG_VEL * angular_throttle_factor;
00249         else
00250           cartesianCmd.arm.linear.z = -(0.5 - joy->axes.at(2) / 2.0) * MAX_ANG_VEL * angular_throttle_factor;
00251       }
00252 
00253       //bumpers control roll
00254       if (joy->buttons.at(5) == 1)
00255         cartesianCmd.arm.angular.z = MAX_ANG_VEL * angular_throttle_factor;
00256       else if (joy->buttons.at(4) == 1)
00257         cartesianCmd.arm.angular.z = -MAX_ANG_VEL * angular_throttle_factor;
00258       else
00259         cartesianCmd.arm.angular.z = 0.0;
00260 
00261       //right joystick controls pitch and yaw
00262       if (controllerType == DIGITAL)
00263       {
00264         cartesianCmd.arm.angular.x = -joy->axes.at(3) * MAX_ANG_VEL * angular_throttle_factor;
00265         cartesianCmd.arm.angular.y = joy->axes.at(2) * MAX_ANG_VEL * angular_throttle_factor;
00266       }
00267       else
00268       {
00269         cartesianCmd.arm.angular.x = -joy->axes.at(4) * MAX_ANG_VEL * angular_throttle_factor;
00270         cartesianCmd.arm.angular.y = joy->axes.at(3) * MAX_ANG_VEL * angular_throttle_factor;
00271       }
00272 
00273       //mode switching
00274       if (controllerType == DIGITAL)
00275         buttonIndex = 0;
00276       else
00277         buttonIndex = 2;
00278 
00279       if (joy->buttons.at(buttonIndex) == 1)
00280       {
00281         //cancel trajectory and switch to finger control mode
00282         cartesianCmd.arm.linear.x = 0.0;
00283         cartesianCmd.arm.linear.y = 0.0;
00284         cartesianCmd.arm.linear.z = 0.0;
00285         cartesianCmd.arm.angular.x = 0.0;
00286         cartesianCmd.arm.angular.y = 0.0;
00287         cartesianCmd.arm.angular.z = 0.0;
00288         cartesian_cmd.publish(cartesianCmd);
00289         mode = FINGER_CONTROL;
00290 
00291         ROS_INFO("Activated finger control mode");
00292       }
00293       break;
00294     case FINGER_CONTROL:
00295       if (joy->axes.at(1) == 0.0)
00296       {
00297         //individual finger control
00298         //thumb controlled by right thumbstick
00299         if (controllerType == DIGITAL)
00300           fingerCmd.fingers[0] = -joy->axes.at(3) * MAX_FINGER_VEL * finger_throttle_factor;
00301         else
00302           fingerCmd.fingers[0] = -joy->axes.at(4) * MAX_FINGER_VEL * finger_throttle_factor;
00303 
00304         //top finger controlled by left triggers
00305         if (controllerType == DIGITAL)
00306         {
00307           if (joy->buttons.at(4) == 1)
00308             fingerCmd.fingers[1] = -MAX_FINGER_VEL * finger_throttle_factor;
00309           else if (joy->buttons.at(6) == 1)
00310             fingerCmd.fingers[1] = MAX_FINGER_VEL * finger_throttle_factor;
00311           else
00312             fingerCmd.fingers[1] = 0.0;
00313         }
00314         else
00315         {
00316           if (joy->buttons.at(4) == 1)
00317             fingerCmd.fingers[1] = -MAX_FINGER_VEL * finger_throttle_factor;
00318           else
00319             fingerCmd.fingers[1] = (0.5 - joy->axes.at(2) / 2.0) * MAX_FINGER_VEL * finger_throttle_factor;
00320         }
00321 
00322         //bottom finger controlled by right bumpers
00323         if (controllerType == DIGITAL)
00324         {
00325           if (joy->buttons.at(5) == 1)
00326             fingerCmd.fingers[2] = -MAX_FINGER_VEL * finger_throttle_factor;
00327           else if (joy->buttons.at(7) == 1)
00328             fingerCmd.fingers[2] = MAX_FINGER_VEL * finger_throttle_factor;
00329           else
00330             fingerCmd.fingers[2] = 0.0;
00331         }
00332         else
00333         {
00334           if (joy->buttons.at(5) == 1)
00335             fingerCmd.fingers[2] = -MAX_FINGER_VEL * finger_throttle_factor;
00336           else
00337             fingerCmd.fingers[2] = (0.5 - joy->axes.at(5) / 2.0) * MAX_FINGER_VEL * finger_throttle_factor;
00338         }
00339       }
00340       else
00341       {
00342         //control full gripper (outprioritizes individual finger control)
00343         fingerCmd.fingers[0] = -joy->axes.at(1) * MAX_FINGER_VEL * finger_throttle_factor;
00344         fingerCmd.fingers[1] = fingerCmd.fingers[0];
00345         fingerCmd.fingers[2] = fingerCmd.fingers[0];
00346       }
00347 
00348       //mode switching
00349       if (controllerType == DIGITAL)
00350         buttonIndex = 1;
00351       else
00352         buttonIndex = 0;
00353 
00354       if (joy->buttons.at(buttonIndex) == 1)
00355       {
00356         //cancel trajectory and switch to arm control mode
00357         fingerCmd.fingers[0] = 0.0;
00358         fingerCmd.fingers[1] = 0.0;
00359         fingerCmd.fingers[2] = 0.0;
00360         angular_cmd.publish(fingerCmd);
00361         mode = ARM_CONTROL;
00362 
00363         ROS_INFO("Activated arm control mode");
00364       }
00365       break;
00366   }
00367 }
00368 
00369 void jaco_joy_teleop::publish_velocity()
00370 {
00371   //publish stop commands if EStop is enabled
00372   if (EStopEnabled)
00373     return;
00374 
00375   switch (mode)
00376   {
00377     case ARM_CONTROL:
00378       //only publish stop message once; this allows other nodes to publish velocities
00379       //while the controller is not being used
00380       if (cartesianCmd.arm.linear.x == 0.0 && cartesianCmd.arm.linear.y == 0.0 && cartesianCmd.arm.linear.z == 0.0
00381           && cartesianCmd.arm.angular.x == 0.0 && cartesianCmd.arm.angular.y == 0.0
00382           && cartesianCmd.arm.angular.z == 0.0)
00383       {
00384         if (!stopMessageSentArm)
00385         {
00386           cartesian_cmd.publish(cartesianCmd);
00387           stopMessageSentArm = true;
00388         }
00389       }
00390       else
00391       {
00392         // send the twist command
00393         cartesian_cmd.publish(cartesianCmd);
00394         stopMessageSentArm = false;
00395       }
00396       break;
00397     case FINGER_CONTROL:
00398       //only publish stop message once; this allows other nodes to publish velocities
00399       //while the controller is not being used
00400       if (fingerCmd.fingers[0] == 0.0 && fingerCmd.fingers[1] == 0.0 && fingerCmd.fingers[2] == 0.0)
00401       {
00402         if (!stopMessageSentFinger)
00403         {
00404           angular_cmd.publish(fingerCmd);
00405           stopMessageSentFinger = true;
00406         }
00407       }
00408       else
00409       {
00410         //send the finger velocity command
00411         angular_cmd.publish(fingerCmd);
00412         stopMessageSentFinger = false;
00413       }
00414       break;
00415   }
00416 }
00417 
00418 bool jaco_joy_teleop::loadParameters(const ros::NodeHandle n)
00419 {
00420   n.param("wpi_jaco/arm_name",                arm_name_,              std::string("jaco"));
00421 
00422   // Update topic prefix
00423   if (arm_name_ == "jaco2")
00424     topic_prefix_ = "jaco";
00425   else
00426     topic_prefix_ = arm_name_;
00427 
00429   return true;
00430 }
00431 
00432 int main(int argc, char **argv)
00433 {
00434   // initialize ROS and the node
00435   ros::init(argc, argv, "jaco_joy_teleop");
00436 
00437   // initialize the joystick controller
00438   jaco_joy_teleop controller;
00439 
00440   ros::Rate loop_rate(60);      //rate at which to publish velocity commands
00441   while (ros::ok())
00442   {
00443     controller.publish_velocity();
00444     ros::spinOnce();
00445     loop_rate.sleep();
00446   }
00447 
00448   return EXIT_SUCCESS;
00449 }


jaco_teleop
Author(s): David Kent
autogenerated on Thu Jun 6 2019 19:43:28