Go to the documentation of this file.00001
00002 #include "ros/ros.h"
00003 #include <sensor_msgs/JoyFeedbackArray.h>
00004 #include <geometry_msgs/Twist.h>
00005 #include <geometry_msgs/Twist.h>
00006 #include <geometry_msgs/Twist.h>
00007 #include <brics_actuator/JointVelocities.h>
00008 #include <brics_actuator/JointVelocities.h>
00009 #include <geometry_msgs/Twist.h>
00010 #include <brics_actuator/JointVelocities.h>
00011 #include <geometry_msgs/Twist.h>
00012 #include <brics_actuator/JointVelocities.h>
00013 #include <brics_actuator/JointVelocities.h>
00014 #include <sensor_msgs/Joy.h>
00015
00016
00017 #include <actionlib/client/simple_action_client.h>
00018 #include <cob_script_server/ScriptAction.h>
00019 #include <string>
00020 #include <vector>
00021 #include <cob_srvs/Trigger.h>
00022
00023
00024 class cob_teleop_cob4_config
00025 {
00026 public:
00027 int button_deadman;
00028 double base_max_linear;
00029 double base_max_angular;
00030 double torso_max_angular;
00031 double head_max_angular;
00032 double sensor_ring_max_angular;
00033 double arm_joint_velocity_max;
00034 double arm_cartesian_max_linear;
00035 double arm_cartesian_max_angular;
00036 double gripper_max_velocity;
00037 int base_x;
00038 int base_y;
00039 int base_yaw;
00040 int arm_x;
00041 int arm_y;
00042 int arm_yaw;
00043 int arm_pitch_up;
00044 int arm_pitch_down;
00045 int arm_roll_right_and_ellbow;
00046 int arm_roll_left_and_ellbow;
00047 int arm_z_up;
00048 int arm_z_down;
00049 int gripper_open;
00050 int gripper_close;
00051 int arm_joint_up;
00052 int arm_joint_down;
00053 int arm_joint_left;
00054 int arm_joint_right;
00055 int arm_joint_12;
00056 int arm_joint_34;
00057 int arm_joint_56;
00058 int arm_joint_7_gripper;
00059 int axis_runfactor;
00060 int button_safety_override;
00061 int button_init_recover;
00062 int button_mode_switch;
00063 int torso_roll;
00064 int torso_pitch;
00065 int torso_yaw_left;
00066 int torso_yaw_right;
00067 int sensorring_yaw_left;
00068 int sensorring_yaw_right;
00069 int head_roll;
00070 int head_pitch;
00071 int head_yaw_left;
00072 int head_yaw_right;
00073 int head_home;
00074 int arm_left_home;
00075 int arm_right_home;
00076 int torso_home;
00077 int sensorring_home;
00078 int gripper_left_home;
00079 int gripper_right_home;
00080 int base_home;
00081 XmlRpc::XmlRpcValue arm_left_uri;
00082 XmlRpc::XmlRpcValue components;
00083 double home_time;
00084 double stop_time;
00085 XmlRpc::XmlRpcValue arm_right_uri;
00086 XmlRpc::XmlRpcValue led_mode;
00087 int gripper_1;
00088 int gripper_2;
00089 double gripper_max_angular;
00090 };
00091
00092 class cob_teleop_cob4_data
00093 {
00094
00095 public:
00096
00097 sensor_msgs::Joy in_joy;
00098
00099 sensor_msgs::JoyFeedbackArray out_joy_feedback;
00100 bool out_joy_feedback_active;
00101 geometry_msgs::Twist out_base_controller_command;
00102 bool out_base_controller_command_active;
00103 geometry_msgs::Twist out_arm_cart_left;
00104 bool out_arm_cart_left_active;
00105 geometry_msgs::Twist out_arm_cart_right;
00106 bool out_arm_cart_right_active;
00107 brics_actuator::JointVelocities out_arm_joint_right;
00108 bool out_arm_joint_right_active;
00109 brics_actuator::JointVelocities out_arm_joint_left;
00110 bool out_arm_joint_left_active;
00111 geometry_msgs::Twist out_head_controller_command;
00112 bool out_head_controller_command_active;
00113 brics_actuator::JointVelocities out_sensorring_controller_command;
00114 bool out_sensorring_controller_command_active;
00115 geometry_msgs::Twist out_torso_controller_command;
00116 bool out_torso_controller_command_active;
00117 brics_actuator::JointVelocities out_gripper_left;
00118 bool out_gripper_left_active;
00119 brics_actuator::JointVelocities out_gripper_right;
00120 bool out_gripper_right_active;
00121 };
00122
00123 class cob_teleop_cob4_impl
00124 {
00125
00126 typedef actionlib::SimpleActionClient<cob_script_server::ScriptAction> Client;
00127 Client * client;
00128
00129 bool once;
00130 bool once_stop;
00131 bool once_mode;
00132
00133 int mode;
00134 float run;
00135 float updown;
00136 float leftright;
00137 geometry_msgs::Twist head;
00138 geometry_msgs::Twist base;
00139 geometry_msgs::Twist torso;
00140 geometry_msgs::Twist arm_cart;
00141 sensor_msgs::Joy joy;
00142 brics_actuator::JointVelocities left;
00143 brics_actuator::JointVelocities right;
00144 brics_actuator::JointVelocities sring;
00145 brics_actuator::JointVelocities gleft;
00146 brics_actuator::JointVelocities gright;
00147 cob_script_server::ScriptGoal sss;
00148
00149 sensor_msgs::JoyFeedbackArray joyfb;
00150
00151
00152 XmlRpc::XmlRpcValue LEDS;
00153
00154 cob_srvs::Trigger trigger;
00155
00156
00157 public:
00158 cob_teleop_cob4_impl()
00159 {
00160
00161 client = new Client("script_server", true);
00162 ROS_INFO("Connecting to script_server");
00163 client->waitForServer();
00164 ROS_INFO("Connected");
00165
00166 }
00167
00168 void configure(cob_teleop_cob4_config config)
00169 {
00170
00171
00172 left.velocities.resize(7);
00173 right.velocities.resize(7);
00174 int i;
00175 for (i=0; i<7; i++)
00176 {
00177 left.velocities[i].unit="rad/sec";
00178 right.velocities[i].unit="rad/sec";
00179 left.velocities[i].joint_uri=static_cast<std::string>(config.arm_left_uri[i]).c_str();
00180 right.velocities[i].joint_uri=static_cast<std::string>(config.arm_right_uri[i]).c_str();
00181 }
00182
00183 sring.velocities.resize(1);
00184 sring.velocities[0].joint_uri="sensorring_joint";
00185 sring.velocities[0].unit="rad/sec";
00186
00187 gleft.velocities.resize(2);
00188 gright.velocities.resize(2);
00189 for (i=0; i<2; i++)
00190 {
00191 gleft.velocities[i].unit="rad/sec";
00192 gright.velocities[i].unit="rad/sec";
00193 gleft.velocities[i].joint_uri="Todo/left";
00194 gright.velocities[i].joint_uri="Todo/right";
00195 }
00196
00197 mode=0;
00198 LEDS=config.led_mode[mode];
00199
00200 }
00201
00202 void update(cob_teleop_cob4_data &data, cob_teleop_cob4_config config)
00203 {
00204
00205 data.out_base_controller_command_active=0;
00206 data.out_sensorring_controller_command_active=0;
00207 data.out_torso_controller_command_active=0;
00208 data.out_arm_joint_left_active=0;
00209 data.out_arm_joint_right_active=0;
00210 data.out_head_controller_command_active=0;
00211 data.out_arm_cart_left_active=0;
00212 data.out_arm_cart_right_active=0;
00213 data.out_gripper_left_active=0;
00214 data.out_gripper_right_active=0;
00215 data.out_joy_feedback=ledsOn(LEDS);
00216
00217 if (data.in_joy.buttons.size()<=5)
00218 {
00219 ROS_WARN("joypad inactive! waiting for array of buttons. Move the Controller");
00220 ros::Duration(0.5).sleep();
00221 return;
00222 }
00223
00224 joy=data.in_joy;
00225 run=1-joy.axes[config.axis_runfactor];
00226 updown=(joy.buttons[config.arm_joint_up]-joy.buttons[config.arm_joint_down]);
00227 leftright=(joy.buttons[config.arm_joint_left]-joy.buttons[config.arm_joint_right]);
00228
00229
00230 if (!joy.buttons[config.button_mode_switch]){once_mode=false;}
00231 if (joy.buttons[config.button_mode_switch] && not joy.buttons[config.button_deadman] && not once_mode)
00232 {
00233 once_mode=true;
00234 ++mode;
00235 if (mode >= 7)
00236 {
00237 mode = 0;
00238 }
00239 ROS_INFO("Mode switched to: %d",mode);
00240 LEDS=config.led_mode[mode];
00241 return;
00242 }
00243
00244 if (joy.buttons[config.button_deadman])
00245 {
00246
00247 switch (mode)
00248 {
00249 case 0:
00250
00251 base.linear.x=joy.axes[config.base_x]*config.base_max_linear*run;
00252 base.linear.y=joy.axes[config.base_y]*config.base_max_linear*run;
00253 base.angular.z=joy.axes[config.base_yaw]*config.base_max_angular*run;
00254 data.out_base_controller_command=base;
00255
00256 data.out_base_controller_command_active=1;
00257 if (!joy.buttons[config.button_init_recover]){once=false;}
00258 if (joy.buttons[config.button_init_recover] && !once)
00259 {
00260 initRecover("base");
00261 once=true;
00262 }
00263 break;
00264
00265 case 1:
00266 arm_cart.linear.x=(joy.axes[config.arm_x])*config.arm_cartesian_max_linear*run;
00267 arm_cart.linear.y=(joy.axes[config.arm_y])*config.arm_cartesian_max_linear*run;
00268 arm_cart.angular.z=(joy.axes[config.arm_yaw])*config.arm_cartesian_max_angular*run;
00269 arm_cart.linear.z=(joy.buttons[config.arm_z_up]-joy.buttons[config.arm_z_down])*run*config.arm_cartesian_max_linear;
00270 arm_cart.angular.x=(joy.buttons[config.arm_roll_left_and_ellbow]-joy.buttons[config.arm_roll_right_and_ellbow])*run*config.arm_cartesian_max_angular;
00271 arm_cart.angular.y=(joy.buttons[config.arm_pitch_up]-joy.buttons[config.arm_pitch_down])*run*config.arm_cartesian_max_angular;
00272 data.out_arm_cart_left=arm_cart;
00273 data.out_arm_cart_left_active=1;
00274 if (!joy.buttons[config.button_init_recover]){once=false;}
00275 if (joy.buttons[config.button_init_recover] && !once)
00276 {
00277 initRecover("arm_left");
00278 once=true;
00279 }
00280 break;
00281
00282 case 2:
00283 arm_cart.linear.x=(joy.axes[config.arm_x])*config.arm_cartesian_max_linear*run;
00284 arm_cart.linear.y=(joy.axes[config.arm_y])*config.arm_cartesian_max_linear*run;
00285 arm_cart.angular.z=(joy.axes[config.arm_yaw])*config.arm_cartesian_max_angular*run;
00286 arm_cart.linear.z=(joy.buttons[config.arm_z_up]-joy.buttons[config.arm_z_down])*run*config.arm_cartesian_max_linear;
00287 arm_cart.angular.x=(joy.buttons[config.arm_roll_left_and_ellbow]-joy.buttons[config.arm_roll_right_and_ellbow])*run*config.arm_cartesian_max_angular;
00288 arm_cart.angular.y=(joy.buttons[config.arm_pitch_up]-joy.buttons[config.arm_pitch_down])*run*config.arm_cartesian_max_angular;
00289 data.out_arm_cart_left=arm_cart;
00290 data.out_arm_cart_right_active=1;
00291 if (!joy.buttons[config.button_init_recover]){once=false;}
00292 if (joy.buttons[config.button_init_recover] && !once)
00293 {
00294 initRecover("arm_right");
00295 once=true;
00296 }
00297 break;
00298
00299 case 3:
00300 left.velocities[0].value=updown*joy.buttons[config.arm_joint_12]*run*config.arm_joint_velocity_max;
00301 left.velocities[1].value=leftright*joy.buttons[config.arm_joint_12]*run*config.arm_joint_velocity_max;
00302 left.velocities[2].value=updown*joy.buttons[config.arm_joint_34]*run*config.arm_joint_velocity_max;
00303 left.velocities[3].value=leftright*joy.buttons[config.arm_joint_34]*run*config.arm_joint_velocity_max;
00304 left.velocities[4].value=updown*joy.buttons[config.arm_joint_56]*run*config.arm_joint_velocity_max;
00305 left.velocities[5].value=leftright*joy.buttons[config.arm_joint_56]*run*config.arm_joint_velocity_max;
00306 left.velocities[6].value=updown*joy.buttons[config.arm_joint_7_gripper]*run*config.arm_joint_velocity_max;
00307 gleft.velocities[0].value=joy.axes[config.gripper_1]*run*config.gripper_max_angular;
00308 gleft.velocities[1].value=joy.axes[config.gripper_2]*run*config.gripper_max_angular;
00309 data.out_gripper_left=gleft;
00310 data.out_arm_joint_left=left;
00311 data.out_arm_joint_left_active=1;
00312 data.out_gripper_left_active=1;
00313 if (!joy.buttons[config.button_init_recover]){once=false;}
00314 if (joy.buttons[config.button_init_recover] && !once)
00315 {
00316 initRecover("arm_left");
00317 once=true;
00318 }
00319 break;
00320
00321 case 4:
00322 right.velocities[0].value=updown*joy.buttons[config.arm_joint_12]*run*config.arm_joint_velocity_max;
00323 right.velocities[1].value=leftright*joy.buttons[config.arm_joint_12]*run*config.arm_joint_velocity_max;
00324 right.velocities[2].value=updown*joy.buttons[config.arm_joint_34]*run*config.arm_joint_velocity_max;
00325 right.velocities[3].value=leftright*joy.buttons[config.arm_joint_34]*run*config.arm_joint_velocity_max;
00326 right.velocities[4].value=updown*joy.buttons[config.arm_joint_56]*run*config.arm_joint_velocity_max;
00327 right.velocities[5].value=leftright*joy.buttons[config.arm_joint_56]*run*config.arm_joint_velocity_max;
00328 right.velocities[6].value=updown*joy.buttons[config.arm_joint_7_gripper]*run*config.arm_joint_velocity_max;
00329 gright.velocities[0].value=joy.axes[config.gripper_1]*run*config.gripper_max_angular;
00330 gright.velocities[1].value=joy.axes[config.gripper_2]*run*config.gripper_max_angular;
00331 data.out_gripper_right=gright;
00332 data.out_arm_joint_right=right;
00333 data.out_arm_joint_right_active=1;
00334 data.out_gripper_right_active=1;
00335 if (!joy.buttons[config.button_init_recover]){once=false;}
00336 if (joy.buttons[config.button_init_recover] && !once)
00337 {
00338 initRecover("arm_right");
00339 once=true;
00340 }
00341 break;
00342
00343 case 5 :
00344 once_stop=false;
00345 bool recover;
00346 if (joy.buttons[config.head_home]){sss.component_name="head";}
00347 else if (joy.buttons[config.arm_left_home]){sss.component_name="arm_left";}
00348 else if (joy.buttons[config.arm_right_home]){sss.component_name="arm_right";}
00349 else if (joy.buttons[config.torso_home]){sss.component_name="torso";}
00350 else if (joy.buttons[config.sensorring_home]){sss.component_name="sensorring";}
00351 else if (joy.buttons[config.gripper_left_home]){sss.component_name="gripper_left";}
00352 else if (joy.buttons[config.gripper_right_home]){sss.component_name="gripper_right";}
00353 else if (joy.buttons[config.base_home]){sss.component_name="base";}
00354 else if (joy.buttons[config.button_init_recover]){recover=true;}
00355 else {once=false;recover=false; break;}
00356 if (!once && !recover)
00357 {
00358 once=true;
00359 ROS_INFO("Homing %s",sss.component_name.c_str());
00360 sss.function_name="move";
00361 sss.parameter_name="home";
00362 client->sendGoal(sss);
00363 }
00364 if (!once && recover)
00365 {
00366 once=true;
00367 int j;
00368 for (j=0; j<(config.components.size()); j++)
00369 {
00370 initRecover(static_cast<std::string>(config.components[j]).c_str());
00371 }
00372 }
00373 break;
00374
00375
00376 case 6:
00377
00378 sring.velocities[0].value=(joy.buttons[config.sensorring_yaw_left]-joy.buttons[config.sensorring_yaw_right])*config.sensor_ring_max_angular*run;
00379 data.out_sensorring_controller_command=sring;
00380 data.out_sensorring_controller_command_active=1;
00381
00382 head.angular.x=joy.axes[config.head_roll]*config.torso_max_angular*run;
00383 head.angular.y=joy.axes[config.head_pitch]*config.torso_max_angular*run;
00384 head.angular.z=(joy.buttons[config.head_yaw_left]-joy.buttons[config.head_yaw_right])*config.torso_max_angular*run;
00385 data.out_head_controller_command=head;
00386 data.out_head_controller_command_active=1;
00387
00388 torso.angular.x=joy.axes[config.torso_roll]*config.torso_max_angular*run;
00389 torso.angular.y=joy.axes[config.torso_pitch]*config.torso_max_angular*run;
00390 torso.angular.z=(joy.buttons[config.torso_yaw_left]-joy.buttons[config.torso_yaw_right])*config.torso_max_angular*run;
00391 data.out_torso_controller_command=torso;
00392 data.out_torso_controller_command_active=1;
00393
00394 if (!joy.buttons[config.button_init_recover]){once=false;}
00395 if (joy.buttons[config.button_init_recover] && !once)
00396 {
00397 initRecover("sensorring");
00398 initRecover("head");
00399 initRecover("torso");
00400 once=true;
00401 }
00402 break;
00403 }
00404 }
00405
00406 else if(!once_stop && mode==5)
00407 {
00408 once_stop=true;
00409 sss.function_name="stop";
00410 int j;
00411 for (j=0; j<(config.components.size()); j++)
00412 {
00413 serviceCall(static_cast<std::string>(config.components[j]).c_str(),"stop");
00414 }
00415 }
00416
00417
00418 }
00419
00420
00421
00422 void serviceCall(const std::string component, const std::string command)
00423 {
00424 std::stringstream ss;
00425 ss << "/" << component.c_str() << "_controller/" << command.c_str();
00426 ROS_INFO("triggering service: %s",ss.str().c_str());
00427 ros::service::call(((ss.str()).c_str()),trigger);
00428 }
00429 void initRecover(const std::string component)
00430 {
00431 std::stringstream ss;
00432 ss << "/" << component.c_str() << "_controller/init";
00433 ROS_INFO("init %s",component.c_str());
00434 ros::service::call(ss.str().c_str(),trigger);
00435 ss << "/" << component.c_str() << "_controller/recover";
00436 ROS_INFO("recover %s",component.c_str());
00437 ros::service::call(ss.str().c_str(),trigger);
00438 }
00439
00440 sensor_msgs::JoyFeedbackArray ledsOn(XmlRpc::XmlRpcValue leds)
00441 {
00442 int i;
00443 for (i=0; i<4; i++)
00444 {
00445 joyfb.array.resize(4);
00446 joyfb.array[i].type=0;
00447 joyfb.array[i].id=i;
00448 joyfb.array[i].intensity=static_cast<int>(leds[i]);
00449 }
00450 return joyfb;
00451 }
00452
00453 };