EReturn OMPLsolver::convertPath(const ompl::geometric::PathGeometric &pg, Eigen::MatrixXd & traj) { traj.resize(pg.getStateCount(), state_space_->getDimension()); Eigen::VectorXd tmp(state_space_->getDimension()); for (int i = 0; i < (int) pg.getStateCount(); ++i) { if (!ok( compound_ ? boost::static_pointer_cast<OMPLSE3RNCompoundStateSpace>( state_space_)->OMPLStateToEigen(pg.getState(i), tmp) : boost::static_pointer_cast<OMPLStateSpace>(state_space_)->copyFromOMPLState( pg.getState(i), tmp))) { ERROR("Can't copy state "<<i); return FAILURE; } else { traj.row(i) = tmp; } } return SUCCESS; }
void OmnidirectionalMotionModel::generateOpenLoopControlsForPath(const ompl::geometric::PathGeometric path, std::vector<ompl::control::Control*> &openLoopControls) { for(int i=0;i<path.getStateCount()-1;i++) { std::vector<ompl::control::Control*> olc; this->generateOpenLoopControls(path.getState(i),path.getState(i+1),olc) ; openLoopControls.insert(openLoopControls.end(),olc.begin(),olc.end()); } }
OpenRAVE::PlannerStatus ToORTrajectory( OpenRAVE::RobotBasePtr const &robot, ompl::geometric::PathGeometric& ompl_traj, OpenRAVE::TrajectoryBasePtr or_traj) { using ompl::geometric::PathGeometric; size_t const num_dof = robot->GetActiveDOF(); or_traj->Init(robot->GetActiveConfigurationSpecification("linear")); ompl::base::StateSpacePtr space = ompl_traj.getSpaceInformation()->getStateSpace(); for (size_t i = 0; i < ompl_traj.getStateCount(); ++i){ std::vector<double> values; space->copyToReals(values, ompl_traj.getState(i)); or_traj->Insert(i, values, true); } return OpenRAVE::PS_HasSolution; }
static void path_cleanup( struct aa_rx_mp *mp, ompl::geometric::PathGeometric &path ) { amino::sgSpaceInformation::Ptr &si = mp->space_information; if( mp->simplify ) { ompl::geometric::PathSimplifier ps(si); int n = (int)path.getStateCount(); path.interpolate(n*10); for( int i = 0; i < 10; i ++ ) { ps.reduceVertices(path); ps.collapseCloseVertices(path); ps.shortcutPath(path); } ps.smoothBSpline(path, 3, path.length()/100.0); } }
void ompl::tools::LightningDB::addPathHelper(ompl::geometric::PathGeometric &solutionPath) { // Create a new planner data instance ompl::base::PlannerDataPtr plannerData(new ompl::base::PlannerData(si_)); // Add the states to one nodes files for (std::size_t i = 0; i < solutionPath.getStates().size(); ++i) { ompl::base::PlannerDataVertex vert( solutionPath.getStates()[i] ); // TODO tag? plannerData->addVertex(vert); } // Deep copy the states in the vertices so that when the planner goes out of scope, all data remains intact plannerData->decoupleFromPlanner(); // Add to nearest neighbor tree nn_->add(plannerData); numUnsavedPaths_++; }
bool ompl::tools::Lightning::reversePathIfNecessary(og::PathGeometric &path1, og::PathGeometric &path2) { // Reverse path2 if it matches better const ob::State* s1 = path1.getState(0); const ob::State* s2 = path2.getState(0); const ob::State* g1 = path1.getState(path1.getStateCount()-1); const ob::State* g2 = path2.getState(path2.getStateCount()-1); double regularDistance = si_->distance(s1, s2) + si_->distance(g1, g2); double reversedDistance = si_->distance(s1, g2) + si_->distance(s2, g1); // Check if path is reversed from normal [start->goal] direction if ( regularDistance > reversedDistance ) { // needs to be reversed path2.reverse(); return true; } return false; }
void ompl::tools::Lightning::convertPlannerData(const ob::PlannerDataPtr& plannerData, og::PathGeometric &path) { // Convert the planner data verticies into a vector of states for (std::size_t i = 0; i < plannerData->numVertices(); ++i) path.append(plannerData->getVertex(i).getState()); }
EReturn OMPLsolver::getSimplifiedPath(ompl::geometric::PathGeometric &pg, Eigen::MatrixXd & traj, ob::PlannerTerminationCondition &ptc) { if (smooth_->data) { HIGHLIGHT("Simplifying solution"); int original_cnt = pg.getStateCount(); ros::Time start = ros::Time::now(); //ompl_simple_setup_->simplifySolution(d); // Lets do our own simplifier ~:) if (original_cnt >= 3) { og::PathSimplifierPtr psf_ = ompl_simple_setup_->getPathSimplifier(); const ob::SpaceInformationPtr &si = ompl_simple_setup_->getSpaceInformation(); bool tryMore = false; if (ptc == false) tryMore = psf_->reduceVertices(pg); if (ptc == false) psf_->collapseCloseVertices(pg); int times = 0; while (tryMore && ptc == false) { tryMore = psf_->reduceVertices(pg); times++; } if (si->getStateSpace()->isMetricSpace()) { if (ptc == false) tryMore = psf_->shortcutPath(pg); else tryMore = false; times = 0; while (tryMore && ptc == false) { tryMore = psf_->shortcutPath(pg); times++; } } std::vector<ob::State*> &states = pg.getStates(); // Calculate number of states required unsigned int length = 0; const int n1 = states.size() - 1; for (int i = 0; i < n1; ++i) length += si->getStateSpace()->validSegmentCount(states[i], states[i + 1]); // // Forward reducing // HIGHLIGHT("States before forward reducing: "<<pg.getStateCount()); // pg.interpolate(length); // // bool need_backward = true; // for (int i = states.size() - 1; i > 0; i--) // { // if (si->checkMotion(states[0], states[i])) // { // ob::State *start = si->cloneState(states[0]); // pg.keepAfter(states[i]); // pg.prepend(start); // need_backward = (i == states.size() - 1) ? false : true; // break; // } // } // // // Backward reducing // ob::State *mid; // if (need_backward) // { // HIGHLIGHT("States before backward reducing: "<<pg.getStateCount()); // pg.interpolate(length); // for (int i = 1; i < states.size(); i++) // { // if (si->checkMotion(states[states.size() - 1], states[i])) // { // ob::State *goal = si->cloneState(states[states.size() - 1]); // pg.keepBefore(states[i]); // pg.append(goal); // mid = si->cloneState(states[i]); // break; // } // } // } pg.interpolate(length); } // if (ompl_simple_setup_->haveSolutionPath()) // { // pg.interpolate(); // } HIGHLIGHT_NAMED("OMPLSolver", "Simplification took "<<ros::Duration(ros::Time::now()-start).toSec()<<"sec. States: "<<original_cnt<<"->"<<pg.getStateCount()); } convertPath(pg, traj); return SUCCESS; }
bool ompl::geometric::LightningRetrieveRepair::repairPath(const base::PlannerTerminationCondition &ptc, ompl::geometric::PathGeometric &primaryPath) { // \todo: we should reuse our collision checking from the previous step to make this faster OMPL_INFORM("LightningRetrieveRepair: Repairing path"); // Error check if (primaryPath.getStateCount() < 2) { OMPL_ERROR("LightningRetrieveRepair: Cannot repair a path with less than 2 states"); return false; } // Loop through every pair of states and make sure path is valid. // If not, replan between those states for (std::size_t toID = 1; toID < primaryPath.getStateCount(); ++toID) { std::size_t fromID = toID - 1; // this is our last known valid state ompl::base::State *fromState = primaryPath.getState(fromID); ompl::base::State *toState = primaryPath.getState(toID); // Check if our planner is out of time if (ptc == true) { OMPL_DEBUG("LightningRetrieveRepair: Repair path function interrupted because termination condition is true."); return false; } // Check path between states if (!si_->checkMotion(fromState, toState)) { // Path between (from, to) states not valid, but perhaps to STATE is // Search until next valid STATE is found in existing path std::size_t subsearchID = toID; ompl::base::State *new_to; OMPL_DEBUG("LightningRetrieveRepair: Searching for next valid state, because state %d to %d was not valid out %d total states", fromID,toID,primaryPath.getStateCount()); while (subsearchID < primaryPath.getStateCount()) { new_to = primaryPath.getState(subsearchID); if (si_->isValid(new_to)) { OMPL_DEBUG("LightningRetrieveRepair: State %d was found to valid, we can now repair between states", subsearchID); // This future state is valid, we can stop searching toID = subsearchID; toState = new_to; break; } ++subsearchID; // keep searching for a new state to plan to } // Check if we ever found a next state that is valid if (subsearchID >= primaryPath.getStateCount()) { // We never found a valid state to plan to, instead we reached the goal state and it too wasn't valid. This is bad. // I think this is a bug. OMPL_ERROR("LightningRetrieveRepair: No state was found valid in the remainder of the path. Invalid goal state. This should not happen."); return false; } // Plan between our two valid states PathGeometric newPathSegment(si_); // Not valid motion, replan OMPL_DEBUG("LightningRetrieveRepair: Planning from %d to %d", fromID, toID); if (!replan(fromState, toState, newPathSegment, ptc)) { OMPL_INFORM("LightningRetrieveRepair: Unable to repair path between state %d and %d", fromID, toID); return false; } // TODO make sure not approximate solution // Reference to the path std::vector<base::State*> &primaryPathStates = primaryPath.getStates(); // Remove all invalid states between (fromID, toID) - not including those states themselves while (fromID != toID - 1) { OMPL_INFORM("LightningRetrieveRepair: Deleting state %d", fromID + 1); primaryPathStates.erase(primaryPathStates.begin() + fromID + 1); --toID; // because vector has shrunk OMPL_INFORM("LightningRetrieveRepair: toID is now %d", toID); } // Insert new path segment into current path OMPL_DEBUG("LightningRetrieveRepair: Inserting new %d states into old path. Previous length: %d", newPathSegment.getStateCount()-2, primaryPathStates.size()); // Note: skip first and last states because they should be same as our start and goal state, same as `fromID` and `toID` for (std::size_t i = 1; i < newPathSegment.getStateCount() - 1; ++i) { std::size_t insertLocation = toID + i - 1; OMPL_DEBUG("LightningRetrieveRepair: Inserting newPathSegment state %d into old path at position %d", i, insertLocation); primaryPathStates.insert(primaryPathStates.begin() + insertLocation, si_->cloneState(newPathSegment.getStates()[i]) ); } OMPL_DEBUG("LightningRetrieveRepair: Inserted new states into old path. New length: %d", primaryPathStates.size()); // Set the toID to jump over the newly inserted states to the next unchecked state. Subtract 2 because we ignore start and goal toID = toID + newPathSegment.getStateCount() - 2; OMPL_DEBUG("LightningRetrieveRepair: Continuing searching at state %d", toID); } } OMPL_INFORM("LightningRetrieveRepair: Done repairing"); return true; }
bool ompl::LTLVis::VRVPlanner::DijkstraSearch(const ompl::base::PlannerTerminationCondition &ptc, ompl::geometric::PathGeometric &solution) { //update the value we use to check that a vertex has been initialized, or visited, in the current search ++crVisitation_; WorkingVertexVector pqueue; pqueue.clear(); bool reachedGoal = false; bool goalDisconnected = false; ompl::LTLVis::tIndex goalIndexReached = 0; WorkingVertexVector pathCandidate; ompl::LTLVis::tIndex maxK = vertices_.size(); for(ompl::LTLVis::tIndex k = 0; k < maxK; k++) { if(vertices_[k].getIsStart()) { vertices_[k].setNegativeDistance(0); vertices_[k].setLastInitAlg(crVisitation_); pqueue.push_back(&vertices_[k]); } } make_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare); while(pqueue.size() && (ptc == false)) { VRVVertex *cVertex(pqueue.front()); pop_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare); pqueue.pop_back(); if(cVertex->getLastVisitation() < crVisitation_) { cVertex->setLastVisitation(crVisitation_); if(cVertex->getIsGoal()) { reachedGoal = true; goalIndexReached = cVertex->getIndex(); break; } ompl::LTLVis::tIndex kMax = cVertex->getEdgeCount(); for(ompl::LTLVis::tIndex k = 0; k < kMax; k++) { double weight; ompl::LTLVis::tIndex towards; cVertex->getEdge(k, weight, towards); VRVVertex *cTarget(&vertices_[towards]); if(cTarget->isInteresting()) { //STL heap is a max heap, so we use negative edge weights to 'convert' it to a min-heap if(cTarget->getLastInitAlg() < crVisitation_) { cTarget->setLastInitAlg(crVisitation_); cTarget->setNegativeDistance(cVertex->getNegativeDistance() - weight - cTarget->getNodeCost()); cTarget->setPreceding(cVertex->getIndex()); cTarget->setPrecedingEdge(k); pqueue.push_back(cTarget); push_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare); } else { double negativeDist = cVertex->getNegativeDistance() - weight - cTarget->getNodeCost(); if(negativeDist > cTarget->getNegativeDistance()) { cTarget->setNegativeDistance(negativeDist); cTarget->setPreceding(cVertex->getIndex()); cTarget->setPrecedingEdge(k); pqueue.push_back(cTarget); push_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare); } } } } } } if(reachedGoal) { pathCandidate.clear(); ompl::LTLVis::tIndex cIndex = goalIndexReached; while(!vertices_[cIndex].getIsStart()) { pathCandidate.push_back(&vertices_[cIndex]); cIndex = vertices_[cIndex].getPreceding(); } pathCandidate.push_back(&vertices_[cIndex]); ompl::LTLVis::tIndex kMax = pathCandidate.size(); for(ompl::LTLVis::tIndex k = 0, kPrev = 0; (k < kMax); k++) { if(0 < k) { if(0.000001 < si_->distance(pathCandidate[kMax - 1 - k]->getStateData(), pathCandidate[kMax - 1 - kPrev]->getStateData())) { solution.append(pathCandidate[kMax - 1 - k]->getStateData()); kPrev = k; } } else { solution.append(pathCandidate[kMax - 1 - k]->getStateData()); } } return true; } return false; }