chomp_planner_node.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2009, 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 the 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 
00037 #include <chomp_motion_planner/chomp_planner_node.h>
00038 #include <chomp_motion_planner/chomp_trajectory.h>
00039 #include <chomp_motion_planner/chomp_utils.h>
00040 #include <chomp_motion_planner/chomp_parameters.h>
00041 #include <chomp_motion_planner/chomp_optimizer.h>
00042 #include <kdl/jntarray.hpp>
00043 #include <angles/angles.h>
00044 #include <visualization_msgs/MarkerArray.h>
00045 #include <spline_smoother/cubic_trajectory.h>
00046 #include <arm_navigation_msgs/FilterJointTrajectory.h>
00047 #include <planning_environment/models/model_utils.h>
00048 #include <spline_smoother/fritsch_butland_spline_smoother.h>
00049 
00050 #include <map>
00051 #include <vector>
00052 #include <string>
00053 
00054 using namespace std;
00055 using namespace planning_models;
00056 using namespace collision_proximity;
00057 
00058 namespace chomp
00059 {
00060 
00061 ChompPlannerNode::ChompPlannerNode(ros::NodeHandle node_handle, CollisionProximitySpace* space) : node_handle_(node_handle), collision_proximity_space_(space)
00062                                                                   //filter_constraints_chain_("arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Request")
00063 {
00064 
00065 }
00066 
00067 bool ChompPlannerNode::init()
00068 {
00069   // load in some default parameters
00070   node_handle_.param("trajectory_duration", trajectory_duration_, 3.0);
00071   node_handle_.param("trajectory_discretization", trajectory_discretization_, 0.03);
00072   node_handle_.param("use_additional_trajectory_filter", use_trajectory_filter_, false);
00073   node_handle_.param("minimum_spline_points", minimum_spline_points_, 40);
00074   node_handle_.param("maximum_spline_points", maximum_spline_points_, 100);
00075   if(node_handle_.hasParam("joint_velocity_limits")) {
00076     XmlRpc::XmlRpcValue velocity_limits;
00077     
00078     node_handle_.getParam("joint_velocity_limits", velocity_limits);
00079 
00080     if(velocity_limits.getType() ==  XmlRpc::XmlRpcValue::TypeStruct) {
00081       if(velocity_limits.size() > 0) {
00082         for(XmlRpc::XmlRpcValue::iterator it = velocity_limits.begin();
00083             it != velocity_limits.end();
00084             it++) {
00085           joint_velocity_limits_[it->first] = it->second;
00086           ROS_DEBUG_STREAM("Vel limit for " << it->first << " is " << joint_velocity_limits_[it->first]);
00087         }
00088       }
00089     }  
00090   } 
00091 
00092   //filter_constraints_chain_.configure("filter_chain",node_handle_);
00093 
00094 
00095   collision_models_ = collision_proximity_space_->getCollisionModelsInterface();
00096 
00097   if(!collision_models_->loadedModels()) {
00098     ROS_ERROR("Collision models could not load models");
00099     return false;
00100   }
00101 
00102 
00103 
00104   reference_frame_ = collision_proximity_space_->getCollisionModelsInterface()->getWorldFrameId();
00105 
00106 
00107   robot_model_= (planning_models::KinematicModel*)collision_proximity_space_->getCollisionModelsInterface()->getKinematicModel();
00108 
00109   // load chomp parameters:
00110   chomp_parameters_.initFromNodeHandle();
00111   
00112   collision_proximity_space_->setCollisionTolerance(.05);
00113 
00114   // initialize the visualization publisher:
00115   vis_marker_array_publisher_ = root_handle_.advertise<visualization_msgs::MarkerArray>( "visualization_marker_array", 0 );
00116   vis_marker_publisher_ = root_handle_.advertise<visualization_msgs::Marker>( "visualization_marker", 0 );
00117 
00118   // advertise the planning service
00119   plan_kinematic_path_service_ = root_handle_.advertiseService("chomp_planner_longrange/plan_path", &ChompPlannerNode::planKinematicPath, this);
00120 
00121   filter_joint_trajectory_service_ = root_handle_.advertiseService("chomp_planner_longrange/filter_trajectory_with_constraints", &ChompPlannerNode::filterJointTrajectory, this);
00122 
00123   if(use_trajectory_filter_) {
00124     filter_trajectory_client_ = root_handle_.serviceClient<arm_navigation_msgs::FilterJointTrajectoryWithConstraints>("trajectory_filter/filter_trajectory_with_constraints");    
00125   
00126     ros::service::waitForService("trajectory_filter/filter_trajectory_with_constraints");
00127   }
00128 
00129   ROS_INFO("Initalized CHOMP planning service...");
00130 
00131   return true;
00132 }
00133 
00134 ChompPlannerNode::~ChompPlannerNode()
00135 {
00136   delete collision_models_;
00137 }
00138 
00139 int ChompPlannerNode::run()
00140 {
00141   ros::spin();
00142   return 0;
00143 }
00144 
00145 bool ChompPlannerNode::planKinematicPath(arm_navigation_msgs::GetMotionPlan::Request &reqIn, arm_navigation_msgs::GetMotionPlan::Response &res)
00146 {
00147   arm_navigation_msgs::GetMotionPlan::Request req = reqIn;
00148   if (!(req.motion_plan_request.goal_constraints.position_constraints.empty() && req.motion_plan_request.goal_constraints.orientation_constraints.empty()))
00149   {
00150     ROS_ERROR("CHOMP cannot handle pose contraints yet.");
00151     res.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::INVALID_GOAL_POSITION_CONSTRAINTS;
00152     return false;
00153   }
00154 
00155   sensor_msgs::JointState joint_goal_chomp = arm_navigation_msgs::jointConstraintsToJointState(req.motion_plan_request.goal_constraints.joint_constraints);
00156   ROS_INFO("Chomp goal");
00157 
00158   if(joint_goal_chomp.name.size() != joint_goal_chomp.position.size())
00159   {
00160     ROS_ERROR("Invalid chomp goal");
00161     res.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::INVALID_GOAL_JOINT_CONSTRAINTS;
00162     return false;
00163   }
00164 
00165   for(unsigned int i=0; i<joint_goal_chomp.name.size(); i++)
00166   {
00167     ROS_INFO("%s %f",joint_goal_chomp.name[i].c_str(),joint_goal_chomp.position[i]);
00168   }
00169 
00170   ros::WallTime start_time = ros::WallTime::now();
00171   ROS_INFO("Received planning request...");
00172 
00173   string group_name;
00174   group_name = req.motion_plan_request.group_name;
00175 
00176   vector<string> linkNames;
00177   vector<string> attachedBodies;
00178   ros::WallTime start = ros::WallTime::now();
00179   collision_proximity_space_->setupForGroupQueries(group_name,
00180                                                    req.motion_plan_request.start_state,
00181                                                    linkNames,
00182                                                    attachedBodies);
00183   ROS_INFO_STREAM("Setting up for queries time is " << (ros::WallTime::now() - start));
00184   //collision_proximity_space_->visualizeObjectSpheres(collision_proximity_space_->getCurrentLinkNames());
00185   ChompTrajectory trajectory(robot_model_, trajectory_duration_, trajectory_discretization_, group_name);
00186 
00187   ROS_INFO("Initial trajectory has %d points", trajectory.getNumPoints());
00188   // set the start state:
00189   jointStateToArray(req.motion_plan_request.start_state.joint_state, group_name, trajectory.getTrajectoryPoint(0));
00190 
00191   ROS_INFO_STREAM("Joint state has " << req.motion_plan_request.start_state.joint_state.name.size() << " joints");
00192 
00193   // set the goal state equal to start state, and override the joints specified in the goal
00194   // joint constraints
00195   int goal_index = trajectory.getNumPoints()- 1;
00196   trajectory.getTrajectoryPoint(goal_index) = trajectory.getTrajectoryPoint(0);
00197   jointStateToArray(arm_navigation_msgs::jointConstraintsToJointState(req.motion_plan_request.goal_constraints.joint_constraints), group_name, trajectory.getTrajectoryPoint(goal_index));
00198 
00199 
00200   map<string, KinematicModel::JointModelGroup*> groupMap = robot_model_->getJointModelGroupMap();
00201   KinematicModel::JointModelGroup* modelGroup = groupMap[group_name];
00202 
00203 
00204   // fix the goal to move the shortest angular distance for wrap-around joints:
00205   for (size_t i = 0; i < modelGroup->getJointModels().size(); i++)
00206   {
00207     const KinematicModel::JointModel* model = modelGroup->getJointModels()[i];
00208     const KinematicModel::RevoluteJointModel* revoluteJoint = dynamic_cast<const KinematicModel::RevoluteJointModel*>(model);
00209 
00210     if (revoluteJoint != NULL)
00211     {
00212       if(revoluteJoint->continuous_)
00213       {
00214         double start = (trajectory)(0, i);
00215         double end = (trajectory)(goal_index, i);
00216         (trajectory)(goal_index, i) = start + angles::shortest_angular_distance(start, end);
00217       }
00218     }
00219   }
00220 
00221   // fill in an initial quintic spline trajectory
00222   trajectory.fillInMinJerk();
00223 
00224   // set the max planning time:
00225   chomp_parameters_.setPlanningTimeLimit(req.motion_plan_request.allowed_planning_time.toSec());
00226 
00227   // optimize!
00228   ros::WallTime create_time = ros::WallTime::now();
00229   ChompOptimizer optimizer(&trajectory, robot_model_, group_name, &chomp_parameters_,
00230       vis_marker_array_publisher_, vis_marker_publisher_, collision_proximity_space_);
00231   ROS_INFO("Optimization took %f sec to create", (ros::WallTime::now() - create_time).toSec());
00232   optimizer.optimize();
00233   ROS_INFO("Optimization actually took %f sec to run", (ros::WallTime::now() - create_time).toSec());
00234   create_time = ros::WallTime::now();
00235   // assume that the trajectory is now optimized, fill in the output structure:
00236 
00237   ROS_INFO("Output trajectory has %d joints", trajectory.getNumJoints());
00238   vector<double> velocity_limits(trajectory.getNumJoints(), numeric_limits<double>::max());
00239 
00240   // fill in joint names:
00241   res.trajectory.joint_trajectory.joint_names.resize(trajectory.getNumJoints());
00242   for (size_t i = 0; i < modelGroup->getJointModels().size(); i++)
00243   {
00244     res.trajectory.joint_trajectory.joint_names[i] = modelGroup->getJointModels()[i]->getName();
00245     // try to retrieve the joint limits:
00246     if (joint_velocity_limits_.find(res.trajectory.joint_trajectory.joint_names[i])==joint_velocity_limits_.end())
00247     {
00248       joint_velocity_limits_[res.trajectory.joint_trajectory.joint_names[i]] = numeric_limits<double>::max();
00249     }
00250     velocity_limits[i] = joint_velocity_limits_[res.trajectory.joint_trajectory.joint_names[i]];
00251   }
00252 
00253   res.trajectory.joint_trajectory.header = req.motion_plan_request.start_state.joint_state.header; // @TODO this is probably a hack
00254 
00255   // fill in the entire trajectory
00256   res.trajectory.joint_trajectory.points.resize(trajectory.getNumPoints());
00257   for (int i=0; i < trajectory.getNumPoints(); i++)
00258   {
00259     res.trajectory.joint_trajectory.points[i].positions.resize(trajectory.getNumJoints());
00260     for (size_t j=0; j < res.trajectory.joint_trajectory.points[i].positions.size(); j++)
00261     {
00262       res.trajectory.joint_trajectory.points[i].positions[j] = trajectory.getTrajectoryPoint(i)(j);
00263     }
00264     // Setting invalid timestamps.
00265     // Further filtering is required to set valid timestamps accounting for velocity and acceleration constraints.
00266     res.trajectory.joint_trajectory.points[i].time_from_start = ros::Duration(0.0);
00267   }
00268 
00269   ROS_INFO("Bottom took %f sec to create", (ros::WallTime::now() - create_time).toSec());
00270   ROS_INFO("Serviced planning request in %f wall-seconds, trajectory duration is %f", (ros::WallTime::now() - start_time).toSec(), res.trajectory.joint_trajectory.points[goal_index].time_from_start.toSec());
00271   res.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::SUCCESS;
00272   res.planning_time = ros::Duration((ros::WallTime::now() - start_time).toSec());
00273   return true;
00274 }
00275 
00276 bool ChompPlannerNode::filterJointTrajectory(arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Request &request, arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Response &res)
00277 {
00278   arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Request req = request;
00279   ros::WallTime start_time = ros::WallTime::now();
00280   ROS_INFO_STREAM("Received filtering request with trajectory size " << req.trajectory.points.size());
00281 
00282   if(req.path_constraints.joint_constraints.size() > 0 ||
00283      req.path_constraints.position_constraints.size() > 0 ||
00284      req.path_constraints.orientation_constraints.size() > 0 ||
00285      req.path_constraints.visibility_constraints.size() > 0) {
00286     if(use_trajectory_filter_) {
00287       ROS_INFO("Chomp can't handle path constraints, passing through to other trajectory filters");
00288       if(!filter_trajectory_client_.call(req,res)) {
00289         ROS_INFO("Pass through failed");
00290       } else {
00291         ROS_INFO("Pass through succeeded");
00292       }
00293     } else {
00294       ROS_INFO("Chomp can't handle path constraints, and not set up to use additional filter");
00295     }
00296     return true;
00297   } 
00298   for (unsigned int i=0; i< req.trajectory.points.size(); i++)
00299   {
00300     req.trajectory.points[i].velocities.resize(req.trajectory.joint_names.size(),0.0);
00301   }
00302 
00303   getLimits(req.trajectory, req.limits);
00304 
00305   trajectory_msgs::JointTrajectory jtraj;
00306 
00307   int num_points = req.trajectory.points.size();
00308   if(num_points > maximum_spline_points_) {
00309     num_points = maximum_spline_points_;
00310   } else if(num_points < minimum_spline_points_) {
00311     num_points = minimum_spline_points_;
00312   }
00313 
00314 
00315   //create a spline from the trajectory
00316   spline_smoother::CubicTrajectory trajectory_solver;
00317   spline_smoother::SplineTrajectory spline;
00318 
00319   planning_environment::setRobotStateAndComputeTransforms(req.start_state,
00320                                                           *collision_proximity_space_->getCollisionModelsInterface()->getPlanningSceneState());
00321   
00322   trajectory_solver.parameterize(req.trajectory,req.limits,spline);  
00323   
00324   double smoother_time;
00325   spline_smoother::getTotalTime(spline, smoother_time);
00326   
00327   ROS_INFO_STREAM("Total time given is " << smoother_time);
00328   
00329   double t = 0.0;
00330   vector<double> times(num_points);
00331   for(int i = 0; i < num_points; i++,t += smoother_time/(1.0*(num_points-1))) {
00332     times[i] = t;
00333   }
00334     
00335   spline_smoother::sampleSplineTrajectory(spline, times, jtraj);
00336   
00337   //double planner_time = req.trajectory.points.back().time_from_start.toSec();
00338   
00339   t = 0.0;
00340   for(unsigned int i = 0; i < jtraj.points.size(); i++, t += smoother_time/(1.0*(num_points-1))) {
00341     jtraj.points[i].time_from_start = ros::Duration(t);
00342   }
00343   
00344   ROS_INFO_STREAM("Sampled trajectory has " << jtraj.points.size() << " points with " << jtraj.points[0].positions.size() << " joints");
00345 
00346 
00347   string group_name;
00348   group_name = req.group_name;
00349 
00350   vector<string> linkNames;
00351   vector<string> attachedBodies;
00352   collision_proximity_space_->setupForGroupQueries(group_name,
00353                                                    req.start_state,
00354                                                    linkNames,
00355                                                    attachedBodies);
00356 
00357   ChompTrajectory trajectory(robot_model_, group_name, jtraj);
00358 
00359   //configure the distance field - this should just use current state
00360   arm_navigation_msgs::RobotState robot_state = req.start_state;
00361 
00362   jointStateToArray(arm_navigation_msgs::createJointState(req.trajectory.joint_names, jtraj.points[0].positions), group_name, trajectory.getTrajectoryPoint(0));
00363 
00364   //set the goal state equal to start state, and override the joints specified in the goal
00365   //joint constraints
00366   int goal_index = trajectory.getNumPoints()-1;
00367   trajectory.getTrajectoryPoint(goal_index) = trajectory.getTrajectoryPoint(0);
00368 
00369   sensor_msgs::JointState goal_state = arm_navigation_msgs::createJointState(req.trajectory.joint_names, jtraj.points.back().positions);
00370 
00371   jointStateToArray(goal_state, group_name,trajectory.getTrajectoryPoint(goal_index));
00372   
00373   map<string, KinematicModel::JointModelGroup*> groupMap = robot_model_->getJointModelGroupMap();
00374   KinematicModel::JointModelGroup* modelGroup = groupMap[group_name];
00375 
00376   // fix the goal to move the shortest angular distance for wrap-around joints:
00377   for (size_t i = 0; i < modelGroup->getJointModels().size(); i++)
00378   {
00379     const KinematicModel::JointModel* model = modelGroup->getJointModels()[i];
00380     const KinematicModel::RevoluteJointModel* revoluteJoint = dynamic_cast<const KinematicModel::RevoluteJointModel*>(model);
00381 
00382     if (revoluteJoint != NULL)
00383     {
00384       if(revoluteJoint->continuous_)
00385       {
00386         double start = trajectory(0, i);
00387         double end = trajectory(goal_index, i);
00388         trajectory(goal_index, i) = start + angles::shortest_angular_distance(start, end);
00389       }
00390     }
00391   }
00392 
00393   //sets other joints
00394   trajectory.fillInMinJerk();
00395   trajectory.overwriteTrajectory(jtraj);
00396   
00397   // set the max planning time:
00398   chomp_parameters_.setPlanningTimeLimit(req.allowed_time.toSec());
00399   chomp_parameters_.setFilterMode(true);
00400   // optimize!
00401   ChompOptimizer optimizer(&trajectory, robot_model_, group_name, &chomp_parameters_,
00402       vis_marker_array_publisher_, vis_marker_publisher_, collision_proximity_space_);
00403   optimizer.optimize();
00404   
00405   // assume that the trajectory is now optimized, fill in the output structure:
00406 
00407   vector<double> velocity_limits(trajectory.getNumJoints(), numeric_limits<double>::max());
00408   res.trajectory.points.resize(trajectory.getNumPoints());
00409   // fill in joint names:
00410   res.trajectory.joint_names.resize(trajectory.getNumJoints());
00411   for (size_t i = 0; i < modelGroup->getJointModels().size(); i++)
00412   {
00413     res.trajectory.joint_names[i] = modelGroup->getJointModels()[i]->getName();
00414     velocity_limits[i] = joint_limits_[res.trajectory.joint_names[i]].max_velocity;
00415   }
00416   
00417   res.trajectory.header.stamp = ros::Time::now();
00418   res.trajectory.header.frame_id = reference_frame_;
00419 
00420   // fill in the entire trajectory
00421 
00422   for (size_t i = 0; i < (unsigned int)trajectory.getNumPoints(); i++)
00423   {
00424     res.trajectory.points[i].positions.resize(trajectory.getNumJoints());
00425     res.trajectory.points[i].velocities.resize(trajectory.getNumJoints());
00426     for (size_t j=0; j < res.trajectory.points[i].positions.size(); j++)
00427     {
00428       res.trajectory.points[i].positions[j] = trajectory(i, j);
00429     }
00430     if (i==0)
00431       res.trajectory.points[i].time_from_start = ros::Duration(0.0);
00432     else
00433     {
00434       double duration = trajectory.getDiscretization();
00435       // check with all the joints if this duration is ok, else push it up
00436       for (int j=0; j < trajectory.getNumJoints(); j++)
00437       {
00438         double d = fabs(res.trajectory.points[i].positions[j] - res.trajectory.points[i-1].positions[j]) / velocity_limits[j];
00439         if (d > duration)
00440           duration = d;
00441       }
00442       try {
00443         res.trajectory.points[i].time_from_start = res.trajectory.points[i-1].time_from_start + ros::Duration(duration);
00444       } catch(...) {
00445         ROS_INFO_STREAM("Potentially weird duration of " << duration);
00446       }
00447     }
00448   }
00449   arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Request  next_req;
00450   arm_navigation_msgs::FilterJointTrajectoryWithConstraints::Response next_res;
00451 
00452   if(use_trajectory_filter_) {
00453     next_req = req;
00454     next_req.trajectory = res.trajectory;  
00455     next_req.allowed_time=ros::Duration(1.0);//req.allowed_time/2.0;
00456     
00457     if(filter_trajectory_client_.call(next_req, next_res)) {
00458       ROS_INFO_STREAM("Filter call ok. Sent trajectory had " << res.trajectory.points.size() << " points.  Returned trajectory has " << next_res.trajectory.points.size() << " points ");
00459     } else {
00460       ROS_INFO("Filter call not ok");
00461     }
00462     
00463     res.trajectory = next_res.trajectory;
00464     res.error_code = next_res.error_code;
00465     res.trajectory.header.stamp = ros::Time::now();
00466     res.trajectory.header.frame_id = reference_frame_;
00467   } else {
00468     res.error_code.val = res.error_code.val = res.error_code.SUCCESS;
00469   }
00470 
00471   // for every point in time:
00472   for (unsigned int i=1; i<res.trajectory.points.size()-1; ++i)
00473   {
00474     double dt1 = (res.trajectory.points[i].time_from_start - res.trajectory.points[i-1].time_from_start).toSec();
00475     double dt2 = (res.trajectory.points[i+1].time_from_start - res.trajectory.points[i].time_from_start).toSec();
00476 
00477     // for every (joint) trajectory
00478     for (int j=0; j < trajectory.getNumJoints(); ++j)
00479     {
00480       double dx1 = res.trajectory.points[i].positions[j] - res.trajectory.points[i-1].positions[j];
00481       double dx2 = res.trajectory.points[i+1].positions[j] - res.trajectory.points[i].positions[j];
00482 
00483       double v1 = dx1/dt1;
00484       double v2 = dx2/dt2;
00485 
00486       res.trajectory.points[i].velocities[j] = 0.5*(v1 + v2);
00487     }
00488   }
00489 
00490   ROS_INFO("Serviced filter request in %f wall-seconds, trajectory duration is %f", (ros::WallTime::now() - start_time).toSec(), res.trajectory.points.back().time_from_start.toSec());
00491   return true;
00492 
00493 }
00494 
00495 
00496 void ChompPlannerNode::getLimits(const trajectory_msgs::JointTrajectory& trajectory, 
00497                                  vector<arm_navigation_msgs::JointLimits>& limits_out)
00498 {
00499   int num_joints = trajectory.joint_names.size();
00500   limits_out.resize(num_joints);
00501   for (int i=0; i<num_joints; ++i)
00502   {
00503     map<string, arm_navigation_msgs::JointLimits>::const_iterator limit_it = joint_limits_.find(trajectory.joint_names[i]);
00504     arm_navigation_msgs::JointLimits limits;
00505     if (limit_it == joint_limits_.end())
00506     {
00507       // load the limits from the param server
00508       node_handle_.param("joint_limits/"+trajectory.joint_names[i]+"/min_position", limits.min_position, -numeric_limits<double>::max());
00509       node_handle_.param("joint_limits/"+trajectory.joint_names[i]+"/max_position", limits.max_position, numeric_limits<double>::max());
00510       node_handle_.param("joint_limits/"+trajectory.joint_names[i]+"/max_velocity", limits.max_velocity, numeric_limits<double>::max());
00511       node_handle_.param("joint_limits/"+trajectory.joint_names[i]+"/max_acceleration", limits.max_acceleration, numeric_limits<double>::max());
00512       bool boolean;
00513       node_handle_.param("joint_limits/"+trajectory.joint_names[i]+"/has_position_limits", boolean, false);
00514       limits.has_position_limits = boolean?1:0;
00515       node_handle_.param("joint_limits/"+trajectory.joint_names[i]+"/has_velocity_limits", boolean, false);
00516       limits.has_velocity_limits = boolean?1:0;
00517       node_handle_.param("joint_limits/"+trajectory.joint_names[i]+"/has_acceleration_limits", boolean, false);
00518       limits.has_acceleration_limits = boolean?1:0;
00519       joint_limits_.insert(make_pair(trajectory.joint_names[i], limits));
00520     }
00521     else
00522     {
00523       limits = limit_it->second;
00524     }
00525     limits_out[i] = limits;
00526   }
00527 }
00528 
00529 } // namespace chomp
00530 
00531 int main(int argc, char** argv)
00532 {
00533   ros::init(argc, argv, "chomp_planner_node");
00534 
00535   //ros::AsyncSpinner spinner(1); // Use 1 thread
00536   //spinner.start();
00537 
00538   ros::NodeHandle node_handle("~");
00539   string robotDescription;
00540   ros::param::param<string>("robot_description_file_name", robotDescription, "");
00541   bool use_signed_environment_field = false;
00542   bool use_signed_self_field = false;
00543   ros::param::param<bool>("use_signed_environment_field", use_signed_environment_field, false);
00544   ros::param::param<bool>("use_signed_self_field", use_signed_self_field, false);
00545   chomp::ChompPlannerNode chomp_planner_node(node_handle, new CollisionProximitySpace("robot_description",true,use_signed_environment_field, use_signed_self_field));
00546   if (!chomp_planner_node.init())
00547     return 1;
00548   return chomp_planner_node.run();
00549   //ros::waitForShutdown();
00550 }


chomp_motion_planner
Author(s): Mrinal Kalakrishnan / mail@mrinal.net
autogenerated on Thu Dec 12 2013 11:08:58