visual-tracking-control
BrownianMotionPose.cpp
Go to the documentation of this file.
1 #include <BrownianMotionPose.h>
2 
3 #include <cmath>
4 #include <iostream>
5 #include <utility>
6 
7 using namespace Eigen;
8 
9 
10 BrownianMotionPose::BrownianMotionPose(const float q_xy, const float q_z, const float theta, const float cone_angle, const unsigned int seed) noexcept :
11  q_xy_(q_xy),
12  q_z_(q_z),
13  theta_(theta * (M_PI/180.0)),
14  cone_angle_(cone_angle * (M_PI/180.0)),
15  cone_dir_(Vector4f(0.0, 0.0, 1.0, 0.0)),
16  generator_(std::mt19937_64(seed)),
17  distribution_pos_xy_(std::normal_distribution<float>(0.0, q_xy)),
18  distribution_pos_z_(std::normal_distribution<float>(0.0, q_z)),
19  distribution_theta_(std::normal_distribution<float>(0.0, theta_)),
20  distribution_cone_(std::uniform_real_distribution<float>(0.0, 1.0)),
21  gaussian_random_pos_xy_([&] { return (distribution_pos_xy_)(generator_); }),
22  gaussian_random_pos_z_([&] { return (distribution_pos_z_)(generator_); }),
23  gaussian_random_theta_([&] { return (distribution_theta_)(generator_); }),
24  gaussian_random_cone_([&] { return (distribution_cone_)(generator_); }) { }
25 
26 
27 BrownianMotionPose::BrownianMotionPose(const float q_xy, const float q_z, const float theta, const float cone_angle) noexcept :
28  BrownianMotionPose(q_xy, q_z, theta, cone_angle, 1) { }
29 
30 
32  BrownianMotionPose(0.005, 0.005, 3.0, 2.5, 1) { }
33 
34 
36  q_xy_(brown.q_xy_),
37  q_z_(brown.q_z_),
38  theta_(brown.theta_),
39  cone_angle_(brown.cone_angle_),
40  cone_dir_(brown.cone_dir_),
41  generator_(brown.generator_),
42  distribution_pos_xy_(brown.distribution_pos_xy_),
43  distribution_pos_z_(brown.distribution_pos_z_),
44  distribution_theta_(brown.distribution_theta_),
45  distribution_cone_(brown.distribution_cone_),
46  gaussian_random_pos_xy_(brown.gaussian_random_pos_xy_),
47  gaussian_random_pos_z_(brown.gaussian_random_pos_z_),
48  gaussian_random_theta_(brown.gaussian_random_theta_),
49  gaussian_random_cone_(brown.gaussian_random_cone_) { }
50 
51 
53  q_xy_(brown.q_xy_),
54  theta_(brown.theta_),
55  cone_angle_(brown.cone_angle_),
56  cone_dir_(std::move(brown.cone_dir_)),
57  generator_(std::move(brown.generator_)),
58  distribution_pos_xy_(std::move(brown.distribution_pos_xy_)),
59  distribution_pos_z_(std::move(brown.distribution_pos_z_)),
60  distribution_theta_(std::move(brown.distribution_theta_)),
61  distribution_cone_(std::move(brown.distribution_cone_)),
62  gaussian_random_pos_xy_(std::move(brown.gaussian_random_pos_xy_)),
63  gaussian_random_pos_z_(std::move(brown.gaussian_random_pos_z_)),
64  gaussian_random_theta_(std::move(brown.gaussian_random_theta_)),
65  gaussian_random_cone_(std::move(brown.gaussian_random_cone_))
66 {
67  brown.q_xy_ = 0.0;
68  brown.q_z_ = 0.0;
69  brown.theta_ = 0.0;
70  brown.cone_angle_ = 0.0;
71 }
72 
73 
75 
76 
78 {
79  BrownianMotionPose tmp(brown);
80  *this = std::move(tmp);
81 
82  return *this;
83 }
84 
85 
87 {
88  q_xy_ = brown.q_xy_;
89  q_z_ = brown.q_z_;
90  theta_ = brown.theta_;
91  cone_angle_ = brown.cone_angle_;
92  cone_dir_ = std::move(brown.cone_dir_);
93 
94  generator_ = std::move(brown.generator_);
95  distribution_pos_xy_ = std::move(brown.distribution_pos_xy_);
96  distribution_pos_z_ = std::move(brown.distribution_pos_z_);
97  distribution_theta_ = std::move(brown.distribution_theta_);
98  distribution_cone_ = std::move(brown.distribution_cone_);
99  gaussian_random_pos_xy_ = std::move(brown.gaussian_random_pos_xy_);
100  gaussian_random_pos_z_ = std::move(brown.gaussian_random_pos_z_);
101  gaussian_random_theta_ = std::move(brown.gaussian_random_theta_);
102  gaussian_random_cone_ = std::move(brown.gaussian_random_cone_);
103 
104  brown.q_xy_ = 0.0;
105  brown.q_z_ = 0.0;
106  brown.theta_ = 0.0;
107  brown.cone_angle_ = 0.0;
108 
109  return *this;
110 }
111 
112 
113 void BrownianMotionPose::propagate(const Eigen::Ref<const Eigen::MatrixXf>& cur_state, Eigen::Ref<Eigen::MatrixXf> prop_state)
114 {
115  prop_state = cur_state;
116 }
117 
118 
119 void BrownianMotionPose::motion(const Eigen::Ref<const Eigen::MatrixXf>& cur_state, Eigen::Ref<Eigen::MatrixXf> mot_state)
120 {
121  propagate(cur_state, mot_state);
122 
123  MatrixXf sample(7, mot_state.cols());
124  sample = getNoiseSample(mot_state.cols());
125 
126  mot_state.topRows<3>() += sample.topRows<3>();
127  addAxisangleDisturbance(sample.bottomRows<4>(), mot_state.bottomRows<4>());
128 }
129 
130 
131 Eigen::MatrixXf BrownianMotionPose::getNoiseSample(const int num)
132 {
133  MatrixXf sample(7, num);
134 
135  /* Position */
136  for (unsigned int i = 0; i < num; ++i)
137  {
138  sample(0, i) = gaussian_random_pos_xy_();
139  sample(1, i) = gaussian_random_pos_xy_();
140  sample(2, i) = gaussian_random_pos_z_();
141  }
142 
143  /* Axis-angle vector */
144  /* Generate points on the spherical cap around the north pole [1]. */
145  /* [1] http://math.stackexchange.com/a/205589/81266 */
146  for(unsigned int i = 0; i < num; ++i)
147  {
148  float z = gaussian_random_cone_() * (1 - cos(cone_angle_)) + cos(cone_angle_);
149  float phi = gaussian_random_cone_() * (2.0 * M_PI);
150  float x = sqrt(1 - (z * z)) * cos(phi);
151  float y = sqrt(1 - (z * z)) * sin(phi);
152 
153  sample(3, i) = x;
154  sample(4, i) = y;
155  sample(5, i) = z;
156  sample(6, i) = gaussian_random_theta_();
157  }
158 
159  return sample;
160 }
161 
162 
163 void BrownianMotionPose::addAxisangleDisturbance(const Ref<const MatrixXf>& disturbance_vec, Ref<MatrixXf> current_vec)
164 {
165  for (unsigned int i = 0; i < current_vec.cols(); ++i)
166  {
167  float ang = current_vec(3, i) + disturbance_vec(3, i);
168 
169  if (ang > M_PI) ang -= 2.0 * M_PI;
170  else if (ang <= -M_PI) ang += 2.0 * M_PI;
171 
172 
173  /* Find the rotation axis 'u' and rotation angle 'rot' [1] */
174  Vector3f def_dir(0.0, 0.0, 1.0);
175 
176  Vector3f u = def_dir.cross(current_vec.col(i).head<3>()).normalized();
177 
178  float rot = static_cast<float>(std::acos(current_vec.col(i).head<3>().dot(def_dir)));
179 
180 
181  /* Convert rotation axis and angle to 3x3 rotation matrix [2] */
182  /* [2] https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle */
183  Matrix3f cross_matrix;
184  cross_matrix << 0, -u(2), u(1),
185  u(2), 0, -u(0),
186  -u(1), u(0), 0;
187 
188  Matrix3f R = std::cos(rot) * Matrix3f::Identity() + std::sin(rot) * cross_matrix + (1 - std::cos(rot)) * (u * u.transpose());
189 
190 
191  current_vec.col(i).head<3>() = (R * disturbance_vec.col(i).head<3>()).normalized();
192  current_vec(3, i) = ang;
193  }
194 }
std::function< float()> gaussian_random_pos_xy_
std::normal_distribution< float > distribution_pos_xy_
BrownianMotionPose & operator=(const BrownianMotionPose &bm)
void propagate(const Eigen::Ref< const Eigen::MatrixXf > &cur_state, Eigen::Ref< Eigen::MatrixXf > prop_state) override
std::normal_distribution< float > distribution_pos_z_
Eigen::Vector4f cone_dir_
void addAxisangleDisturbance(const Eigen::Ref< const Eigen::MatrixXf > &disturbance_vec, Eigen::Ref< Eigen::MatrixXf > current_vec)
void motion(const Eigen::Ref< const Eigen::MatrixXf > &cur_state, Eigen::Ref< Eigen::MatrixXf > mot_state) override
std::function< float()> gaussian_random_pos_z_
std::uniform_real_distribution< float > distribution_cone_
std::normal_distribution< float > distribution_theta_
Eigen::MatrixXf getNoiseSample(const int num) override
std::function< float()> gaussian_random_cone_
std::mt19937_64 generator_
std::function< float()> gaussian_random_theta_