forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
random_rotation.h
63 lines (54 loc) · 2.27 KB
/
random_rotation.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#pragma once
#include <random>
#include <Eigen/Dense>
#include "drake/common/constants.h"
#include "drake/common/eigen_types.h"
#include "drake/math/axis_angle.h"
namespace drake {
namespace math {
/// Generates a rotation (in the axis-angle representation) that rotates a
/// point on the unit sphere to another point on the unit sphere with a uniform
/// distribution over the sphere.
///
/// Justification for the algorithm can be found in, e.g.:
/// Mervin E. Muller. 1959. A note on a method for generating points
/// uniformly on n-dimensional spheres. Commun. ACM 2, 4 (April 1959), 19-20.
/// DOI=http://dx.doi.org/10.1145/377939.377946
template <class Generator>
// TODO(#2274) Fix NOLINTNEXTLINE(runtime/references).
Eigen::Vector4d UniformlyRandomAxisAngle(Generator& generator) {
std::normal_distribution<double> normal;
std::uniform_real_distribution<double> uniform(-M_PI, M_PI);
double angle = uniform(generator);
Eigen::Vector3d axis(normal(generator), normal(generator), normal(generator));
axis.normalize();
Eigen::Vector4d a;
a << axis, angle;
return a;
}
/// Generates a rotation (in the quaternion representation) that rotates a
/// point on the unit sphere to another point on the unit sphere with a uniform
/// distribution over the sphere.
template <class Generator>
// TODO(#2274) Fix NOLINTNEXTLINE(runtime/references).
Eigen::Vector4d UniformlyRandomQuat(Generator& generator) {
return axis2quat(UniformlyRandomAxisAngle(generator));
}
/// Generates a rotation (in the rotation matrix representation) that rotates a
/// point on the unit sphere to another point on the unit sphere with a uniform
/// distribution over the sphere.
template <class Generator>
// TODO(#2274) Fix NOLINTNEXTLINE(runtime/references).
Eigen::Matrix3d UniformlyRandomRotmat(Generator& generator) {
return axis2rotmat(UniformlyRandomAxisAngle(generator));
}
/// Generates a rotation (in the roll-pitch-yaw representation) that rotates a
/// point on the unit sphere to another point on the unit sphere with a uniform
/// distribution over the sphere.
template <class Generator>
// TODO(#2274) Fix NOLINTNEXTLINE(runtime/references).
Eigen::Vector3d UniformlyRandomRPY(Generator& generator) {
return axis2rpy(UniformlyRandomAxisAngle(generator));
}
} // namespace math
} // namespace drake