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()); } }
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; }
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); } }
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; }