38 #define BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR 40 #include "ompl/util/RandomNumbers.h" 41 #include "ompl/util/Exception.h" 45 #include <boost/math/constants/constants.hpp> 46 #include <boost/scoped_ptr.hpp> 47 #include <boost/random/uniform_on_sphere.hpp> 48 #include <boost/random/variate_generator.hpp> 50 #include <boost/numeric/ublas/vector.hpp> 58 class RNGSeedGenerator
62 someSeedsGenerated_(false),
63 firstSeed_(
std::chrono::duration_cast<
std::chrono::microseconds>(
64 std::chrono::system_clock::
now() -
65 std::chrono::system_clock::time_point::min()).count()),
71 std::uint_fast32_t firstSeed()
73 std::lock_guard<std::mutex> slock(rngMutex_);
77 void setSeed(std::uint_fast32_t seed)
79 std::lock_guard<std::mutex> slock(rngMutex_);
82 if (someSeedsGenerated_)
84 OMPL_ERROR(
"Random number generation already started. Changing seed now will not lead to deterministic sampling.");
94 if (someSeedsGenerated_)
96 OMPL_WARN(
"Random generator seed cannot be 0. Ignoring seed.");
101 OMPL_WARN(
"Random generator seed cannot be 0. Using 1 instead.");
108 std::uint_fast32_t nextSeed()
110 std::lock_guard<std::mutex> slock(rngMutex_);
111 someSeedsGenerated_ =
true;
112 return sDist_(sGen_);
116 bool someSeedsGenerated_;
117 std::uint_fast32_t firstSeed_;
118 std::mutex rngMutex_;
119 std::ranlux24_base sGen_;
120 std::uniform_int_distribution<> sDist_;
123 static std::once_flag g_once;
124 static boost::scoped_ptr<RNGSeedGenerator> g_RNGSeedGenerator;
126 void initRNGSeedGenerator()
128 g_RNGSeedGenerator.reset(
new RNGSeedGenerator());
131 RNGSeedGenerator& getRNGSeedGenerator()
133 std::call_once(g_once, &initRNGSeedGenerator);
134 return *g_RNGSeedGenerator;
142 class ompl::RNG::SphericalData
146 typedef boost::numeric::ublas::shallow_array_adaptor<double> container_type_t;
149 typedef boost::uniform_on_sphere<double, container_type_t> spherical_dist_t;
152 typedef boost::variate_generator<std::mt19937*, spherical_dist_t > variate_generator_t;
155 SphericalData(std::mt19937* generatorPtr) : generatorPtr_(generatorPtr)
160 container_type_t generate(
unsigned int dim)
166 allocateDimension(dim);
169 return (*dimVector_.at(dim).second)();
176 for (
unsigned int i = 0u; i < dimVector_.size(); ++i)
179 if (
bool(dimVector_.at(i).first) ==
true)
182 dimVector_.at(i).first->reset();
190 typedef std::pair<std::shared_ptr<spherical_dist_t>,
191 std::shared_ptr<variate_generator_t> > dist_gen_pair_t;
194 std::vector<dist_gen_pair_t> dimVector_;
197 std::mt19937* generatorPtr_;
200 void growVector(
unsigned int dim)
203 while (dim >= dimVector_.size())
206 dimVector_.push_back(dist_gen_pair_t());
211 void allocateDimension(
unsigned int dim)
214 if (dimVector_.at(dim).first ==
nullptr)
218 dimVector_.at(dim).first = std::make_shared<spherical_dist_t> (dim);
220 dimVector_.at(dim).second = std::make_shared<variate_generator_t> (generatorPtr_, *dimVector_.at(dim).first);
229 return getRNGSeedGenerator().firstSeed();
234 getRNGSeedGenerator().setSeed(seed);
238 localSeed_(getRNGSeedGenerator().nextSeed()),
239 generator_(localSeed_),
242 sphericalDataPtr_(
std ::make_shared<SphericalData> (&generator_))
247 localSeed_(localSeed),
248 generator_(localSeed_),
251 sphericalDataPtr_(
std::make_shared<SphericalData> (&generator_))
258 localSeed_ = localSeed;
261 generator_.seed(localSeed_);
266 sphericalDataPtr_->reset();
272 assert(r_min <= r_max);
274 const double mean = r_max - r_min;
275 double v =
gaussian(mean, mean/focus);
277 if (v > mean) v = 2.0 * mean - v;
278 double r = v >= 0.0 ? v + r_min : r_min;
279 return r > r_max ? r_max : r;
284 int r = (int)floor(
halfNormalReal((
double)r_min, (
double)(r_max) + 1.0, focus));
285 return (r > r_max) ? r_max : r;
292 double x0 = uniDist_(generator_);
293 double r1 = sqrt(1.0 - x0), r2 = sqrt(x0);
294 double t1 = 2.0 * boost::math::constants::pi<double>() * uniDist_(generator_), t2 = 2.0 * boost::math::constants::pi<double>() * uniDist_(generator_);
295 double c1 = cos(t1), s1 = sin(t1);
296 double c2 = cos(t2), s2 = sin(t2);
306 value[0] = boost::math::constants::pi<double>() * (-2.0 * uniDist_(generator_) + 1.0);
307 value[1] = acos(1.0 - 2.0 * uniDist_(generator_)) - boost::math::constants::pi<double>() / 2.0;
308 value[2] = boost::math::constants::pi<double>() * (-2.0 * uniDist_(generator_) + 1.0);
315 SphericalData::container_type_t rVector(n, value);
318 rVector = sphericalDataPtr_->generate(n);
328 double radiusScale = r * std::pow(
uniformReal(0.0, 1.0), 1.0 / static_cast<double>(n));
331 for (
unsigned int i = 0u; i < n; ++i)
333 value[i] = radiusScale * value[i];
338 void ompl::RNG::uniformProlateHyperspheroidSurface(
const std::shared_ptr<const ProlateHyperspheroid> &phsPtr,
double value[])
342 std::vector<double> sphere(phsPtr->getDimension());
348 phsPtr->transform(&sphere[0], value);
351 void ompl::RNG::uniformProlateHyperspheroid(
const std::shared_ptr<const ProlateHyperspheroid> &phsPtr,
double value[])
355 std::vector<double> sphere(phsPtr->getDimension());
361 phsPtr->transform(&sphere[0], value);
void quaternion(double value[4])
Uniform random unit quaternion sampling. The computed value has the order (x,y,z,w). The return variable value is expected to already exist.
RNG()
Constructor. Always sets a different random seed.
void eulerRPY(double value[3])
Uniform random sampling of Euler roll-pitch-yaw angles, each in the range (-pi, pi]. The computed value has the order (roll, pitch, yaw). The return variable value is expected to already exist.
int halfNormalInt(int r_min, int r_max, double focus=3.0)
Generate a random integer using a half-normal distribution. The value is within specified bounds ([r_...
void uniformNormalVector(unsigned int n, double value[])
Uniform random sampling of a unit-length vector. I.e., the surface of an n-ball. The return variable ...
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
double uniformReal(double lower_bound, double upper_bound)
Generate a random real within given bounds: [lower_bound, upper_bound)
static std::uint_fast32_t getSeed()
Get the seed used to generate the seeds of each RNG instance. Passing the returned value to setSeed()...
#define OMPL_WARN(fmt,...)
Log a formatted warning string.
double halfNormalReal(double r_min, double r_max, double focus=3.0)
Generate a random real using a half-normal distribution. The value is within specified bounds [r_min...
point now()
Get the current time point.
void setLocalSeed(std::uint_fast32_t localSeed)
Set the seed used for the instance of a RNG. Use this function to ensure that an instance of an RNG g...
static void setSeed(std::uint_fast32_t seed)
Set the seed used to generate the seeds of each RNG instance. Use this function to ensure the same se...
void uniformInBall(double r, unsigned int n, double value[])
Uniform random sampling of the content of an n-ball, with a radius appropriately distributed between ...
double gaussian(double mean, double stddev)
Generate a random real using a normal distribution with given mean and variance.