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
00019 ros::NodeHandle private_nh("~");
00020
00021 loadParameters(node);
00022
00023
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
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
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
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
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
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
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
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
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
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
00274 if (controllerType == DIGITAL)
00275 buttonIndex = 0;
00276 else
00277 buttonIndex = 2;
00278
00279 if (joy->buttons.at(buttonIndex) == 1)
00280 {
00281
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
00298
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
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
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
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
00349 if (controllerType == DIGITAL)
00350 buttonIndex = 1;
00351 else
00352 buttonIndex = 0;
00353
00354 if (joy->buttons.at(buttonIndex) == 1)
00355 {
00356
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
00372 if (EStopEnabled)
00373 return;
00374
00375 switch (mode)
00376 {
00377 case ARM_CONTROL:
00378
00379
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
00393 cartesian_cmd.publish(cartesianCmd);
00394 stopMessageSentArm = false;
00395 }
00396 break;
00397 case FINGER_CONTROL:
00398
00399
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
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
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
00435 ros::init(argc, argv, "jaco_joy_teleop");
00436
00437
00438 jaco_joy_teleop controller;
00439
00440 ros::Rate loop_rate(60);
00441 while (ros::ok())
00442 {
00443 controller.publish_velocity();
00444 ros::spinOnce();
00445 loop_rate.sleep();
00446 }
00447
00448 return EXIT_SUCCESS;
00449 }