00001 #include "arm_movements_by_pose_alg_node.h"
00002
00003 ArmMovementsByPoseAlgNode::ArmMovementsByPoseAlgNode(void) :
00004 algorithm_base::IriBaseAlgorithm<ArmMovementsByPoseAlgorithm>(),
00005 move_right_arm_client_("move_right_arm", true),
00006 move_left_arm_client_("move_left_arm", true)
00007 {
00008
00009
00010
00011
00012 this->visualization_movement_markers_publisher_ = this->public_node_handle_.advertise<visualization_msgs::MarkerArray>("visualization_movement_markers", 1);
00013
00014
00015
00016
00017 this->clean_movement_server_ = this->public_node_handle_.advertiseService("clean_movement", &ArmMovementsByPoseAlgNode::clean_movementCallback, this);
00018
00019
00020 wam_pose_move_client_ = this->public_node_handle_.serviceClient<iri_wam_common_msgs::pose_move>("wam_pose_move");
00021 move_in_joints_client_ = this->public_node_handle_.serviceClient<iri_wam_common_msgs::joints_move>("move_in_joints");
00022 get_joints_from_pose_client_ = this->public_node_handle_.serviceClient<iri_wam_common_msgs::wamInverseKinematics>("get_joints_from_pose");
00023 pose_move_client_ = this->public_node_handle_.serviceClient<iri_wam_common_msgs::pose_move>("pose_move");
00024
00025
00026
00027
00028
00029
00030 if (this->log_movements) {
00031 logfile.open ("movements.txt");
00032 logfile << "Pose (x, y, z) | Quaternion (x, y, z, w) | Status \n";
00033 }
00034
00035 }
00036
00037 ArmMovementsByPoseAlgNode::~ArmMovementsByPoseAlgNode(void)
00038 {
00039
00040
00041 logfile.close();
00042 }
00043
00044 void ArmMovementsByPoseAlgNode::mainNodeThread(void)
00045 {
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 }
00089
00090
00091
00092
00093 bool ArmMovementsByPoseAlgNode::clean_movementCallback(estirabot_msgs::ArmMovementsPosesSrv::Request &req,
00094 estirabot_msgs::ArmMovementsPosesSrv::Response &res)
00095 {
00096 std::vector<geometry_msgs::PoseStamped> movement_poses;
00097 ROS_DEBUG("ArmMovementsByPoseAlgNode::clean_movementCallback: New Request Received!");
00098
00099
00100
00101
00102
00103 if (req.movement_type == 1) {
00104 movement_poses = this->alg_.get_transformed_poses(req.poses, req.plane_coefficients);
00105 get_poses_markers(req.poses, req.secondary_arm);
00106 if(this->visualization_movement_markers_publisher_.getNumSubscribers())
00107 {
00108 this->visualization_movement_markers_publisher_.publish(this->MarkerArray_msg_);
00109 }
00110 }
00111 else {
00112 movement_poses = this->alg_.get_initial_position();
00113 req.secondary_arm.push_back(false);
00114 }
00115
00116 res.success = true;
00117 this->MarkerArray_msg_.markers.clear();
00118 for (size_t i = 0; i < movement_poses.size(); i++) {
00119 geometry_msgs::PoseStamped target_pose = movement_poses[i];
00120 target_pose = movement_poses[i];
00121 target_pose.pose.orientation = this->alg_.rotate_roll(target_pose.pose.orientation, roll_rotation);
00122 target_pose.pose.orientation = this->alg_.rotate_yaw(target_pose.pose.orientation, yaw_rotation);
00123 target_pose.pose.orientation = this->alg_.rotate_pitch(target_pose.pose.orientation, pitch_rotation);
00124
00125 if (i==0)
00126 ROS_INFO_STREAM("Moving to " << target_pose);
00127 else
00128 ROS_DEBUG_STREAM("Moving to " << target_pose);
00129
00130 if (fake_movements) {
00131 if (i==0)
00132 ROS_WARN_STREAM("Fake movement is active");
00133 }
00134
00135 else if (robot_wam) {
00136 if (req.secondary_arm[i] == false) {
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 get_joints_from_pose_srv_.request.pose = target_pose;
00154 ROS_DEBUG("ArmMovementsByPoseAlgNode:: Sending New Request!");
00155 if (get_joints_from_pose_client_.call(get_joints_from_pose_srv_))
00156 {
00157 ROS_DEBUG("ArmMovementsByPoseAlgNode:: IK ok.");
00158
00159 if (get_joints_from_pose_srv_.response.joints.position.size() > 0) {
00160 move_in_joints_srv_.request.joints = get_joints_from_pose_srv_.response.joints.position;
00161 move_in_joints_srv_.request.velocities = get_wam_movement_speed();
00162 move_in_joints_srv_.request.accelerations = get_wam_movement_speed();
00163 ROS_DEBUG("ArmMovementsByPoseAlgNode:: Sending New Request!");
00164 if (move_in_joints_client_.call(move_in_joints_srv_))
00165 {
00166 ROS_DEBUG_STREAM("ArmMovementsByPoseAlgNode:: Movement sucess: " << move_in_joints_srv_.response.success);
00167 }
00168 else
00169 {
00170 ROS_WARN("ArmMovementsByPoseAlgNode:: Failed to Call Server on topic move_in_joints ");
00171 }
00172 }
00173 else
00174 ROS_WARN("ArmMovementsByPoseAlgNode:: Obtained no joints positions from IK.");
00175 }
00176 else
00177 {
00178 ROS_WARN("ArmMovementsByPoseAlgNode:: Failed to Call Server on topic get_joints_from_pose ");
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 }
00197 else {
00198
00199 ROS_ERROR_STREAM("WAM secondary arm not implemented yet!!!");
00200 ros::Duration(3).sleep();
00201 }
00202 }
00203 else {
00204 if (req.secondary_arm[i] == false) {
00205 if (move_right_armMakeActionRequest(target_pose))
00206 ROS_DEBUG("Movement successful");
00207 else {
00208 res.success = false;
00209 res.too_far_points_indexes.push_back(i);
00210 }
00211 }
00212 else {
00213 if (move_left_armMakeActionRequest(target_pose))
00214 ROS_DEBUG("Movement successful");
00215 else {
00216 res.success = false;
00217 res.too_far_points_indexes.push_back(i);
00218 }
00219 }
00220 }
00221 }
00222
00223
00224
00225
00226
00227
00228 return true;
00229 }
00230
00231
00232
00233
00234 void ArmMovementsByPoseAlgNode::move_right_armDone(const actionlib::SimpleClientGoalState& state, const arm_navigation_msgs::MoveArmResultConstPtr& result)
00235 {
00236 if( state.toString().compare("SUCCEEDED") == 0 )
00237 ROS_INFO("ArmMovementsByPoseAlgNode::move_right_armDone: Goal Achieved!");
00238 else
00239 ROS_INFO("ArmMovementsByPoseAlgNode::move_right_armDone: %s", state.toString().c_str());
00240
00241
00242 }
00243
00244 void ArmMovementsByPoseAlgNode::move_right_armActive()
00245 {
00246
00247 }
00248
00249 void ArmMovementsByPoseAlgNode::move_right_armFeedback(const arm_navigation_msgs::MoveArmFeedbackConstPtr& feedback)
00250 {
00251
00252
00253 bool feedback_is_ok = true;
00254
00255
00256 if( !feedback_is_ok )
00257 {
00258 move_right_arm_client_.cancelGoal();
00259
00260 }
00261 }
00262 void ArmMovementsByPoseAlgNode::move_left_armDone(const actionlib::SimpleClientGoalState& state, const arm_navigation_msgs::MoveArmResultConstPtr& result)
00263 {
00264 if( state.toString().compare("SUCCEEDED") == 0 )
00265 ROS_INFO("ArmMovementsByPoseAlgNode::move_left_armDone: Goal Achieved!");
00266 else
00267 ROS_INFO("ArmMovementsByPoseAlgNode::move_left_armDone: %s", state.toString().c_str());
00268
00269
00270 }
00271
00272 void ArmMovementsByPoseAlgNode::move_left_armActive()
00273 {
00274
00275 }
00276
00277 void ArmMovementsByPoseAlgNode::move_left_armFeedback(const arm_navigation_msgs::MoveArmFeedbackConstPtr& feedback)
00278 {
00279
00280
00281 bool feedback_is_ok = true;
00282
00283
00284 if( !feedback_is_ok )
00285 {
00286 move_left_arm_client_.cancelGoal();
00287
00288 }
00289 }
00290
00291
00292
00293
00294 bool ArmMovementsByPoseAlgNode::move_right_armMakeActionRequest(geometry_msgs::PoseStamped pose_st)
00295 {
00296 ROS_DEBUG("ArmMovementsByPoseAlgNode::move_right_armMakeActionRequest: Starting New Request!");
00297
00298 arm_navigation_msgs::SimplePoseConstraint desired_pose;
00299 std::string group_name;
00300
00301 desired_pose.header.frame_id = pose_st.header.frame_id;
00302 desired_pose.pose = pose_st.pose;
00303
00304 if (robot_wam) {
00305 group_name = "iri_wam";
00306 desired_pose.link_name = "lk_wam7";
00307
00308 desired_pose.absolute_position_tolerance.x = 0.01;
00309 desired_pose.absolute_position_tolerance.y = 0.01;
00310 desired_pose.absolute_position_tolerance.z = 0.01;
00311
00312 desired_pose.absolute_roll_tolerance = 0.2;
00313 desired_pose.absolute_pitch_tolerance = 0.2;
00314 desired_pose.absolute_yaw_tolerance = 0.2;
00315 }
00316 else {
00317 group_name = "right_arm_torso";
00318 desired_pose.link_name = "arm_right_7_link";
00319
00320 desired_pose.absolute_position_tolerance.x = 0.03;
00321 desired_pose.absolute_position_tolerance.y = 0.03;
00322 desired_pose.absolute_position_tolerance.z = 0.03;
00323
00324 desired_pose.absolute_roll_tolerance = 0.3;
00325 desired_pose.absolute_pitch_tolerance = 0.3;
00326 desired_pose.absolute_yaw_tolerance = 0.3;
00327 }
00328
00329 return move_armMakeActionRequest(true, desired_pose, group_name);
00330 }
00331
00332
00333 bool ArmMovementsByPoseAlgNode::move_left_armMakeActionRequest(geometry_msgs::PoseStamped pose_st)
00334 {
00335 ROS_DEBUG("ArmMovementsByPoseAlgNode::move_left_armMakeActionRequest: Starting New Request!");
00336
00337 arm_navigation_msgs::SimplePoseConstraint desired_pose;
00338 std::string group_name;
00339
00340 desired_pose.header.frame_id = pose_st.header.frame_id;
00341 desired_pose.pose = pose_st.pose;
00342
00343 if (robot_wam) {
00344 group_name = "iri_wam";
00345 desired_pose.link_name = "lk_wam7";
00346
00347 desired_pose.absolute_position_tolerance.x = 0.01;
00348 desired_pose.absolute_position_tolerance.y = 0.01;
00349 desired_pose.absolute_position_tolerance.z = 0.01;
00350
00351 desired_pose.absolute_roll_tolerance = 0.2;
00352 desired_pose.absolute_pitch_tolerance = 0.2;
00353 desired_pose.absolute_yaw_tolerance = 0.2;
00354 }
00355 else {
00356 group_name = "left_arm";
00357 desired_pose.link_name = "arm_left_7_link";
00358
00359
00360
00361
00362 desired_pose.pose.orientation = this->alg_.rotate_pitch(pose_st.pose.orientation, M_PI);
00363 desired_pose.pose.position = pose_st.pose.position;
00364
00365 desired_pose.absolute_position_tolerance.x = 0.03;
00366 desired_pose.absolute_position_tolerance.y = 0.03;
00367 desired_pose.absolute_position_tolerance.z = 0.03;
00368
00369 desired_pose.absolute_roll_tolerance = 0.3;
00370 desired_pose.absolute_pitch_tolerance = 0.3;
00371 desired_pose.absolute_yaw_tolerance = 0.3;
00372 }
00373
00374 return move_armMakeActionRequest(false, desired_pose, group_name);
00375 }
00376
00377 bool ArmMovementsByPoseAlgNode::move_armMakeActionRequest(bool right_arm, arm_navigation_msgs::SimplePoseConstraint desired_pose, std::string group_name)
00378 {
00379
00380
00381 actionlib::SimpleActionClient<arm_navigation_msgs::MoveArmAction> *move_arm_client;
00382
00383 if (right_arm)
00384 move_arm_client = &move_right_arm_client_;
00385 else
00386 move_arm_client = &move_left_arm_client_;
00387
00388 move_arm_client->waitForServer();
00389 ROS_DEBUG("ArmMovementsByPoseAlgNode::move_armMakeActionRequest: Server is Available!");
00390
00391 arm_navigation_msgs::MoveArmGoal my_goal;
00392
00393
00394 my_goal.motion_plan_request.group_name=group_name;
00395 my_goal.motion_plan_request.num_planning_attempts = 1;
00396 my_goal.motion_plan_request.allowed_planning_time = ros::Duration(5.0);
00397 my_goal.motion_plan_request.planner_id = std::string("");
00398 my_goal.planner_service_name=std::string("ompl_planning/plan_kinematic_path");
00399 my_goal.motion_plan_request.expected_path_dt = ros::Duration(3.0);
00400
00401 arm_navigation_msgs::addGoalConstraintToMoveArmGoal(desired_pose,my_goal);
00402
00403 if (this->log_movements) {
00404 logfile << group_name << " " << desired_pose.pose.position.x << ", " << desired_pose.pose.position.y << ", " << desired_pose.pose.position.z << ", " << " | " ;
00405 logfile << desired_pose.pose.orientation.x << ", " << desired_pose.pose.orientation.y << ", " <<
00406 desired_pose.pose.orientation.z << ", " << desired_pose.pose.orientation.w << ", " << " | ";
00407 }
00408
00409 if (right_arm)
00410 move_left_arm_client_.sendGoal(my_goal,
00411 boost::bind(&ArmMovementsByPoseAlgNode::move_left_armDone, this, _1, _2),
00412 boost::bind(&ArmMovementsByPoseAlgNode::move_left_armActive, this),
00413 boost::bind(&ArmMovementsByPoseAlgNode::move_left_armFeedback, this, _1));
00414 else
00415 move_right_arm_client_.sendGoal(my_goal,
00416 boost::bind(&ArmMovementsByPoseAlgNode::move_right_armDone, this, _1, _2),
00417 boost::bind(&ArmMovementsByPoseAlgNode::move_right_armActive, this),
00418 boost::bind(&ArmMovementsByPoseAlgNode::move_right_armFeedback, this, _1));
00419
00420 ROS_DEBUG("ArmMovementsByPoseAlgNode::move_armMakeActionRequest: Goal Sent. Wait for Result!");
00421
00422 bool finished_within_time = false;
00423 finished_within_time = move_arm_client->waitForResult(ros::Duration(6.0));
00424 if (!finished_within_time)
00425 {
00426 ROS_WARN_STREAM("Timed out achieving arm goal for " << group_name);
00427 move_arm_client->cancelGoal();
00428 actionlib::SimpleClientGoalState state = move_arm_client->getState();
00429
00430 ROS_WARN_STREAM("After cancel, State is " << state.toString());
00431
00432 if (this->log_movements) {
00433 logfile << "Timed out: " << state.toString() << " and ";
00434 }
00435
00436 move_arm_client->waitForResult(ros::Duration(10.0));
00437 state = move_arm_client->getState();
00438 ROS_WARN_STREAM("After time out, State is " << state.toString());
00439
00440 if (this->log_movements) {
00441 logfile << state.toString() << "\n";
00442 }
00443 }
00444 else
00445 {
00446 actionlib::SimpleClientGoalState state = move_arm_client->getState();
00447 bool success = (state == actionlib::SimpleClientGoalState::SUCCEEDED);
00448 if(success) {
00449 ROS_DEBUG_STREAM("Move " << group_name << " action finished: " << state.toString().c_str());
00450 if (this->log_movements) {
00451 logfile << "Ok: " << state.toString() << "\n";
00452 }
00453 }
00454 else {
00455 ROS_WARN_STREAM("Move " << group_name << " action failed: " << state.toString().c_str());
00456 if (this->log_movements) {
00457 logfile << "Failed: " << state.toString() << "\n";
00458 }
00459 if (state.toString().compare("ABORTED") == 0)
00460 return false;
00461 }
00462 }
00463
00464 return true;
00465 }
00466
00467
00468
00469 void ArmMovementsByPoseAlgNode::addNodeDiagnostics(void)
00470 {
00471 }
00472
00473
00474 int main(int argc,char *argv[])
00475 {
00476 return algorithm_base::main<ArmMovementsByPoseAlgNode>(argc, argv, "arm_movements_by_pose_alg_node");
00477 }
00478
00479
00480 std::vector< double > ArmMovementsByPoseAlgNode::get_wam_movement_speed() {
00481 std::vector< double > res;
00482 for (size_t i = 0; i < 7; i++)
00483 res.push_back(this->robot_movement_speed_);
00484 return res;
00485 }
00486
00487
00488 void ArmMovementsByPoseAlgNode::get_poses_markers(std::vector<geometry_msgs::PoseStamped> poses, std::vector< uint8_t> secondary_arm) {
00489
00490 visualization_msgs::MarkerArray markers_msg;
00491 size_t last_main_idx = 1000, last_secondary_idx = 1000, last_idx;
00492 for (size_t i = 0; i < poses.size(); i++) {
00493
00494 visualization_msgs::Marker marker;
00495 marker.header.frame_id = poses[i].header.frame_id;
00496 marker.ns = "WAM movements";
00497 marker.id = i;
00498 marker.header.stamp = ros::Time();
00499 marker.type = visualization_msgs::Marker::ARROW;
00500 marker.action = visualization_msgs::Marker::ADD;
00501
00502
00503 marker.scale.x = 0.02;
00504 marker.scale.y = 0.02;
00505 marker.scale.z = 0.02;
00506
00507 marker.color.a = 1.0;
00508
00509 if (secondary_arm[i] == false) {
00510 last_idx = last_main_idx;
00511 last_main_idx = i;
00512
00513 marker.color.r = 0.0;
00514 marker.color.g = 1.0;
00515 marker.color.b = 0.0;
00516 }
00517 else {
00518 last_idx = last_secondary_idx;
00519 last_secondary_idx = i;
00520
00521 marker.color.r = 1.0;
00522 marker.color.g = 0.0;
00523 marker.color.b = 0.0;
00524 }
00525
00526 if (last_idx == 1000) {
00527 marker.type = visualization_msgs::Marker::SPHERE;
00528 marker.pose = poses[i].pose;
00529 }
00530 else {
00531 marker.type = visualization_msgs::Marker::ARROW;
00532 marker.points.push_back(poses[last_idx].pose.position);
00533 marker.points.push_back(poses[i].pose.position);
00534 }
00535
00536
00537 markers_msg.markers.push_back(marker);
00538 }
00539
00540
00541 for (size_t i = markers_msg.markers.size(); i < 50; i++) {
00542
00543 visualization_msgs::Marker marker;
00544
00545 marker.header.frame_id = poses[0].header.frame_id;
00546 marker.header.stamp = ros::Time();
00547 marker.ns = "WAM movements";
00548 marker.id = i;
00549 marker.action = visualization_msgs::Marker::ADD;
00550 marker.type = visualization_msgs::Marker::SPHERE;
00551
00552 marker.pose = poses[0].pose;
00553
00554 marker.scale.x = 0.01;
00555 marker.scale.y = 0.01;
00556 marker.scale.z = 0.01;
00557
00558 marker.color.a = 0.0;
00559 marker.color.r = 1.0;
00560 marker.color.g = 1.0;
00561 marker.color.b = 1.0;
00562
00563 markers_msg.markers.push_back(marker);
00564 }
00565
00566 this->MarkerArray_msg_ = markers_msg;
00567 }
00568
00569
00570
00571 void ArmMovementsByPoseAlgNode::node_config_update(Config &config, uint32_t level)
00572 {
00573 this->alg_.lock();
00574
00575 this->fake_movements = config.fake_movements;
00576 this->robot_wam = config.robot_wam;
00577 this->roll_rotation = config.roll_rotation;
00578 this->yaw_rotation = config.yaw_rotation;
00579 this->pitch_rotation = config.pitch_rotation;
00580 this->robot_movement_speed_ = config.robot_movement_speed;
00581
00582 if ( (not this->log_movements) && config.log_movements ) {
00583 logfile.open ("movements.txt");
00584 logfile << "Pose (x, y, z) | Quaternion (x, y, z, w) | Status \n";
00585 }
00586 else if ( this->log_movements && (not config.log_movements) ) {
00587 logfile.close();
00588 }
00589
00590 this->log_movements = config.log_movements;
00591
00592 this->alg_.unlock();
00593 }