sparse_planner.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Apache License)
00003  *
00004  * Copyright (c) 2014, Southwest Research Institute
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  * http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 /*
00019  * sparse_planner.cpp
00020  *
00021  *  Created on: Dec 17, 2014
00022  *      Author: Jorge Nicho 
00023  */
00024 
00025 #include <descartes_planner/sparse_planner.h>
00026 #include <algorithm>
00027 
00028 using namespace descartes_core;
00029 using namespace descartes_trajectory;
00030 
00031 namespace
00032 {
00033     std::vector<descartes_core::TimingConstraint>
00034     extractTiming(const std::vector<descartes_core::TrajectoryPtPtr>& points)
00035     {
00036       std::vector<descartes_core::TimingConstraint> result;
00037       result.reserve(points.size());
00038 
00039       for (const auto& ptr : points)
00040       {
00041         result.push_back(ptr->getTiming());
00042       }
00043       return result;
00044     }
00045 }
00046 
00047 
00048 namespace descartes_planner
00049 {
00050 
00051 const int INVALID_INDEX = -1;
00052 const double MAX_JOINT_CHANGE = M_PI_4;
00053 const double DEFAULT_SAMPLING = 0.1f;
00054 const std::string SAMPLING_CONFIG = "sampling";
00055 
00056 SparsePlanner::SparsePlanner(RobotModelConstPtr model,double sampling):
00057     sampling_(sampling),
00058     error_code_(descartes_core::PlannerError::UNINITIALIZED)
00059 {
00060   error_map_ = {
00061                  {PlannerError::OK,"OK"},
00062                  {PlannerError::EMPTY_PATH,"No path plan has been generated"},
00063                  {PlannerError::INVALID_ID,"ID is nil or isn't part of the path"},
00064                  {PlannerError::IK_NOT_AVAILABLE,"One or more ik solutions could not be found"},
00065                  {PlannerError::UNINITIALIZED,"Planner has not been initialized with a robot model"},
00066                  {PlannerError::INCOMPLETE_PATH,"Input trajectory and output path point cound differ"}
00067                };
00068 
00069   initialize(std::move(model));
00070   config_ = {{SAMPLING_CONFIG,std::to_string(sampling)}};
00071 }
00072 
00073 SparsePlanner::SparsePlanner():
00074     sampling_(DEFAULT_SAMPLING),
00075     error_code_(descartes_core::PlannerError::UNINITIALIZED)
00076 {
00077   error_map_ = {
00078                  {PlannerError::OK,"OK"},
00079                  {PlannerError::EMPTY_PATH,"No path plan has been generated"},
00080                  {PlannerError::INVALID_ID,"ID is nil or isn't part of the path"},
00081                  {PlannerError::IK_NOT_AVAILABLE,"One or more ik solutions could not be found"},
00082                  {PlannerError::UNINITIALIZED,"Planner has not been initialized with a robot model"},
00083                  {PlannerError::INCOMPLETE_PATH,"Input trajectory and output path point cound differ"}
00084                };
00085 
00086   config_ = {{SAMPLING_CONFIG,std::to_string(DEFAULT_SAMPLING)}};
00087 }
00088 
00089 bool SparsePlanner::initialize(RobotModelConstPtr model)
00090 {
00091   planning_graph_ = boost::shared_ptr<descartes_planner::PlanningGraph>(new descartes_planner::PlanningGraph(std::move(model)));
00092   error_code_ = PlannerError::EMPTY_PATH;
00093   return true;
00094 }
00095 
00096 bool SparsePlanner::setConfig(const descartes_core::PlannerConfig& config)
00097 {
00098   std::stringstream ss;
00099   static std::vector<std::string> keys = {SAMPLING_CONFIG};
00100 
00101   // verifying keys
00102   for(auto kv: config_)
00103   {
00104     if(config.count(kv.first)==0)
00105     {
00106       error_code_ = descartes_core::PlannerError::INVALID_CONFIGURATION_PARAMETER;
00107       return false;
00108     }
00109   }
00110 
00111   // translating string values
00112   try
00113   {
00114     config_[SAMPLING_CONFIG] = config.at(SAMPLING_CONFIG);
00115     sampling_ = std::stod(config.at(SAMPLING_CONFIG));
00116   }
00117   catch(std::invalid_argument& exp)
00118   {
00119     ROS_ERROR_STREAM("Unable to parse configuration value(s)");
00120     error_code_ = descartes_core::PlannerError::INVALID_CONFIGURATION_PARAMETER;
00121     return false;
00122   }
00123 
00124   return true;
00125 }
00126 
00127 void SparsePlanner::getConfig(descartes_core::PlannerConfig& config) const
00128 {
00129   config = config_;
00130 }
00131 
00132 SparsePlanner::~SparsePlanner()
00133 {
00134 
00135 }
00136 
00137 void SparsePlanner::setSampling(double sampling)
00138 {
00139   sampling_ = sampling;
00140 }
00141 
00142 bool SparsePlanner::planPath(const std::vector<TrajectoryPtPtr>& traj)
00143 {
00144   if(error_code_ == descartes_core::PlannerError::UNINITIALIZED)
00145   {
00146     ROS_ERROR_STREAM("Planner has not been initialized");
00147     return false;
00148   }
00149 
00150   ros::Time start_time = ros::Time::now();
00151 
00152   // Save the timing information
00153   timing_cache_ = extractTiming(traj);
00154   // Unconstrain the times for the sparse sampling
00155   for (std::size_t i = 0; i < traj.size(); ++i)
00156   {
00157     traj[i]->setTiming(descartes_core::TimingConstraint()); // default timing is (0,0)
00158   }
00159 
00160   cart_points_.assign(traj.begin(),traj.end());
00161   std::vector<TrajectoryPtPtr> sparse_trajectory_array;
00162   sampleTrajectory(sampling_,cart_points_,sparse_trajectory_array);
00163   ROS_INFO_STREAM("Sampled trajectory contains "<<sparse_trajectory_array.size()<<" points from "<<cart_points_.size()<<
00164                   " points in the dense trajectory");
00165 
00166   if(planning_graph_->insertGraph(&sparse_trajectory_array) && plan())
00167   {
00168     int planned_count = sparse_solution_array_.size();
00169     int interp_count = cart_points_.size()  - sparse_solution_array_.size();
00170     ROS_INFO("Sparse planner succeeded with %i planned point and %i interpolated points in %f seconds",planned_count,interp_count,
00171              (ros::Time::now() - start_time).toSec());
00172     error_code_ = descartes_core::PlannerError::OK;
00173   }
00174   else
00175   {
00176     error_code_ = descartes_core::PlannerError::IK_NOT_AVAILABLE;
00177     return false;
00178   }
00179 
00180 
00181   return true;
00182 }
00183 
00184 bool SparsePlanner::addAfter(const TrajectoryPt::ID& ref_id,TrajectoryPtPtr cp)
00185 {
00186   ros::Time start_time = ros::Time::now();
00187   int sparse_index;
00188   int index;
00189   TrajectoryPt::ID prev_id, next_id;
00190 
00191   sparse_index= findNearestSparsePointIndex(ref_id);
00192   if(sparse_index == INVALID_INDEX)
00193   {
00194     ROS_ERROR_STREAM("A point in sparse array near point "<<ref_id<<" could not be found, aborting");
00195     return false;
00196   }
00197 
00198   // setting ids from sparse array
00199   prev_id = std::get<1>(sparse_solution_array_[sparse_index - 1])->getID();
00200   next_id = std::get<1>(sparse_solution_array_[sparse_index])->getID();
00201 
00202   // inserting into dense array
00203   index = getDensePointIndex(ref_id);
00204   if(index == INVALID_INDEX)
00205   {
00206     ROS_ERROR_STREAM("Point  "<<ref_id<<" could not be found in dense array, aborting");
00207     return false;
00208   }
00209   auto pos = cart_points_.begin();
00210   std::advance(pos,index + 1);
00211   cart_points_.insert(pos,cp);
00212 
00213   // replanning
00214   if(planning_graph_->addTrajectory(cp,prev_id,next_id) && plan())
00215   {
00216     int planned_count = sparse_solution_array_.size();
00217     int interp_count = cart_points_.size()  - sparse_solution_array_.size();
00218     ROS_INFO("Sparse planner add operation succeeded, %i planned point and %i interpolated points in %f seconds",
00219              planned_count,interp_count,(ros::Time::now() -start_time).toSec());
00220   }
00221   else
00222   {
00223     return false;
00224   }
00225 
00226   return true;
00227 }
00228 
00229 bool SparsePlanner::addBefore(const TrajectoryPt::ID& ref_id,TrajectoryPtPtr cp)
00230 {
00231   ros::Time start_time = ros::Time::now();
00232   int sparse_index;
00233   int index;
00234   TrajectoryPt::ID prev_id, next_id;
00235 
00236   sparse_index= findNearestSparsePointIndex(ref_id,false);
00237   if(sparse_index == INVALID_INDEX)
00238   {
00239     ROS_ERROR_STREAM("A point in sparse array near point "<<ref_id<<" could not be found, aborting");
00240     return false;
00241   }
00242 
00243   prev_id = (sparse_index == 0) ? descartes_core::TrajectoryID::make_nil() : std::get<1>(sparse_solution_array_[sparse_index - 1])->getID();
00244   next_id = std::get<1>(sparse_solution_array_[sparse_index])->getID();
00245 
00246   // inserting into dense array
00247   index = getDensePointIndex(ref_id);
00248   if(index == INVALID_INDEX)
00249   {
00250     ROS_ERROR_STREAM("Point  "<<ref_id<<" could not be found in dense array, aborting");
00251     return false;
00252   }
00253   auto pos = cart_points_.begin();
00254   std::advance(pos,index);
00255   cart_points_.insert(pos,cp);
00256 
00257   if(planning_graph_->addTrajectory(cp,prev_id,next_id) && plan())
00258   {
00259     int planned_count = sparse_solution_array_.size();
00260     int interp_count = cart_points_.size()  - sparse_solution_array_.size();
00261     ROS_INFO("Sparse planner add operation succeeded, %i planned point and %i interpolated points in %f seconds",
00262              planned_count,interp_count,(ros::Time::now() -start_time).toSec());
00263   }
00264   else
00265   {
00266     return false;
00267   }
00268 
00269   return true;
00270 }
00271 
00272 bool SparsePlanner::remove(const TrajectoryPt::ID& ref_id)
00273 {
00274   ros::Time start_time = ros::Time::now();
00275   int index = getDensePointIndex(ref_id);
00276   if(index == INVALID_INDEX)
00277   {
00278     ROS_ERROR_STREAM("Point  "<<ref_id<<" could not be found in dense array, aborting");
00279     return false;
00280   }
00281 
00282   if(isInSparseTrajectory(ref_id))
00283   {
00284     if(!planning_graph_->removeTrajectory(cart_points_[index]))
00285     {
00286       ROS_ERROR_STREAM("Failed to removed point "<<ref_id<<" from sparse trajectory, aborting");
00287       return false;
00288     }
00289   }
00290 
00291   // removing from dense array
00292   auto pos = cart_points_.begin();
00293   std::advance(pos,index);
00294   cart_points_.erase(pos);
00295 
00296   if(plan())
00297   {
00298     int planned_count = sparse_solution_array_.size();
00299     int interp_count = cart_points_.size()  - sparse_solution_array_.size();
00300     ROS_INFO("Sparse planner remove operation succeeded, %i planned point and %i interpolated points in %f seconds",
00301              planned_count,interp_count,(ros::Time::now() -start_time).toSec());
00302   }
00303   else
00304   {
00305     return false;
00306   }
00307 
00308   return true;
00309 }
00310 
00311 bool SparsePlanner::modify(const TrajectoryPt::ID& ref_id,TrajectoryPtPtr cp)
00312 {
00313   ros::Time start_time = ros::Time::now();
00314   int sparse_index;
00315   TrajectoryPt::ID prev_id, next_id;
00316 
00317   sparse_index= getSparsePointIndex(ref_id);
00318   cp->setID(ref_id);
00319   if(sparse_index == INVALID_INDEX)
00320   {
00321     sparse_index = findNearestSparsePointIndex(ref_id);
00322     prev_id = std::get<1>(sparse_solution_array_[sparse_index - 1])->getID();
00323     next_id = std::get<1>(sparse_solution_array_[sparse_index])->getID();
00324     if(!planning_graph_->addTrajectory(cp,prev_id,next_id))
00325     {
00326       ROS_ERROR_STREAM("Failed to add point to sparse trajectory, aborting");
00327       return false;
00328     }
00329   }
00330   else
00331   {
00332     if(!planning_graph_->modifyTrajectory(cp))
00333     {
00334       ROS_ERROR_STREAM("Failed to modify point in sparse trajectory, aborting");
00335       return false;
00336     }
00337   }
00338 
00339   int index = getDensePointIndex(ref_id);
00340   cart_points_[index] = cp;
00341   if( plan())
00342   {
00343     int planned_count = sparse_solution_array_.size();
00344     int interp_count = cart_points_.size()  - sparse_solution_array_.size();
00345     ROS_INFO("Sparse planner modify operation succeeded, %i planned point and %i interpolated points in %f seconds",
00346              planned_count,interp_count,(ros::Time::now() -start_time).toSec());
00347   }
00348   else
00349   {
00350     return false;
00351   }
00352 
00353   return true;
00354 }
00355 
00356 bool SparsePlanner::isInSparseTrajectory(const TrajectoryPt::ID& ref_id)
00357 {
00358   auto predicate = [&ref_id](std::tuple<int,TrajectoryPtPtr,JointTrajectoryPt>& t)
00359     {
00360       return ref_id == std::get<1>(t)->getID();
00361     };
00362 
00363   return (std::find_if(sparse_solution_array_.begin(),
00364                        sparse_solution_array_.end(),predicate) != sparse_solution_array_.end());
00365 }
00366 
00367 int SparsePlanner::getDensePointIndex(const TrajectoryPt::ID& ref_id)
00368 {
00369   int index = INVALID_INDEX;
00370   auto predicate = [&ref_id](TrajectoryPtPtr cp)
00371     {
00372       return ref_id == cp->getID();
00373     };
00374 
00375   auto pos = std::find_if(cart_points_.begin(),cart_points_.end(),predicate);
00376   if(pos != cart_points_.end())
00377   {
00378     index = std::distance(cart_points_.begin(),pos);
00379   }
00380 
00381   return index;
00382 }
00383 
00384 int SparsePlanner::getSparsePointIndex(const TrajectoryPt::ID& ref_id)
00385 {
00386   int index = INVALID_INDEX;
00387   auto predicate = [ref_id](std::tuple<int,TrajectoryPtPtr,JointTrajectoryPt>& t)
00388     {
00389       return ref_id == std::get<1>(t)->getID();
00390     };
00391 
00392   auto pos = std::find_if(sparse_solution_array_.begin(),sparse_solution_array_.end(),predicate);
00393   if(pos != sparse_solution_array_.end())
00394   {
00395     index = std::distance(sparse_solution_array_.begin(),pos);
00396   }
00397 
00398   return index;
00399 }
00400 
00401 int SparsePlanner::findNearestSparsePointIndex(const TrajectoryPt::ID& ref_id,bool skip_equal)
00402 {
00403   int index = INVALID_INDEX;
00404   int dense_index = getDensePointIndex(ref_id);
00405 
00406   if(dense_index == INVALID_INDEX)
00407   {
00408     return index;
00409   }
00410 
00411   auto predicate = [&dense_index,&skip_equal](std::tuple<int,TrajectoryPtPtr,JointTrajectoryPt>& t)
00412     {
00413 
00414       if(skip_equal)
00415       {
00416         return dense_index < std::get<0>(t);
00417       }
00418       else
00419       {
00420         return dense_index <= std::get<0>(t);
00421       }
00422     };
00423 
00424   auto pos = std::find_if(sparse_solution_array_.begin(),sparse_solution_array_.end(),predicate);
00425   if(pos != sparse_solution_array_.end())
00426   {
00427     index = std::distance(sparse_solution_array_.begin(), pos);
00428   }
00429   else
00430   {
00431     index = sparse_solution_array_.size()-1; // last
00432   }
00433 
00434   return index;
00435 }
00436 
00437 bool SparsePlanner::getSparseSolutionArray(SolutionArray& sparse_solution_array)
00438 {
00439   std::list<JointTrajectoryPt> sparse_joint_points;
00440   std::vector<TrajectoryPtPtr> sparse_cart_points;
00441   double cost;
00442   ros::Time start_time = ros::Time::now();
00443   if(planning_graph_->getShortestPath(cost,sparse_joint_points))
00444   {
00445     ROS_INFO_STREAM("Sparse solution was found in "<<(ros::Time::now() - start_time).toSec()<<" seconds");
00446     bool success = getOrderedSparseArray(sparse_cart_points) && (sparse_joint_points.size() == sparse_cart_points.size());
00447     if(!success)
00448     {
00449       ROS_ERROR_STREAM("Failed to retrieve sparse solution due to unequal array sizes, cartetian pts: "<<
00450                        sparse_cart_points.size()<<", joints pts: "<<sparse_joint_points.size());
00451       return false;
00452     }
00453   }
00454   else
00455   {
00456     ROS_ERROR_STREAM("Failed to find sparse joint solution");
00457     return false;
00458   }
00459 
00460   unsigned int i = 0;
00461   unsigned int index;
00462   sparse_solution_array.clear();
00463   sparse_solution_array.reserve(sparse_cart_points.size());
00464   for(auto& item : sparse_joint_points)
00465   {
00466     TrajectoryPtPtr cp = sparse_cart_points[i++];
00467     JointTrajectoryPt& jp = item;
00468     index = getDensePointIndex(cp->getID());
00469 
00470     if(index == INVALID_INDEX)
00471     {
00472       ROS_ERROR_STREAM("Cartesian point "<<cp->getID()<<" not found");
00473       return false;
00474     }
00475     else
00476     {
00477       ROS_DEBUG_STREAM("Point with dense index "<<index<<" and id "<< cp->getID()<< " added to sparse");
00478     }
00479 
00480     sparse_solution_array.push_back(std::make_tuple(index,cp,jp));
00481   }
00482   return true;
00483 }
00484 
00485 bool SparsePlanner::getOrderedSparseArray(std::vector<TrajectoryPtPtr>& sparse_array)
00486 {
00487   const CartesianMap& cart_map = planning_graph_->getCartesianMap();
00488   TrajectoryPt::ID first_id = descartes_core::TrajectoryID::make_nil();
00489   auto predicate = [&first_id](const std::pair<TrajectoryPt::ID,CartesianPointInformation>& p)
00490     {
00491       const auto& info = p.second;
00492       if(info.links_.id_previous == descartes_core::TrajectoryID::make_nil())
00493       {
00494         first_id = p.first;
00495         return true;
00496       }
00497       else
00498       {
00499         return false;
00500       }
00501     };
00502 
00503   // finding first point
00504   if(cart_map.empty()
00505       || (std::find_if(cart_map.begin(),cart_map.end(),predicate) == cart_map.end())
00506       || first_id == descartes_core::TrajectoryID::make_nil())
00507   {
00508     return false;
00509   }
00510 
00511   // copying point pointers in order
00512   sparse_array.resize(cart_map.size());
00513   TrajectoryPt::ID current_id = first_id;
00514   for(int i = 0; i < sparse_array.size(); i++)
00515   {
00516     if(cart_map.count(current_id) == 0)
00517     {
00518       ROS_ERROR_STREAM("Trajectory point "<<current_id<<" was not found in sparse trajectory.");
00519       return false;
00520     }
00521 
00522     const CartesianPointInformation& info  = cart_map.at(current_id);
00523     sparse_array[i] = info.source_trajectory_;
00524     current_id = info.links_.id_next;
00525   }
00526 
00527   return true;
00528 }
00529 
00530 bool SparsePlanner::getSolutionJointPoint(const CartTrajectoryPt::ID& cart_id, JointTrajectoryPt& j)
00531 {
00532   if(joint_points_map_.count(cart_id) > 0)
00533   {
00534     j = joint_points_map_[cart_id];
00535   }
00536   else
00537   {
00538     ROS_ERROR_STREAM("Solution for point "<<cart_id<<" was not found");
00539     return false;
00540   }
00541 
00542   return true;
00543 }
00544 
00545 bool SparsePlanner::getPath(std::vector<TrajectoryPtPtr>& path) const
00546 {
00547   if(cart_points_.empty() || joint_points_map_.empty())
00548   {
00549     return false;
00550   }
00551 
00552   path.resize(cart_points_.size());
00553   for(int i = 0; i < cart_points_.size();i++)
00554   {
00555     TrajectoryPtPtr p = cart_points_[i];
00556     const JointTrajectoryPt& j = joint_points_map_.at(p->getID());
00557     TrajectoryPtPtr new_pt = TrajectoryPtPtr(new JointTrajectoryPt(j));
00558     new_pt->setTiming(timing_cache_[i]);
00559     path[i] = new_pt;
00560   }
00561 
00562   return true;
00563 }
00564 
00565 int SparsePlanner::getErrorCode() const
00566 {
00567   return error_code_;
00568 }
00569 
00570 bool SparsePlanner::getErrorMessage(int error_code, std::string& msg) const
00571 {
00572   std::map<int,std::string>::const_iterator it = error_map_.find(error_code);
00573 
00574   if(it != error_map_.cend())
00575   {
00576     msg = it->second;
00577   }
00578   else
00579   {
00580     return false;
00581   }
00582   return true;
00583 }
00584 
00585 void SparsePlanner::sampleTrajectory(double sampling,const std::vector<TrajectoryPtPtr>& dense_trajectory_array,
00586                       std::vector<TrajectoryPtPtr>& sparse_trajectory_array)
00587 {
00588   std::stringstream ss;
00589   int skip = std::ceil(double(1.0f)/sampling);
00590   ROS_INFO_STREAM("Sampling skip val: "<<skip<< " from sampling val: "<<sampling);
00591   ss<<"[";
00592   for(int i = 0; i < dense_trajectory_array.size();i+=skip)
00593   {
00594     sparse_trajectory_array.push_back(dense_trajectory_array[i]);
00595     ss<<i<<" ";
00596   }
00597   ss<<"]";
00598   ROS_INFO_STREAM("Sparse Indices:\n"<<ss.str());
00599 
00600   // add the last one
00601   if(sparse_trajectory_array.back()->getID() != dense_trajectory_array.back()->getID())
00602   {
00603     sparse_trajectory_array.push_back(dense_trajectory_array.back());
00604   }
00605 }
00606 
00607 bool SparsePlanner::interpolateJointPose(const std::vector<double>& start,const std::vector<double>& end,
00608     double t,std::vector<double>& interp)
00609 {
00610   if(start.size() != end.size() )
00611   {
00612     ROS_ERROR_STREAM("Joint arrays have unequal size, interpolation failed");
00613     return false;
00614   }
00615 
00616   if((t > 1 || t < 0))
00617   {
00618     return false;
00619   }
00620 
00621   interp.resize(start.size());
00622   double val = 0.0f;
00623   for(int i = 0; i < start.size(); i++)
00624   {
00625     val = end[i] - (end[i] - start[i]) * (1 - t);
00626     interp[i] = val;
00627   }
00628 
00629   return true;
00630 }
00631 
00632 bool SparsePlanner::plan()
00633 {
00634 
00635   // solving coarse trajectory
00636   bool replan = true;
00637   bool succeeded = false;
00638   int max_replanning_attempts = cart_points_.size()/2;
00639   int replanning_attempts = 0;
00640   while(replan && getSparseSolutionArray(sparse_solution_array_))
00641   {
00642     int sparse_index, point_pos;
00643     int result = interpolateSparseTrajectory(sparse_solution_array_,sparse_index,point_pos);
00644     TrajectoryPt::ID prev_id, next_id;
00645     TrajectoryPtPtr cart_point;
00646     switch(result)
00647     {
00648       case int(InterpolationResult::REPLAN):
00649           replan = true;
00650           cart_point = cart_points_[point_pos];
00651 
00652           if(sparse_index == 0)
00653           {
00654             prev_id = descartes_core::TrajectoryID::make_nil();
00655             next_id = std::get<1>(sparse_solution_array_[sparse_index])->getID();
00656           }
00657           else
00658           {
00659             prev_id = std::get<1>(sparse_solution_array_[sparse_index-1])->getID();
00660             next_id = std::get<1>(sparse_solution_array_[sparse_index])->getID();
00661           }
00662 
00663           if(planning_graph_->addTrajectory(cart_point,prev_id,next_id))
00664           {
00665             sparse_solution_array_.clear();
00666             ROS_INFO_STREAM("Added new point to sparse trajectory from dense trajectory at position "<<
00667                             point_pos<<", re-planning entire trajectory");
00668           }
00669           else
00670           {
00671             ROS_ERROR_STREAM("Adding point "<<point_pos <<"to sparse trajectory failed, aborting");
00672             replan = false;
00673             succeeded = false;
00674           }
00675 
00676           break;
00677       case int(InterpolationResult::SUCCESS):
00678           replan = false;
00679           succeeded = true;
00680           break;
00681       case int(InterpolationResult::ERROR):
00682           replan = false;
00683           succeeded = false;
00684           break;
00685     }
00686 
00687     if(replanning_attempts++ > max_replanning_attempts)
00688     {
00689       ROS_ERROR_STREAM("Maximum number of replanning attempts exceeded, aborting");
00690       replan = false;
00691       succeeded = false;
00692       break;
00693     }
00694 
00695   }
00696 
00697   return succeeded;
00698 }
00699 
00700 bool SparsePlanner::checkJointChanges(const std::vector<double>& s1,
00701                                       const std::vector<double>& s2, const double& max_change)
00702 {
00703   if(s1.size()!=s2.size())
00704   {
00705     ROS_ERROR_STREAM("Joint arrays have unequal size, failed to check for large joint changes");
00706     return false;
00707   }
00708 
00709   for(int i = 0; i < s1.size();i++)
00710   {
00711     if(std::abs(s1[i] - s2[i])> max_change)
00712     {
00713       return false;
00714     }
00715   }
00716 
00717   return true;
00718 }
00719 
00720 int SparsePlanner::interpolateSparseTrajectory(const SolutionArray& sparse_solution_array,int &sparse_index, int &point_pos)
00721 {
00722   // populating full path
00723   joint_points_map_.clear();
00724   descartes_core::RobotModelConstPtr robot_model = planning_graph_->getRobotModel();
00725   std::vector<double> start_jpose, end_jpose, rough_interp, aprox_interp, seed_pose(robot_model->getDOF(),0);
00726   for(int k = 1; k < sparse_solution_array.size(); k++)
00727   {
00728     auto start_index = std::get<0>(sparse_solution_array[k-1]);
00729     auto end_index = std::get<0>(sparse_solution_array[k]);
00730     TrajectoryPtPtr start_tpoint = std::get<1>(sparse_solution_array[k-1]);
00731     TrajectoryPtPtr end_tpoint = std::get<1>(sparse_solution_array[k]);
00732     const JointTrajectoryPt& start_jpoint = std::get<2>(sparse_solution_array[k-1]);
00733     const JointTrajectoryPt& end_jpoint = std::get<2>(sparse_solution_array[k]);
00734 
00735 
00736     start_jpoint.getNominalJointPose(seed_pose,*robot_model,start_jpose);
00737     end_jpoint.getNominalJointPose(seed_pose,*robot_model,end_jpose);
00738 
00739     // adding start joint point to solution
00740     joint_points_map_.insert(std::make_pair(start_tpoint->getID(),start_jpoint));
00741 
00742     // interpolating
00743     int step = end_index - start_index;
00744     ROS_DEBUG_STREAM("Interpolation parameters: step : "<<step<<", start index "<<start_index<<", end index "<<end_index);
00745     for(int j = 1; (j < step) && ( (start_index + j) < cart_points_.size()); j++)
00746     {
00747       int pos = start_index+j;
00748       double t = double(j)/double(step);
00749       if(!interpolateJointPose(start_jpose,end_jpose,t,rough_interp))
00750       {
00751         ROS_ERROR_STREAM("Interpolation for point at position "<<pos<< "failed, aborting");
00752         return (int)InterpolationResult::ERROR;
00753       }
00754 
00755       TrajectoryPtPtr cart_point = cart_points_[pos];
00756       if(cart_point->getClosestJointPose(rough_interp,*robot_model,aprox_interp) )
00757       {
00758         if(checkJointChanges(rough_interp,aprox_interp,MAX_JOINT_CHANGE))
00759         {
00760           ROS_DEBUG_STREAM("Interpolated point at position "<<pos);
00761 
00762           // look up previous points joint solution
00763           const JointTrajectoryPt& last_joint_pt = joint_points_map_.at(cart_points_[pos-1]->getID());
00764           std::vector<double> last_joint_pose;
00765           last_joint_pt.getNominalJointPose(std::vector<double>(), *robot_model, last_joint_pose);
00766 
00767           // retreiving timing constraint
00768           const descartes_core::TimingConstraint& tm = timing_cache_[pos];
00769 
00770           // check validity of joint motion
00771           if (tm.isSpecified() && !robot_model->isValidMove(last_joint_pose, aprox_interp, tm.upper))
00772           {
00773             ROS_WARN_STREAM("Joint velocity checking failed for point " << pos << ". Replanning.");
00774             sparse_index = k;
00775             point_pos = pos;
00776             return static_cast<int>(InterpolationResult::REPLAN);
00777           }
00778 
00779           // otherwise add point
00780           joint_points_map_.insert(std::make_pair(cart_point->getID(),JointTrajectoryPt(aprox_interp)));
00781         }
00782         else
00783         {
00784           ROS_WARN_STREAM("Joint changes greater that "<<MAX_JOINT_CHANGE<<" detected for point "<<pos<<
00785                           ", replanning");
00786           sparse_index = k;
00787           point_pos = pos;
00788           return (int)InterpolationResult::REPLAN;
00789         }
00790       }
00791       else
00792       {
00793 
00794           ROS_WARN_STREAM("Couldn't find a closest joint pose for point "<< cart_point->getID()<<", replanning");
00795           sparse_index = k;
00796           point_pos = pos;
00797           return (int)InterpolationResult::REPLAN;
00798       }
00799     }
00800 
00801     // adding end joint point to solution
00802     joint_points_map_.insert(std::make_pair(end_tpoint->getID(),end_jpoint));
00803   }
00804 
00805   return (int)InterpolationResult::SUCCESS;
00806 }
00807 
00808 } /* namespace descartes_planner */


descartes_planner
Author(s): Jorge Nicho
autogenerated on Wed Aug 26 2015 11:21:35