move_arm_utils.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *
00035  *********************************************************************/
00036 
00037 /* \author: Matthew Klingensmith, E. Gil Jones */
00038 
00039 //#include <move_arm_warehouse/move_arm_utils.h>
00040 #include "srs_assisted_arm_navigation/move_arm_utils/move_arm_utils.h"
00041 #include <assert.h>
00042 #include <geometric_shapes/shape_operations.h>
00043 #include <planning_environment/util/construct_object.h>
00044 
00045 using namespace std;
00046 using namespace arm_navigation_msgs;
00047 using namespace planning_scene_utils;
00048 using namespace collision_space;
00049 using namespace kinematics_msgs;
00050 using namespace arm_navigation_msgs;
00051 using namespace head_monitor_msgs;
00052 using namespace move_arm_warehouse;
00053 using namespace planning_environment;
00054 using namespace planning_models;
00055 using namespace std_msgs;
00056 using namespace trajectory_msgs;
00057 using namespace visualization_msgs;
00058 using namespace arm_navigation_msgs;
00059 using namespace actionlib;
00060 using namespace control_msgs;
00061 using namespace interactive_markers;
00062 
00063 //#define MARKER_REFRESH_TIME 0.05
00064 #define MARKER_REFRESH_TIME 0.5
00065 #define SAFE_DELETE(x) if(x != NULL) { delete x; x = NULL; }
00066 #define NOT_MOVING_VELOCITY_THRESHOLD 0.005
00067 #define NOT_MOVING_TIME_THRESHOLD 0.5   //seconds
00068 
00069 std_msgs::ColorRGBA makeRandomColor(float brightness, float alpha)
00070 {
00071   std_msgs::ColorRGBA toReturn;
00072   toReturn.a = alpha;
00073 
00074   toReturn.r = ((float)(random()) / (float)RAND_MAX) * (1.0f - brightness) + brightness;
00075   toReturn.g = ((float)(random()) / (float)RAND_MAX) * (1.0f - brightness) + brightness;
00076   toReturn.b = ((float)(random()) / (float)RAND_MAX) * (1.0f - brightness) + brightness;
00077 
00078   toReturn.r = min(toReturn.r, 1.0f);
00079   toReturn.g = min(toReturn.g, 1.0f);
00080   toReturn.b = min(toReturn.b, 1.0f);
00081 
00082   return toReturn;
00083 }
00084 
00086 // PLANNING SCENE DATA
00088 
00089 PlanningSceneData::PlanningSceneData()
00090 {
00091   setId(0);
00092   setTimeStamp(ros::Time(ros::/*WallTime*/Time::now().toSec()));
00093 }
00094 
00095 PlanningSceneData::PlanningSceneData(unsigned int id, const ros::Time& timestamp, const PlanningScene& scene)
00096 {
00097   setId(id);
00098   setPlanningScene(scene);
00099   setTimeStamp(timestamp);
00100 }
00101 
00102 void PlanningSceneData::getRobotState(KinematicState* state)
00103 {
00104   // Actually converts a robot state message to a kinematic state message (possibly very slow)
00105   setRobotStateAndComputeTransforms(getPlanningScene().robot_state, *state);
00106 }
00107 
00109 //TRAJECTORY DATA
00111 
00112 TrajectoryData::TrajectoryData()
00113 {
00114   setCurrentState(NULL);
00115   setSource("");
00116   setGroupName("");
00117   //setColor(makeRandomColor(0.3f, 0.6f));
00118   std_msgs::ColorRGBA green;
00119 
00120   green.r = 0.0;
00121   green.g = 1.0;
00122   green.b = 0.0;
00123   green.a = 0.6;
00124 
00125   setColor(green);
00126 
00127   reset();
00128   setId(0);
00129   showCollisions();
00130   should_refresh_colors_ = false;
00131   has_refreshed_colors_ = true;
00132   refresh_timer_ = ros::Duration(0.0);
00133   trajectory_error_code_.val = 0;
00134   setRenderType(CollisionMesh);
00135   trajectory_render_type_ = Kinematic;
00136 }
00137 
00138 TrajectoryData::TrajectoryData(const unsigned int& id, const string& source, const string& groupName,
00139                   const JointTrajectory& trajectory)
00140 {
00141   setCurrentState(NULL);
00142   setId(id);
00143   setSource(source);
00144   setGroupName(groupName);
00145   setTrajectory(trajectory);
00146   //setColor(makeRandomColor(0.3f, 0.6f));
00147 
00148   std_msgs::ColorRGBA green;
00149 
00150   green.r = 0.0;
00151   green.g = 1.0;
00152   green.b = 0.0;
00153   green.a = 0.6;
00154 
00155   setColor(green);
00156 
00157   reset();
00158   showCollisions();
00159   should_refresh_colors_ = false;
00160   has_refreshed_colors_ = true;
00161   refresh_timer_ = ros::Duration(0.0);
00162   trajectory_error_code_.val = 0;
00163   setRenderType(CollisionMesh);
00164   trajectory_render_type_ = Kinematic;
00165 }
00166 
00167 TrajectoryData::TrajectoryData(const unsigned int& id, const string& source, const string& groupName,
00168                   const JointTrajectory& trajectory, const trajectory_msgs::JointTrajectory& trajectory_error)
00169 {
00170   setCurrentState(NULL);
00171   setId(id);
00172   setSource(source);
00173   setGroupName(groupName);
00174   setTrajectory(trajectory);
00175   setTrajectoryError(trajectory_error);
00176   //setColor(makeRandomColor(0.3f, 0.6f));
00177 
00178   std_msgs::ColorRGBA green;
00179 
00180   green.r = 0.0;
00181   green.g = 1.0;
00182   green.b = 0.0;
00183   green.a = 0.6;
00184 
00185   setColor(green);
00186 
00187   reset();
00188   showCollisions();
00189   should_refresh_colors_ = false;
00190   has_refreshed_colors_ = true;
00191   refresh_timer_ = ros::Duration(0.0);
00192   trajectory_error_code_.val = 0;
00193   setRenderType(CollisionMesh);
00194   trajectory_render_type_ = Kinematic;
00195 }
00196 
00197 void TrajectoryData::advanceToNextClosestPoint(ros::Time time)
00198 {
00199   unsigned int tsize = getTrajectorySize();
00200 
00201   if(tsize == 0 || getCurrentState() == NULL)
00202   {
00203     return;
00204   }
00205 
00206   unsigned int current_point = getCurrentPoint();
00207   unsigned int best_point = current_point;
00208   ros::Duration playback_time_from_start = time - playback_start_time_;
00209 
00210   // Assume strictly increasing timestamps
00211   // Does not seach through all points, only the points after the current_point.
00212   for( unsigned int point_index=current_point; point_index<tsize; point_index++ )
00213   {
00214     if( trajectory_.points[point_index].time_from_start <= playback_time_from_start )
00215     {
00216       best_point = point_index;
00217     }
00218     else
00219     {
00220       break;
00221     }
00222   }
00223   
00224   if( best_point != getCurrentPoint() )
00225   {
00226     setCurrentPoint((int)best_point);
00227   }
00228 
00229   if( getCurrentPoint() >= tsize - 1)
00230   {
00231    setCurrentPoint(tsize-1);
00232    stop();
00233   }
00234 
00235   updateCurrentState();
00236 }
00237 
00238 void TrajectoryData::advanceThroughTrajectory(int step)
00239 {
00240   unsigned int tsize = getTrajectorySize();
00241 
00242   if(tsize == 0 || getCurrentState() == NULL)
00243   {
00244     return;
00245   }
00246 
00247   // Possibly negative point
00248   if((int)getCurrentPoint() + step < 0)
00249   {
00250     setCurrentPoint(0);
00251   }
00252   else
00253   {
00254     setCurrentPoint((int)getCurrentPoint() + step);
00255   }
00256 
00257   // Possibly overstepped the end of the trajectory.
00258   if(getCurrentPoint() >= tsize - 1)
00259   {
00260     setCurrentPoint(tsize - 1);
00261     stop();
00262   }
00263 
00264   // Create new kinematic state.
00265   updateCurrentState();
00266 }
00267 
00268 void TrajectoryData::updateCurrentState()
00269 {
00270   if(getTrajectory().points.size() <= 0)
00271   {
00272     return;
00273   }
00274 
00275   map<string, double> joint_values;
00276   for(unsigned int i = 0; i < getTrajectory().joint_names.size(); i++)
00277   {
00278     joint_values[getTrajectory().joint_names[i]] = getTrajectory().points[getCurrentPoint()].positions[i];
00279   }
00280 
00281   getCurrentState()->setKinematicState(joint_values);
00282 }
00283 
00284 void TrajectoryData::updateCollisionMarkers(CollisionModels* cm_, MotionPlanRequestData& motionPlanRequest,
00285                                             ros::ServiceClient* distance_state_validity_service_client_)
00286 {
00287   if(areCollisionsVisible())
00288   {
00289     const KinematicState* state = getCurrentState();
00290     collision_markers_.markers.clear();
00291     if(state == NULL)
00292     {
00293       return;
00294     }
00295     std_msgs::ColorRGBA bad_color;
00296     bad_color.a = 0.6f;
00297     bad_color.r = 1.0f;
00298     bad_color.g = 0.0f;
00299     bad_color.b = 0.0f;
00300 
00301     collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm_->getCurrentAllowedCollisionMatrix();
00302     cm_->disableCollisionsForNonUpdatedLinks(getGroupName());
00303     // Get all collisions as little red spheres.
00304     cm_->getAllCollisionPointMarkers(*state, collision_markers_, bad_color, ros::Duration(MARKER_REFRESH_TIME));
00305 
00306     const KinematicState::JointStateGroup* jsg = state->getJointStateGroup(getGroupName());
00307     Constraints empty_constraints;
00308     ArmNavigationErrorCodes code;
00309     Constraints path_constraints;
00310     if(motionPlanRequest.hasPathConstraints()) {
00311       path_constraints = motionPlanRequest.getMotionPlanRequest().path_constraints;
00312     }
00313     
00314     // Update validity of the current state.
00315     cm_->isKinematicStateValid(*state, jsg->getJointNames(), code, empty_constraints,
00316                                path_constraints, true);
00317 
00318     cm_->setAlteredAllowedCollisionMatrix(acm);
00319     GetStateValidity::Request val_req;
00320     GetStateValidity::Response val_res;
00321     convertKinematicStateToRobotState(*state, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
00322                                       val_req.robot_state);
00323 
00324     if(distance_state_validity_service_client_ != NULL) {
00325       if(!distance_state_validity_service_client_->call(val_req, val_res))
00326       {
00327         ROS_INFO_STREAM("Something wrong with distance server");
00328       }
00329     }
00330   }
00331 }
00332 
00333 
00334 
00335 
00337 // MOTION PLAN REQUEST DATA
00339 
00340 MotionPlanRequestData::MotionPlanRequestData(const KinematicState* robot_state)
00341 {
00342   setSource("");
00343   setStartColor(makeRandomColor(0.3f, 0.6f));
00344   setGoalColor(makeRandomColor(0.3f, 0.6f));
00345   setStartEditable(true);
00346   setGoalEditable(true);
00347   setHasGoodIKSolution(true, StartPosition);
00348   setHasGoodIKSolution(true, GoalPosition);
00349   setId(0);
00350   setPathConstraints(false);
00351   setConstrainRoll(false);
00352   setConstrainPitch(false);
00353   setConstrainYaw(false);
00354   setRollTolerance(.05);
00355   setPitchTolerance(.05);
00356   setYawTolerance(.05);
00357   name_ = "";
00358   show();
00359   showCollisions();
00360   // Note: these must be registered as StateRegistry entries after this request has been created.
00361   start_state_ = new KinematicState(*robot_state);
00362   goal_state_ = new KinematicState(*robot_state);
00363   should_refresh_colors_ = false;
00364   has_refreshed_colors_ = true;
00365   refresh_timer_ = ros::Duration(0.0);
00366   are_joint_controls_visible_ = false;
00367   setRenderType(CollisionMesh);
00368 }
00369 
00370 MotionPlanRequestData::MotionPlanRequestData(const unsigned int& id, const string& source, const MotionPlanRequest& request,
00371                                              const KinematicState* robot_state,
00372                                              const std::string& end_effector_name)
00373 {
00374   // Note: these must be registered as StateRegistry entries after this request has been created.
00375   start_state_ = new KinematicState(*robot_state);
00376   goal_state_ = new KinematicState(*robot_state);
00377 
00378   setId(id);
00379   setSource(source);
00380   setEndEffectorLink(end_effector_name);
00381   setMotionPlanRequest(request);
00382 
00383   //setStartColor(makeRandomColor(0.3f, 0.6f));
00384   //setGoalColor(makeRandomColor(0.3f, 0.6f));
00385 
00386   std_msgs::ColorRGBA c;
00387 
00388   c.r = 205.0/255;
00389   c.g = c.r;
00390   c.b = 0.0;
00391   c.a = 0.6;
00392 
00393   setStartColor(c);
00394 
00395   c.r = 238.0/255;
00396   c.g = c.r;
00397   c.b = 0.0;
00398   c.a = 0.6;
00399 
00400   setGoalColor(c);
00401 
00402   setStartEditable(true);
00403   setGoalEditable(true);
00404   setHasGoodIKSolution(true, StartPosition);
00405   setHasGoodIKSolution(true, GoalPosition);
00406 
00407   if(request.path_constraints.orientation_constraints.size() > 0) {
00408     const OrientationConstraint& oc = request.path_constraints.orientation_constraints[0];
00409     setPathConstraints(true);
00410     if(oc.absolute_roll_tolerance < 3.0) {
00411       setConstrainRoll(true);
00412       setRollTolerance(oc.absolute_roll_tolerance);
00413     } else {
00414       setConstrainRoll(false);
00415       setRollTolerance(0.05);
00416     }
00417     if(oc.absolute_pitch_tolerance < 3.0) {
00418       setConstrainPitch(true);
00419       setPitchTolerance(oc.absolute_pitch_tolerance);
00420     } else {
00421       setConstrainPitch(false);
00422       setPitchTolerance(0.05);
00423     }
00424     if(oc.absolute_yaw_tolerance < 3.0) {
00425       setConstrainYaw(true);
00426       setYawTolerance(oc.absolute_yaw_tolerance);
00427     } else {
00428       setConstrainYaw(false);
00429       setYawTolerance(0.05);
00430     }
00431   } else {
00432     setPathConstraints(false);
00433     setConstrainRoll(false);
00434     setConstrainPitch(false);
00435     setConstrainYaw(false);
00436     setRollTolerance(.05);
00437     setPitchTolerance(.05);
00438     setYawTolerance(.05);
00439   }
00440   show();
00441   showCollisions();
00442 
00443   should_refresh_colors_ = false;
00444   has_refreshed_colors_ = true;
00445   refresh_timer_ = ros::Duration(0.0);
00446   are_joint_controls_visible_ = false;
00447 
00448   setRenderType(CollisionMesh);
00449 }
00450 
00451 // Kinematic states must be converted to joint constraint message
00452 void MotionPlanRequestData::updateGoalState()
00453 {
00454   setRobotStateAndComputeTransforms(getMotionPlanRequest().start_state, *goal_state_);
00455 
00456   vector<JointConstraint>& constraints = getMotionPlanRequest().goal_constraints.joint_constraints;
00457 
00458   map<string, double> jointValues;
00459   for(size_t i = 0; i < constraints.size(); i++)
00460   {
00461     JointConstraint& constraint = constraints[i];
00462     jointValues[constraint.joint_name] = constraint.position;
00463   }
00464 
00465   goal_state_->setKinematicState(jointValues);
00466 
00467   if(getMotionPlanRequest().goal_constraints.position_constraints.size() > 0 &&
00468      getMotionPlanRequest().goal_constraints.orientation_constraints.size() > 0) {
00469     if(getMotionPlanRequest().goal_constraints.position_constraints[0].link_name != end_effector_link_) {
00470       ROS_WARN_STREAM("Can't apply position constraints to link " 
00471                       << getMotionPlanRequest().goal_constraints.position_constraints[0].link_name
00472                       << " instead of link " << end_effector_link_);
00473       return;
00474     }
00475     ROS_DEBUG_STREAM("Tolerances are " << motion_plan_request_.path_constraints.orientation_constraints[0].absolute_roll_tolerance 
00476                     << " " << motion_plan_request_.path_constraints.orientation_constraints[0].absolute_pitch_tolerance 
00477                     << " " << motion_plan_request_.path_constraints.orientation_constraints[0].absolute_yaw_tolerance);
00478 
00479     geometry_msgs::PoseStamped pose = 
00480       arm_navigation_msgs::poseConstraintsToPoseStamped(getMotionPlanRequest().goal_constraints.position_constraints[0],
00481                                                         getMotionPlanRequest().goal_constraints.orientation_constraints[0]);
00482     tf::Transform end_effector_pose = toBulletTransform(pose.pose);
00483     goal_state_->updateKinematicStateWithLinkAt(end_effector_link_, end_effector_pose);
00484   }
00485 }
00486 
00487 // Kinematic state must be converted to robot state message
00488 void MotionPlanRequestData::updateStartState()
00489 {
00490   setRobotStateAndComputeTransforms(getMotionPlanRequest().start_state, *start_state_);
00491 }
00492 
00493 void MotionPlanRequestData::setJointControlsVisible(bool visible, PlanningSceneEditor* editor)
00494 {
00495   are_joint_controls_visible_ = visible;
00496 
00497   if(visible)
00498   {
00499     if(isStartVisible() && isStartEditable())
00500     {
00501       editor->createJointMarkers(*this, StartPosition);
00502     }
00503     else
00504     {
00505       editor->deleteJointMarkers(*this, StartPosition);
00506     }
00507     if(isEndVisible() && isGoalEditable())
00508     {
00509       editor->createJointMarkers(*this, GoalPosition);
00510     }
00511     else
00512     {
00513       editor->deleteJointMarkers(*this, GoalPosition);
00514     }
00515   }
00516   else
00517   {
00518     editor->deleteJointMarkers(*this, StartPosition);
00519     editor->deleteJointMarkers(*this, GoalPosition);
00520   }
00521 }
00522 
00523 void MotionPlanRequestData::setStartStateValues(std::map<std::string, double>& joint_values)
00524 {
00525   setStateChanged(true);
00526   start_state_->setKinematicState(joint_values);
00527 }
00528 
00529 void MotionPlanRequestData::setGoalStateValues(std::map<std::string, double>& joint_values)
00530 {
00531   setStateChanged(true);
00532   goal_state_->setKinematicState(joint_values);
00533 
00534   getMotionPlanRequest().goal_constraints.joint_constraints.resize(joint_values.size());
00535   int constraints = 0;
00536   for(std::map<std::string, double>::iterator it = joint_values.begin(); it != joint_values.end(); it++, constraints++)
00537   {
00538     getMotionPlanRequest().goal_constraints.joint_constraints[constraints].joint_name = it->first;
00539     getMotionPlanRequest().goal_constraints.joint_constraints[constraints].position = it->second;
00540     getMotionPlanRequest().goal_constraints.joint_constraints[constraints].tolerance_above = 0.001;
00541     getMotionPlanRequest().goal_constraints.joint_constraints[constraints].tolerance_below = 0.001;
00542   }
00543 
00544   if(getMotionPlanRequest().goal_constraints.position_constraints.size() > 0 &&
00545      getMotionPlanRequest().goal_constraints.orientation_constraints.size() > 0) {
00546     if(getMotionPlanRequest().goal_constraints.position_constraints[0].link_name != end_effector_link_) {
00547       ROS_WARN_STREAM("Can't apply position constraints to link " 
00548                       << getMotionPlanRequest().goal_constraints.position_constraints[0].link_name
00549                       << " instead of link " << end_effector_link_);
00550       return;
00551     }
00552     MotionPlanRequest mpr;
00553     setGoalAndPathPositionOrientationConstraints(mpr, GoalPosition);
00554     motion_plan_request_.goal_constraints.position_constraints = mpr.goal_constraints.position_constraints;
00555     motion_plan_request_.goal_constraints.orientation_constraints = mpr.goal_constraints.orientation_constraints;
00556     motion_plan_request_.path_constraints.position_constraints = mpr.path_constraints.position_constraints;
00557     motion_plan_request_.path_constraints.orientation_constraints = mpr.path_constraints.orientation_constraints;
00558 
00559     ROS_DEBUG_STREAM("Tolerances are " << motion_plan_request_.path_constraints.orientation_constraints[0].absolute_roll_tolerance 
00560                      << " " << motion_plan_request_.path_constraints.orientation_constraints[0].absolute_pitch_tolerance 
00561                      << " " << motion_plan_request_.path_constraints.orientation_constraints[0].absolute_yaw_tolerance);
00562   }
00563 }
00564 
00565 void MotionPlanRequestData::setGoalAndPathPositionOrientationConstraints(arm_navigation_msgs::MotionPlanRequest& mpr, 
00566                                                                          planning_scene_utils::PositionType type) const
00567 {
00568   mpr = motion_plan_request_;
00569 
00570   KinematicState* state = NULL;
00571 
00572   if(type == StartPosition)
00573   {
00574     state = start_state_;
00575   }
00576   else
00577   {
00578     state = goal_state_;
00579   }
00580 
00581   std::string world_frame = state->getKinematicModel()->getRoot()->getParentFrameId();
00582 
00583   mpr.goal_constraints.joint_constraints.clear();
00584 
00585   mpr.goal_constraints.position_constraints.resize(1);
00586   mpr.goal_constraints.orientation_constraints.resize(1);    
00587   geometry_msgs::PoseStamped end_effector_wrist_pose;
00588   tf::poseTFToMsg(goal_state_->getLinkState(end_effector_link_)->getGlobalLinkTransform(),
00589                   end_effector_wrist_pose.pose);
00590   end_effector_wrist_pose.header.frame_id = world_frame;
00591   arm_navigation_msgs::poseStampedToPositionOrientationConstraints(end_effector_wrist_pose,
00592                                                                    end_effector_link_,
00593                                                                    mpr.goal_constraints.position_constraints[0],
00594                                                                    mpr.goal_constraints.orientation_constraints[0]);
00595   mpr.path_constraints.orientation_constraints.resize(1);
00596 
00597   arm_navigation_msgs::OrientationConstraint& goal_constraint = mpr.goal_constraints.orientation_constraints[0];
00598   arm_navigation_msgs::OrientationConstraint& path_constraint = mpr.path_constraints.orientation_constraints[0];
00599 
00600   tf::Transform cur = state->getLinkState(end_effector_link_)->getGlobalLinkTransform();
00601   //tfScalar roll, pitch, yaw;
00602   //cur.getBasis().getRPY(roll,pitch,yaw);
00603   goal_constraint.header.frame_id = world_frame;
00604   goal_constraint.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
00605   goal_constraint.link_name = end_effector_link_;
00606   tf::quaternionTFToMsg(cur.getRotation(), goal_constraint.orientation);
00607   goal_constraint.absolute_roll_tolerance = 0.04;
00608   goal_constraint.absolute_pitch_tolerance = 0.04;
00609   goal_constraint.absolute_yaw_tolerance = 0.04;
00610 
00611   path_constraint.header.frame_id = world_frame;
00612   path_constraint.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
00613   path_constraint.link_name = end_effector_link_;
00614   tf::quaternionTFToMsg(cur.getRotation(), path_constraint.orientation);
00615   path_constraint.type = path_constraint.HEADER_FRAME;
00616   if(getConstrainRoll()) {
00617     path_constraint.absolute_roll_tolerance = getRollTolerance();
00618   } else {
00619     path_constraint.absolute_roll_tolerance = M_PI;
00620   }
00621   if(getConstrainPitch()) {
00622     path_constraint.absolute_pitch_tolerance = getPitchTolerance();
00623   } else {
00624     path_constraint.absolute_pitch_tolerance = M_PI;
00625   }
00626   if(getConstrainYaw()) {
00627     path_constraint.absolute_yaw_tolerance = getYawTolerance();
00628   } else {
00629     path_constraint.absolute_yaw_tolerance = M_PI;
00630   }
00631 }
00632 
00633 void MotionPlanRequestData::updateCollisionMarkers(CollisionModels* cm_,
00634                                                    ros::ServiceClient* distance_state_validity_service_client_)
00635 {
00636   if(areCollisionsVisible())
00637   {
00638     const KinematicState* state = getStartState();
00639     collision_markers_.markers.clear();
00640     if(state == NULL)
00641     {
00642       return;
00643     }
00644 
00646     // Start state block
00648     std_msgs::ColorRGBA bad_color;
00649     bad_color.a = 1.0f;
00650     bad_color.r = 1.0f;
00651     bad_color.g = 0.0f;
00652     bad_color.b = 0.0f;
00653     collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm_->getCurrentAllowedCollisionMatrix();
00654     cm_->disableCollisionsForNonUpdatedLinks(getGroupName());
00655     // Get all the collision points as little red spheres.
00656     if(isStartVisible()) {
00657       cm_->getAllCollisionPointMarkers(*state, collision_markers_, bad_color, ros::Duration(MARKER_REFRESH_TIME));
00658       const KinematicState::JointStateGroup* jsg = state->getJointStateGroup(getGroupName());
00659       ArmNavigationErrorCodes code;
00660       Constraints empty_constraints;
00661       // Ensure that the state is valid.
00662       Constraints path_constraints;
00663       if(hasPathConstraints()) {
00664         path_constraints = getMotionPlanRequest().path_constraints;
00665       }
00666       cm_->isKinematicStateValid(*state, jsg->getJointNames(), code, empty_constraints,
00667                                  path_constraints, true);
00668       
00669       GetStateValidity::Request val_req;
00670       GetStateValidity::Response val_res;
00671       convertKinematicStateToRobotState(*state, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
00672                                         val_req.robot_state);
00673       
00674       if(distance_state_validity_service_client_ != NULL) {
00675         if(!distance_state_validity_service_client_->call(val_req, val_res))
00676         {
00677           ROS_INFO_STREAM("Something wrong with distance server");
00678         }
00679       }
00680     }
00682     // End State block
00684     if(isEndVisible()) {
00685       state = getGoalState();
00686       if(state == NULL)
00687       {
00688         return;
00689       }
00690       cm_->getAllCollisionPointMarkers(*state, collision_markers_, bad_color, ros::Duration(MARKER_REFRESH_TIME));
00691       const KinematicState::JointStateGroup* jsg = state->getJointStateGroup(getGroupName());
00692       ArmNavigationErrorCodes code;
00693       Constraints empty_constraints;
00694       Constraints path_constraints;
00695       if(hasPathConstraints()) {
00696         path_constraints = getMotionPlanRequest().path_constraints;
00697       }
00698       cm_->isKinematicStateValid(*state, jsg->getJointNames(), code, empty_constraints,
00699                                  path_constraints, true);
00700 
00701       GetStateValidity::Request val_req;
00702       GetStateValidity::Response val_res;
00703       convertKinematicStateToRobotState(*state, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
00704                                         val_req.robot_state);
00705 
00706       if(distance_state_validity_service_client_ != NULL) {
00707         if(!distance_state_validity_service_client_->call(val_req, val_res))
00708         {
00709           ROS_INFO_STREAM("Something wrong with distance server");
00710         }
00711       }
00712     }
00713     cm_->setAlteredAllowedCollisionMatrix(acm);
00714   }
00715 }
00716 
00717 // Warning: lots of copying going on here.
00718 std::vector<std::string> MotionPlanRequestData::getJointNamesInGoal()
00719 {
00720   std::vector<JointConstraint>& constraints = getMotionPlanRequest().goal_constraints.joint_constraints;
00721   std::vector<std::string> toReturn;
00722 
00723   for(size_t i = 0; i < constraints.size(); i++)
00724   {
00725     JointConstraint& constraint = constraints[i];
00726     toReturn.push_back(constraint.joint_name);
00727   }
00728 
00729   return toReturn;
00730 }
00731 
00732 // Warning: calls getJointNamesInGoal
00733 bool MotionPlanRequestData::isJointNameInGoal(std::string joint)
00734 {
00735   vector<string> joints = getJointNamesInGoal();
00736   for(size_t i = 0; i < joints.size(); i++)
00737   {
00738     if(joints[i] == joint)
00739     {
00740       return true;
00741     }
00742   }
00743 
00744   return false;
00745 }
00746 
00748 // PLANNING SCENE EDITOR
00750 
00751 PlanningSceneEditor::PlanningSceneEditor()
00752 {
00753   setRobotState(NULL, false);
00754   setCollisionModel(NULL, false);
00755   interactive_marker_server_ = NULL;
00756   collision_aware_ik_services_ = NULL;
00757   non_collision_aware_ik_services_ = NULL;
00758   interpolated_ik_services_ = NULL;
00759   selectable_objects_ = NULL;
00760   ik_controllers_ = NULL;
00761   max_collision_object_id_ = 0;
00762   active_planner_index_ = 1;
00763   use_primary_filter_ = true;
00764   string robot_description_name = nh_.resolveName("robot_description", true);
00765   cm_ = new CollisionModels(robot_description_name);
00766 }
00767 
00768 PlanningSceneEditor::PlanningSceneEditor(PlanningSceneParameters& params)
00769 {
00773   params_ = params;
00774   monitor_status_ = idle;
00775   max_collision_object_id_ = 0;
00776   active_planner_index_ = 1;
00777   use_primary_filter_ = true;
00778   last_collision_object_color_.r = 0.7;
00779   last_collision_object_color_.g = 0.7;
00780   last_collision_object_color_.b = 0.7;
00781   last_collision_object_color_.a = 1.0;
00782   last_mesh_object_color_.r = 0.7;
00783   last_mesh_object_color_.g = 0.7;
00784   last_mesh_object_color_.b = 0.7;
00785   last_mesh_object_color_.a = 1.0;
00786 
00787   collision_aware_ik_services_ = new map<string, ros::ServiceClient*> ();
00788   non_collision_aware_ik_services_ = new map<string, ros::ServiceClient*> ();
00789   interpolated_ik_services_ = new map<string, ros::ServiceClient*> ();
00790   selectable_objects_ = new map<string, SelectableObject> ();
00791   ik_controllers_ = new map<string, IKController> ();
00792 
00793   string robot_description_name = nh_.resolveName("robot_description", true);
00794   cm_ = new CollisionModels(robot_description_name);
00795   robot_state_ = new KinematicState(cm_->getKinematicModel());
00796   robot_state_->setKinematicStateToDefault();
00797 
00801   interactive_marker_server_
00802       = new interactive_markers::InteractiveMarkerServer("planning_scene_warehouse_viewer_controls", "", false);
00803 
00804   collision_object_movement_feedback_ptr_
00805       = boost::bind(&PlanningSceneEditor::collisionObjectMovementCallback, this, _1);
00806   collision_object_selection_feedback_ptr_ = boost::bind(&PlanningSceneEditor::collisionObjectSelectionCallback, this,
00807                                                          _1);
00808   joint_control_feedback_ptr_ = boost::bind(&PlanningSceneEditor::JointControllerCallback, this, _1);
00809   ik_control_feedback_ptr_ = boost::bind(&PlanningSceneEditor::IKControllerCallback, this, _1);
00810   attached_collision_object_feedback_ptr_ = boost::bind(&PlanningSceneEditor::attachedCollisionObjectInteractiveCallback, this, _1);
00811 
00815   joint_state_publisher_ = nh_.advertise<sensor_msgs::JointState> ("joint_states", 10);
00816   vis_marker_publisher_ = nh_.advertise<visualization_msgs::Marker> (params.vis_topic_name_, 128);
00817   vis_marker_array_publisher_ = nh_.advertise<visualization_msgs::MarkerArray> (params.vis_topic_name_ + "_array", 128);
00818   move_arm_warehouse_logger_reader_ = new MoveArmWarehouseLoggerReader();
00819 
00820 
00824   // if(params.sync_robot_state_with_gazebo_)
00825   // {
00826   //   ros::service::waitForService("/gazebo/set_model_configuration");
00827   //   ros::service::waitForService(params.list_controllers_service_);
00828   //   ros::service::waitForService(params.load_controllers_service_);
00829   //   ros::service::waitForService(params.unload_controllers_service_);
00830   //   ros::service::waitForService(params.switch_controllers_service_);
00831   //   ros::service::waitForService("/gazebo/pause_physics");
00832   //   ros::service::waitForService("/gazebo/unpause_physics");
00833   //   ros::service::waitForService("/gazebo/set_link_properties");
00834   //   ros::service::waitForService("/gazebo/get_link_properties");
00835   // }
00836 
00837   if(params.left_arm_group_ != "none")
00838   {
00839     ros::service::waitForService(params.left_ik_name_);
00840   }
00841 
00842   if(params.right_arm_group_ != "none")
00843   {
00844     ros::service::waitForService(params.right_ik_name_);
00845   }
00846 
00847   if(params.planner_1_service_name_ != "none")
00848   {
00849     ros::service::waitForService(params.planner_1_service_name_);
00850   }
00851 
00852   if(params.proximity_space_service_name_ != "none")
00853   {
00854     ros::service::waitForService(params.proximity_space_service_name_);
00855   }
00856 
00857   if(params.proximity_space_validity_name_ != "none")
00858   {
00859     ros::service::waitForService(params.proximity_space_validity_name_);
00860   }
00861 
00862   // if(params.sync_robot_state_with_gazebo_)
00863   // {
00864   //   gazebo_joint_state_client_ = nh_.serviceClient<gazebo_msgs::SetModelConfiguration>("/gazebo/set_model_configuration", true);
00865   //   list_controllers_client_ = nh_.serviceClient<pr2_mechanism_msgs::ListControllers>(params.list_controllers_service_, true);
00866   //   load_controllers_client_ = nh_.serviceClient<pr2_mechanism_msgs::LoadController>(params.load_controllers_service_, true);
00867   //   unload_controllers_client_ = nh_.serviceClient<pr2_mechanism_msgs::UnloadController>(params.unload_controllers_service_, true);
00868   //   switch_controllers_client_ = nh_.serviceClient<pr2_mechanism_msgs::SwitchController>(params.switch_controllers_service_, true);
00869   //   pause_gazebo_client_ = nh_.serviceClient<std_srvs::Empty>("/gazebo/pause_physics", true);
00870   //   unpause_gazebo_client_ = nh_.serviceClient<std_srvs::Empty>("/gazebo/unpause_physics", true);
00871   //   set_link_properties_client_ = nh_.serviceClient<gazebo_msgs::SetLinkProperties>("/gazebo/set_link_properties", true);
00872   //   get_link_properties_client_ = nh_.serviceClient<gazebo_msgs::GetLinkProperties>("/gazebo/get_link_properties", true);
00873   // }
00874 
00875   if(params.left_arm_group_ != "none")
00876   {
00877     left_ik_service_client_ = nh_.serviceClient<GetConstraintAwarePositionIK> (params.left_ik_name_, true);
00878     non_coll_left_ik_service_client_ = nh_.serviceClient<GetPositionIK> (params.non_coll_left_ik_name_, true);
00879   }
00880   if(params.right_arm_group_ != "none")
00881   {
00882     right_ik_service_client_ = nh_.serviceClient<GetConstraintAwarePositionIK> (params.right_ik_name_, true);
00883     non_coll_right_ik_service_client_ = nh_.serviceClient<GetPositionIK> (params.non_coll_right_ik_name_, true);
00884   }
00885 
00886   if(params.planner_1_service_name_ != "none")
00887   {
00888     planning_1_service_client_ = nh_.serviceClient<GetMotionPlan> (params.planner_1_service_name_, true);
00889   }
00890 
00891   if(params.planner_2_service_name_ != "none")
00892   {
00893     planning_2_service_client_ = nh_.serviceClient<GetMotionPlan> (params.planner_2_service_name_, true);
00894   }
00895 
00896   if(params.trajectory_filter_1_service_name_ != "none")
00897   {
00898     trajectory_filter_1_service_client_
00899         = nh_.serviceClient<FilterJointTrajectoryWithConstraints> (params.trajectory_filter_1_service_name_);
00900   }
00901 
00902   if(params.trajectory_filter_2_service_name_ != "none")
00903   {
00904     trajectory_filter_2_service_client_
00905         = nh_.serviceClient<FilterJointTrajectoryWithConstraints> (params.trajectory_filter_2_service_name_);
00906   }
00907 
00908   if(params.proximity_space_service_name_ != "none")
00909   {
00910     distance_aware_service_client_ = nh_.serviceClient<GetMotionPlan> (params.proximity_space_service_name_, true);
00911   }
00912 
00913   if(params.proximity_space_validity_name_ != "none")
00914   {
00915     distance_state_validity_service_client_
00916         = nh_.serviceClient<GetStateValidity> (params.proximity_space_validity_name_, true);
00917   }
00918 
00919   if(params.proximity_space_planner_name_ != "none")
00920   {
00921     collision_proximity_planner_client_ = nh_.serviceClient<GetMotionPlan> (params.proximity_space_planner_name_, true);
00922   }
00923 
00924   set_planning_scene_diff_client_ = nh_.serviceClient<SetPlanningSceneDiff> (params.set_planning_scene_diff_name_);
00925 
00926   if(params.use_robot_data_)
00927   {
00928     if(params_.right_arm_group_ != "none")
00929     {
00930       arm_controller_map_[params_.right_arm_group_] = new actionlib::SimpleActionClient<
00931           control_msgs::FollowJointTrajectoryAction>(params.execute_right_trajectory_, true);
00932 
00933       while(ros::ok() && !arm_controller_map_[params_.right_arm_group_]->waitForServer(ros::Duration(1.0)))
00934       {
00935         ROS_INFO("Waiting for the right_joint_trajectory_action server to come up.");
00936       }
00937     }
00938 
00939     if(params.left_arm_group_ != "none")
00940     {
00941       arm_controller_map_[params.left_arm_group_] = new actionlib::SimpleActionClient<
00942           control_msgs::FollowJointTrajectoryAction>(params.execute_left_trajectory_, true);
00943 
00944       while(ros::ok() && !arm_controller_map_[params.left_arm_group_]->waitForServer(ros::Duration(1.0)))
00945       {
00946         ROS_INFO("Waiting for the left_joint_trajectory_action server to come up.");
00947       }
00948     }
00949   }
00950 
00951   if(params.left_arm_group_ != "none")
00952   {
00953     (*collision_aware_ik_services_)[params.left_ik_link_] = &left_ik_service_client_;
00954   }
00955 
00956   if(params.right_arm_group_ != "none")
00957   {
00958     (*collision_aware_ik_services_)[params.right_ik_link_] = &right_ik_service_client_;
00959   }
00960 
00961   if(params.left_arm_group_ != "none")
00962   {
00963     (*non_collision_aware_ik_services_)[params.left_ik_link_] = &non_coll_left_ik_service_client_;
00964   }
00965 
00966   if(params.left_arm_group_ != "none")
00967   {
00968     (*non_collision_aware_ik_services_)[params.right_ik_link_] = &non_coll_right_ik_service_client_;
00969   }
00970 
00971   if(params.right_interpolate_service_name_ != "none")
00972   {
00973     while(ros::ok() && !ros::service::waitForService(params.right_interpolate_service_name_, ros::Duration(1.0)))
00974     {
00975       ROS_INFO_STREAM("Waiting for the right interpolation server to come up: " << params.right_interpolate_service_name_);
00976     }
00977     right_interpolate_service_client_ = nh_.serviceClient<GetMotionPlan> (params.right_interpolate_service_name_, true);
00978     (*interpolated_ik_services_)[params.right_ik_link_] = &right_interpolate_service_client_;
00979   }
00980   if(params.left_interpolate_service_name_ != "none")
00981   {
00982     while(ros::ok() && !ros::service::waitForService(params.left_interpolate_service_name_, ros::Duration(1.0)))
00983     {
00984       ROS_INFO("Waiting for the left interpolation server to come up.");
00985     }
00986     left_interpolate_service_client_ = nh_.serviceClient<GetMotionPlan> (params.left_interpolate_service_name_, true);
00987     (*interpolated_ik_services_)[params.left_ik_link_] = &left_interpolate_service_client_;
00988   }
00989 
00993   menu_entry_maps_["Collision Object"] = MenuEntryMap();
00994   menu_entry_maps_["Collision Object Selection"] = MenuEntryMap();
00995   menu_entry_maps_["IK Control"] = MenuEntryMap();
00996   registerMenuEntry("Collision Object Selection", "Delete", collision_object_selection_feedback_ptr_);
00997   registerMenuEntry("Collision Object Selection", "Select", collision_object_selection_feedback_ptr_);
00998   registerMenuEntry("Collision Object", "Delete", collision_object_movement_feedback_ptr_);
00999   registerMenuEntry("Collision Object", "Deselect", collision_object_movement_feedback_ptr_);
01000   registerMenuEntry("Collision Object", "Attach", collision_object_movement_feedback_ptr_);
01001   registerMenuEntry("Attached Collision Object", "Detach", attached_collision_object_feedback_ptr_);
01002   MenuHandler::EntryHandle resize_mode_entry = registerMenuEntry("Collision Object", "Resize Mode", collision_object_movement_feedback_ptr_);
01003   MenuHandler::EntryHandle off = menu_handler_map_["Collision Object"].insert(resize_mode_entry, "Off", collision_object_movement_feedback_ptr_);
01004   menu_entry_maps_["Collision Object"]["Off"] = off;
01005   menu_handler_map_["Collision Object"].setCheckState(off, MenuHandler::CHECKED);
01006   last_resize_handle_ = off;
01007   MenuHandler::EntryHandle grow = menu_handler_map_["Collision Object"].insert(resize_mode_entry, "Grow", collision_object_movement_feedback_ptr_);
01008   menu_entry_maps_["Collision Object"]["Grow"] = grow;
01009   menu_handler_map_["Collision Object"].setCheckState(grow, MenuHandler::UNCHECKED);
01010   MenuHandler::EntryHandle shrink = menu_handler_map_["Collision Object"].insert(resize_mode_entry, "Shrink", collision_object_movement_feedback_ptr_);
01011   menu_handler_map_["Collision Object"].setCheckState(shrink, MenuHandler::UNCHECKED);
01012   menu_entry_maps_["Collision Object"]["Shrink"] = shrink;
01013   //registerMenuEntry("IK Control", "Map to Robot State", ik_control_feedback_ptr_);
01014   //registerMenuEntry("IK Control", "Map from Robot State", ik_control_feedback_ptr_);
01015   //registerMenuEntry("IK Control", "Map to Other Orientation", ik_control_feedback_ptr_);
01016   //registerMenuEntry("IK Control", "Go To Last Good State", ik_control_feedback_ptr_);
01017   //registerMenuEntry("IK Control", "Randomly Perturb", ik_control_feedback_ptr_);
01018   //registerMenuEntry("IK Control", "Plan New Trajectory", ik_control_feedback_ptr_);
01019   //registerMenuEntry("IK Control", "Filter Last Trajectory", ik_control_feedback_ptr_);
01020   //registerMenuEntry("IK Control", "Delete Request", ik_control_feedback_ptr_);
01021 
01022   /*if(params_.use_robot_data_)
01023   {
01024     registerMenuEntry("IK Control", "Execute Last Trajectory", ik_control_feedback_ptr_);
01025   }*/
01026 
01030   if(params.use_robot_data_)
01031   {
01032     joint_state_subscriber_ = nh_.subscribe("joint_states", 25, &PlanningSceneEditor::jointStateCallback, this);
01033   }
01034 
01037   if(params.use_robot_data_)
01038   {
01039     r_arm_controller_state_subscriber_ = nh_.subscribe("r_arm_controller/state", 25, &PlanningSceneEditor::jointTrajectoryControllerStateCallback, this);
01040     l_arm_controller_state_subscriber_ = nh_.subscribe("l_arm_controller/state", 25, &PlanningSceneEditor::jointTrajectoryControllerStateCallback, this);
01041   }
01042 }
01043 
01044 void PlanningSceneEditor::jointStateCallback(const sensor_msgs::JointStateConstPtr& joint_state)
01045 {
01046   if(robot_state_ == NULL) return;
01047 
01048   std::map<std::string, double> joint_state_map;
01049   std::map<std::string, double> joint_velocity_map;
01050 
01051   if (joint_state->position.size() != joint_state->velocity.size() ) {
01052 
01053           ROS_WARN_ONCE("Problem with joint states! Position field size is %d, velocity %d. This warning will appear once.",(int)joint_state->position.size(),(int)joint_state->velocity.size());
01054 
01055           return;
01056 
01057   }
01058 
01059   //message already been validated in kmsm
01060   for(unsigned int i = 0; i < joint_state->position.size(); ++i)
01061   {
01062         joint_state_map[joint_state->name[i]] = joint_state->position[i];
01063         joint_velocity_map[joint_state->name[i]] = joint_state->velocity[i];
01064   }
01065 
01066   //getting base transform
01067   lockScene();
01068   std::vector<planning_models::KinematicState::JointState*>& joint_state_vector = robot_state_->getJointStateVector();  
01069   for(std::vector<planning_models::KinematicState::JointState*>::iterator it = joint_state_vector.begin();
01070       it != joint_state_vector.end();
01071       it++) {
01072     bool tfSets = false;
01073     //see if we need to update any transforms
01074     std::string parent_frame_id = (*it)->getParentFrameId();
01075     std::string child_frame_id = (*it)->getChildFrameId();
01076     if(!parent_frame_id.empty() && !child_frame_id.empty()) {
01077       std::string err;
01078       ros::Time tm;
01079       tf::StampedTransform transf;
01080       bool ok = false;
01081       if (transform_listener_.getLatestCommonTime(parent_frame_id, child_frame_id, tm, &err) == tf::NO_ERROR) {
01082         ok = true;
01083         try
01084         {
01085           transform_listener_.lookupTransform(parent_frame_id, child_frame_id, tm, transf);
01086         }
01087         catch(tf::TransformException& ex)
01088         {
01089           ROS_ERROR("Unable to lookup transform from %s to %s.  Exception: %s", parent_frame_id.c_str(), child_frame_id.c_str(), ex.what());
01090           ok = false;
01091         }
01092       } else {
01093         ROS_DEBUG("Unable to lookup transform from %s to %s: no common time.", parent_frame_id.c_str(), child_frame_id.c_str());
01094         ok = false;
01095       }
01096       if(ok) {
01097         tfSets = (*it)->setJointStateValues(transf);
01098       }
01099     }
01100     (*it)->setJointStateValues(joint_state_map);
01101   }
01102   robot_state_->updateKinematicLinks();
01103   robot_state_->getKinematicStateValues(robot_state_joint_values_);
01104   unlockScene();
01105 }
01106 
01107 void PlanningSceneEditor::jointTrajectoryControllerStateCallback(const pr2_controllers_msgs::JointTrajectoryControllerStateConstPtr& joint_controller_state)
01108 {
01109   trajectory_msgs::JointTrajectoryPoint actual = joint_controller_state->actual;
01110   trajectory_msgs::JointTrajectoryPoint error = joint_controller_state->error;
01111   bool robot_stopped = true;
01112 
01113   // Records trajectory if currently executing.
01114   if(monitor_status_ == Executing || monitor_status_ == WaitingForStop)
01115   {
01116     // Filter out the joints of the other group/arm
01117     if( logged_trajectory_.joint_names[0] != joint_controller_state->joint_names[0] )
01118     {
01119       return;
01120     }
01121 
01122     trajectory_msgs::JointTrajectoryPoint point;
01123     trajectory_msgs::JointTrajectoryPoint error_point;
01124 
01125     // note-- could record accelerations as well, if we wanted to.
01126     unsigned int num_joints = logged_trajectory_.joint_names.size();
01127     point.positions.resize(num_joints);
01128     point.velocities.resize(num_joints);
01129     error_point.positions.resize(num_joints);
01130     error_point.velocities.resize(num_joints);
01131 
01132     for(unsigned int i = 0; i < num_joints; i++)
01133     {
01134       point.positions[i] = actual.positions[i];
01135       point.velocities[i] = actual.velocities[i];
01136       error_point.positions[i] = error.positions[i];
01137       error_point.velocities[i] = error.velocities[i];
01138     }
01139 
01140     ros::Duration time_from_start = ros::Time(ros::Time::now().toSec()) - logged_trajectory_start_time_;
01141     point.time_from_start = time_from_start;
01142     error_point.time_from_start = time_from_start;
01143 
01144     logged_trajectory_.points.push_back(point);
01145     logged_trajectory_controller_error_.points.push_back(error_point);
01146 
01147     // Stop recording if the robot has stopped for a period of time.
01148     if(monitor_status_ == WaitingForStop )
01149     {
01150       for(unsigned int i = 0; i < num_joints; i++)
01151       {
01152         if( point.velocities[i] > NOT_MOVING_VELOCITY_THRESHOLD )
01153         {
01154           robot_stopped = false;
01155         }
01156       }
01157 
01158       if( robot_stopped )
01159       {
01160         if( (ros::Time::now()-time_of_last_moving_notification_).toSec() >= NOT_MOVING_TIME_THRESHOLD )
01161         {
01162           armHasStoppedMoving();
01163         }
01164       }
01165       else
01166       {
01167         time_of_last_moving_notification_ = ros::Time::now();
01168       }
01169     }
01170   }
01171 }
01172 
01173 PlanningSceneEditor::~PlanningSceneEditor()
01174 {
01175   SAFE_DELETE(robot_state_);
01176   SAFE_DELETE(interactive_marker_server_);
01177   SAFE_DELETE(selectable_objects_);
01178   SAFE_DELETE(ik_controllers_);
01179   SAFE_DELETE(collision_aware_ik_services_);
01180   SAFE_DELETE(non_collision_aware_ik_services_);
01181   SAFE_DELETE(interpolated_ik_services_);
01182 }
01183 
01184 void PlanningSceneEditor::makeSelectableAttachedObjectFromPlanningScene(const arm_navigation_msgs::PlanningScene& scene,
01185                                                                         arm_navigation_msgs::AttachedCollisionObject& att)
01186 {
01187   std_msgs::ColorRGBA color;
01188   color.r = 0.5;
01189   color.g = 0.5;
01190   color.b = 0.5;
01191   color.a = 1.0;
01192   
01193   //need to get this in the right frame for adding the collision object
01194   //intentionally copying object
01195   arm_navigation_msgs::CollisionObject coll = att.object;
01196   {
01197     planning_models::KinematicState state(cm_->getKinematicModel());
01198     planning_environment::setRobotStateAndComputeTransforms(scene.robot_state,
01199                                                             state);
01200     geometry_msgs::PoseStamped ret_pose;
01201     cm_->convertPoseGivenWorldTransform(*robot_state_,
01202                                         cm_->getWorldFrameId(),
01203                                         coll.header,
01204                                         coll.poses[0],
01205                                         ret_pose);
01206     coll.header = ret_pose.header;
01207     coll.poses[0] = ret_pose.pose;
01208   }
01209   createSelectableMarkerFromCollisionObject(coll, coll.id, "", color);
01210   attachCollisionObject(att.object.id,
01211                         att.link_name,
01212                         att.touch_links);
01213   changeToAttached(att.object.id);
01214 }
01215 
01216 void PlanningSceneEditor::setCurrentPlanningScene(std::string planning_scene_name, bool loadRequests, bool loadTrajectories)
01217 {
01218   if(planning_scene_map_.find(planning_scene_name) == planning_scene_map_.end()) {
01219     ROS_INFO_STREAM("Haven't got a planning scene for name " << planning_scene_name << " so can't set");
01220     return;
01221   }
01222 
01223   lockScene();
01224 
01225   // Need to do this to clear old scene state.
01226   deleteKinematicStates();
01227 
01228   if(planning_scene_name == "")
01229   {
01230     ROS_INFO_STREAM("No new scene");
01231     current_planning_scene_name_ = planning_scene_name;
01232     unlockScene();
01233     return;
01234   }
01235 
01239   for(map<string, SelectableObject>::iterator it = selectable_objects_->begin(); it != selectable_objects_->end(); it++)
01240   {
01241     interactive_marker_server_->erase(it->second.selection_marker_.name);
01242     interactive_marker_server_->erase(it->second.control_marker_.name);
01243   }
01244   selectable_objects_->clear();
01245 
01246   for(map<string, IKController>::iterator it = (*ik_controllers_).begin(); it != (*ik_controllers_).end(); it++)
01247   {
01248     interactive_marker_server_->erase(it->second.end_controller_.name);
01249     interactive_marker_server_->erase(it->second.start_controller_.name);
01250   }
01251   interactive_marker_server_->applyChanges();
01252 
01253   (*ik_controllers_).clear();
01254 
01255 
01256   std::vector<unsigned int> mprDeletions;
01260   for(map<string, MotionPlanRequestData>::iterator it = motion_plan_map_.begin(); it != motion_plan_map_.end(); it ++)
01261   {
01262     mprDeletions.push_back(it->second.getId());
01263   }
01264 
01265   std::vector<unsigned int> erased_trajectories;
01266   for(size_t i = 0; i < mprDeletions.size(); i++)
01267   {
01268     deleteMotionPlanRequest(mprDeletions[i], erased_trajectories);
01269   } 
01270 
01271   motion_plan_map_.clear();
01272 
01273   if(!trajectory_map_.empty()) {
01274     ROS_INFO_STREAM("Some trajectories orphaned");
01275   }
01276 
01280   current_planning_scene_name_ = planning_scene_name;
01281   PlanningSceneData& scene = planning_scene_map_[planning_scene_name];
01282   error_map_.clear();
01283   scene.getPipelineStages().clear();
01284   scene.getErrorCodes().clear();
01285   getPlanningSceneOutcomes(scene.getId(), scene.getPipelineStages(), scene.getErrorCodes(), error_map_);
01286   
01290   for(size_t i = 0; i < scene.getPlanningScene().collision_objects.size(); i++)
01291   {
01292     //otherwise might be associated with an attached collision object
01293     std_msgs::ColorRGBA color;
01294     color.r = 0.5;
01295     color.g = 0.5;
01296     color.b = 0.5;
01297     color.a = 1.0;
01298     createSelectableMarkerFromCollisionObject(scene.getPlanningScene().collision_objects[i], scene.getPlanningScene().collision_objects[i].id, scene.getPlanningScene().collision_objects[i].id, color);
01299   }
01300 
01304   for(size_t i = 0; i < scene.getPlanningScene().attached_collision_objects.size(); i++)
01305   {
01306     makeSelectableAttachedObjectFromPlanningScene(scene.getPlanningScene(),
01307                                                   scene.getPlanningScene().attached_collision_objects[i]);
01308   }
01309   
01313   if(loadRequests)
01314   {
01315     vector<unsigned int> ids;
01316     vector<string> stageNames;
01317     vector<MotionPlanRequest> requests;
01318     move_arm_warehouse_logger_reader_->getAssociatedMotionPlanRequests("", scene.getId(), ids, stageNames, requests);
01319     unsigned int planning_scene_id = getPlanningSceneIdFromName(planning_scene_name);
01320     initMotionPlanRequestData(planning_scene_id, ids, stageNames, requests);
01321     
01322     for(size_t j = 0; j < ids.size(); j++)
01323     {
01324       MotionPlanRequest req;
01325       unsigned int motion_id = ids[j];
01326 
01327       MotionPlanRequestData& motion_data = motion_plan_map_[getMotionPlanRequestNameFromId(motion_id)];
01328       motion_data.setPlanningSceneId(planning_scene_id);
01329 
01330       std::vector<JointTrajectory> trajs;
01331       std::vector<JointTrajectory> traj_cnt_errs;
01332       std::vector<string> sources;
01333       std::vector<unsigned int> traj_ids;
01334       std::vector<ros::Duration> durations;
01335       std::vector<int32_t> errors;
01336       
01340       if(loadTrajectories)
01341       {
01342         move_arm_warehouse_logger_reader_->getAssociatedJointTrajectories("", scene.getId(), motion_id, trajs, traj_cnt_errs, sources,
01343                                                                           traj_ids, durations, errors);
01344 
01345         for(size_t k = 0; k < trajs.size(); k++)
01346         {
01347           TrajectoryData trajectory_data;
01348           trajectory_data.setTrajectory(trajs[k]);
01349           trajectory_data.setTrajectoryError(traj_cnt_errs[k]);
01350           trajectory_data.setSource(sources[k]);
01351           trajectory_data.setId(traj_ids[k]);
01352           trajectory_data.setMotionPlanRequestId(motion_data.getId());
01353           trajectory_data.setPlanningSceneId(planning_scene_id);
01354           trajectory_data.setVisible(true);
01355           trajectory_data.setGroupName(motion_data.getGroupName());
01356           trajectory_data.setDuration(durations[k]);
01357           trajectory_data.trajectory_error_code_.val = errors[k];
01358 
01359           motion_data.addTrajectoryId(trajectory_data.getId());
01360 
01361           if(hasTrajectory(motion_data.getName(),
01362                             trajectory_data.getName())) {
01363             ROS_WARN_STREAM("Motion plan request " << motion_data.getName() << " really shouldn't already have a trajectory " << trajectory_data.getName());
01364           }
01365 
01366           trajectory_map_[motion_data.getName()][trajectory_data.getName()] = trajectory_data;
01367           //playTrajectory(motion_data,trajectory_map_[motion_data.getName()][trajectory_data.getName()]);
01368         }
01369       }
01370     }
01371     sendPlanningScene(scene);
01372     // if(loadRequests) {
01373     //   for(map<string, MotionPlanRequestData>::iterator it = motion_plan_map_.begin(); it != motion_plan_map_.end(); it ++)
01374     //   {
01375     //     if(it->second->hasPathConstraints()) {
01376     //       solveIKForEndEffectorPose(it->second,
01377     //                                 GoalPosition,
01378                                     
01379     //                                 }
01380     //     }
01381     //   }
01382   }
01383 
01384   interactive_marker_server_->applyChanges();
01385   unlockScene();
01386 }
01387 
01388 void PlanningSceneEditor::getTrajectoryMarkers(visualization_msgs::MarkerArray& arr)
01389 {
01390   // For each trajectory. 
01391   for(map<string, map<string, TrajectoryData> >::iterator it = trajectory_map_.begin(); it != trajectory_map_.end(); it++)
01392   {
01393     for(map<string, TrajectoryData>::iterator it2 = it->second.begin(); it2 != it->second.end(); it2++) {
01394       // If a trajectory is playing, then show the closest matching pose in the trajectory.
01395       if(it2->second.isPlaying())
01396       {
01397         if(it2->second.getTrajectoryRenderType() == Kinematic)
01398         {
01399           // Assume that timestamps are invalid, and render based on index
01400           it2->second.advanceThroughTrajectory(2);
01401         }
01402         else
01403         {
01404           // assume timestamps are fine, and render based on time.
01405           it2->second.advanceToNextClosestPoint(ros::Time::now());
01406         }
01407 
01408         if( it->first == selected_motion_plan_name_ &&
01409             it2->first == selected_trajectory_name_ )
01410         {
01411           selectedTrajectoryCurrentPointChanged( it2->second.getCurrentPoint() );
01412         }
01413       }
01414 
01415       if(it2->second.getCurrentState() == NULL)
01416       {
01417         continue;
01418       }
01419 
01420       it2->second.updateCurrentState();
01421       
01422       // When the color of a trajectory has changed, we have to wait for
01423       // a few milliseconds before the change is registered in rviz.
01424       if(it2->second.shouldRefreshColors())
01425       {
01426         it2->second.refresh_timer_ += marker_dt_;
01427         
01428         if(it2->second.refresh_timer_.toSec() > MARKER_REFRESH_TIME + 0.05)
01429         {
01430           it2->second.setHasRefreshedColors(true);
01431           it2->second.refresh_timer_ = ros::Duration(0.0);
01432         }
01433       }
01434       else
01435       {
01436         if(it2->second.isVisible())
01437         {
01438           ROS_DEBUG_STREAM("Should be showing trajectory for " <<
01439                            it->first << " " << it2->first
01440                            << it2->second.getGroupName() << 
01441                            " " << (cm_->getKinematicModel()->getModelGroup(it2->second.getGroupName()) == NULL));
01442           const vector<const KinematicModel::LinkModel*>& updated_links =
01443             cm_->getKinematicModel()->getModelGroup(it2->second.getGroupName())->getUpdatedLinkModels();
01444 
01445           vector<string> lnames;
01446           lnames.resize(updated_links.size());
01447           for(unsigned int i = 0; i < updated_links.size(); i++)
01448           {
01449             lnames[i] = updated_links[i]->getName();
01450           }
01451 
01452           // Links in group
01453           switch(it2->second.getRenderType())
01454           {
01455           case VisualMesh:
01456             cm_->getRobotMarkersGivenState(*(it2->second.getCurrentState()), arr, it2->second.getColor(),
01457                                            getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())+" "+it2->first + "_trajectory", 
01458                                            ros::Duration(MARKER_REFRESH_TIME), 
01459                                            &lnames, 1.0, false);
01460             // Bodies held by robot
01461             cm_->getAttachedCollisionObjectMarkers(*(it2->second.getCurrentState()), arr, 
01462                                                    getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())+" "+it2->first + "_trajectory", 
01463                                                    it2->second.getColor(), ros::Duration(MARKER_REFRESH_TIME), false, &lnames);
01464 
01465             break;
01466           case CollisionMesh:
01467             cm_->getRobotMarkersGivenState(*(it2->second.getCurrentState()), arr, it2->second.getColor(),
01468                                            getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())+" "+it2->first + "_trajectory", 
01469                                            ros::Duration(MARKER_REFRESH_TIME), 
01470                                            &lnames, 1.0, true);
01471             cm_->getAttachedCollisionObjectMarkers(*(it2->second.getCurrentState()), arr, 
01472                                                    getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())+" "+it2->first + "_trajectory", 
01473                                                    it2->second.getColor(), ros::Duration(MARKER_REFRESH_TIME), false, &lnames);
01474             break;
01475           case PaddingMesh:
01476             cm_->getRobotPaddedMarkersGivenState((const KinematicState&)*(it2->second.getCurrentState()),
01477                                                  arr,
01478                                                  it2->second.getColor(),
01479                                                  getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())+" "+it2->first + "_trajectory", 
01480                                                  ros::Duration(MARKER_REFRESH_TIME)*2.0,
01481                                                  (const vector<string>*)&lnames);
01482             cm_->getAttachedCollisionObjectMarkers(*(it2->second.getCurrentState()), arr,
01483                                                    getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())+" "+it2->first + "_trajectory", 
01484                                                    it2->second.getColor(), ros::Duration(MARKER_REFRESH_TIME)*2.0, true, &lnames);
01485             break;
01486           }
01487 
01488         }
01489       }
01490 
01491 
01495       if(it2->second.areCollisionsVisible() && it2->second.isVisible())
01496       {
01497 
01498         if(motion_plan_map_.find(getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())) == motion_plan_map_.end()) {
01499           ROS_INFO_STREAM("Making empty mprs in trajectory");
01500           continue;
01501         }
01502 
01503         // Update markers
01504         if(it2->second.hasStateChanged())
01505         {
01506           if(params_.proximity_space_validity_name_ == "none")
01507           {
01508             it2->second.updateCollisionMarkers(cm_, motion_plan_map_[getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())],
01509                                                NULL);
01510           
01511           } else {
01512             it2->second.updateCollisionMarkers(cm_, motion_plan_map_[getMotionPlanRequestNameFromId(it2->second.getMotionPlanRequestId())],
01513                                                &distance_state_validity_service_client_);
01514           
01515           }
01516           it2->second.setStateChanged(false);
01517         }
01518 
01519         // Then add them to the global array
01520         for(size_t i = 0; i < it2->second.getCollisionMarkers().markers.size(); i++)
01521         {
01522           collision_markers_.markers.push_back(it2->second.getCollisionMarkers().markers[i]);
01523         }
01524       }
01525     }
01526   }
01527 }
01528 
01529 void PlanningSceneEditor::getMotionPlanningMarkers(visualization_msgs::MarkerArray& arr)
01530 {
01531   vector<string> removals;
01532 
01533   // For each motion plan request ...
01534   for(map<string, MotionPlanRequestData>::iterator it = motion_plan_map_.begin(); it != motion_plan_map_.end(); it++)
01535   {
01536     if(it->second.getName() == "") {
01537       ROS_WARN("Someone's making empty stuff");
01538     }
01539     MotionPlanRequestData& data = it->second;
01540 
01541     // TODO: Find out why this happens.
01542     if(motion_plan_map_.find(it->first) == motion_plan_map_.end() || data.getName() == "")
01543     {
01544       ROS_WARN("Attempting to publish non-existant motion plan request %s Erasing this request!", it->first.c_str());
01545       removals.push_back(it->first);
01546       continue;
01547     }
01548 
01549     // TODO: Find out why this happens.
01550     if(data.getStartState() == NULL || data.getGoalState() == NULL)
01551     {
01552       return;
01553     }
01554 
01555     // When a motion plan request has its colors changed,
01556     // we must wait a few milliseconds before rviz registers the change.
01557     if(data.shouldRefreshColors())
01558     {
01559       data.refresh_timer_ += marker_dt_;
01560 
01561       if(data.refresh_timer_.toSec() > MARKER_REFRESH_TIME + 0.05)
01562       {
01563         data.setHasRefreshedColors(true);
01564         data.refresh_timer_ = ros::Duration(0.0);
01565       }
01566     }
01567     else
01568     {
01569       std_msgs::ColorRGBA fail_color_c; // collision
01570       std_msgs::ColorRGBA fail_color_o; // out of reach
01571 
01572       fail_color_c.a = 0.6;
01573       fail_color_c.r = 1.0;
01574       fail_color_c.g = 0.0;
01575       fail_color_c.b = 0.0;
01576 
01577       fail_color_o.a = 0.6;
01578           fail_color_o.r = 0.6;
01579           fail_color_o.g = 0.0;
01580           fail_color_o.b = 0.0;
01581 
01585       if(data.isStartVisible())
01586       {
01587         const vector<const KinematicModel::LinkModel*>& updated_links =
01588             cm_->getKinematicModel()->getModelGroup(data.getMotionPlanRequest().group_name)->getUpdatedLinkModels();
01589 
01590         vector<string> lnames;
01591         lnames.resize(updated_links.size());
01592         for(unsigned int i = 0; i < updated_links.size(); i++)
01593         {
01594           lnames[i] = updated_links[i]->getName();
01595         }
01596 
01597 
01598         // If we have a good ik solution, publish with the normal color
01599         // else use bright red.
01600         std_msgs::ColorRGBA col;
01601         if(data.hasGoodIKSolution(StartPosition))
01602         {
01603           col = data.getStartColor();
01604           //data.getCollisionMarkers().markers.clear(); // TODO check if it works as expected (it will probably work only for collision aware ik??)
01605           ROS_DEBUG("We have good IK, publish markers with normal color.");
01606         } else {
01607           col = fail_color_o;
01608 
01609         }
01610         
01611         if (data.getCollisionMarkers().markers.size() != 0) {
01612 
01613                 // in collision, set different color
01614                 col = fail_color_c;
01615 
01616         }
01617 
01618         switch(data.getRenderType())
01619         {
01620         case VisualMesh:
01621           cm_->getRobotMarkersGivenState(*(data.getStartState()), arr, col,
01622                                          it->first + "_start", ros::Duration(MARKER_REFRESH_TIME), 
01623                                          &lnames, 1.0, false);
01624           // Bodies held by robot
01625           cm_->getAttachedCollisionObjectMarkers(*(data.getStartState()), arr, it->first + "_start",
01626                                                  col, ros::Duration(MARKER_REFRESH_TIME), false, &lnames);
01627           
01628           ROS_DEBUG("using VisualMesh");
01629 
01630           break;
01631         case CollisionMesh:
01632           cm_->getRobotMarkersGivenState(*(data.getStartState()), arr, col,
01633                                          it->first + "_start", ros::Duration(MARKER_REFRESH_TIME), 
01634                                          &lnames, 1.0, true);
01635           cm_->getAttachedCollisionObjectMarkers(*(data.getStartState()), arr, it->first + "_start",
01636                                                  col, ros::Duration(MARKER_REFRESH_TIME), false, &lnames);
01637           break;
01638         case PaddingMesh:
01639           cm_->getRobotPaddedMarkersGivenState(*(data.getStartState()),
01640                                                arr,
01641                                                col,
01642                                                it->first + "_start",
01643                                                ros::Duration(MARKER_REFRESH_TIME),
01644                                                (const vector<string>*)&lnames);
01645           cm_->getAttachedCollisionObjectMarkers(*(data.getStartState()), arr, it->first + "_start",
01646                                                  col, ros::Duration(MARKER_REFRESH_TIME), true, &lnames);
01647           break;
01648         }
01649       }
01650 
01654       if(data.isEndVisible())
01655       {
01656         const vector<const KinematicModel::LinkModel*>& updated_links =
01657             cm_->getKinematicModel()->getModelGroup(data.getMotionPlanRequest().group_name)->getUpdatedLinkModels();
01658 
01659         vector<string> lnames;
01660         lnames.resize(updated_links.size());
01661         for(unsigned int i = 0; i < updated_links.size(); i++)
01662         {
01663           lnames[i] = updated_links[i]->getName();
01664         }
01665 
01666         std_msgs::ColorRGBA col;
01667         if(data.hasGoodIKSolution(GoalPosition))
01668         {
01669           col = data.getGoalColor();
01670           //data.getCollisionMarkers().markers.clear(); // TODO check if it works as expected (it will probably work only for collision aware ik??)
01671           ROS_DEBUG("We have good IK, publish (goal pos) markers with normal color.");
01672         } else {
01673           col = fail_color_o;
01674         }
01675         
01676         if (data.getCollisionMarkers().markers.size() != 0) {
01677 
01678                         // in collision, set different color
01679                         col = fail_color_c;
01680 
01681                 }
01682 
01683         switch(data.getRenderType())
01684         {
01685         case VisualMesh:
01686           cm_->getRobotMarkersGivenState(*(data.getGoalState()), arr, col,
01687                                          it->first + "_Goal", ros::Duration(MARKER_REFRESH_TIME),
01688                                          &lnames, 1.0, false);
01689 
01690           ROS_DEBUG("Using VisualMesh.");
01691 
01692           // Bodies held by robot
01693           cm_->getAttachedCollisionObjectMarkers(*(data.getGoalState()), arr, it->first + "_Goal",
01694                                                  col, ros::Duration(MARKER_REFRESH_TIME), false, &lnames);
01695           
01696           break;
01697         case CollisionMesh:
01698           cm_->getRobotMarkersGivenState(*(data.getGoalState()), arr, col,
01699                                          it->first + "_Goal", ros::Duration(MARKER_REFRESH_TIME),
01700                                          &lnames, 1.0, true);
01701           cm_->getAttachedCollisionObjectMarkers(*(data.getGoalState()), arr, it->first + "_Goal",
01702                                                  col, ros::Duration(MARKER_REFRESH_TIME), false, &lnames);
01703           break;
01704         case PaddingMesh:
01705           cm_->getRobotPaddedMarkersGivenState(*(data.getGoalState()),
01706                                                arr,
01707                                                col,
01708                                                it->first + "_Goal",
01709                                                ros::Duration(MARKER_REFRESH_TIME),
01710                                                (const vector<string>*)&lnames);
01711           cm_->getAttachedCollisionObjectMarkers(*(data.getGoalState()), arr, it->first + "_Goal",
01712                                                  col, ros::Duration(MARKER_REFRESH_TIME), true, &lnames);
01713           break;
01714         }
01715       }
01716     }
01717 
01721     if(it->second.areCollisionsVisible() && (it->second.isStartVisible() || it->second.isEndVisible()))
01722     {
01723       // Update collision markers
01724       if(it->second.hasStateChanged())
01725       {
01726         if(params_.proximity_space_validity_name_ == "none")
01727         {
01728           it->second.updateCollisionMarkers(cm_, NULL);
01729         } else {
01730           it->second.updateCollisionMarkers(cm_, &distance_state_validity_service_client_);
01731         }
01732         it->second.setStateChanged(false);
01733       }
01734 
01735       // Add them to the global array.
01736       for(size_t i = 0; i < it->second.getCollisionMarkers().markers.size(); i++)
01737       {
01738         collision_markers_.markers.push_back(it->second.getCollisionMarkers().markers[i]);
01739       }
01740     }
01741 
01742   }
01743 
01747   for(size_t i = 0; i < removals.size(); i++)
01748   {
01749     motion_plan_map_.erase(removals[i]);
01750   }
01751 }
01752 
01753 void PlanningSceneEditor::createMotionPlanRequest(const planning_models::KinematicState& start_state,
01754                                                   const planning_models::KinematicState& end_state, 
01755                                                   const std::string& group_name,
01756                                                   const std::string& end_effector_name, 
01757                                                   const unsigned int& planning_scene_id, 
01758                                                   const bool from_robot_state,
01759                                                   unsigned int& motion_plan_id_out)
01760 
01761 {
01762   MotionPlanRequest motion_plan_request;
01763   motion_plan_request.group_name = group_name;
01764   motion_plan_request.num_planning_attempts = 3; // TODO make it configurable
01765   motion_plan_request.allowed_planning_time = ros::Duration(5.0); // TODO make it configurable
01766   const KinematicState::JointStateGroup* jsg = end_state.getJointStateGroup(group_name);
01767   motion_plan_request.goal_constraints.joint_constraints.resize(jsg->getJointNames().size());
01768 
01769   // Must convert kinematic state to robot state message.
01770   vector<double> joint_values;
01771   jsg->getKinematicStateValues(joint_values);
01772   for(unsigned int i = 0; i < jsg->getJointNames().size(); i++)
01773   {
01774     motion_plan_request.goal_constraints.joint_constraints[i].joint_name = jsg->getJointNames()[i];
01775     motion_plan_request.goal_constraints.joint_constraints[i].position = joint_values[i];
01776     motion_plan_request.goal_constraints.joint_constraints[i].tolerance_above = 0.001;
01777     motion_plan_request.goal_constraints.joint_constraints[i].tolerance_below = 0.001;
01778   }
01779 
01780   // Create start state from kinematic state passed in if robot data is being used
01781   if(!from_robot_state)
01782   {
01783     convertKinematicStateToRobotState(start_state, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
01784                                       motion_plan_request.start_state);
01785   }
01786   // Otherwise, use the current robot state.
01787   else
01788   {
01789     convertKinematicStateToRobotState(*robot_state_, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
01790                                       motion_plan_request.start_state);
01791   }
01792 
01793   if(planning_scene_map_.find(getPlanningSceneNameFromId(planning_scene_id)) == planning_scene_map_.end()) {
01794     ROS_WARN_STREAM("Creating new planning scene for motion plan request - bad!!");
01795   }
01796 
01797   PlanningSceneData& planningSceneData = planning_scene_map_[getPlanningSceneNameFromId(planning_scene_id)];
01798   
01799   // Turn the motion plan request message into a MotionPlanData
01800   unsigned int id = planningSceneData.getNextMotionPlanRequestId();
01801   motion_plan_request.group_name = group_name;
01802   MotionPlanRequestData data(id, "Planner", motion_plan_request, robot_state_, end_effector_name);
01803   data.setGoalEditable(true);
01804   if(from_robot_state)
01805   {
01806     data.setStartEditable(false);
01807   }
01808 
01809   // Book keeping for kinematic state storage
01810   StateRegistry start;
01811   start.state = data.getStartState();
01812   start.source = "Motion Plan Request Data Start create request";
01813   StateRegistry end;
01814   end.state = data.getGoalState();
01815   end.source = "Motion Plan Request Data End from create request";
01816   states_.push_back(start);
01817   states_.push_back(end);
01818 
01819   motion_plan_map_[getMotionPlanRequestNameFromId(id)] = data;
01820   data.setPlanningSceneId(planning_scene_id);
01821 
01822   // Add request to the planning scene
01823   planningSceneData.addMotionPlanRequestId(id);
01824 
01825   motion_plan_id_out = data.getId();
01826   createIkControllersFromMotionPlanRequest(data, false);
01827   sendPlanningScene(planningSceneData);
01828 }
01829 
01830 bool PlanningSceneEditor::planToKinematicState(const KinematicState& state, const string& group_name, const string& end_effector_name,
01831                                                unsigned int& trajectory_id_out, unsigned int& planning_scene_id)
01832 {
01833   unsigned int motion_plan_id;
01834   createMotionPlanRequest(*robot_state_, state, group_name, end_effector_name, planning_scene_id,
01835                           false, motion_plan_id);
01836   MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(motion_plan_id)];
01837   return planToRequest(data, trajectory_id_out);
01838 }
01839 
01840 bool PlanningSceneEditor::planToRequest(const std::string& request_id, unsigned int& trajectory_id_out)
01841 {
01842   return planToRequest(motion_plan_map_[request_id], trajectory_id_out);
01843 }
01844 
01845 bool PlanningSceneEditor::planToRequest(MotionPlanRequestData& data, unsigned int& trajectory_id_out)
01846 {
01847   GetMotionPlan::Request plan_req;
01848   ros::ServiceClient* planner;
01849   std::string source;
01850   if(active_planner_index_ == 3) {
01851     source = "Interpolator";
01852     arm_navigation_msgs::MotionPlanRequest req;
01853     req.group_name = data.getGroupName();
01854     req.num_planning_attempts = 1;
01855     req.allowed_planning_time = ros::Duration(10.0);
01856     req.start_state = data.getMotionPlanRequest().start_state;
01857     req.start_state.multi_dof_joint_state.child_frame_ids[0] = data.getEndEffectorLink();
01858     req.start_state.multi_dof_joint_state.frame_ids[0] = cm_->getWorldFrameId();
01859     tf::poseTFToMsg(data.getStartState()->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform(), 
01860                     req.start_state.multi_dof_joint_state.poses[0]);
01861     geometry_msgs::PoseStamped end_effector_wrist_pose;
01862     tf::poseTFToMsg(data.getGoalState()->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform(), 
01863                     end_effector_wrist_pose.pose);
01864     end_effector_wrist_pose.header.frame_id = cm_->getWorldFrameId();
01865     req.goal_constraints.position_constraints.resize(1);
01866     req.goal_constraints.orientation_constraints.resize(1);
01867     
01868     arm_navigation_msgs::poseStampedToPositionOrientationConstraints(end_effector_wrist_pose,
01869                                                                      data.getEndEffectorLink(),
01870                                                                      req.goal_constraints.position_constraints[0],
01871                                                                      req.goal_constraints.orientation_constraints[0]);
01872     
01873     plan_req.motion_plan_request = req;
01874     planner = (*interpolated_ik_services_)[data.getEndEffectorLink()];
01875   } else {
01876     source = "Planner";
01877     if( active_planner_index_ == 2 )
01878     {
01879       planner = &planning_2_service_client_;
01880     }
01881     else
01882     {
01883       planner = &planning_1_service_client_;
01884     }
01885 
01886     if(data.hasPathConstraints()) {
01887       data.setGoalAndPathPositionOrientationConstraints(plan_req.motion_plan_request, GoalPosition);
01888       plan_req.motion_plan_request.group_name += "_cartesian";
01889     } else {
01890       plan_req.motion_plan_request = data.getMotionPlanRequest();
01891       plan_req.motion_plan_request.goal_constraints.position_constraints.clear();
01892       plan_req.motion_plan_request.goal_constraints.orientation_constraints.clear();
01893       plan_req.motion_plan_request.path_constraints.position_constraints.clear();
01894       plan_req.motion_plan_request.path_constraints.orientation_constraints.clear();
01895     }
01896     plan_req.motion_plan_request.allowed_planning_time = ros::Duration(10.0);
01897   }
01898   GetMotionPlan::Response plan_res;
01899 
01900   if(!planner->call(plan_req, plan_res))
01901   {
01902     ROS_INFO("Something wrong with planner client");
01903     planCallback(plan_res.error_code);
01904     return false;
01905   }
01906 
01907   unsigned int id = data.getNextTrajectoryId();
01908 
01909   TrajectoryData trajectory_data;
01910   trajectory_data.setTrajectory(plan_res.trajectory.joint_trajectory);
01911   trajectory_data.setGroupName(data.getMotionPlanRequest().group_name);
01912   trajectory_data.setMotionPlanRequestId(data.getId());
01913   trajectory_id_out = id;
01914   trajectory_data.setPlanningSceneId(data.getPlanningSceneId());
01915   trajectory_data.setId(trajectory_id_out);
01916   trajectory_data.setSource(source);
01917   trajectory_data.setDuration(plan_res.planning_time);
01918   trajectory_data.setVisible(true);
01919   trajectory_data.setTrajectoryRenderType(Kinematic);
01920   trajectory_data.play();
01921 
01922   bool success = (plan_res.error_code.val == plan_res.error_code.SUCCESS);
01923   trajectory_data.trajectory_error_code_.val = plan_res.error_code.val;
01924   lockScene();
01925   data.addTrajectoryId(id);
01926   trajectory_map_[data.getName()][trajectory_data.getName()] = trajectory_data;
01927   unlockScene();
01928 
01929   if(success) {
01930     selected_trajectory_name_ = trajectory_data.getName();
01931   } else {
01932     ROS_INFO_STREAM("Bad planning error code " << plan_res.error_code.val);
01933   }
01934   planCallback(trajectory_data.trajectory_error_code_);
01935   return success;
01936 }
01937 
01938 // void PlanningSceneEditor::determineOrientationConstraintsGivenState(const MotionPlanRequestData& mpr,
01939 //                                                                     const KinematicState& state,
01940 //                                                                     OrientationConstraint& goal_constraint,
01941 //                                                                     OrientationConstraint& path_constraint)
01942 // {
01943 //   tf::Transform cur = state.getLinkState(mpr.getEndEffectorLink())->getGlobalLinkTransform();
01944 //   //tfScalar roll, pitch, yaw;
01945 //   //cur.getBasis().getRPY(roll,pitch,yaw);
01946 //   goal_constraint.header.frame_id = cm_->getWorldFrameId();
01947 //   goal_constraint.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
01948 //   goal_constraint.link_name = mpr.getEndEffectorLink();
01949 //   tf::quaternionTFToMsg(cur.getRotation(), goal_constraint.orientation);
01950 //   goal_constraint.absolute_roll_tolerance = 0.04;
01951 //   goal_constraint.absolute_pitch_tolerance = 0.04;
01952 //   goal_constraint.absolute_yaw_tolerance = 0.04;
01953 
01954 //   path_constraint.header.frame_id = cm_->getWorldFrameId();
01955 //   path_constraint.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
01956 //   path_constraint.link_name = mpr.getEndEffectorLink();
01957 //   tf::quaternionTFToMsg(cur.getRotation(), path_constraint.orientation);
01958 //   path_constraint.type = path_constraint.HEADER_FRAME;
01959 //   if(mpr.getConstrainRoll()) {
01960 //     path_constraint.absolute_roll_tolerance = mpr.getRollTolerance();
01961 //   } else {
01962 //     path_constraint.absolute_roll_tolerance = M_PI;
01963 //   }
01964 //   if(mpr.getConstrainPitch()) {
01965 //     path_constraint.absolute_pitch_tolerance = mpr.getPitchTolerance();
01966 //   } else {
01967 //     path_constraint.absolute_pitch_tolerance = M_PI;
01968 //   }
01969 //   if(mpr.getConstrainYaw()) {
01970 //     path_constraint.absolute_yaw_tolerance = mpr.getYawTolerance();
01971 //   } else {
01972 //     path_constraint.absolute_yaw_tolerance = M_PI;
01973 //   }
01974 // }
01975 
01976 void PlanningSceneEditor::printTrajectoryPoint(const vector<string>& joint_names, const vector<double>& joint_values)
01977 {
01978   for(unsigned int i = 0; i < joint_names.size(); i++)
01979   {
01980     ROS_INFO_STREAM("Joint name " << joint_names[i] << " value " << joint_values[i]);
01981   }
01982 }
01983 
01984 bool PlanningSceneEditor::filterTrajectory(MotionPlanRequestData& requestData, TrajectoryData& trajectory,
01985                                            unsigned int& filter_id)
01986 {
01987   FilterJointTrajectoryWithConstraints::Request filter_req;
01988   FilterJointTrajectoryWithConstraints::Response filter_res;
01989 
01990   // Filter request has to have robot state message filled
01991   convertKinematicStateToRobotState(*robot_state_, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
01992                                     filter_req.start_state);
01993 
01994   filter_req.trajectory = trajectory.getTrajectory();
01995   filter_req.group_name = trajectory.getGroupName();
01996   filter_req.goal_constraints = requestData.getMotionPlanRequest().goal_constraints;
01997   filter_req.path_constraints = requestData.getMotionPlanRequest().path_constraints;
01998   filter_req.allowed_time = ros::Duration(5.0); // TODO make it configurable
01999 
02000   /*std::vector<std::string> joint_names = trajectory.getTrajectory().joint_names;
02001 
02002   // altering joint limits here doesn't make sense -> trajectory filter ignores this...
02003   for (unsigned int i = 0; i < joint_names.size(); i++) {
02004 
02005           JointLimits lim;
02006 
02007           ROS_INFO("Tuning filter joint limits for %s joint.",joint_names[i].c_str());
02008 
02009           bool tmp;
02010 
02011           ros::param::param<bool>("/trajectory_filter_server/joint_limits/" + joint_names[i] + "/has_acceleration_limits",tmp,true);
02012           lim.has_acceleration_limits = (uint8_t)tmp;
02013           ros::param::param<bool>("/trajectory_filter_server/joint_limits/" + joint_names[i] + "/has_position_limits",tmp,true);
02014           lim.has_position_limits = (uint8_t)tmp;
02015           ros::param::param<bool>("/trajectory_filter_server/joint_limits/" + joint_names[i] + "/has_velocity_limits",tmp,true);
02016           lim.has_velocity_limits = (uint8_t)tmp;
02017 
02018           ros::param::param<double>("/trajectory_filter_server/joint_limits/" + joint_names[i] + "/min_position",lim.min_position,0.0);
02019           ros::param::param<double>("/trajectory_filter_server/joint_limits/" + joint_names[i] + "/max_position",lim.max_position,0.0);
02020 
02021           ros::param::param<double>("/trajectory_filter_server/joint_limits/" + joint_names[i] + "/max_velocity",lim.max_velocity,0.0);
02022           ros::param::param<double>("/trajectory_filter_server/joint_limits/" + joint_names[i] + "/max_acceleration",lim.max_acceleration,0.0);
02023 
02024           lim.min_position += 0.05;
02025           lim.max_position -= 0.05;
02026 
02027           lim.joint_name = joint_names[i];
02028 
02029           filter_req.limits.push_back(lim);
02030 
02031   }*/
02032 
02033   // Select the filter
02034   ros::ServiceClient* trajectory_filter_service_client;
02035   if( use_primary_filter_ )
02036   {
02037     trajectory_filter_service_client = &trajectory_filter_1_service_client_;
02038   }
02039   else
02040   {
02041     trajectory_filter_service_client = &trajectory_filter_2_service_client_;
02042   }
02043 
02044   // Time the filtering
02045   ros::Time startTime = ros::Time(ros::/*WallTime*/Time::now().toSec());
02046   if(!trajectory_filter_service_client->call(filter_req, filter_res))
02047   {
02048     ROS_INFO("Problem with trajectory filter");
02049     filterCallback(filter_res.error_code);
02050     return false;
02051   }
02052 
02053   unsigned int id = requestData.getNextTrajectoryId();
02054 
02055   // Convert returned joint trajectory to TrajectoryData
02056   TrajectoryData data(id, "Trajectory Filterer", trajectory.getGroupName(),
02057                       filter_res.trajectory);
02058   data.setPlanningSceneId(requestData.getPlanningSceneId());
02059   data.setMotionPlanRequestId(requestData.getId());
02060   data.setDuration(ros::Time(ros::/*WallTime*/Time::now().toSec()) - startTime);
02061   data.setTrajectoryRenderType(Temporal);
02062   requestData.addTrajectoryId(id);
02063 
02064   data.trajectory_error_code_.val = filter_res.error_code.val;
02065   trajectory_map_[requestData.getName()][data.getName()] = data;
02066   filter_id = data.getId();
02067   data.setVisible(true);
02068   data.play();
02069   selected_trajectory_name_ = data.getName();
02070 
02071   bool success = (filter_res.error_code.val == filter_res.error_code.SUCCESS);
02072   if(!success) {
02073     ROS_INFO_STREAM("Bad trajectory_filter error code " << filter_res.error_code.val);
02074   } else {
02075     playTrajectory(requestData, trajectory_map_[requestData.getName()][data.getName()]);
02076   }
02077   filterCallback(filter_res.error_code);
02078   return success;
02079 }
02080 
02081 void PlanningSceneEditor::updateJointStates()
02082 {
02083 
02084   // If using robot data, the joint states are handled by whatever is
02085   // running on the robot (presumably)
02086   if(params_.use_robot_data_)
02087   {
02088     return;
02089   }
02090 
02091   sensor_msgs::JointState msg;
02092   msg.header.frame_id = cm_->getWorldFrameId();
02093   msg.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
02094 
02095   vector<KinematicState::JointState*> jointStates = getRobotState()->getJointStateVector();
02096 
02097   map<string, double> stateMap;
02098   getRobotState()->getKinematicStateValues(stateMap);
02099   getRobotState()->setKinematicState(stateMap);
02100 
02101   // Send each joint state out as part of a message to the robot state publisher.
02102   for(size_t i = 0; i < jointStates.size(); i++)
02103   {
02104     KinematicState::JointState* state = jointStates[i];
02105     msg.name.push_back(state->getName());
02106 
02107     // Assume that joints only have one value.
02108     if(state->getJointStateValues().size() > 0)
02109     {
02110       msg.position.push_back(state->getJointStateValues()[0]);
02111     }
02112     else
02113     {
02114       msg.position.push_back(0.0f);
02115     }
02116   }
02117   joint_state_publisher_.publish(msg);
02118 
02119 }
02120 
02121 void PlanningSceneEditor::sendMarkers()
02122 {
02123   marker_dt_ = (ros::Time::now() - last_marker_start_time_);
02124   last_marker_start_time_ = ros::Time::now();
02125   lockScene();
02126 
02127   sendTransformsAndClock();
02128   visualization_msgs::MarkerArray arr;
02129 
02130   getTrajectoryMarkers(arr);
02131   getMotionPlanningMarkers(arr);
02132 
02133   vis_marker_array_publisher_.publish(arr);
02134   vis_marker_array_publisher_.publish(collision_markers_);
02135   collision_markers_.markers.clear();
02136 
02137   ROS_DEBUG("markers are published (%u)",(unsigned int)arr.markers.size());
02138 
02139   unlockScene();
02140 }
02141 
02142 bool PlanningSceneEditor::getPlanningSceneOutcomes(const unsigned int id,
02143                                                    vector<string>& pipeline_stages,
02144                                                    vector<ArmNavigationErrorCodes>& error_codes,
02145                                                    map<std::string, ArmNavigationErrorCodes>& error_map)
02146 {
02147   if(!move_arm_warehouse_logger_reader_->getAssociatedOutcomes("", id, pipeline_stages, error_codes))
02148   {
02149     ROS_DEBUG_STREAM("No outcome associated with planning scene");
02150     return false;
02151   }
02152 
02153   // Fill error map for convenience
02154   for(size_t i = 0; i < error_codes.size(); i++)
02155   {
02156     error_map[pipeline_stages[i]] = error_codes[i];
02157   }
02158 
02159   return true;
02160 }
02161 
02162 std::string PlanningSceneEditor::createNewPlanningScene()
02163 {
02164   lock_scene_.lock();
02165 
02166   if(robot_state_ == NULL)
02167   {
02168     robot_state_ = new KinematicState(cm_->getKinematicModel());
02169   } else {
02170     if(robot_state_joint_values_.empty()) {
02171       robot_state_->setKinematicStateToDefault();
02172     } else {
02173       robot_state_->setKinematicState(robot_state_joint_values_);
02174     }
02175   }
02176   
02177   PlanningSceneData data;
02178   data.setId(generateNewPlanningSceneId());
02179   data.setTimeStamp(ros::Time(ros::/*WallTime*/Time::now().toSec()));
02180 
02181   convertKinematicStateToRobotState(*robot_state_, data.getTimeStamp(), cm_->getWorldFrameId(),
02182                                     data.getPlanningScene().robot_state);
02183   //end_effector_state_ = planning_state_;
02184 
02185   std::vector<string> collisionObjects;
02186 
02187   for(map<string, SelectableObject>::iterator it = selectable_objects_->begin(); it != selectable_objects_->end(); it++)
02188   {
02189     collisionObjects.push_back(it->first);
02190   }
02191 
02192   //this also does attached collision objects
02193   for(size_t i = 0; i < collisionObjects.size(); i++)
02194   {
02195     deleteCollisionObject(collisionObjects[i]);
02196   }
02197 
02198   selectable_objects_->clear();
02199 
02200   char hostname[256];
02201   gethostname(hostname, 256);
02202   data.setHostName(std::string(hostname));
02203 
02204   planning_scene_map_[data.getName()] = data;
02205   lock_scene_.unlock();
02206 
02207   updateJointStates();
02208 
02209   return data.getName();
02210 }
02211 
02212 void PlanningSceneEditor::loadAllWarehouseData()
02213 {
02214   max_collision_object_id_ = 0;
02215 
02216   motion_plan_map_.clear();
02217   trajectory_map_.clear();
02218   planning_scene_map_.clear();
02219   vector<ros::Time> planning_scene_times;
02220   vector<unsigned int> planning_scene_ids;
02221   getAllPlanningSceneTimes(planning_scene_times,
02222                            planning_scene_ids);
02223   
02224   ROS_INFO_STREAM("Starting load");
02225 
02226   // For each planning scene
02227   for(size_t i = 0; i < planning_scene_times.size(); i++)
02228   {
02229     ros::Time& time = planning_scene_times[i];
02230     // Load it
02231     loadPlanningScene(time, planning_scene_ids[i]);
02232 
02233     ROS_DEBUG_STREAM("Got planning scene " << planning_scene_ids[i] << " from warehouse.");
02234     PlanningSceneData& data = planning_scene_map_[getPlanningSceneNameFromId(planning_scene_ids[i])];
02235     data.getPipelineStages().clear();
02236     data.getErrorCodes().clear();
02237     getPlanningSceneOutcomes(planning_scene_ids[i], data.getPipelineStages(), data.getErrorCodes(), error_map_);
02238     onPlanningSceneLoaded((int)i, (int)planning_scene_times.size());
02239   }
02240 
02241   error_map_.clear();
02242 }
02243 
02244 void PlanningSceneEditor::savePlanningScene(PlanningSceneData& data, bool copy)
02245 {
02246   PlanningScene* actual_planning_scene;
02247   unsigned int id_to_push;
02248 
02249   std::string name_to_push = "";
02250 
02251   warehouse_data_loaded_once_ = false;
02252   
02253   //overwriting timestamp
02254   data.setTimeStamp(ros::Time(ros::/*WallTime*/Time::now().toSec()));
02255 
02256   // Have to do this in case robot state was corrupted by sim time.
02257   if(!copy) {
02258     bool has;
02259     has = move_arm_warehouse_logger_reader_->hasPlanningScene(data.getHostName(),
02260                                                               data.getId());
02261     //ROS_INFO_STREAM("Has is " << has);
02262 
02263     if(has) {
02264       move_arm_warehouse_logger_reader_->removePlanningSceneAndAssociatedDataFromWarehouse(data.getHostName(),
02265                                                                                            data.getId());
02266     }
02267     id_to_push = data.getId();
02268 
02269     actual_planning_scene = &(data.getPlanningScene());
02270 
02271     ROS_INFO("Saving Planning Scene %s", data.getName().c_str());
02272   } else {
02273     //force reload
02274     PlanningSceneData ndata = data;
02275     ndata.setId(generateNewPlanningSceneId());
02276     id_to_push = ndata.getId();
02277     ROS_INFO("Copying Planning Scene %s to %s", data.getName().c_str(), ndata.getName().c_str());
02278     planning_scene_map_[ndata.getName()] = ndata;
02279     name_to_push = ndata.getName();
02280     actual_planning_scene = &planning_scene_map_[ndata.getName()].getPlanningScene();
02281   }
02282 
02283   move_arm_warehouse_logger_reader_->pushPlanningSceneToWarehouse(*actual_planning_scene, 
02284                                                                   id_to_push);
02285   
02286   for(std::set<unsigned int>::iterator it = data.getRequests().begin(); it != data.getRequests().end(); it++) {
02287     MotionPlanRequestData& req = motion_plan_map_[getMotionPlanRequestNameFromId(*it)];
02288     MotionPlanRequest mpr;
02289     if(req.hasPathConstraints()) {
02290       req.setGoalAndPathPositionOrientationConstraints(mpr, GoalPosition);
02291     } else {
02292       mpr = req.getMotionPlanRequest();
02293     }
02294     move_arm_warehouse_logger_reader_->pushMotionPlanRequestToWarehouse(id_to_push, 
02295                                                                         req.getId(),
02296                                                                         req.getSource(),
02297                                                                         mpr);
02298     ROS_DEBUG_STREAM("Saving Request " << req.getId());
02299     for(std::set<unsigned int>::iterator it2 = req.getTrajectories().begin(); it2 != req.getTrajectories().end(); it2++) {
02300       TrajectoryData& traj = trajectory_map_[req.getName()][getTrajectoryNameFromId(*it2)];
02301       move_arm_warehouse_logger_reader_->pushJointTrajectoryToWarehouse(id_to_push,
02302                                                                         traj.getSource(),
02303                                                                         traj.getDuration(), 
02304                                                                         traj.getTrajectory(),
02305                                                                         traj.getTrajectoryError(),
02306                                                                         traj.getId(),
02307                                                                         traj.getMotionPlanRequestId(), 
02308                                                                         traj.trajectory_error_code_);
02309       move_arm_warehouse_logger_reader_->pushOutcomeToWarehouse(id_to_push,
02310                                                                 traj.getSource(),
02311                                                                 traj.trajectory_error_code_);
02312       ROS_DEBUG_STREAM("Saving Trajectory " << traj.getId());
02313     }
02314   }
02315   if(!name_to_push.empty()) {
02316     setCurrentPlanningScene(name_to_push);
02317   }
02318 }
02319 
02320 bool PlanningSceneEditor::getAllPlanningSceneTimes(vector<ros::Time>& planning_scene_times,
02321                                                    vector<unsigned int>& planning_scene_ids)
02322 {
02323   move_arm_warehouse_logger_reader_->getAvailablePlanningSceneList("", 
02324                                                                    planning_scene_ids,
02325                                                                    last_creation_time_query_);
02326   planning_scene_times = last_creation_time_query_;
02327   return true;
02328 }
02329 
02330 bool PlanningSceneEditor::loadPlanningScene(const ros::Time& time, 
02331                                             const unsigned int id)
02332 {
02333   PlanningSceneData data;
02334   data.setTimeStamp(time);
02335   data.setId(id);
02336   std::string host;
02337   if(!move_arm_warehouse_logger_reader_->getPlanningScene("", id, data.getPlanningScene(), host))
02338   {
02339     return false;
02340   }
02341 
02342   data.setHostName(host);
02343 
02344   std::pair<string, PlanningSceneData> p(data.getName(), data);
02345   planning_scene_map_.insert(p);
02346   return true;
02347 }
02348 
02349 bool PlanningSceneEditor::getAllAssociatedMotionPlanRequests(const unsigned int id,
02350                                                              vector<unsigned int>& ids,
02351                                                              vector<string>& stages,
02352                                                              vector<MotionPlanRequest>& requests)
02353 {
02354   move_arm_warehouse_logger_reader_->getAssociatedMotionPlanRequests("", id, ids, stages, requests);
02355   return true;
02356 }
02357 
02358 void PlanningSceneEditor::deleteKinematicStates()
02359 {
02360   lockScene();
02361   std::vector<KinematicState*> removals;
02362   for(map<string, map<string, TrajectoryData> >::iterator it = trajectory_map_.begin(); it != trajectory_map_.end(); it++)
02363   {
02364     for(map<string, TrajectoryData>::iterator it2 = it->second.begin(); it2 != it->second.end(); it2++) {
02365       removals.push_back(it2->second.getCurrentState());
02366       it2->second.reset();
02367     }
02368   }
02369 
02370   for(map<string, MotionPlanRequestData>::iterator it = motion_plan_map_.begin(); it != motion_plan_map_.end(); it++)
02371   {
02372     removals.push_back(it->second.getStartState());
02373     removals.push_back(it->second.getGoalState());
02374     it->second.reset();
02375   }
02376 
02377   for(size_t i = 0; i < states_.size(); i++)
02378   {
02379     if(states_[i].state != NULL)
02380     {
02381       bool shouldBreak = false;
02382       for(size_t j = 0; j < removals.size(); j++)
02383       {
02384         if(states_[i].state == removals[j])
02385         {
02386           shouldBreak = true;
02387           break;
02388         }
02389       }
02390 
02391       if(shouldBreak)
02392       {
02393         continue;
02394       }
02395       ROS_INFO("Missed a state from %s!", states_[i].source.c_str());
02396       delete states_[i].state;
02397       states_[i].state = NULL;
02398     }
02399   }
02400   states_.clear();
02401   unlockScene();
02402 }
02403 
02404 bool PlanningSceneEditor::sendPlanningScene(PlanningSceneData& data)
02405 {
02406   lockScene();
02407   last_collision_set_error_code_.val = 0;
02408 
02409   SetPlanningSceneDiff::Request planning_scene_req;
02410   SetPlanningSceneDiff::Response planning_scene_res;
02411 
02412   planning_scene_req.planning_scene_diff = data.getPlanningScene();
02413   if(params_.use_robot_data_) {
02414     //just will get latest data from the monitor
02415     arm_navigation_msgs::RobotState emp;
02416     planning_scene_req.planning_scene_diff.robot_state = emp;
02417   }
02418 
02419   collision_space::EnvironmentModel::AllowedCollisionMatrix acm; 
02420   if(planning_scene_req.planning_scene_diff.allowed_collision_matrix.link_names.empty()) {
02421     acm = cm_->getDefaultAllowedCollisionMatrix();
02422   } else {
02423     acm = planning_environment::convertFromACMMsgToACM(planning_scene_req.planning_scene_diff.allowed_collision_matrix);
02424   }
02425   planning_scene_req.planning_scene_diff.collision_objects = std::vector<CollisionObject>();
02426   planning_scene_req.planning_scene_diff.attached_collision_objects = std::vector<AttachedCollisionObject>();
02427   deleteKinematicStates();
02428 
02429   if(robot_state_ != NULL)
02430   {
02431     cm_->revertPlanningScene(robot_state_);
02432     robot_state_ = NULL;
02433   }
02434 
02435   vector<string> removals;
02436   // Handle additions and removals of planning scene objects.
02437   for(map<string, SelectableObject>::iterator it = (*selectable_objects_).begin(); it
02438       != (*selectable_objects_).end(); it++)
02439   {
02440     string name = it->first;
02441     arm_navigation_msgs::CollisionObject& object = it->second.collision_object_;
02442 
02443     if(it->second.attach_) {
02444       if(acm.hasEntry(object.id)) {
02445         acm.changeEntry(object.id, false);
02446       } else {
02447         acm.addEntry(object.id, false);
02448       }
02449       //first doing group expansion of touch links
02450       std::vector<std::string>& touch_links = it->second.attached_collision_object_.touch_links;
02451       std::vector<std::string> modded_touch_links;
02452       for(unsigned int i = 0; i < touch_links.size(); i++) {
02453         if(cm_->getKinematicModel()->getModelGroup(touch_links[i])) {
02454           std::vector<std::string> links = cm_->getKinematicModel()->getModelGroup(touch_links[i])->getGroupLinkNames();
02455           modded_touch_links.insert(modded_touch_links.end(), links.begin(), links.end());
02456         } else {
02457           modded_touch_links.push_back(touch_links[i]);
02458         }
02459       }
02460       std::string& link_name = it->second.attached_collision_object_.link_name;
02461       if(find(modded_touch_links.begin(), modded_touch_links.end(), link_name) == modded_touch_links.end()) {
02462         modded_touch_links.push_back(link_name);
02463       }
02464       touch_links = modded_touch_links;
02465       acm.changeEntry(object.id, touch_links, true);
02466       it->second.attached_collision_object_.object.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD; 
02467       it->second.attach_ = false;
02468     } else if(it->second.detach_) {
02469       if(acm.hasEntry(object.id)) {
02470         acm.changeEntry(object.id, false);
02471       }
02472       (*selectable_objects_)[name].attached_collision_object_.object.operation.operation = arm_navigation_msgs::CollisionObjectOperation::REMOVE;      
02473       (*selectable_objects_)[name].collision_object_.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
02474       (*selectable_objects_)[name].detach_ = false;
02475     }
02476 
02477     if(it->second.attached_collision_object_.object.operation.operation == arm_navigation_msgs::CollisionObjectOperation::ADD) {
02478       planning_scene_req.planning_scene_diff.attached_collision_objects.push_back(it->second.attached_collision_object_);
02479     } else if(object.operation.operation != arm_navigation_msgs::CollisionObjectOperation::REMOVE) {
02480       if(!acm.hasEntry(object.id)) {
02481         acm.addEntry(object.id, false);
02482       }
02483       planning_scene_req.planning_scene_diff.collision_objects.push_back(object);
02484     } else {
02485       if(acm.hasEntry(object.id)) {
02486         acm.removeEntry(object.id);
02487       }
02488       removals.push_back(it->first);
02489       interactive_marker_server_->erase(it->first);
02490     }
02491   }
02492 
02493   planning_environment::convertFromACMToACMMsg(acm, planning_scene_req.planning_scene_diff.allowed_collision_matrix);
02494 
02495   if(!set_planning_scene_diff_client_.call(planning_scene_req, planning_scene_res))
02496   {
02497     ROS_WARN("Can't get planning scene");
02498     unlockScene();
02499     return false;
02500   }
02501 
02502   // Delete collision poles from the map which were removed.
02503   for(size_t i = 0; i < removals.size(); i++)
02504   {
02505     selectable_objects_->erase(removals[i]);
02506   }
02507 
02508   data.setPlanningScene(planning_scene_res.planning_scene);
02509 
02510   setRobotState(cm_->setPlanningScene(data.getPlanningScene()));
02511 
02512   if(getRobotState() == NULL)
02513   {
02514     ROS_ERROR("Something wrong with planning scene");
02515     unlockScene();
02516     return false;
02517   }
02518 
02519   std_msgs::ColorRGBA add_color;
02520   add_color.a = 1.0f;
02521   add_color.r = 0.0f;
02522   add_color.g = 1.0f;
02523   add_color.b = 0.0f;
02524 
02525   //check if there are new objects we don't know about
02526   for(unsigned int i = 0; i < planning_scene_res.planning_scene.collision_objects.size(); i++) {
02527     arm_navigation_msgs::CollisionObject& coll = planning_scene_res.planning_scene.collision_objects[i];
02528     if(selectable_objects_->find(coll.id) == selectable_objects_->end()) {
02529       createSelectableMarkerFromCollisionObject(coll,
02530                                                 coll.id,
02531                                                 coll.id,
02532                                                 add_color,
02533                                                 true);
02534     }
02535   }
02536 
02537   for(unsigned int i = 0; i < planning_scene_res.planning_scene.attached_collision_objects.size(); i++) {
02538     arm_navigation_msgs::CollisionObject& coll = planning_scene_res.planning_scene.attached_collision_objects[i].object;
02539     if(selectable_objects_->find(coll.id) == selectable_objects_->end()) {
02540       makeSelectableAttachedObjectFromPlanningScene(planning_scene_res.planning_scene,
02541                                                     planning_scene_res.planning_scene.attached_collision_objects[i]);
02542     }
02543   }
02544 
02545   //Now we may need to update the positions of attached collision objects
02546   for(std::map<std::string, SelectableObject>::iterator it = selectable_objects_->begin();
02547       it != selectable_objects_->end(); 
02548       it++) {
02549     if(it->second.attached_collision_object_.object.operation.operation == arm_navigation_msgs::CollisionObjectOperation::ADD) {
02550       planning_models::KinematicState::AttachedBodyState* att_state = 
02551         robot_state_->getAttachedBodyState(it->second.attached_collision_object_.object.id);
02552       if(att_state == NULL) {
02553         ROS_WARN_STREAM("Some problem with " << it->first);
02554         continue;
02555       } 
02556       std_msgs::Header header;
02557       header.frame_id = cm_->getWorldFrameId();
02558       header.stamp = ros::Time::now();
02559       interactive_marker_server_->setPose(it->second.selection_marker_.name,
02560                                           toGeometryPose(att_state->getGlobalCollisionBodyTransforms()[0]),
02561                                           header);
02562       interactive_marker_server_->applyChanges();
02563       it->second.collision_object_.poses[0] = toGeometryPose(att_state->getGlobalCollisionBodyTransforms()[0]);
02564     }
02565   }
02566 
02567   robot_state_->getKinematicStateValues(robot_state_joint_values_);
02568 
02569   for(map<string, MotionPlanRequestData>::iterator it = motion_plan_map_.begin(); it != motion_plan_map_.end(); it++)
02570   {
02571     it->second.setStartState(new KinematicState(*robot_state_));
02572     it->second.setGoalState(new KinematicState(*robot_state_));
02573     StateRegistry start;
02574     start.state = it->second.getStartState();
02575     start.source = "Motion Plan Start After Sending Scene";
02576     states_.push_back(start);
02577     StateRegistry end;
02578     end.state = it->second.getGoalState();
02579     end.source = "Motion Plan End After Sending Scene";
02580     states_.push_back(end);
02581     it->second.updateStartState();
02582     it->second.updateGoalState();
02583   }
02584 
02585   //setShowCollisions(false);
02586 
02587   unlockScene();
02588   return true;
02589 }
02590 
02591 void PlanningSceneEditor::initMotionPlanRequestData(const unsigned int& planning_scene_id, 
02592                                                     const std::vector<unsigned int>& ids,
02593                                                     const std::vector<std::string>& stages,
02594                                                     const std::vector<arm_navigation_msgs::MotionPlanRequest>& requests)
02595 {
02596   lockScene();
02597   for(size_t i = 0; i < requests.size(); i++)
02598   {
02599     const MotionPlanRequest& mpr = requests[i];
02600     cm_->disableCollisionsForNonUpdatedLinks(mpr.group_name);
02601 
02602     setRobotStateAndComputeTransforms(mpr.start_state, *robot_state_);
02603 
02604     GetMotionPlan::Request plan_req;
02605     plan_req.motion_plan_request = mpr;
02606     GetMotionPlan::Response plan_res;
02607 
02608     if(params_.proximity_space_service_name_ != "none") {
02609       if(!distance_aware_service_client_.call(plan_req, plan_res))
02610       {
02611         ROS_INFO("Something wrong with distance client");
02612       }
02613     }
02614 
02615     const KinematicModel::GroupConfig& config =
02616         cm_->getKinematicModel()->getJointModelGroupConfigMap().at(mpr.group_name);
02617     std::string tip = config.tip_link_;
02618 
02619     MotionPlanRequestData data(ids[i],
02620                                stages[i], 
02621                                mpr,
02622                                robot_state_,
02623                                tip);
02624     data.setPlanningSceneId(planning_scene_id);
02625 
02626     StateRegistry start;
02627     start.state = data.getStartState();
02628     start.source = "Motion Plan Request Data Start from createRequest";
02629     StateRegistry end;
02630     end.state = data.getGoalState();
02631     end.source = "Motion Plan Request Data End from createRequest";
02632     states_.push_back(start);
02633     states_.push_back(end);
02634 
02635 
02636     PlanningSceneData& planningSceneData = planning_scene_map_[getPlanningSceneNameFromId(planning_scene_id)];
02637     planningSceneData.addMotionPlanRequestId(ids[i]);
02638 
02639     std::vector<unsigned int> erased_trajectories;
02640     if(motion_plan_map_.find(data.getName()) != motion_plan_map_.end())
02641     {
02642       ROS_INFO_STREAM("Shouldn't be replacing trajectories here");
02643       deleteMotionPlanRequest(data.getId(), erased_trajectories);
02644     }
02645     motion_plan_map_[getMotionPlanRequestNameFromId(data.getId())] = data;
02646 
02647     createIkControllersFromMotionPlanRequest(data, false);
02648   }
02649   unlockScene();
02650 }
02651 
02652 // bool PlanningSceneEditor::getMotionPlanRequest(const ros::Time& time, const unsigned int id, const string& stage, MotionPlanRequest& mpr,
02653 //                                                string& id, string& planning_scene_id)
02654 // {
02655 //   if(!move_arm_warehouse_logger_reader_->getAssociatedMotionPlanRequest("", id, time, stage, mpr))
02656 //   {
02657 //     ROS_INFO_STREAM("No request with stage " << stage);
02658 //     return false;
02659 //   }
02660 
02661 //   lockScene();
02662 //   cm_->disableCollisionsForNonUpdatedLinks(mpr.group_name);
02663 
02664 //   setRobotStateAndComputeTransforms(mpr.start_state, *robot_state_);
02665 
02666 //   GetMotionPlan::Request plan_req;
02667 //   plan_req.motion_plan_request = mpr;
02668 //   GetMotionPlan::Response plan_res;
02669 
02670 //   if(params_.proximity_space_service_name_ != "none") {
02671 //     if(!distance_aware_service_client_.call(plan_req, plan_res))
02672 //     {
02673 //       ROS_INFO("Something wrong with distance client");
02674 //     }
02675 //   }
02676 
02677 //   MotionPlanRequestData data(robot_state_);
02678 //   data.setId(generateNewMotionPlanId());
02679 
02680 //   data.setMotionPlanRequest(mpr);
02681 //   data.setPlanningSceneName(planning_scene_id);
02682 //   data.setGroupName(mpr.group_name);
02683 //   data.setSource("Planner");
02684 //   StateRegistry start;
02685 //   start.state = data.getStartState();
02686 //   start.source = "Motion Plan Request Data Start from loadRequest";
02687 //   StateRegistry end;
02688 //   end.state = data.getGoalState();
02689 //   end.source = "Motion Plan Request Data End from line loadRequest";
02690 //   states_.push_back(start);
02691 //   states_.push_back(end);
02692 
02693 //   const KinematicModel::GroupConfig& config =
02694 //       cm_->getKinematicModel()->getJointModelGroupConfigMap().at(mpr.group_name);
02695 //   std::string tip = config.tip_link_;
02696 //   data.setEndEffectorLink(tip);
02697 
02698 //   PlanningSceneData& planningSceneData = planning_scene_map_[planning_scene_id];
02699 //   planningSceneData.getRequests().push_back(data.getId());
02700 
02701 //   motion_plan_map_[data.getId()] = data;
02702 //   id = data.getId();
02703 
02704 //   lock_scene_.unlock();
02705 
02706 //   createIkControllersFromMotionPlanRequest(data, false);
02707 //   return true;
02708 // }
02709 
02710 bool PlanningSceneEditor::getAllAssociatedTrajectorySources(const unsigned int planning_id, 
02711                                                             const unsigned int mpr_id, 
02712                                                             vector<unsigned int>& trajectory_ids,
02713                                                             vector<string>& trajectory_sources)
02714 {
02715   if(!move_arm_warehouse_logger_reader_->getAssociatedJointTrajectorySources("", planning_id, mpr_id, 
02716                                                                              trajectory_ids,
02717                                                                              trajectory_sources))
02718   {
02719     return false;
02720   }
02721   return true;
02722 }
02723 
02724 bool PlanningSceneEditor::getAllAssociatedPausedStates(const unsigned int id, 
02725                                                        vector<ros::Time>& paused_times)
02726 {
02727   if(!move_arm_warehouse_logger_reader_->getAssociatedPausedStates("", id, paused_times))
02728   {
02729     return false;
02730   }
02731   return true;
02732 }
02733 
02734 bool PlanningSceneEditor::getPausedState(const unsigned int id, 
02735                                          const ros::Time& paused_time,
02736                                          HeadMonitorFeedback& paused_state)
02737 {
02738   if(!move_arm_warehouse_logger_reader_->getAssociatedPausedState("", id, paused_time, paused_state))
02739   {
02740     return false;
02741   }
02742   return true;
02743 }
02744 
02745 bool PlanningSceneEditor::playTrajectory(MotionPlanRequestData& requestData, TrajectoryData& data)
02746 {
02747   lock_scene_.lock();
02748   for(size_t i = 0; i < states_.size(); i++)
02749   {
02750     if(states_[i].state == data.getCurrentState())
02751     {
02752       states_[i].state = NULL;
02753     }
02754   }
02755 
02756   data.reset();
02757 
02758   data.play();
02759   data.setVisible(true);
02760   if(data.getTrajectory().points.size() == 0)
02761   {
02762     lock_scene_.unlock();
02763     return false;
02764   }
02765 
02766   if(data.getCurrentState() == NULL)
02767   {
02768     data.setCurrentState(new KinematicState(*robot_state_));
02769     StateRegistry currentState;
02770     currentState.state = data.getCurrentState();
02771     currentState.source = "Trajectory from play trajectory";
02772     states_.push_back(currentState);
02773   }
02774 
02775   data.setCurrentPoint(0);
02776   ArmNavigationErrorCodes oldValue;
02777   oldValue.val = data.trajectory_error_code_.val;
02778   ArmNavigationErrorCodes& errorCode = data.trajectory_error_code_;
02779   collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm_->getCurrentAllowedCollisionMatrix();
02780   cm_->disableCollisionsForNonUpdatedLinks(data.getGroupName());
02781 
02782   vector<ArmNavigationErrorCodes> trajectory_error_codes;
02783   arm_navigation_msgs::Constraints path_constraints;
02784   arm_navigation_msgs::Constraints goal_constraints;
02785   if(requestData.hasPathConstraints()) {
02786     path_constraints = requestData.getMotionPlanRequest().path_constraints;
02787     goal_constraints.position_constraints = requestData.getMotionPlanRequest().goal_constraints.position_constraints;
02788     goal_constraints.orientation_constraints = requestData.getMotionPlanRequest().goal_constraints.orientation_constraints;
02789   } else {
02790     goal_constraints.joint_constraints = requestData.getMotionPlanRequest().goal_constraints.joint_constraints;
02791   }
02792   
02793   cm_->isJointTrajectoryValid(*(data.getCurrentState()), data.getTrajectory(),
02794                               goal_constraints,
02795                               path_constraints, errorCode,
02796                               trajectory_error_codes, false);
02797 
02798   cm_->setAlteredAllowedCollisionMatrix(acm);
02799 
02800   if(errorCode.val != errorCode.SUCCESS)
02801   {
02802     if(trajectory_error_codes.size() > 0)
02803     {
02804       data.setBadPoint(trajectory_error_codes.size() - 1);
02805     }
02806     else
02807     {
02808       data.setBadPoint(0);
02809     }
02810   }
02811   else
02812   {
02813     data.setBadPoint(-1);
02814     errorCode.val = oldValue.val;
02815   }
02816 
02817   data.setCurrentPoint(0);
02818   lock_scene_.unlock();
02819   return true;
02820 }
02821 
02822 void PlanningSceneEditor::createSelectableMarkerFromCollisionObject(CollisionObject& object, 
02823                                                                     string name,
02824                                                                     string description, 
02825                                                                     std_msgs::ColorRGBA color,
02826                                                                     bool insert_selection)
02827 {
02828   SelectableObject selectable;
02829   selectable.id_ = name;
02830   selectable.collision_object_ = object;
02831   selectable.control_marker_.pose = object.poses[0];
02832   selectable.control_marker_.header.frame_id = "/" + cm_->getWorldFrameId();
02833   selectable.control_marker_.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
02834 
02835   selectable.selection_marker_.pose = object.poses[0];
02836   selectable.selection_marker_.header.frame_id = "/" + cm_->getWorldFrameId();
02837   selectable.selection_marker_.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
02838 
02839   selectable.color_ = color;
02840 
02841   InteractiveMarkerControl button;
02842   button.name = "button";
02843   button.interaction_mode = InteractiveMarkerControl::BUTTON;
02844   button.description = "";
02845 
02846   //min scale initialized
02847   double scale_to_use = .2f;
02848 
02849   for(size_t i = 0; i < object.shapes.size(); i++)
02850   {
02851     arm_navigation_msgs::Shape& shape = object.shapes[i];
02852     Marker mark;
02853     mark.color = color;
02854     planning_environment::setMarkerShapeFromShape(shape, mark);
02855 
02856     shapes::Shape* s = planning_environment::constructObject(shape);
02857     bodies::Body* b = bodies::createBodyFromShape(s);
02858     
02859     bodies::BoundingSphere bs;
02860     b->computeBoundingSphere(bs);
02861 
02862     delete b;
02863     delete s;
02864 
02865     if(bs.radius * 2.0 > scale_to_use) {
02866       scale_to_use = bs.radius*2.0;
02867     }
02868 
02869     //need to make slightly larger
02870     mark.scale.x = mark.scale.x * 1.01f;
02871     mark.scale.y = mark.scale.y * 1.01f;
02872     mark.scale.z = mark.scale.z * 1.01f;
02873     
02874     if(mark.type == Marker::LINE_LIST) {
02875       mark.points.clear();
02876       mark.type = Marker::TRIANGLE_LIST;
02877       mark.scale.x = 1.01;
02878       mark.scale.y = 1.01;
02879       mark.scale.z = 1.01;
02880       for(unsigned int i = 0; i < shape.triangles.size(); i += 3) { 
02881         mark.points.push_back(shape.vertices[shape.triangles[i]]);
02882         mark.points.push_back(shape.vertices[shape.triangles[i+1]]);
02883         mark.points.push_back(shape.vertices[shape.triangles[i+2]]);
02884       }
02885     }
02886 
02887     button.markers.push_back(mark);
02888   }
02889   
02890   selectable.selection_marker_.controls.push_back(button);
02891 
02892   InteractiveMarkerControl sixDof;
02893   sixDof.orientation.w = 1;
02894   sixDof.orientation.x = 1;
02895   sixDof.orientation.y = 0;
02896   sixDof.orientation.z = 0;
02897   sixDof.always_visible = false;
02898   sixDof.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
02899   selectable.control_marker_.controls.push_back(sixDof);
02900   sixDof.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
02901   selectable.control_marker_.controls.push_back(sixDof);
02902 
02903   sixDof.orientation.w = 1;
02904   sixDof.orientation.x = 0;
02905   sixDof.orientation.y = 1;
02906   sixDof.orientation.z = 0;
02907   sixDof.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
02908   selectable.control_marker_.controls.push_back(sixDof);
02909   sixDof.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
02910   selectable.control_marker_.controls.push_back(sixDof);
02911 
02912   sixDof.orientation.w = 1;
02913   sixDof.orientation.x = 0;
02914   sixDof.orientation.y = 0;
02915   sixDof.orientation.z = 1;
02916   sixDof.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
02917   selectable.control_marker_.controls.push_back(sixDof);
02918   sixDof.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
02919   selectable.control_marker_.controls.push_back(sixDof);
02920 
02921   selectable.control_marker_.controls.push_back(button);
02922   selectable.control_marker_.description = description;
02923 
02924   selectable.control_marker_.name = name + "_control";
02925   selectable.selection_marker_.name = name + "_selection";
02926 
02927   selectable.selection_marker_.scale = scale_to_use;
02928   selectable.control_marker_.scale = scale_to_use;
02929   (*selectable_objects_)[name] = selectable;
02930   if(insert_selection) {
02931     interactive_marker_server_->insert(selectable.selection_marker_, collision_object_selection_feedback_ptr_);
02932     menu_handler_map_["Collision Object Selection"].apply(*interactive_marker_server_, selectable.selection_marker_.name);
02933     interactive_marker_server_->applyChanges();
02934   } 
02935 }
02936 
02937 void PlanningSceneEditor::JointControllerCallback(const InteractiveMarkerFeedbackConstPtr &feedback)
02938 {
02939   std::string id = "";
02940   std::string MPR = "";
02941   PositionType type = StartPosition;
02942 
02943   if(feedback->marker_name.rfind("_start_control") != std::string::npos)
02944   {
02945     std::string sub1 = feedback->marker_name.substr(0, feedback->marker_name.rfind("_start_control"));
02946     id = sub1.substr(0, sub1.rfind("_mpr_"));
02947     MPR = sub1.substr(sub1.rfind("_mpr_") + 5, sub1.length());
02948     type = StartPosition;
02949   }
02950   else if(feedback->marker_name.rfind("_end_control") != std::string::npos)
02951   {
02952     std::string sub1 = feedback->marker_name.substr(0, feedback->marker_name.rfind("_end_control"));
02953     id = sub1.substr(0, sub1.rfind("_mpr_"));
02954     MPR = sub1.substr(sub1.rfind("_mpr_") + 5, sub1.length());
02955     type = GoalPosition;
02956   }
02957 
02958   if(motion_plan_map_.find(MPR) == motion_plan_map_.end()) {
02959     ROS_INFO_STREAM("Making mpr in joint controller callback");
02960   }
02961   setJointState(motion_plan_map_[MPR], type, id, toBulletTransform(feedback->pose));
02962 }
02963 
02964 void PlanningSceneEditor::IKControllerCallback(const InteractiveMarkerFeedbackConstPtr &feedback)
02965 {
02966   std::string id = "";
02967   PositionType type = StartPosition;
02968 
02969   bool findIKSolution = false;
02970   if(feedback->marker_name.rfind("_start_control") != std::string::npos)
02971   {
02972     id = feedback->marker_name.substr(0, feedback->marker_name.rfind("_start_control"));
02973     type = StartPosition;
02974   }
02975   else if(feedback->marker_name.rfind("_end_control") != std::string::npos)
02976   {
02977     id = feedback->marker_name.substr(0, feedback->marker_name.rfind("_end_control"));
02978     type = GoalPosition;
02979   }
02980   else
02981   {
02982     return;
02983   }
02984 
02985   IKController& controller = (*ik_controllers_)[id];
02986 
02987   if(motion_plan_map_.find(getMotionPlanRequestNameFromId(controller.motion_plan_id_)) == motion_plan_map_.end()) {
02988     ROS_INFO_STREAM("Making empty mpr in ik controller callback");
02989   }
02990 
02991   if(feedback->event_type == InteractiveMarkerFeedback::POSE_UPDATE)
02992   {
02993     tf::Transform pose = toBulletTransform(feedback->pose);
02994 
02995     if(type == StartPosition)
02996     {
02997       motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].getStartState()->
02998         updateKinematicStateWithLinkAt(motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].getEndEffectorLink(),
02999                                        pose);
03000       findIKSolution = true;
03001       if(selected_motion_plan_name_ != getMotionPlanRequestNameFromId(controller.motion_plan_id_))
03002       {
03003         selected_motion_plan_name_ = getMotionPlanRequestNameFromId(controller.motion_plan_id_);
03004         updateState();
03005       }
03006     }
03007     else
03008     {
03009       motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].getGoalState()->
03010         updateKinematicStateWithLinkAt(motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].getEndEffectorLink(),
03011                                        pose);
03012       findIKSolution = true;
03013       if(selected_motion_plan_name_ != getMotionPlanRequestNameFromId(controller.motion_plan_id_))
03014       {
03015         selected_motion_plan_name_ = getMotionPlanRequestNameFromId(controller.motion_plan_id_);
03016         updateState();
03017       }
03018     }
03019 
03020   }
03021   else if(feedback->event_type == InteractiveMarkerFeedback::MENU_SELECT)
03022   {
03023     if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Map to Robot State"])
03024     {
03025       MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)];
03026       if(data.hasGoodIKSolution(type)) {
03027         const planning_models::KinematicState* state;
03028         if(type == StartPosition) {
03029           state = data.getStartState();
03030         } else {
03031           state = data.getGoalState();
03032         }
03033         planning_environment::convertKinematicStateToRobotState(*state,
03034                                                                 ros::Time::now(),
03035                                                                 cm_->getWorldFrameId(),
03036                                                                 planning_scene_map_[current_planning_scene_name_].getPlanningScene().robot_state);
03037         
03038         sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03039       }
03040     } else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Map from Robot State"])
03041     {
03042       MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)];
03043 
03044       std::map<std::string, double> vals;
03045       robot_state_->getKinematicStateValues(vals);
03046 
03047       planning_models::KinematicState* state;
03048       if(type == StartPosition)
03049       {
03050         data.setStartStateValues(vals);
03051         state = data.getStartState();
03052         convertKinematicStateToRobotState(*state, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
03053                                           data.getMotionPlanRequest().start_state);
03054         data.setLastGoodStartPose((state->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform()));
03055       }
03056       else
03057       {
03058         state = data.getGoalState();
03059         data.setGoalStateValues(vals);
03060         data.setLastGoodGoalPose((state->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform()));
03061       }
03062       interactive_marker_server_->setPose(feedback->marker_name, 
03063                                           toGeometryPose(state->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform()),
03064                                           feedback->header);
03065     } else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Map to Other Orientation"])
03066     {
03067       MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)];
03068       if(type == StartPosition)
03069       {
03070         tf::Transform cur_transform = data.getStartState()->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform();
03071         tf::Transform other_transform = data.getGoalState()->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform();
03072         cur_transform.setRotation(other_transform.getRotation());
03073         data.getStartState()->updateKinematicStateWithLinkAt(data.getEndEffectorLink(), cur_transform);
03074         interactive_marker_server_->setPose(feedback->marker_name, 
03075                                             toGeometryPose(cur_transform),
03076                                             feedback->header);
03077         findIKSolution = true;
03078       }
03079       else
03080       {
03081         tf::Transform cur_transform = data.getGoalState()->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform();
03082         tf::Transform other_transform = data.getStartState()->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform();
03083         cur_transform.setRotation(other_transform.getRotation());
03084         data.getGoalState()->updateKinematicStateWithLinkAt(data.getEndEffectorLink(), cur_transform);
03085         interactive_marker_server_->setPose(feedback->marker_name, 
03086                                             toGeometryPose(cur_transform),
03087                                             feedback->header);
03088         findIKSolution = true;
03089       }
03090     } else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Go To Last Good State"])
03091     {
03092       MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)];
03093 
03094       if(type == StartPosition)
03095       {
03096         data.getStartState()->updateKinematicStateWithLinkAt(data.getEndEffectorLink(), (data.getLastGoodStartPose()));
03097         interactive_marker_server_->setPose(feedback->marker_name, toGeometryPose(data.getLastGoodStartPose()),
03098                                             feedback->header);
03099         findIKSolution = true;
03100       }
03101       else
03102       {
03103         data.getGoalState()->updateKinematicStateWithLinkAt(data.getEndEffectorLink(), (data.getLastGoodGoalPose()));
03104         interactive_marker_server_->setPose(feedback->marker_name, toGeometryPose(data.getLastGoodGoalPose()),
03105                                             feedback->header);
03106         findIKSolution = true;
03107       }
03108     }
03109     else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Randomly Perturb"])
03110     {
03111       MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)];
03112 
03113       randomlyPerturb(data, type);
03114       if(type == StartPosition)
03115       {
03116         interactive_marker_server_->setPose(feedback->marker_name, toGeometryPose(data.getLastGoodStartPose()),
03117                                             feedback->header);
03118       }
03119       else
03120       {
03121         interactive_marker_server_->setPose(feedback->marker_name, toGeometryPose(data.getLastGoodGoalPose()),
03122                                             feedback->header);
03123       }
03124     }
03125     else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Plan New Trajectory"])
03126     {
03127       MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)];
03128       unsigned int trajectory;
03129       planToRequest(data, trajectory);
03130       selected_trajectory_name_ = getTrajectoryNameFromId(trajectory);
03131       playTrajectory(data, trajectory_map_[data.getName()][selected_trajectory_name_]);
03132       updateState();
03133     }
03134     else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Filter Last Trajectory"])
03135     {
03136       MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)];
03137       unsigned int trajectory;
03138       if(selected_trajectory_name_ != "" && hasTrajectory(data.getName(), selected_trajectory_name_)) {
03139         filterTrajectory(data, trajectory_map_[data.getName()][selected_trajectory_name_], trajectory);
03140         selected_trajectory_name_ = getTrajectoryNameFromId(trajectory); 
03141         playTrajectory(data, trajectory_map_[data.getName()][selected_trajectory_name_]);
03142         updateState();
03143       }
03144     }
03145     else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Execute Last Trajectory"])
03146     {
03147       std::string trajectory;
03148       if(selected_trajectory_name_ != "") 
03149       {
03150         executeTrajectory(selected_motion_plan_name_, selected_trajectory_name_);
03151         updateState();
03152       }
03153     }
03154     else if(feedback->menu_entry_id == menu_entry_maps_["IK Control"]["Delete Request"])
03155     {
03156       std::vector<unsigned int> erased_trajectories;
03157       deleteMotionPlanRequest(controller.motion_plan_id_, erased_trajectories);
03158     }
03159   }
03160 
03161   if(findIKSolution)
03162   {
03163     if(!solveIKForEndEffectorPose(motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)], type, true))
03164     {
03165       if(motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].hasGoodIKSolution(type))
03166       {
03167         motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].refreshColors();
03168       }
03169       motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].setHasGoodIKSolution(false, type);
03170     }
03171     else
03172     {
03173       if(!motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].hasGoodIKSolution(type))
03174       {
03175         motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].refreshColors();
03176       }
03177       motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].setHasGoodIKSolution(true, type);
03178     }
03179   }
03180 
03181   if(motion_plan_map_.find(getMotionPlanRequestNameFromId(controller.motion_plan_id_)) == motion_plan_map_.end()) {
03182     ROS_DEBUG_STREAM("Would be empty mpr in ik controller callback");
03183   } else if(motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].areJointControlsVisible())
03184   {
03185     createJointMarkers(motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)], type);
03186   }
03187   interactive_marker_server_->applyChanges();
03188 }
03189 
03190 void PlanningSceneEditor::createIkControllersFromMotionPlanRequest(MotionPlanRequestData& data, bool rePose)
03191 {
03192   if(data.isStartEditable())
03193   {
03194     createIKController(data, StartPosition, rePose);
03195   }
03196 
03197   if(data.isGoalEditable())
03198   {
03199     createIKController(data, GoalPosition, rePose);
03200   }
03201 
03202   interactive_marker_server_->applyChanges();
03203 }
03204 
03205 void PlanningSceneEditor::createIKController(MotionPlanRequestData& data, PositionType type, bool rePose)
03206 {
03207   KinematicState* state = NULL;
03208   std::string nametag = "";
03209   if(type == StartPosition)
03210   {
03211     state = data.getStartState();
03212     nametag = "_start_control";
03213   }
03214   else
03215   {
03216     state = data.getGoalState();
03217     nametag = "_end_control";
03218   }
03219 
03220   tf::Transform transform = state->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform();
03221   InteractiveMarker marker;
03222 
03223 
03224   if(interactive_marker_server_->get(data.getName() + nametag, marker) && rePose)
03225   {
03226     geometry_msgs::Pose pose =  toGeometryPose(transform);
03227     interactive_marker_server_->setPose(data.getName() + nametag, pose);
03228     return;
03229   }
03230 
03231 
03232   marker.header.frame_id = "/" + cm_->getWorldFrameId();
03233   marker.pose.position.x = transform.getOrigin().x();
03234   marker.pose.position.y = transform.getOrigin().y();
03235   marker.pose.position.z = transform.getOrigin().z();
03236   marker.pose.orientation.w = transform.getRotation().w();
03237   marker.pose.orientation.x = transform.getRotation().x();
03238   marker.pose.orientation.y = transform.getRotation().y();
03239   marker.pose.orientation.z = transform.getRotation().z();
03240   marker.scale = 0.225f;
03241   marker.name = data.getName() + nametag;
03242   marker.description = /*data.getName() + nametag;*/ ""; // TODO check !!!!!!! if it's fine to not fill anything ;)
03243 
03244 
03245   InteractiveMarkerControl control;
03246   control.orientation.w = 1;
03247   control.orientation.x = 1;
03248   control.orientation.y = 0;
03249   control.orientation.z = 0;
03250   control.always_visible = false;
03251   control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
03252   marker.controls.push_back(control);
03253   control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
03254   marker.controls.push_back(control);
03255 
03256   control.orientation.w = 1;
03257   control.orientation.x = 0;
03258   control.orientation.y = 1;
03259   control.orientation.z = 0;
03260   control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
03261   marker.controls.push_back(control);
03262   control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
03263   marker.controls.push_back(control);
03264 
03265   control.orientation.w = 1;
03266   control.orientation.x = 0;
03267   control.orientation.y = 0;
03268   control.orientation.z = 1;
03269   control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
03270   marker.controls.push_back(control);
03271   control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
03272   marker.controls.push_back(control);
03273 
03274 
03275   /*InteractiveMarkerControl control;
03276   control.always_visible = false;
03277   control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
03278   control.orientation.w = 0.707;
03279   control.orientation.x = 0;
03280   control.orientation.y = -0.707;
03281   control.orientation.z = 0;
03282 
03283   marker.controls.push_back( control );
03284 
03285   InteractiveMarkerControl control2;
03286   control2.always_visible = false;
03287   control2.interaction_mode = InteractiveMarkerControl::MOVE_ROTATE;
03288   control2.orientation.w = 1;
03289   control2.orientation.x = 1;
03290   control2.orientation.y = 0; // it was 1 here (Materna)
03291   control2.orientation.z = 0;
03292 
03293 
03294 
03295   Marker marker2;
03296   marker2.type = Marker::CUBE;
03297   marker2.scale.x = .2;
03298   marker2.scale.y = .15;
03299   marker2.scale.z = .002;
03300   marker2.pose.position.z = 0.1; // added
03301 
03302   // added (Materna)
03303   marker2.pose.orientation.w = 0.707;
03304   marker2.pose.orientation.x = 0;
03305   marker2.pose.orientation.y = -0.707;
03306   marker2.pose.orientation.z = 0;
03307 
03308 
03309   marker2.color.r = 0;
03310   marker2.color.g = 0;
03311   marker2.color.b = 0.5;
03312   marker2.color.a = 1;
03313   control2.markers.push_back( marker2 );
03314   marker2.scale.x = .1;
03315   marker2.scale.y = .35;
03316   marker2.pose.position.z = 0; // added
03317   control2.markers.push_back( marker2 );
03318 
03319   marker.controls.push_back( control2 );
03320 
03321   InteractiveMarkerControl control3;
03322   control3.always_visible = false;
03323   control3.interaction_mode = InteractiveMarkerControl::MOVE_ROTATE;
03324   control3.orientation.w = 1;
03325   control3.orientation.x = 0;
03326   control3.orientation.y = 0;
03327   control3.orientation.z = 1;
03328 
03329 
03330   Marker marker3;
03331   marker3.type = Marker::CUBE;
03332   marker3.scale.x = .2;
03333   marker3.scale.y = .002;
03334   marker3.scale.z = .15;
03335   //marker3.pose.position.x = .1;
03336   marker3.pose.position.z = 0.1; // added
03337 
03338   // added (Materna)
03339   marker3.pose.orientation.w = 0.707;
03340   marker3.pose.orientation.x = 0;
03341   marker3.pose.orientation.y = -0.707;
03342   marker3.pose.orientation.z = 0;
03343 
03344   marker3.color.r = 0;
03345   marker3.color.g = .5;
03346   marker3.color.b = 0;
03347   marker3.color.a = 1;
03348   control3.markers.push_back( marker3 );
03349   marker3.scale.x = .1;
03350   marker3.scale.z = .35;
03351   marker3.pose.position.z = 0; // added (Materna)
03352   control3.markers.push_back( marker3 );
03353 
03354   marker.controls.push_back( control3 );*/
03355 
03356   interactive_marker_server_->insert(marker, ik_control_feedback_ptr_);
03357   control.interaction_mode = InteractiveMarkerControl::MENU;
03358   //control.markers.push_back(makeMarkerSphere(marker));
03359   marker.controls.push_back(control);
03360 
03361   (*ik_controllers_)[data.getName()].motion_plan_id_ = data.getId();
03362   if(type == StartPosition)
03363   {
03364     (*ik_controllers_)[data.getName()].start_controller_ = marker;
03365     data.setLastGoodStartPose(toBulletTransform((*ik_controllers_)[data.getName()].start_controller_.pose));
03366   }
03367   else
03368   {
03369     (*ik_controllers_)[data.getName()].end_controller_ = marker;
03370     data.setLastGoodGoalPose(toBulletTransform((*ik_controllers_)[data.getName()].end_controller_.pose));
03371   }
03372 
03373   menu_handler_map_["IK Control"].apply(*interactive_marker_server_, marker.name);
03374 
03375 }
03376 
03377 void PlanningSceneEditor::deleteCollisionObject(std::string& name)
03378 {
03379   (*selectable_objects_)[name].collision_object_.operation.operation
03380       = arm_navigation_msgs::CollisionObjectOperation::REMOVE;
03381   (*selectable_objects_)[name].attached_collision_object_.object.operation.operation
03382       = arm_navigation_msgs::CollisionObjectOperation::REMOVE;
03383   interactive_marker_server_->erase((*selectable_objects_)[name].selection_marker_.name);
03384   interactive_marker_server_->erase((*selectable_objects_)[name].control_marker_.name);
03385   interactive_marker_server_->applyChanges();
03386 }
03387 
03388 void PlanningSceneEditor::collisionObjectSelectionCallback(const InteractiveMarkerFeedbackConstPtr &feedback)
03389 {
03390   std::string name = feedback->marker_name.substr(0, feedback->marker_name.rfind("_selection"));
03391   bool should_select = false;
03392   switch (feedback->event_type)
03393   {
03394     case InteractiveMarkerFeedback::BUTTON_CLICK:
03395       {
03396         visualization_msgs::InteractiveMarker mark;
03397         should_select = true;
03398       }
03399       break;
03400     case InteractiveMarkerFeedback::MENU_SELECT:
03401       if(feedback->menu_entry_id == menu_entry_maps_["Collision Object Selection"]["Delete"])
03402       {
03403         deleteCollisionObject(name);
03404         sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);       
03405         selectable_objects_->erase(name);
03406       }
03407       else if(feedback->menu_entry_id == menu_entry_maps_["Collision Object Selection"]["Select"])
03408       {
03409         should_select = true;
03410       }
03411       break;
03412   }
03413 
03414   if(should_select)
03415   {
03416     interactive_marker_server_->erase((*selectable_objects_)[name].selection_marker_.name);
03417     (*selectable_objects_)[name].control_marker_.pose = feedback->pose;
03418     (*selectable_objects_)[name].control_marker_.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
03419 
03420     interactive_marker_server_->insert((*selectable_objects_)[name].control_marker_,
03421                                        collision_object_movement_feedback_ptr_);
03422 
03423     menu_handler_map_["Collision Object"].apply(*interactive_marker_server_,
03424                                                 (*selectable_objects_)[name].control_marker_.name);
03425   }
03426   interactive_marker_server_->applyChanges();
03427 
03428 }
03429 
03430 void PlanningSceneEditor::collisionObjectMovementCallback(const InteractiveMarkerFeedbackConstPtr &feedback)
03431 {
03432   std::string name = feedback->marker_name.substr(0, feedback->marker_name.rfind("_control"));
03433 
03434   switch (feedback->event_type)
03435   {
03436     case InteractiveMarkerFeedback::MOUSE_UP:
03437       if(feedback->control_name == "button") return;
03438       if(last_resize_handle_ == menu_entry_maps_["Collision Object"]["Off"]) {
03439         for(size_t i = 0; i < (*selectable_objects_)[name].collision_object_.poses.size(); i++)
03440         {
03441           (*selectable_objects_)[name].collision_object_.poses[i] = feedback->pose;
03442         }
03443         sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03444       } else {
03445         CollisionObject coll = (*selectable_objects_)[name].collision_object_;
03446         tf::Transform orig, cur;
03447         tf::poseMsgToTF(coll.poses[0], orig);
03448         tf::poseMsgToTF(feedback->pose, cur);
03449         tf::Transform nt = orig.inverse()*cur;
03450         if(last_resize_handle_ == menu_entry_maps_["Collision Object"]["Grow"]) {
03451           if(coll.shapes[0].type == arm_navigation_msgs::Shape::BOX) {
03452             coll.shapes[0].dimensions[0] += fabs(nt.getOrigin().x());
03453             coll.shapes[0].dimensions[1] += fabs(nt.getOrigin().y());
03454             coll.shapes[0].dimensions[2] += fabs(nt.getOrigin().z());
03455           } else if(coll.shapes[0].type == arm_navigation_msgs::Shape::CYLINDER) {
03456             coll.shapes[0].dimensions[0] += fmax(fabs(nt.getOrigin().x()), fabs(nt.getOrigin().y()));
03457             coll.shapes[0].dimensions[1] += fabs(nt.getOrigin().z());
03458           } else if(coll.shapes[0].type == arm_navigation_msgs::Shape::SPHERE) {
03459             coll.shapes[0].dimensions[0] += fmax(fmax(fabs(nt.getOrigin().x()), fabs(nt.getOrigin().y())), fabs(nt.getOrigin().z()));
03460           }
03461         } else {
03462           //shrinking
03463           if(nt.getOrigin().x() > 0) {
03464             nt.getOrigin().setX(-nt.getOrigin().x());
03465           }
03466           if(nt.getOrigin().y() > 0) {
03467             nt.getOrigin().setY(-nt.getOrigin().y());
03468           }
03469           if(nt.getOrigin().z() > 0) {
03470             nt.getOrigin().setZ(-nt.getOrigin().z());
03471           }
03472           //can't be bigger than the current dimensions
03473           if(coll.shapes[0].type == arm_navigation_msgs::Shape::BOX) {
03474             nt.getOrigin().setX(fmax(nt.getOrigin().x(), -coll.shapes[0].dimensions[0]+.01));
03475             nt.getOrigin().setY(fmax(nt.getOrigin().y(), -coll.shapes[0].dimensions[1]+.01));
03476             nt.getOrigin().setZ(fmax(nt.getOrigin().z(), -coll.shapes[0].dimensions[2]+.01));
03477             coll.shapes[0].dimensions[0] += nt.getOrigin().x();
03478             coll.shapes[0].dimensions[1] += nt.getOrigin().y();
03479             coll.shapes[0].dimensions[2] += nt.getOrigin().z();
03480           } else if(coll.shapes[0].type == arm_navigation_msgs::Shape::CYLINDER) {
03481             nt.getOrigin().setX(fmax(nt.getOrigin().x(), -coll.shapes[0].dimensions[0]+.01));
03482             nt.getOrigin().setY(fmax(nt.getOrigin().y(), -coll.shapes[0].dimensions[0]+.01));
03483             nt.getOrigin().setZ(fmax(nt.getOrigin().z(), -coll.shapes[0].dimensions[1]+.01));
03484             coll.shapes[0].dimensions[0] += fmin(nt.getOrigin().x(), nt.getOrigin().y());
03485             coll.shapes[0].dimensions[1] += nt.getOrigin().z();
03486           } else if(coll.shapes[0].type == arm_navigation_msgs::Shape::SPHERE) {
03487             nt.getOrigin().setX(fmax(nt.getOrigin().x(), -coll.shapes[0].dimensions[0]+.01));
03488             nt.getOrigin().setY(fmax(nt.getOrigin().y(), -coll.shapes[0].dimensions[0]+.01));
03489             nt.getOrigin().setZ(fmax(nt.getOrigin().z(), -coll.shapes[0].dimensions[0]+.01));
03490             coll.shapes[0].dimensions[0] += fmin(fmin(nt.getOrigin().x(), nt.getOrigin().y()), nt.getOrigin().z());
03491           }
03492         }
03493         nt.setOrigin(nt.getOrigin()*.5);
03494         tf::poseTFToMsg(orig*nt, coll.poses[0]);
03495         
03496         createSelectableMarkerFromCollisionObject(coll, coll.id, coll.id, (*selectable_objects_)[name].color_, false);
03497         (*selectable_objects_)[name].control_marker_.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
03498         
03499         interactive_marker_server_->insert((*selectable_objects_)[name].control_marker_,
03500                                            collision_object_movement_feedback_ptr_);
03501         menu_handler_map_["Collision Object"].apply(*interactive_marker_server_,
03502                                                     (*selectable_objects_)[name].control_marker_.name);
03503         interactive_marker_server_->applyChanges();
03504         sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03505       }
03506       break;
03507     case InteractiveMarkerFeedback::MOUSE_DOWN:
03508       if(feedback->control_name == "button") {
03509         interactive_marker_server_->erase((*selectable_objects_)[name].control_marker_.name);
03510         (*selectable_objects_)[name].selection_marker_.pose = feedback->pose;
03511         (*selectable_objects_)[name].selection_marker_.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
03512         interactive_marker_server_->insert((*selectable_objects_)[name].selection_marker_,
03513                                            collision_object_selection_feedback_ptr_);
03514         menu_handler_map_["Collision Object Selection"].apply(*interactive_marker_server_,
03515                                                               (*selectable_objects_)[name].selection_marker_.name);
03516       } 
03517       break;
03518     case InteractiveMarkerFeedback::MENU_SELECT:
03519       if(feedback->menu_entry_id == menu_entry_maps_["Collision Object"]["Delete"])
03520       {
03521         deleteCollisionObject(name);
03522         sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03523         selectable_objects_->erase(name);
03524       }
03525       else if(feedback->menu_entry_id == menu_entry_maps_["Collision Object"]["Deselect"])
03526       {
03527         interactive_marker_server_->erase((*selectable_objects_)[name].control_marker_.name);
03528         (*selectable_objects_)[name].selection_marker_.pose = feedback->pose;
03529         (*selectable_objects_)[name].selection_marker_.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
03530         interactive_marker_server_->insert((*selectable_objects_)[name].selection_marker_,
03531                                            collision_object_selection_feedback_ptr_);
03532         menu_handler_map_["Collision Object Selection"].apply(*interactive_marker_server_,
03533                                                               (*selectable_objects_)[name].selection_marker_.name);
03534 
03535       } else if(feedback->menu_entry_id == menu_entry_maps_["Collision Object"]["Off"] || 
03536                 feedback->menu_entry_id == menu_entry_maps_["Collision Object"]["Grow"] ||
03537                 feedback->menu_entry_id == menu_entry_maps_["Collision Object"]["Shrink"]) {  
03538         menu_handler_map_["Collision Object"].setCheckState(last_resize_handle_, MenuHandler::UNCHECKED);
03539         last_resize_handle_ = feedback->menu_entry_id;
03540         menu_handler_map_["Collision Object"].setCheckState(last_resize_handle_, MenuHandler::CHECKED);
03541         menu_handler_map_["Collision Object"].reApply(*interactive_marker_server_);
03542       } else if(feedback->menu_entry_id == menu_entry_maps_["Collision Object"]["Attach"]) {
03543         (*selectable_objects_)[name].control_marker_.pose = feedback->pose;
03544         attachObjectCallback(name);
03545       }
03546       break;
03547     case InteractiveMarkerFeedback::POSE_UPDATE:
03548       break;
03549   }
03550 
03551   interactive_marker_server_->applyChanges();
03552 }
03553 
03554 void PlanningSceneEditor::changeToAttached(const std::string& name)
03555 {
03556   (*selectable_objects_)[name].selection_marker_.pose = (*selectable_objects_)[name].control_marker_.pose;
03557   (*selectable_objects_)[name].selection_marker_.description = "attached_"+name;
03558   interactive_marker_server_->erase((*selectable_objects_)[name].control_marker_.name);
03559   (*selectable_objects_)[name].selection_marker_.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
03560   interactive_marker_server_->insert((*selectable_objects_)[name].selection_marker_,
03561                                      attached_collision_object_feedback_ptr_);
03562   menu_handler_map_["Attached Collision Object"].apply(*interactive_marker_server_,
03563                                                      (*selectable_objects_)[name].selection_marker_.name);
03564   interactive_marker_server_->applyChanges();
03565 }
03566 
03567 void PlanningSceneEditor::attachedCollisionObjectInteractiveCallback(const InteractiveMarkerFeedbackConstPtr &feedback)
03568 {
03569   std::string name = feedback->marker_name.substr(0, feedback->marker_name.rfind("_selection"));
03570 
03571   switch (feedback->event_type)
03572   {
03573   case InteractiveMarkerFeedback::BUTTON_CLICK:
03574     {
03575       if((*selectable_objects_)[name].selection_marker_.description.empty()) {
03576         (*selectable_objects_)[name].selection_marker_.description = "attached_"+(*selectable_objects_)[name].collision_object_.id;
03577       } else {
03578         (*selectable_objects_)[name].selection_marker_.description = "";
03579       }
03580       interactive_marker_server_->insert((*selectable_objects_)[name].selection_marker_,
03581                                           attached_collision_object_feedback_ptr_);
03582       std_msgs::Header header;
03583       header.frame_id = cm_->getWorldFrameId();
03584       header.stamp = ros::Time::now();
03585       interactive_marker_server_->setPose(feedback->marker_name,
03586                                           (*selectable_objects_)[name].collision_object_.poses[0],
03587                                           header);
03588       menu_handler_map_["Attached Collision Object"].apply(*interactive_marker_server_,
03589                                                            (*selectable_objects_)[name].selection_marker_.name);
03590       interactive_marker_server_->applyChanges();
03591     }
03592     break;
03593   case InteractiveMarkerFeedback::MENU_SELECT:
03594     if(feedback->menu_entry_id == menu_entry_maps_["Attached Collision Object"]["Detach"])
03595     {
03596       (*selectable_objects_)[name].detach_ = true;
03597       
03598       (*selectable_objects_)[name].control_marker_.pose = (*selectable_objects_)[name].collision_object_.poses[0];
03599       (*selectable_objects_)[name].control_marker_.description = (*selectable_objects_)[name].collision_object_.id;
03600       (*selectable_objects_)[name].selection_marker_.description = "";
03601       interactive_marker_server_->erase((*selectable_objects_)[name].selection_marker_.name);
03602       interactive_marker_server_->insert((*selectable_objects_)[name].control_marker_,
03603                                          collision_object_movement_feedback_ptr_);
03604       menu_handler_map_["Collision Object"].apply(*interactive_marker_server_,
03605                                                   (*selectable_objects_)[name].control_marker_.name);
03606       sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03607       interactive_marker_server_->applyChanges();
03608     }
03609     break;
03610   default:
03611     break;
03612   }
03613 }
03614 std::string PlanningSceneEditor::createMeshObject(const std::string& name,
03615                                                   geometry_msgs::Pose pose,
03616                                                   const std::string& filename,
03617                                                   const tf::Vector3& scale,
03618                                                   std_msgs::ColorRGBA color)
03619 {
03620   shapes::Mesh* mesh = shapes::createMeshFromFilename(filename, &scale);
03621   if(mesh == NULL) {
03622     return "";
03623   }
03624   arm_navigation_msgs::Shape object;
03625   if(!planning_environment::constructObjectMsg(mesh, object)) {
03626     ROS_WARN_STREAM("Object construction fails");
03627     return "";
03628   }
03629   delete mesh;
03630   arm_navigation_msgs::CollisionObject collision_object;
03631   collision_object.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
03632   collision_object.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
03633   collision_object.header.frame_id = cm_->getWorldFrameId();
03634   if(name.empty()) {
03635     collision_object.id = generateNewCollisionObjectId();
03636   } else {
03637     collision_object.id = name;
03638   }
03639   collision_object.shapes.push_back(object);
03640   collision_object.poses.push_back(pose);
03641 
03642   lockScene();
03643   createSelectableMarkerFromCollisionObject(collision_object, collision_object.id, collision_object.id, color);
03644 
03645   ROS_INFO("Created collision object.");
03646   ROS_INFO("Sending planning scene %s", current_planning_scene_name_.c_str());
03647 
03648   sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03649 
03650   unlockScene();
03651   return collision_object.id;
03652 }
03653 
03654 std::string PlanningSceneEditor::createCollisionObject(const std::string& name,
03655                                                        geometry_msgs::Pose pose, PlanningSceneEditor::GeneratedShape shape,
03656                                                        float scaleX, float scaleY, float scaleZ, std_msgs::ColorRGBA color,
03657                                                        bool selectable=false)
03658 {
03659   lockScene();
03660   arm_navigation_msgs::CollisionObject collision_object;
03661   collision_object.operation.operation = arm_navigation_msgs::CollisionObjectOperation::ADD;
03662   collision_object.header.stamp = ros::Time(ros::Time::now().toSec());
03663 
03664   ROS_INFO_ONCE("Using %s as frame_id for collision object.",cm_->getWorldFrameId().c_str());
03665   collision_object.header.frame_id = cm_->getWorldFrameId();
03666   //ros::param::param<std::string>("~world_frame",collision_object.header.frame_id,"base_link");
03667   //cout << "collision_object.header.frame_id==" << collision_object.header.frame_id << endl;;
03668 
03669   if(name.empty()) {
03670     collision_object.id = generateNewCollisionObjectId();
03671   } else {
03672     collision_object.id = name;
03673   }
03674   arm_navigation_msgs::Shape object;
03675 
03676   switch (shape)
03677   {
03678     case PlanningSceneEditor::Box:
03679       object.type = arm_navigation_msgs::Shape::BOX;
03680       object.dimensions.resize(3);
03681       object.dimensions[0] = scaleX;
03682       object.dimensions[1] = scaleY;
03683       object.dimensions[2] = scaleZ;
03684       break;
03685     case PlanningSceneEditor::Cylinder:
03686       object.type = arm_navigation_msgs::Shape::CYLINDER;
03687       object.dimensions.resize(2);
03688       object.dimensions[0] = scaleX * 0.5f;
03689       object.dimensions[1] = scaleZ;
03690       break;
03691     case PlanningSceneEditor::Sphere:
03692       object.type = arm_navigation_msgs::Shape::SPHERE;
03693       object.dimensions.resize(1);
03694       object.dimensions[0] = scaleX * 0.5f;
03695       break;
03696     default:
03697       object.type = arm_navigation_msgs::Shape::SPHERE;
03698       object.dimensions.resize(1);
03699       object.dimensions[0] = scaleX * 0.5f;
03700       break;
03701   };
03702 
03703   collision_object.shapes.push_back(object);
03704   collision_object.poses.push_back(pose);
03705 
03706   createSelectableMarkerFromCollisionObject(collision_object, collision_object.id, collision_object.id, color,selectable);
03707 
03708   ROS_INFO("Created collision object.");
03709   ROS_INFO("Sending planning scene %s", current_planning_scene_name_.c_str());
03710 
03711   sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03712 
03713   unlockScene();
03714   return collision_object.id;
03715 
03716 }
03717 
03718 void PlanningSceneEditor::attachCollisionObject(const std::string& name,
03719                                                 const std::string& link_name,
03720                                                 const std::vector<std::string>& touch_links) {
03721   lockScene();
03722   if(selectable_objects_->find(name) == selectable_objects_->end()) {
03723     ROS_WARN("Must already have selectable object to add collision object");
03724     unlockScene();
03725     return;
03726   }
03727 
03728   SelectableObject& selectable = (*selectable_objects_)[name];
03729 
03730   selectable.attached_collision_object_.object = selectable.collision_object_;
03731   selectable.attached_collision_object_.link_name = link_name;
03732   selectable.attached_collision_object_.touch_links = touch_links;
03733   selectable.attached_collision_object_.object.operation.operation = selectable.attached_collision_object_.object.operation.ADD; 
03734   selectable.attach_ = true;
03735   //now we need to map the collision object pose into the attached object pose
03736   geometry_msgs::Pose p = selectable.attached_collision_object_.object.poses[0];
03737   geometry_msgs::PoseStamped ret_pose;
03738   ROS_DEBUG_STREAM("Before attach object pose frame " << selectable.attached_collision_object_.object.header.frame_id << " is " 
03739                   << p.position.x << " " << p.position.y << " " << p.position.z); 
03740   cm_->convertPoseGivenWorldTransform(*robot_state_,
03741                                       link_name, 
03742                                       selectable.attached_collision_object_.object.header,
03743                                       selectable.attached_collision_object_.object.poses[0],
03744                                       ret_pose);
03745   selectable.attached_collision_object_.object.header = ret_pose.header;
03746   selectable.attached_collision_object_.object.poses[0] = ret_pose.pose;
03747   ROS_DEBUG_STREAM("Converted attach object pose frame " << ret_pose.header.frame_id << " is " << ret_pose.pose.position.x << " " << ret_pose.pose.position.y << " " << ret_pose.pose.position.z); 
03748   sendPlanningScene(planning_scene_map_[current_planning_scene_name_]);
03749   unlockScene();
03750 }
03751 
03752 bool PlanningSceneEditor::solveIKForEndEffectorPose(MotionPlanRequestData& data,
03753                                                     planning_scene_utils::PositionType type, 
03754                                                     bool coll_aware,
03755                                                     double change_redundancy)
03756 {
03757   kinematics_msgs::PositionIKRequest ik_request;
03758   ik_request.ik_link_name = data.getEndEffectorLink();
03759   ik_request.pose_stamped.header.frame_id = cm_->getWorldFrameId();
03760   ik_request.pose_stamped.header.stamp = ros::Time(ros::/*WallTime*/Time::now().toSec());
03761   
03762   ROS_DEBUG("Solving IK for %s link in %s world frame id.",ik_request.ik_link_name.c_str(),cm_->getWorldFrameId().c_str());
03763 
03764   KinematicState* state = NULL;
03765   if(type == StartPosition)
03766   {
03767     state = data.getStartState();
03768   }
03769   else
03770   {
03771     state = data.getGoalState();
03772   }
03773 
03774   tf::poseTFToMsg(state->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform(), ik_request.pose_stamped.pose);
03775 
03776   convertKinematicStateToRobotState(*state, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
03777                                     ik_request.robot_state);
03778   ik_request.ik_seed_state = ik_request.robot_state;
03779 
03780   map<string, double> joint_values;
03781   vector<string> joint_names;
03782 
03783   if(coll_aware)
03784   {
03785     kinematics_msgs::GetConstraintAwarePositionIK::Request ik_req;
03786     kinematics_msgs::GetConstraintAwarePositionIK::Response ik_res;
03787     if(data.hasPathConstraints())
03788     {
03789       planning_scene_utils::PositionType other_type;
03790       if(type == StartPosition)
03791       {
03792         other_type = GoalPosition;
03793       }
03794       else
03795       {
03796         other_type = StartPosition;
03797       }
03798       MotionPlanRequest mpr;
03799       data.setGoalAndPathPositionOrientationConstraints(mpr, other_type);
03800       mpr.goal_constraints.position_constraints.clear();
03801         
03802       arm_navigation_msgs::ArmNavigationErrorCodes err;
03803       if(!cm_->isKinematicStateValid(*state, std::vector<std::string>(), err, mpr.goal_constraints, mpr.path_constraints))
03804       {
03805         ROS_DEBUG_STREAM("Violates rp constraints");
03806         return false;
03807       }
03808       ik_req.constraints = mpr.goal_constraints;
03809     }
03810     ik_req.ik_request = ik_request;
03811     ik_req.timeout = ros::Duration(0.8); // TODO make it configurable
03812     if(!(*collision_aware_ik_services_)[data.getEndEffectorLink()]->call(ik_req, ik_res))
03813     {
03814       ROS_INFO("Problem with ik service call");
03815       return false;
03816     }
03817     if(ik_res.error_code.val != ik_res.error_code.SUCCESS)
03818     {
03819       ROS_DEBUG_STREAM("Call yields bad error code " << ik_res.error_code.val);
03820       return false;
03821     }
03822     joint_names = ik_res.solution.joint_state.name;
03823 
03824     for(unsigned int i = 0; i < ik_res.solution.joint_state.name.size(); i++)
03825     {
03826       joint_values[ik_res.solution.joint_state.name[i]] = ik_res.solution.joint_state.position[i];
03827     }
03828 
03829   }
03830   else
03831   {
03832     kinematics_msgs::GetPositionIK::Request ik_req;
03833     kinematics_msgs::GetPositionIK::Response ik_res;
03834     ik_req.ik_request = ik_request;
03835     ik_req.timeout = ros::Duration(0.8); // TODO make it configurable
03836     if(!(*non_collision_aware_ik_services_)[data.getEndEffectorLink()]->call(ik_req, ik_res))
03837     {
03838       ROS_INFO("Problem with ik service call");
03839       return false;
03840     }
03841     if(ik_res.error_code.val != ik_res.error_code.SUCCESS)
03842     {
03843       ROS_DEBUG_STREAM("Call yields bad error code " << ik_res.error_code.val);
03844       return false;
03845     }
03846     for(unsigned int i = 0; i < ik_res.solution.joint_state.name.size(); i++)
03847     {
03848       joint_values[ik_res.solution.joint_state.name[i]] = ik_res.solution.joint_state.position[i];
03849     }
03850 
03851   }
03852 
03853   lockScene();
03854   state->setKinematicState(joint_values);
03855 
03856   if(coll_aware)
03857   {
03858     Constraints emp_con;
03859     ArmNavigationErrorCodes error_code;
03860 
03861     collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm_->getCurrentAllowedCollisionMatrix();
03862     cm_->disableCollisionsForNonUpdatedLinks(data.getGroupName());
03863 
03864     if(!cm_->isKinematicStateValid(*state, joint_names, error_code, emp_con, emp_con, true))
03865     {
03866       ROS_INFO_STREAM("Problem with response");
03867       cm_->setAlteredAllowedCollisionMatrix(acm);
03868       unlockScene();
03869       return false;
03870     }
03871     cm_->setAlteredAllowedCollisionMatrix(acm);
03872   }
03873 
03874   if(type == StartPosition)
03875   {
03876     data.setStartStateValues(joint_values);
03877     convertKinematicStateToRobotState(*state, ros::Time(ros::/*WallTime*/Time::now().toSec()), cm_->getWorldFrameId(),
03878                                       data.getMotionPlanRequest().start_state);
03879     data.setLastGoodStartPose((state->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform()));
03880   }
03881   else
03882   {
03883     data.setGoalStateValues(joint_values);
03884     data.setLastGoodGoalPose((state->getLinkState(data.getEndEffectorLink())->getGlobalLinkTransform()));
03885   }
03886   unlockScene();
03887 
03888   return true;
03889 }
03890 
03891 void PlanningSceneEditor::setJointState(MotionPlanRequestData& data, PositionType position, std::string& jointName,
03892                                         tf::Transform value)
03893 {
03894   KinematicState* currentState = NULL;
03895 
03896   if(position == StartPosition)
03897   {
03898     currentState = data.getStartState();
03899   }
03900   else if(position == GoalPosition)
03901   {
03902     currentState = data.getGoalState();
03903   }
03904 
03905   if(currentState == NULL)
03906   {
03907     ROS_ERROR("Robot state for request %s is null!", data.getName().c_str());
03908     return;
03909   }
03910 
03911   string parentLink = currentState->getKinematicModel()->getJointModel(jointName)->getParentLinkModel()->getName();
03912   string childLink = currentState->getKinematicModel()->getJointModel(jointName)->getChildLinkModel()->getName();
03913   KinematicState::JointState* jointState = currentState->getJointState(jointName);
03914   const KinematicModel::JointModel* jointModel = jointState->getJointModel();
03915 
03916   bool isRotational = (dynamic_cast<const KinematicModel::RevoluteJointModel*> (jointModel) != NULL);
03917   bool isPrismatic = (dynamic_cast<const KinematicModel::PrismaticJointModel*> (jointModel) != NULL);
03918 
03919   KinematicState::LinkState* linkState = currentState->getLinkState(parentLink);
03920   tf::Transform transformedValue;
03921 
03922   if(isPrismatic)
03923   {
03924     value.setRotation(jointState->getVariableTransform().getRotation());
03925     transformedValue = currentState->getLinkState(childLink)->getLinkModel()->getJointOriginTransform().inverse()
03926         * linkState->getGlobalLinkTransform().inverse() * value;
03927   }
03928   else if(isRotational)
03929   {
03930     transformedValue = currentState->getLinkState(childLink)->getLinkModel()->getJointOriginTransform().inverse()
03931         * linkState->getGlobalLinkTransform().inverse() * value;
03932   }
03933 
03934   tf::Transform oldState = jointState->getVariableTransform();
03935   jointState->setJointStateValues(transformedValue);
03936 
03937   map<string, double> stateMap;
03938   if(currentState->isJointWithinBounds(jointName))
03939   {
03940     currentState->getKinematicStateValues(stateMap);
03941     currentState->setKinematicState(stateMap);
03942 
03943 
03944     // Send state to robot model.
03945     if(position == StartPosition)
03946     {
03947       convertKinematicStateToRobotState(*currentState,
03948                                         data.getMotionPlanRequest().start_state.joint_state.header.stamp,
03949                                         data.getMotionPlanRequest().start_state.joint_state.header.frame_id,
03950                                         data.getMotionPlanRequest().start_state);
03951     }
03952     else
03953     {
03954       std::vector<JointConstraint>& constraints = data.getMotionPlanRequest().goal_constraints.joint_constraints;
03955 
03956       for(size_t i = 0; i < constraints.size(); i++)
03957       {
03958         JointConstraint& constraint = constraints[i];
03959         constraint.position = stateMap[constraint.joint_name];
03960       }
03961     }
03962 
03963 
03964     createIKController(data, position, true);
03965     createJointMarkers(data, position);
03966   }
03967   else
03968   {
03969     jointState->setJointStateValues(oldState);
03970   }
03971 }
03972 
03973 void PlanningSceneEditor::deleteJointMarkers(MotionPlanRequestData& data, PositionType type)
03974 {
03975   vector<string> jointNames = data.getJointNamesInGoal();
03976   for(size_t i = 0; i < jointNames.size(); i++)
03977   {
03978     if(type == StartPosition)
03979     {
03980       std::string markerName = jointNames[i] + "_mpr_" + data.getName() + "_start_control";
03981 
03982       InteractiveMarker dummy;
03983       if(interactive_marker_server_->get(markerName, dummy))
03984       {
03985         interactive_marker_server_->erase(markerName);
03986       }
03987     }
03988     else
03989     {
03990       std::string markerName = jointNames[i] + "_mpr_" + data.getName() + "_end_control";
03991       InteractiveMarker dummy;
03992       if(interactive_marker_server_->get(markerName, dummy))
03993       {
03994         interactive_marker_server_->erase(markerName);
03995       }
03996     }
03997   }
03998 }
03999 
04000 void PlanningSceneEditor::createJointMarkers(MotionPlanRequestData& data, PositionType position)
04001 {
04002   vector<string> jointNames = data.getJointNamesInGoal();
04003 
04004   KinematicState* state = NULL;
04005   std::string sauce = "";
04006 
04007   if(position == StartPosition)
04008   {
04009     state = data.getStartState();
04010     sauce = "_start_control";
04011   }
04012   else if(position == GoalPosition)
04013   {
04014     state = data.getGoalState();
04015     sauce = "_end_control";
04016   }
04017 
04018   // For each joint model, find the location of its axis and make a control there.
04019   for(size_t i = 0; i < jointNames.size(); i++)
04020   {
04021     const string& jointName = jointNames[i];
04022     KinematicModel::JointModel* model =
04023         (KinematicModel::JointModel*)(state->getKinematicModel()->getJointModel(jointName));
04024 
04025     std::string controlName = jointName + "_mpr_" + data.getName() + sauce;
04026     joint_clicked_map_[controlName] = false;
04027 
04028     if(model->getParentLinkModel() != NULL)
04029     {
04030       string parentLinkName = model->getParentLinkModel()->getName();
04031       string childLinkName = model->getChildLinkModel()->getName();
04032       tf::Transform transform = state->getLinkState(parentLinkName)->getGlobalLinkTransform()
04033           * (state->getKinematicModel()->getLinkModel(childLinkName)->getJointOriginTransform()
04034               * (state->getJointState(jointName)->getVariableTransform()));
04035 
04036       joint_prev_transform_map_[controlName] = transform;
04037 
04038       InteractiveMarker dummy;
04039       if(interactive_marker_server_->get(controlName, dummy))
04040       {
04041         dummy.header.frame_id = cm_->getWorldFrameId();
04042         interactive_marker_server_->setPose(controlName, toGeometryPose(transform), dummy.header);
04043         continue;
04044       }
04045 
04046       const shapes::Shape* linkShape = model->getChildLinkModel()->getLinkShape();
04047       const shapes::Mesh* meshShape = dynamic_cast<const shapes::Mesh*> (linkShape);
04048 
04049       KinematicModel::RevoluteJointModel* revoluteJoint = dynamic_cast<KinematicModel::RevoluteJointModel*> (model);
04050       KinematicModel::PrismaticJointModel* prismaticJoint = dynamic_cast<KinematicModel::PrismaticJointModel*> (model);
04051       double maxDimension = 0.0f;
04052       if(meshShape != NULL)
04053       {
04054 
04055         for(unsigned int i = 0; i < meshShape->vertexCount; i++)
04056         {
04057           double x = meshShape->vertices[3 * i];
04058           double y = meshShape->vertices[3 * i];
04059           double z = meshShape->vertices[3 * i];
04060 
04061           if(abs(maxDimension) < abs(sqrt(x * x + y * y + z * z)))
04062           {
04063             maxDimension = abs(x);
04064           }
04065 
04066         }
04067 
04068         maxDimension *= 3.0;
04069 
04070         maxDimension = max(0.15, maxDimension);
04071         maxDimension = min(0.5, maxDimension);
04072       }
04073       else
04074       {
04075         maxDimension = 0.15;
04076       }
04077 
04078       if(revoluteJoint != NULL)
04079       {
04080         makeInteractive1DOFRotationMarker(transform, revoluteJoint->axis_, controlName, "", (float)maxDimension,
04081                                           state->getJointState(jointName)->getJointStateValues()[0]);
04082       }
04083       else if(prismaticJoint != NULL)
04084       {
04085         makeInteractive1DOFTranslationMarker(transform, prismaticJoint->axis_, controlName, "", (float)maxDimension,
04086                                              state-> getJointState(jointName)->getJointStateValues()[0]);
04087       }
04088 
04089     }
04090   }
04091   interactive_marker_server_->applyChanges();
04092 }
04093 
04094 void PlanningSceneEditor::makeInteractive1DOFTranslationMarker(tf::Transform transform, tf::Vector3 axis, string name,
04095                                                                string description, float scale, float value)
04096 {
04097   InteractiveMarker marker;
04098   marker.header.frame_id = cm_->getWorldFrameId();
04099   marker.pose.position.x = transform.getOrigin().x();
04100   marker.pose.position.y = transform.getOrigin().y();
04101   marker.pose.position.z = transform.getOrigin().z();
04102   marker.pose.orientation.w = transform.getRotation().w();
04103   marker.pose.orientation.x = transform.getRotation().x();
04104   marker.pose.orientation.y = transform.getRotation().y();
04105   marker.pose.orientation.z = transform.getRotation().z();
04106   marker.scale = scale;
04107   marker.name = name;
04108   marker.description = description;
04109   InteractiveMarker dummy;
04110   InteractiveMarkerControl control;
04111   if(interactive_marker_server_->get(marker.name, dummy))
04112   {
04113     interactive_marker_server_->setPose(marker.name, marker.pose, marker.header);
04114   }
04115   else
04116   {
04117     control.orientation.x = axis.x();
04118     control.orientation.y = axis.z();
04119     control.orientation.z = axis.y();
04120     control.orientation.w = 1;
04121     control.independent_marker_orientation = false;
04122     control.always_visible = false;
04123     control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
04124     marker.controls.push_back(control);
04125     interactive_marker_server_->insert(marker);
04126     interactive_marker_server_->setCallback(marker.name, joint_control_feedback_ptr_);
04127   }
04128 
04129 }
04130 
04131 void PlanningSceneEditor::makeInteractive1DOFRotationMarker(tf::Transform transform, tf::Vector3 axis, string name,
04132                                                             string description, float scale, float angle)
04133 {
04134   InteractiveMarker marker;
04135   marker.header.frame_id = cm_->getWorldFrameId();
04136   marker.pose.position.x = transform.getOrigin().x();
04137   marker.pose.position.y = transform.getOrigin().y();
04138   marker.pose.position.z = transform.getOrigin().z();
04139   marker.pose.orientation.w = transform.getRotation().w();
04140   marker.pose.orientation.x = transform.getRotation().x();
04141   marker.pose.orientation.y = transform.getRotation().y();
04142   marker.pose.orientation.z = transform.getRotation().z();
04143   marker.scale = scale;
04144   marker.name = name;
04145   marker.description = description;
04146 
04147   InteractiveMarker dummy;
04148   if(interactive_marker_server_->get(marker.name, dummy))
04149   {
04150     interactive_marker_server_->setPose(marker.name, marker.pose, marker.header);
04151   }
04152   else
04153   {
04154     InteractiveMarkerControl control;
04155     control.orientation.x = axis.x();
04156     control.orientation.y = axis.z();
04157     control.orientation.z = axis.y();
04158     control.orientation.w = 1;
04159     control.independent_marker_orientation = false;
04160     control.always_visible = false;
04161     control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
04162     marker.controls.push_back(control);
04163     interactive_marker_server_->insert(marker);
04164     interactive_marker_server_->setCallback(marker.name, joint_control_feedback_ptr_);
04165   }
04166 }
04167 
04168 void PlanningSceneEditor::setIKControlsVisible(std::string id, PositionType type, bool visible)
04169 {
04170   if(!visible)
04171   {
04172     if(type == StartPosition)
04173     {
04174       interactive_marker_server_->erase((*ik_controllers_)[id].start_controller_.name);
04175     }
04176     else
04177     {
04178       interactive_marker_server_->erase((*ik_controllers_)[id].end_controller_.name);
04179     }
04180     interactive_marker_server_->applyChanges();
04181   }
04182   else
04183   {
04184     createIKController(motion_plan_map_[id], type, false);
04185     interactive_marker_server_->applyChanges();
04186   }
04187 }
04188 
04189 void PlanningSceneEditor::executeTrajectory(TrajectoryData& trajectory)
04190 {
04191   // if(params_.sync_robot_state_with_gazebo_)
04192   // {
04193   //   pr2_mechanism_msgs::ListControllers listControllers;
04194 
04195   //   if(!list_controllers_client_.call(listControllers.request, listControllers.response))
04196   //   {
04197   //     ROS_ERROR("Failed to get list of controllers!");
04198   //     return;
04199   //   }
04200 
04201   //   std::map<std::string, planning_models::KinematicModel::JointModelGroup*> jointModelGroupMap =
04202   //       cm_->getKinematicModel()->getJointModelGroupMap();
04203   //   planning_models::KinematicModel::JointModelGroup* rightGroup = NULL;
04204   //   planning_models::KinematicModel::JointModelGroup* leftGroup = NULL;
04205   //   if(params_.right_arm_group_ != "none")
04206   //   {
04207   //     rightGroup = jointModelGroupMap[params_.right_arm_group_];
04208   //   }
04209 
04210   //   if(params_.left_arm_group_ != "none")
04211   //   {
04212   //     leftGroup = jointModelGroupMap[params_.left_arm_group_];
04213   //   }
04214 
04215   //   pr2_mechanism_msgs::SwitchController switchControllers;
04216   //   switchControllers.request.stop_controllers = listControllers.response.controllers;
04217   //   if(!switch_controllers_client_.call(switchControllers.request, switchControllers.response))
04218   //   {
04219   //     ROS_ERROR("Failed to shut down controllers!");
04220   //     return;
04221   //   }
04222 
04223   //   ROS_INFO("Shut down controllers.");
04224 
04225   //   MotionPlanRequestData& motionPlanData = motion_plan_map_[getMotionPlanRequestNameFromId(trajectory.getMotionPlanRequestId())];
04226 
04227   //   gazebo_msgs::SetModelConfiguration modelConfiguration;
04228   //   modelConfiguration.request.model_name = params_.gazebo_model_name_;
04229   //   modelConfiguration.request.urdf_param_name = params_.robot_description_param_;
04230 
04231   //   for(size_t i = 0; i < motionPlanData.getStartState()->getJointStateVector().size(); i++)
04232   //   {
04233   //     const KinematicState::JointState* jointState = motionPlanData.getStartState()->getJointStateVector()[i];
04234   //     if(jointState->getJointStateValues().size() > 0)
04235   //     {
04236   //       modelConfiguration.request.joint_names.push_back(jointState->getName());
04237   //       modelConfiguration.request.joint_positions.push_back(jointState->getJointStateValues()[0]);
04238   //     }
04239   //   }
04240 
04241   //   if(!gazebo_joint_state_client_.call(modelConfiguration.request, modelConfiguration.response))
04242   //   {
04243   //     ROS_ERROR("Failed to call gazebo set joint state client!");
04244   //     return;
04245   //   }
04246 
04247   //   ROS_INFO("Set joint state");
04248 
04249   //   if(!modelConfiguration.response.success)
04250   //   {
04251   //     ROS_ERROR("Failed to set gazebo model configuration to start state!");
04252   //     return;
04253   //   }
04254   //   ROS_INFO("Gazebo returned: %s", modelConfiguration.response.status_message.c_str());
04255 
04256   //   pr2_mechanism_msgs::SwitchController restartControllers;
04257   //   restartControllers.request.start_controllers = listControllers.response.controllers;
04258   //   if(!switch_controllers_client_.call(restartControllers.request, restartControllers.response))
04259   //   {
04260   //     ROS_ERROR("Failed to restart controllers: service call failed!");
04261   //     return;
04262   //   }
04263   //   else if(!restartControllers.response.ok)
04264   //   {
04265   //     ROS_ERROR("Failed to restart controllers: Response not ok!");
04266   //   }
04267 
04268   //   ROS_INFO("Restart controllers.");
04269 
04270   //   ros::Time::sleepUntil(ros::Time::now() + ros::Duration(0.5));
04271   //   SimpleActionClient<FollowJointTrajectoryAction>* controller = arm_controller_map_[trajectory.getGroupName()];
04272   //   FollowJointTrajectoryGoal goal;
04273   //   goal.trajectory.joint_names = trajectory.getTrajectory().joint_names;
04274   //   goal.trajectory.header.stamp = ros::Time::now() + ros::Duration(0.2);
04275   //   trajectory_msgs::JointTrajectoryPoint endPoint = trajectory.getTrajectory().points[0];
04276   //   endPoint.time_from_start = ros::Duration(1.0);
04277   //   goal.trajectory.points.push_back(endPoint);
04278   //   controller->sendGoalAndWait(goal, ros::Duration(1.0), ros::Duration(1.0));
04279   //   ros::Time::sleepUntil(ros::Time::now() + ros::Duration(1.0));
04280 
04281   // }
04282 
04283   SimpleActionClient<FollowJointTrajectoryAction>* controller = arm_controller_map_[trajectory.getGroupName()];
04284   FollowJointTrajectoryGoal goal;
04285   goal.trajectory = trajectory.getTrajectory();
04286   goal.trajectory.header.stamp = ros::Time::now() + ros::Duration(0.2);
04287   controller->sendGoal(goal, boost::bind(&PlanningSceneEditor::controllerDoneCallback, this, _1, _2));
04288   logged_group_name_ = trajectory.getGroupName();
04289   logged_motion_plan_request_ = getMotionPlanRequestNameFromId(trajectory.getMotionPlanRequestId());
04290   logged_trajectory_ = trajectory.getTrajectory();
04291   logged_trajectory_.points.clear();
04292   logged_trajectory_controller_error_.points.clear();
04293   logged_trajectory_start_time_ = ros::Time::now() + ros::Duration(0.2);
04294   monitor_status_ = Executing;
04295 
04296 }
04297 
04298 void PlanningSceneEditor::randomlyPerturb(MotionPlanRequestData& mpr, PositionType type)
04299 {
04300   lockScene();
04301 
04302   //Joint space method
04303 
04304   KinematicState* currentState = NULL;
04305 
04306   if(type == StartPosition)
04307   {
04308     currentState = mpr.getStartState();
04309   }
04310   else
04311   {
04312     currentState = mpr.getGoalState();
04313   }
04314 
04315   vector<KinematicState::JointState*>& jointStates = currentState->getJointStateVector();
04316   std::map<string, double> originalState;
04317   std::map<string, double> stateMap;
04318   bool goodSolution = false;
04319   int numIterations = 0;
04320   int maxIterations = 100;
04321   while(!goodSolution && numIterations < maxIterations)
04322   {
04323     currentState->getKinematicStateValues(stateMap);
04324     for(size_t i = 0; i < jointStates.size(); i++)
04325     {
04326       KinematicState::JointState* jointState = jointStates[i];
04327       map<string, pair<double, double> > bounds = jointState->getJointModel()->getAllVariableBounds();
04328       for(map<string, pair<double, double> >::iterator it = bounds.begin(); it != bounds.end(); it++)
04329       {
04330         if(!mpr.isJointNameInGoal(it->first))
04331         {
04332           continue;
04333         }
04334         double range = it->second.second - it->second.first;
04335         if(range == std::numeric_limits<double>::infinity())
04336         {
04337           continue;
04338         }
04339         double randVal = ((double)random() / (double)RAND_MAX) * (range * 0.99) + it->second.first;
04340         stateMap[it->first] = randVal;
04341       }
04342     }
04343 
04344     currentState->setKinematicState(stateMap);
04345 
04346     if(!cm_->isKinematicStateInCollision(*currentState))
04347     {
04348       goodSolution = true;
04349       break;
04350     }
04351     numIterations++;
04352   }
04353 
04354   if(!goodSolution)
04355   {
04356     currentState->setKinematicState(originalState);
04357     unlockScene();
04358     return;
04359   }
04360   else
04361   {
04362     ROS_INFO("Found a good random solution in %d iterations", numIterations);
04363   }
04364 
04365   if(type == StartPosition)
04366   {
04367     convertKinematicStateToRobotState(*currentState, mpr.getMotionPlanRequest().start_state.joint_state.header.stamp,
04368                                       mpr.getMotionPlanRequest().start_state.joint_state.header.frame_id,
04369                                       mpr.getMotionPlanRequest().start_state);
04370   }
04371   else
04372   {
04373     std::vector<JointConstraint>& constraints = mpr.getMotionPlanRequest().goal_constraints.joint_constraints;
04374     for(size_t i = 0; i < constraints.size(); i++)
04375     {
04376       JointConstraint& constraint = constraints[i];
04377       constraint.position = stateMap[constraint.joint_name];
04378     }
04379   }
04380   mpr.setHasGoodIKSolution(true, type);
04381   createIKController(mpr, type, false);
04382   mpr.setJointControlsVisible(mpr.areJointControlsVisible(), this);
04383   interactive_marker_server_->applyChanges();
04384   mpr.refreshColors();
04385   unlockScene();
04386 
04387 }
04388 
04389 void PlanningSceneEditor::controllerDoneCallback(const actionlib::SimpleClientGoalState& state,
04390                                                  const control_msgs::FollowJointTrajectoryResultConstPtr& result)
04391 {
04392   MotionPlanRequestData& mpr = motion_plan_map_[logged_motion_plan_request_];
04393   TrajectoryData logged(mpr.getNextTrajectoryId(), "Robot Monitor", logged_group_name_, logged_trajectory_);
04394   logged.setTrajectoryError(logged_trajectory_controller_error_);
04395   logged.setBadPoint(-1);
04396   logged.setDuration(ros::Time::now() - logged_trajectory_start_time_);
04397   logged.setTrajectoryRenderType(Temporal);
04398   logged.setMotionPlanRequestId(mpr.getId());
04399   logged.trajectory_error_code_.val = result->error_code;
04400   mpr.addTrajectoryId(logged.getId());
04401   trajectory_map_[mpr.getName()][logged.getName()] = logged;
04402   logged_trajectory_.points.clear();
04403   logged_trajectory_controller_error_.points.clear();
04404   //logged_group_name_ = "";
04405   //logged_motion_plan_request_ = "";
04406   selected_trajectory_name_ = getTrajectoryNameFromId(logged.getId());
04407   updateState();
04408   ROS_INFO("CREATING TRAJECTORY %s", logged.getName().c_str());
04409 
04410   // Keep recording a second trajectory to analize the overshoot
04411   monitor_status_ = WaitingForStop;
04412   time_of_controller_done_callback_ = ros::Time::now();
04413   time_of_last_moving_notification_ = ros::Time::now();
04414   logged_trajectory_start_time_ = ros::Time::now();
04415 }
04416 
04417 void PlanningSceneEditor::armHasStoppedMoving()
04418 {
04419   MotionPlanRequestData& mpr = motion_plan_map_[logged_motion_plan_request_];
04420   TrajectoryData logged(mpr.getNextTrajectoryId(), "Overshoot Monitor", logged_group_name_, logged_trajectory_);
04421   logged.setTrajectoryError(logged_trajectory_controller_error_);
04422   logged.setBadPoint(-1);
04423   logged.setDuration(ros::Duration(0));
04424   logged.setTrajectoryRenderType(Temporal);
04425   logged.setMotionPlanRequestId(mpr.getId());
04426   logged.trajectory_error_code_.val = 0;
04427   mpr.addTrajectoryId(logged.getId());
04428   trajectory_map_[mpr.getName()][logged.getName()] = logged;
04429   logged_trajectory_.points.clear();
04430   logged_trajectory_controller_error_.points.clear();
04431   logged_group_name_ = "";
04432   logged_motion_plan_request_ = "";
04433   //selected_trajectory_name_ = getTrajectoryNameFromId(logged.getId());
04434   updateState();
04435   ROS_INFO("CREATING TRAJECTORY %s", logged.getName().c_str());
04436 
04437   monitor_status_ = idle;
04438 }
04439 
04440 void PlanningSceneEditor::getAllRobotStampedTransforms(const planning_models::KinematicState& state,
04441                                   vector<geometry_msgs::TransformStamped>& trans_vector, const ros::Time& stamp)
04442 {
04443   trans_vector.clear();
04444   const map<string, geometry_msgs::TransformStamped>& transforms = cm_->getSceneTransformMap();
04445   geometry_msgs::TransformStamped transvec;
04446   for(map<string, geometry_msgs::TransformStamped>::const_iterator it = transforms.begin(); it
04447       != transforms.end(); it++)
04448   {
04449     if(it->first != cm_->getWorldFrameId())
04450     {
04451       trans_vector.push_back(it->second);
04452     }
04453   }
04454   for(unsigned int i = 0; i < state.getLinkStateVector().size(); i++)
04455   {
04456     const planning_models::KinematicState::LinkState* ls = state.getLinkStateVector()[i];
04457 
04458     if(ls->getName() != cm_->getWorldFrameId())
04459     {
04460       geometry_msgs::TransformStamped ts;
04461       ts.header.stamp = stamp;
04462       ts.header.frame_id = cm_->getWorldFrameId();
04463 
04464       ts.child_frame_id = ls->getName();
04465       tf::transformTFToMsg(ls->getGlobalLinkTransform(), ts.transform);
04466       trans_vector.push_back(ts);
04467     }
04468   }
04469 }
04470 
04471 void PlanningSceneEditor::sendTransformsAndClock()
04472 {
04473   if(robot_state_ == NULL)
04474   {
04475     return;
04476   }
04477 
04478   if(!params_.use_robot_data_)
04479   {
04480     ros::/*WallTime*/Time cur_time = ros::/*WallTime*/Time::now();
04481     rosgraph_msgs::Clock c;
04482     c.clock.nsec = cur_time.nsec;
04483     c.clock.sec = cur_time.sec;
04484     //clock_publisher_.publish(c);
04485 
04486 
04487     getAllRobotStampedTransforms(*robot_state_, robot_transforms_, c.clock);
04488     transform_broadcaster_.sendTransform(robot_transforms_);
04489   }
04490 }
04491 
04492 MenuHandler::EntryHandle PlanningSceneEditor::registerSubMenuEntry(string menu, string name, string subMenu,
04493                                                                    MenuHandler::FeedbackCallback& callback)
04494 {
04495 
04496   MenuHandler::EntryHandle toReturn = menu_handler_map_[menu].insert(menu_entry_maps_[menu][subMenu], name, callback);
04497   menu_entry_maps_[menu][name] = toReturn;
04498   return toReturn;
04499 }
04500 
04501 MenuHandler::EntryHandle PlanningSceneEditor::registerMenuEntry(string menu, string entryName,
04502                                                                 MenuHandler::FeedbackCallback& callback)
04503 {
04504   MenuHandler::EntryHandle toReturn = menu_handler_map_[menu].insert(entryName, callback);
04505   menu_entry_maps_[menu][entryName] = toReturn;
04506   return toReturn;
04507 }
04508 
04509 void PlanningSceneEditor::deleteTrajectory(unsigned int mpr_id, unsigned int traj_id)
04510 {
04511   if(!hasTrajectory(getMotionPlanRequestNameFromId(mpr_id),
04512                     getTrajectoryNameFromId(traj_id))) {
04513     ROS_WARN_STREAM("No trajectory " << traj_id << " in trajectories for " << mpr_id << " for deletion");
04514     return;
04515   }
04516   
04517   if(current_planning_scene_name_ == "") {
04518     ROS_WARN_STREAM("Shouldn't be calling without a planning scene");
04519     return;
04520   }
04521 
04522   lockScene();
04523   
04524   if(motion_plan_map_.find(getMotionPlanRequestNameFromId(mpr_id))
04525      == motion_plan_map_.end()) {
04526     ROS_WARN_STREAM("Can't find mpr id " << mpr_id);
04527     unlockScene();
04528     return;
04529   }
04530 
04531   MotionPlanRequestData& request_data = motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)];
04532   
04533   if(!request_data.hasTrajectoryId(traj_id)) {
04534     ROS_WARN_STREAM("Motion plan request " << mpr_id << " doesn't have trajectory id " << traj_id << " for deletion");
04535     unlockScene();
04536     return;
04537   }
04538   request_data.removeTrajectoryId(traj_id);
04539 
04540   TrajectoryData& traj = trajectory_map_[getMotionPlanRequestNameFromId(mpr_id)][getTrajectoryNameFromId(traj_id)];
04541     
04542   for(size_t i = 0; i < states_.size(); i++)
04543   {
04544     if(states_[i].state == traj.getCurrentState())
04545     {
04546       states_[i].state = NULL;
04547       states_[i].source = "Delete trajectory";
04548     }
04549   }
04550 
04551   traj.reset();
04552   trajectory_map_[getMotionPlanRequestNameFromId(mpr_id)].erase(getTrajectoryNameFromId(traj_id));
04553   if(trajectory_map_[getMotionPlanRequestNameFromId(mpr_id)].empty()) {
04554     trajectory_map_.erase(getMotionPlanRequestNameFromId(mpr_id));
04555   }
04556 
04557   unlockScene();
04558   interactive_marker_server_->applyChanges();
04559 }
04560 
04561 void PlanningSceneEditor::deleteMotionPlanRequest(const unsigned int& id,
04562                                                   std::vector<unsigned int>& erased_trajectories)
04563 {
04564   if(motion_plan_map_.find(getMotionPlanRequestNameFromId(id)) == motion_plan_map_.end())
04565   {
04566     ROS_WARN_STREAM("Trying to delete non-existent motion plan request " << id);
04567     return;
04568   }  
04569   lockScene();
04570   MotionPlanRequestData& motion_plan_data = motion_plan_map_[getMotionPlanRequestNameFromId(id)];
04571   for(size_t i = 0; i < states_.size(); i++)
04572   {
04573     if(states_[i].state == motion_plan_data.getStartState() || states_[i].state
04574        == motion_plan_data.getGoalState())
04575     {
04576       states_[i].state = NULL;
04577       states_[i].source = "Delete motion plan request";
04578     }
04579   }
04580   erased_trajectories.clear();
04581   for(std::set<unsigned int>::iterator it = motion_plan_data.getTrajectories().begin();
04582       it != motion_plan_data.getTrajectories().end();
04583       it++) {
04584     erased_trajectories.push_back(*it);
04585   }
04586   
04587   for(size_t i = 0; i < erased_trajectories.size(); i++)
04588   {
04589     deleteTrajectory(motion_plan_data.getId(), erased_trajectories[i]);
04590   }
04591   
04592   deleteJointMarkers(motion_plan_data, StartPosition);
04593   deleteJointMarkers(motion_plan_data, GoalPosition);
04594   interactive_marker_server_->erase(motion_plan_data.getName() + "_start_control");
04595   interactive_marker_server_->erase(motion_plan_data.getName() + "_end_control");
04596 
04597   motion_plan_data.reset();
04598   motion_plan_map_.erase(getMotionPlanRequestNameFromId(id));
04599 
04600   if(current_planning_scene_name_ == "") {
04601     ROS_WARN_STREAM("Shouldn't be trying to delete an MPR without a current planning scene");
04602   } else {
04603     PlanningSceneData& data = planning_scene_map_[current_planning_scene_name_];
04604     if(!data.hasMotionPlanRequestId(id)) {
04605       ROS_WARN_STREAM("Planning scene " << data.getId() << " doesn't have mpr id " << id << " for delete");
04606     } else {
04607       data.removeMotionPlanRequestId(id);
04608     }
04609   }
04610   updateState();
04611   unlockScene();
04612   interactive_marker_server_->applyChanges();
04613 }
04614 
04615 void PlanningSceneEditor::executeTrajectory(const std::string& mpr_name,
04616                                             const std::string& traj_name)
04617 {
04618   TrajectoryData& traj = trajectory_map_[mpr_name][traj_name];
04619   executeTrajectory(traj);
04620 }
04621 
04622 bool PlanningSceneEditor::hasTrajectory(const std::string& mpr_name, 
04623                                         const std::string& traj_name) const {
04624   if(trajectory_map_.find(mpr_name) == trajectory_map_.end()) {
04625     return false;
04626   }
04627   
04628   if(trajectory_map_.at(mpr_name).find(traj_name) == trajectory_map_.at(mpr_name).end()) {
04629     return false;
04630   }
04631   return true;
04632 }


srs_assisted_arm_navigation
Author(s): Zdenek Materna (imaterna@fit.vutbr.cz), Michal Spanel (spanel@fit.vutbr.cz)
autogenerated on Mon Oct 6 2014 08:12:09