40 #include <ompl/tools/config/SelfConfig.h> 41 #include <boost/date_time/posix_time/posix_time.hpp> 42 #include <boost/filesystem.hpp> 50 void msgToHex(
const T& msg, std::string& hex)
52 static const char symbol[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
58 hex.resize(serial_size_arg * 2);
59 for (std::size_t i = 0; i < serial_size_arg; ++i)
61 hex[i * 2] = symbol[buffer_arg[i] / 16];
62 hex[i * 2 + 1] = symbol[buffer_arg[i] % 16];
67 void hexToMsg(
const std::string& hex, T& msg)
69 const size_t serial_size_arg = hex.length() / 2;
71 for (std::size_t i = 0; i < serial_size_arg; ++i)
73 buffer_arg[i] = (hex[i * 2] <=
'9' ? (hex[i * 2] -
'0') : (hex[i * 2] -
'A' + 10)) * 16 +
74 (hex[i * 2 + 1] <=
'9' ? (hex[i * 2 + 1] -
'0') : (hex[i * 2 + 1] -
'A' + 10));
89 inv_dim_ = space->getDimension() > 0 ? 1.0 / (double)space->getDimension() : 1.0;
97 virtual void sampleUniformNear(ob::State* state,
const ob::State* near,
const double distance)
105 if (!md.first.empty())
107 std::size_t matt = md.first.size() / 3;
111 index = md.first[rng_.uniformInt(0, md.first.size() - 1)];
112 }
while (
dirty_.find(index) !=
dirty_.end() && ++att < matt);
122 double dist = space_->distance(near,
state_storage_->getState(index));
127 space_->interpolate(near,
state_storage_->getState(index), d / dist, state);
133 virtual void sampleGaussian(ob::State* state,
const ob::State* mean,
const double stdDev)
147 const ob::State* to,
const double t, ob::State* state)
152 if (tag_from < 0 || tag_to < 0)
155 if (tag_from == tag_to)
156 state_storage->getStateSpace()->copyState(state, to);
161 std::map<std::size_t, std::pair<std::size_t, std::size_t> >::const_iterator it = md.second.find(tag_to);
162 if (it == md.second.end())
164 const std::pair<std::size_t, std::size_t>& istates = it->second;
165 std::size_t
index = (std::size_t)((istates.second - istates.first + 2) * t + 0.5);
168 state_storage->getStateSpace()->copyState(state, from);
172 if (index >= istates.second - istates.first)
173 state_storage->getStateSpace()->copyState(state, to);
175 state_storage->getStateSpace()->copyState(state, state_storage->getState(istates.first + index));
183 if (explicit_motions_ && milestones_ > 0 && milestones_ < state_storage_->size())
188 ompl::base::StateSamplerPtr
191 std::size_t milestones)
193 std::vector<int> sig;
194 space->computeSignature(sig);
195 if (sig != expected_signature)
196 return ompl::base::StateSamplerPtr();
203 const std::string& group,
const std::string& state_space_parameterization,
bool explicit_motions,
204 const moveit_msgs::Constraints& msg,
const std::string& filename,
const ompl::base::StateStoragePtr& storage,
205 std::size_t milestones)
207 , state_space_parameterization_(state_space_parameterization)
208 , explicit_motions_(explicit_motions)
209 , constraint_msg_(msg)
210 , ompldb_filename_(filename)
211 , state_storage_ptr_(storage)
212 , milestones_(milestones)
220 ompl::base::StateSamplerAllocator
224 return ompl::base::StateSamplerAllocator();
270 constraint_approximations_.clear();
271 std::ifstream fin((path +
"/manifest").c_str());
274 ROS_WARN_NAMED(
"constraints_library",
"Manifest not found in folder '%s'. Not loading constraint approximations.",
279 ROS_INFO_NAMED(
"constraints_library",
"Loading constrained space approximations from '%s'...", path.c_str());
281 while (fin.good() && !fin.eof())
283 std::string group, state_space_parameterization, serialization,
filename;
284 bool explicit_motions;
285 unsigned int milestones;
289 fin >> state_space_parameterization;
292 fin >> explicit_motions;
298 fin >> serialization;
302 ROS_INFO_NAMED(
"constraints_library",
"Loading constraint approximation of type '%s' for group '%s' from '%s'...",
303 state_space_parameterization.c_str(), group.c_str(), filename.c_str());
304 const ModelBasedPlanningContextPtr& pc = context_manager_.getPlanningContext(group, state_space_parameterization);
307 moveit_msgs::Constraints msg;
308 hexToMsg(serialization, msg);
311 cass->load((path +
"/" + filename).c_str());
312 ConstraintApproximationPtr cap(
new ConstraintApproximation(group, state_space_parameterization, explicit_motions,
313 msg, filename, ompl::base::StateStoragePtr(cass),
315 if (constraint_approximations_.find(cap->getName()) != constraint_approximations_.end())
316 ROS_WARN_NAMED(
"constraints_library",
"Overwriting constraint approximation named '%s'",
317 cap->getName().c_str());
318 constraint_approximations_[cap->getName()] = cap;
320 for (std::size_t i = 0; i < cass->size(); ++i)
321 sum += cass->getMetadata(i).first.size();
322 ROS_INFO_NAMED(
"constraints_library",
"Loaded %lu states (%lu milestones) and %lu connections (%0.1lf per state) " 323 "for constraint named '%s'%s",
324 cass->size(), cap->getMilestoneCount(), sum, (double)sum / (
double)cap->getMilestoneCount(),
325 msg.name.c_str(), explicit_motions ?
". Explicit motions included." :
"");
328 ROS_INFO_NAMED(
"constraints_library",
"Done loading constrained space approximations.");
333 ROS_INFO_NAMED(
"constraints_library",
"Saving %u constrained space approximations to '%s'",
334 (
unsigned int)constraint_approximations_.size(), path.c_str());
337 boost::filesystem::create_directories(path);
343 std::ofstream fout((path +
"/manifest").c_str());
345 for (std::map<std::string, ConstraintApproximationPtr>::const_iterator it = constraint_approximations_.begin();
346 it != constraint_approximations_.end(); ++it)
348 fout << it->second->getGroup() << std::endl;
349 fout << it->second->getStateSpaceParameterization() << std::endl;
350 fout << it->second->hasExplicitMotions() << std::endl;
351 fout << it->second->getMilestoneCount() << std::endl;
352 std::string serialization;
353 msgToHex(it->second->getConstraintsMsg(), serialization);
354 fout << serialization << std::endl;
355 fout << it->second->getFilename() << std::endl;
356 if (it->second->getStateStorage())
357 it->second->getStateStorage()->store((path +
"/" + it->second->getFilename()).c_str());
360 ROS_ERROR_NAMED(
"constraints_library",
"Unable to save constraint approximation to '%s'", path.c_str());
366 constraint_approximations_.clear();
371 for (std::map<std::string, ConstraintApproximationPtr>::const_iterator it = constraint_approximations_.begin();
372 it != constraint_approximations_.end(); ++it)
374 out << it->second->getGroup() << std::endl;
375 out << it->second->getStateSpaceParameterization() << std::endl;
376 out << it->second->hasExplicitMotions() << std::endl;
377 out << it->second->getMilestoneCount() << std::endl;
378 out << it->second->getFilename() << std::endl;
379 out << it->second->getConstraintsMsg() << std::endl;
383 const ompl_interface::ConstraintApproximationPtr&
386 std::map<std::string, ConstraintApproximationPtr>::const_iterator it = constraint_approximations_.find(msg.name);
387 if (it != constraint_approximations_.end())
390 static ConstraintApproximationPtr empty;
396 const moveit_msgs::Constraints& constr,
const std::string& group,
399 return addConstraintApproximation(constr, constr, group, scene, options);
404 const moveit_msgs::Constraints& constr_sampling,
const moveit_msgs::Constraints& constr_hard,
405 const std::string& group,
const planning_scene::PlanningSceneConstPtr& scene,
413 pc->setPlanningScene(scene);
414 pc->setCompleteInitialState(scene->getCurrentState());
417 ompl::base::StateStoragePtr ss = constructConstraintApproximation(pc, constr_sampling, constr_hard, options, res);
418 ROS_INFO_NAMED(
"constraints_library",
"Spent %lf seconds constructing the database",
424 group +
"_" + boost::posix_time::to_iso_extended_string(boost::posix_time::microsec_clock::universal_time()) +
427 if (constraint_approximations_.find(ca->getName()) != constraint_approximations_.end())
428 ROS_WARN_NAMED(
"constraints_library",
"Overwriting constraint approximation named '%s'", ca->getName().c_str());
429 constraint_approximations_[ca->getName()] = ca;
433 ROS_ERROR_NAMED(
"constraints_library",
"Unable to construct constraint approximation for group '%s'",
440 const ModelBasedPlanningContextPtr& pcontext,
const moveit_msgs::Constraints& constr_sampling,
446 ob::StateStoragePtr sstor(cass);
450 robot_state::Transforms no_transforms(pcontext->getRobotModel()->getModelFrame());
451 kset.
add(constr_hard, no_transforms);
453 const robot_state::RobotState& default_state = pcontext->getCompleteInitialRobotState();
455 unsigned int attempts = 0;
457 double bounds_val = std::numeric_limits<double>::max() / 2.0 - 1.0;
458 pcontext->getOMPLStateSpace()->setPlanningVolume(-bounds_val, bounds_val, -bounds_val, bounds_val, -bounds_val,
460 pcontext->getOMPLStateSpace()->setup();
464 robot_state::RobotState kstate(default_state);
465 const constraint_samplers::ConstraintSamplerManagerPtr& csmng = pcontext->getConstraintSamplerManager();
469 constraint_samplers::ConstraintSamplerPtr cs =
470 csmng->selectSampler(pcontext->getPlanningScene(), pcontext->getJointModelGroup()->getName(), constr_sampling);
475 ob::StateSamplerPtr ss(csmp ? ob::StateSamplerPtr(csmp) : pcontext->getOMPLStateSpace()->allocDefaultStateSampler());
477 ompl::base::ScopedState<> temp(pcontext->getOMPLStateSpace());
479 bool slow_warn =
false;
480 ompl::time::point start = ompl::time::now();
481 while (sstor->size() < options.
samples)
484 int done_now = 100 * sstor->size() / options.
samples;
485 if (done != done_now)
488 ROS_INFO_NAMED(
"constraints_library",
"%d%% complete (kept %0.1lf%% sampled states)", done,
489 100.0 * (
double)sstor->size() / (double)attempts);
492 if (!slow_warn && attempts > 10 && attempts > sstor->size() * 100)
495 ROS_WARN_NAMED(
"constraints_library",
"Computation of valid state database is very slow...");
498 if (attempts > options.
samples && sstor->size() == 0)
500 ROS_ERROR_NAMED(
"constraints_library",
"Unable to generate any samples");
504 ss->sampleUniform(temp.get());
505 pcontext->getOMPLStateSpace()->copyToRobotState(kstate, temp.get());
506 if (kset.decide(kstate).satisfied)
508 if (sstor->size() < options.
samples)
511 sstor->addState(temp.get());
517 ROS_INFO_NAMED(
"constraints_library",
"Generated %u states in %lf seconds", (
unsigned int)sstor->size(),
528 ROS_INFO_NAMED(
"constraints_library",
"Computing graph connections (max %u edges per sample) ...",
532 const ob::StateSpacePtr& space = pcontext->getOMPLSimpleSetup()->getStateSpace();
533 unsigned int milestones = sstor->size();
535 pcontext->getOMPLSimpleSetup()->getSpaceInformation()->allocStates(int_states);
537 ompl::time::point start = ompl::time::now();
541 for (std::size_t j = 0; j < milestones; ++j)
543 int done_now = 100 * j / milestones;
544 if (done != done_now)
552 const ob::State* sj = sstor->getState(j);
554 for (std::size_t i = j + 1; i < milestones; ++i)
558 double d = space->distance(sstor->getState(i), sj);
561 unsigned int isteps =
563 double step = 1.0 / (double)isteps;
565 space->interpolate(sstor->getState(i), sj, step, int_states[0]);
566 for (
unsigned int k = 1; k < isteps; ++k)
568 double this_step = step / (1.0 - (k - 1) * step);
569 space->interpolate(int_states[k - 1], sj, this_step, int_states[k]);
570 pcontext->getOMPLStateSpace()->copyToRobotState(kstate, int_states[k]);
571 if (!kset.decide(kstate).satisfied)
580 cass->getMetadata(i).first.push_back(j);
581 cass->getMetadata(j).first.push_back(i);
585 cass->getMetadata(i).second[j].first = sstor->size();
586 for (
unsigned int k = 0; k < isteps; ++k)
589 sstor->addState(int_states[k]);
591 cass->getMetadata(i).second[j].second = sstor->size();
592 cass->getMetadata(j).second[i] = cass->getMetadata(i).second[j];
603 ROS_INFO_NAMED(
"constraints_library",
"Computed possible connexions in %lf seconds. Added %d connexions",
605 pcontext->getOMPLSimpleSetup()->getSpaceInformation()->freeStates(int_states);
612 ROS_ERROR_NAMED(
"constraints_library",
"No StateStoragePtr found - implement better solution here.");
std::pair< std::vector< std::size_t >, std::map< std::size_t, std::pair< std::size_t, std::size_t > > > ConstrainedStateMetadata
std::vector< int > space_signature_
#define ROS_INFO_NAMED(name,...)
std::string state_space_parameterization
virtual void sampleUniform(ob::State *state)
std::set< std::size_t > dirty_
#define ROS_WARN_NAMED(name,...)
virtual void sampleGaussian(ob::State *state, const ob::State *mean, const double stdDev)
double state_connection_time
double getConstrainedSamplingRate() const
double sampling_success_rate
ompl::base::StateSamplerPtr allocConstraintApproximationStateSampler(const ob::StateSpace *space, const std::vector< int > &expected_signature, const ConstraintApproximationStateStorage *state_storage, std::size_t milestones)
ConstraintApproximationStateSampler(const ob::StateSpace *space, const ConstraintApproximationStateStorage *state_storage, std::size_t milestones)
The MoveIt! interface to OMPL.
virtual void sampleUniformNear(ob::State *state, const ob::State *near, const double distance)
ompl::base::StateSamplerAllocator getStateSamplerAllocator(const moveit_msgs::Constraints &msg) const
ConstraintApproximationStateStorage * state_storage_
void printConstraintApproximations(std::ostream &out=std::cout) const
bool add(const moveit_msgs::Constraints &c, const robot_state::Transforms &tf)
void saveConstraintApproximations(const std::string &path)
ompl::base::StateStoragePtr state_storage_ptr_
ConstraintApproximationConstructionResults addConstraintApproximation(const moveit_msgs::Constraints &constr_sampling, const moveit_msgs::Constraints &constr_hard, const std::string &group, const planning_scene::PlanningSceneConstPtr &scene, const ConstraintApproximationConstructionOptions &options)
void serialize(Stream &stream, const T &t)
const ConstraintApproximationPtr & getConstraintApproximation(const moveit_msgs::Constraints &msg) const
unsigned int max_explicit_points
const ConstraintApproximationStateStorage * state_storage_
The states to sample from.
double explicit_points_resolution
ConstraintApproximation(const std::string &group, const std::string &state_space_parameterization, bool explicit_motions, const moveit_msgs::Constraints &msg, const std::string &filename, const ompl::base::StateStoragePtr &storage, std::size_t milestones=0)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
uint32_t serializationLength(const T &t)
unsigned int edges_per_sample
void loadConstraintApproximations(const std::string &path)
void clearConstraintApproximations()
bool interpolateUsingStoredStates(const ConstraintApproximationStateStorage *state_storage, const ob::State *from, const ob::State *to, const double t, ob::State *state)
double state_sampling_time
InterpolationFunction getInterpolationFunction() const
#define ROS_ERROR_NAMED(name,...)
ompl::base::StateStorageWithMetadata< ConstrainedStateMetadata > ConstraintApproximationStateStorage
ompl::base::StateStoragePtr constructConstraintApproximation(const ModelBasedPlanningContextPtr &pcontext, const moveit_msgs::Constraints &constr_sampling, const moveit_msgs::Constraints &constr_hard, const ConstraintApproximationConstructionOptions &options, ConstraintApproximationConstructionResults &result)
ConstraintApproximationPtr approx
void deserialize(Stream &stream, T &t)
boost::function< bool(const ompl::base::State *from, const ompl::base::State *to, const double t, ompl::base::State *state)> InterpolationFunction