00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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
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
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);
00413
00414
00415
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
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
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
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
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
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
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
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
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
00874
00875
00876
00877
00878
00879
00880
00881 int main(int argc, char **argv)
00882 {
00883 ros::init(argc, argv, "pr2_telep_general_joystick", ros::init_options::NoSigintHandler);
00884
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
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
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
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
00949 counter++;
00950 pub_rate.sleep();
00951 }
00952
00953 ros::shutdown();
00954 spin_thread.join();
00955 return 0;
00956 }