00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
00153 timing_cache_ = extractTiming(traj);
00154
00155 for (std::size_t i = 0; i < traj.size(); ++i)
00156 {
00157 traj[i]->setTiming(descartes_core::TimingConstraint());
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
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
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
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
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
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;
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
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
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
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
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
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
00740 joint_points_map_.insert(std::make_pair(start_tpoint->getID(),start_jpoint));
00741
00742
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
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
00768 const descartes_core::TimingConstraint& tm = timing_cache_[pos];
00769
00770
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
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
00802 joint_points_map_.insert(std::make_pair(end_tpoint->getID(),end_jpoint));
00803 }
00804
00805 return (int)InterpolationResult::SUCCESS;
00806 }
00807
00808 }