37 #include "ompl/util/RandomNumbers.h" 38 #include "ompl/util/Exception.h" 40 #include <boost/random/lagged_fibonacci.hpp> 41 #include <boost/random/uniform_int.hpp> 42 #include <boost/thread/mutex.hpp> 43 #include <boost/thread/once.hpp> 44 #include <boost/scoped_ptr.hpp> 45 #include <boost/date_time/posix_time/posix_time.hpp> 46 #include <boost/math/constants/constants.hpp> 54 class RNGSeedGenerator
58 someSeedsGenerated_(false),
59 firstSeed_((boost::uint32_t)(boost::posix_time::microsec_clock::universal_time() -
60 boost::posix_time::ptime(boost::date_time::min_date_time)).total_microseconds()),
62 sDist_(1, 1000000000),
67 boost::uint32_t firstSeed()
69 boost::mutex::scoped_lock slock(rngMutex_);
73 void setSeed(boost::uint32_t seed)
75 boost::mutex::scoped_lock slock(rngMutex_);
78 if (someSeedsGenerated_)
80 OMPL_ERROR(
"Random number generation already started. Changing seed now will not lead to deterministic sampling.");
90 if (someSeedsGenerated_)
92 OMPL_WARN(
"Random generator seed cannot be 0. Ignoring seed.");
97 OMPL_WARN(
"Random generator seed cannot be 0. Using 1 instead.");
104 boost::uint32_t nextSeed()
106 boost::mutex::scoped_lock slock(rngMutex_);
107 someSeedsGenerated_ =
true;
112 bool someSeedsGenerated_;
113 boost::uint32_t firstSeed_;
114 boost::mutex rngMutex_;
115 boost::lagged_fibonacci607 sGen_;
116 boost::uniform_int<> sDist_;
117 boost::variate_generator<boost::lagged_fibonacci607&, boost::uniform_int<> > s_;
120 static boost::once_flag g_once = BOOST_ONCE_INIT;
121 static boost::scoped_ptr<RNGSeedGenerator> g_RNGSeedGenerator;
123 void initRNGSeedGenerator()
125 g_RNGSeedGenerator.reset(
new RNGSeedGenerator());
128 RNGSeedGenerator& getRNGSeedGenerator()
130 boost::call_once(&initRNGSeedGenerator, g_once);
131 return *g_RNGSeedGenerator;
138 return getRNGSeedGenerator().firstSeed();
143 getRNGSeedGenerator().setSeed(seed);
147 generator_(getRNGSeedGenerator().nextSeed()),
150 uni_(generator_, uniDist_),
151 normal_(generator_, normalDist_)
157 assert(r_min <= r_max);
159 const double mean = r_max - r_min;
160 double v =
gaussian(mean, mean/focus);
162 if (v > mean) v = 2.0 * mean - v;
163 double r = v >= 0.0 ? v + r_min : r_min;
164 return r > r_max ? r_max : r;
169 int r = (int)floor(
halfNormalReal((
double)r_min, (
double)(r_max) + 1.0, focus));
170 return (r > r_max) ? r_max : r;
178 double r1 = sqrt(1.0 - x0), r2 = sqrt(x0);
179 double t1 = 2.0 * boost::math::constants::pi<double>() * uni_(), t2 = 2.0 * boost::math::constants::pi<double>() * uni_();
180 double c1 = cos(t1), s1 = sin(t1);
181 double c2 = cos(t2), s2 = sin(t2);
191 value[0] = boost::math::constants::pi<double>() * (-2.0 * uni_() + 1.0);
192 value[1] = acos(1.0 - 2.0 * uni_()) - boost::math::constants::pi<double>() / 2.0;
193 value[2] = boost::math::constants::pi<double>() * (-2.0 * uni_() + 1.0);
static void setSeed(boost::uint32_t seed)
Set the seed for random number generation. Use this function to ensure the same sequence of random nu...
void quaternion(double value[4])
Uniform random unit quaternion sampling. The computed value has the order (x,y,z,w) ...
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)
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_...
static boost::uint32_t getSeed()
Get the seed used for random number generation. Passing the returned value to setSeed() at a subseque...
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
#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...
double gaussian(double mean, double stddev)
Generate a random real using a normal distribution with given mean and variance.