1 #ifndef CALICO_SENSORS_GYROSCOPE_MODELS_H_
2 #define CALICO_SENSORS_GYROSCOPE_MODELS_H_
4 #include "calico/typedefs.h"
8 #include "absl/status/statusor.h"
9 #include "absl/strings/str_cat.h"
10 #include "Eigen/Dense"
35 absl::StatusOr<Eigen::Vector3<T>>
Project(
36 const Eigen::VectorX<T>& intrinsics,
37 const Eigen::Vector3<T>& omega_sensor_world)
const;
42 absl::StatusOr<Eigen::Vector3<T>>
Unproject(
43 const Eigen::VectorX<T>& intrinsics,
44 const Eigen::Vector3<T>& measurement)
const;
58 static std::unique_ptr<GyroscopeModel>
Create(
67 static constexpr
int kNumberOfParameters = 1;
82 static absl::StatusOr<Eigen::Vector3<T>>
Project(
83 const Eigen::VectorX<T>& intrinsics,
84 const Eigen::Vector3<T>& omega_sensor_world) {
85 const T& scale = intrinsics(0);
86 return scale * omega_sensor_world;
96 const Eigen::VectorX<T>& intrinsics,
97 const Eigen::Vector3<T>& measurement) {
98 const T& inv_scale =
static_cast<T
>(1.0) / intrinsics(0);
99 return inv_scale * measurement;
107 return kNumberOfParameters;
116 static constexpr
int kNumberOfParameters = 4;
129 template <
typename T>
130 static absl::StatusOr<Eigen::Vector3<T>>
Project(
131 const Eigen::VectorX<T>& intrinsics,
132 const Eigen::Vector3<T>& omega_sensor_world) {
133 if (intrinsics.size() != kNumberOfParameters) {
134 return absl::InvalidArgumentError(absl::StrCat(
135 "Invalid gyroscope intrinsics size. Expected ", kNumberOfParameters,
136 ", got ", intrinsics.size()));
138 const T& scale = intrinsics(0);
139 const Eigen::Ref<const Eigen::Vector3<T>> bias =
140 intrinsics.segment(1, 3);
141 return scale * omega_sensor_world + bias;
150 template <
typename T>
152 const Eigen::VectorX<T>& intrinsics,
153 const Eigen::Vector3<T>& measurement) {
154 if (intrinsics.size() != kNumberOfParameters) {
155 return absl::InvalidArgumentError(absl::StrCat(
156 "Invalid gyroscope intrinsics size. Expected ", kNumberOfParameters,
157 ", got ", intrinsics.size()));
159 const T& inv_scale =
static_cast<T
>(1.0) / intrinsics(0);
160 const Eigen::Ref<const Eigen::Vector3<T>> bias =
161 intrinsics.segment(1, 3);
162 return inv_scale * (measurement - bias);
170 return kNumberOfParameters;
182 static constexpr
int kNumberOfParameters = 12;
207 template <
typename T>
208 static absl::StatusOr<Eigen::Vector3<T>>
Project(
209 const Eigen::VectorX<T>& intrinsics,
210 const Eigen::Vector3<T>& omega_sensor_world) {
211 if (intrinsics.size() != kNumberOfParameters) {
212 return absl::InvalidArgumentError(absl::StrCat(
213 "Invalid gyroscope intrinsics size. Expected ", kNumberOfParameters,
214 ", got ", intrinsics.size()));
216 const T& sx = intrinsics(0);
217 const T& sy = intrinsics(1);
218 const T& sz = intrinsics(2);
219 const T& a1 = intrinsics(3);
220 const T& a2 = intrinsics(4);
221 const T& a3 = intrinsics(5);
222 const T& a4 = intrinsics(6);
223 const T& a5 = intrinsics(7);
224 const T& a6 = intrinsics(8);
225 const T& bx = intrinsics(9);
226 const T& by = intrinsics(10);
227 const T& bz = intrinsics(11);
228 const T& wx = omega_sensor_world.x();
229 const T& wy = omega_sensor_world.y();
230 const T& wz = omega_sensor_world.z();
231 const T fx = bx + sx * (wx + a1 * wy + a2 * wz);
232 const T fy = by + sy * (wy + a3 * wx + a4 * wz);
233 const T fz = bz + sz * (wz + a5 * wx + a6 * wy);
234 return Eigen::Vector3<T>(fx, fy, fz);
255 template <
typename T>
257 const Eigen::VectorX<T>& intrinsics,
258 const Eigen::Vector3<T>& measurement) {
259 if (intrinsics.size() != kNumberOfParameters) {
260 return absl::InvalidArgumentError(absl::StrCat(
261 "Invalid gyroscope intrinsics size. Expected ", kNumberOfParameters,
262 ", got ", intrinsics.size()));
264 const T& sx = intrinsics(0);
265 const T& sy = intrinsics(1);
266 const T& sz = intrinsics(2);
267 const T& a1 = intrinsics(3);
268 const T& a2 = intrinsics(4);
269 const T& a3 = intrinsics(5);
270 const T& a4 = intrinsics(6);
271 const T& a5 = intrinsics(7);
272 const T& a6 = intrinsics(8);
273 const T& fx = measurement.x();
274 const T& fy = measurement.y();
275 const T& fz = measurement.z();
276 const Eigen::Vector3<T> bias(intrinsics(9), intrinsics(10), intrinsics(11));
277 const Eigen::Vector3<T> d = bias - measurement;
279 1.0 - a1*a3 - a2*a5 - a4*a6 + a1*a4*a5 + a2*a3*a6;
280 const T dx_inv_sx_detA = d.x() / (sx * det_A);
281 const T dy_inv_sy_detA = d.y() / (sy * det_A);
282 const T dz_inv_sz_detA = d.z() / (sz * det_A);
283 const T wx = (a4*a6 - 1) * dx_inv_sx_detA + (a1 - a2*a6) * dy_inv_sy_detA +
284 (a2 - a1*a4) * dz_inv_sz_detA;
285 const T wy = (a2*a5 - 1) * dy_inv_sy_detA + (a3 - a4*a5) * dx_inv_sx_detA +
286 (a4 - a2*a3) * dz_inv_sz_detA;
287 const T wz = (a1*a3 - 1) * dz_inv_sz_detA + (a5 - a3*a6) * dx_inv_sx_detA +
288 (a6 - a1*a5) * dy_inv_sy_detA;
289 return Eigen::Vector3<T>(wx, wy, wz);
297 return kNumberOfParameters;
303 template <
typename T>
305 const Eigen::VectorX<T>& intrinsics,
306 const Eigen::Vector3<T>& omega_sensor_world)
const {
308 return derived->Project(intrinsics, omega_sensor_world);
310 if (
const auto derived =
312 return derived->Project(intrinsics, omega_sensor_world);
314 if (
const auto derived =
316 return derived->Project(intrinsics, omega_sensor_world);
318 return absl::InvalidArgumentError(absl::StrCat(
319 "Project for gyroscope model ", this->
GetType(),
" not supported."));
322 template <
typename T>
324 const Eigen::VectorX<T>& intrinsics,
325 const Eigen::Vector3<T>& measurement)
const {
327 return derived->Unproject(intrinsics, measurement);
329 if (
const auto derived =
331 return derived->Unproject(intrinsics, measurement);
333 if (
const auto derived =
335 return derived->Unproject(intrinsics, measurement);
337 return absl::InvalidArgumentError(absl::StrCat(
338 "Unproject for gyroscope model ", this->
GetType(),
" not supported."));
Base class for gyroscope models.
Definition: gyroscope_models.h:28
absl::StatusOr< Eigen::Vector3< T > > Project(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &omega_sensor_world) const
Definition: gyroscope_models.h:304
virtual int NumberOfParameters() const =0
Getter for the number of parameters for this model.
absl::StatusOr< Eigen::Vector3< T > > Unproject(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &measurement) const
Definition: gyroscope_models.h:323
virtual GyroscopeIntrinsicsModel GetType() const =0
Getter for gyroscope model type.
static std::unique_ptr< GyroscopeModel > Create(GyroscopeIntrinsicsModel gyroscope_model)
Definition: gyroscope_models.cpp:5
Definition: gyroscope_models.h:114
static absl::StatusOr< Eigen::Vector3< T > > Project(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &omega_sensor_world)
Definition: gyroscope_models.h:130
GyroscopeIntrinsicsModel GetType() const final
Getter for gyroscope model type.
Definition: gyroscope_models.h:165
static absl::StatusOr< Eigen::Vector3< T > > Unproject(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &measurement)
Definition: gyroscope_models.h:151
int NumberOfParameters() const final
Getter for the number of parameters for this model.
Definition: gyroscope_models.h:169
Definition: gyroscope_models.h:65
GyroscopeIntrinsicsModel GetType() const final
Getter for gyroscope model type.
Definition: gyroscope_models.h:102
static absl::StatusOr< Eigen::Vector3< T > > Project(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &omega_sensor_world)
Definition: gyroscope_models.h:82
int NumberOfParameters() const final
Getter for the number of parameters for this model.
Definition: gyroscope_models.h:106
static absl::StatusOr< Eigen::Vector3< T > > Unproject(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &measurement)
Definition: gyroscope_models.h:95
Definition: gyroscope_models.h:180
static absl::StatusOr< Eigen::Vector3< T > > Unproject(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &measurement)
Definition: gyroscope_models.h:256
GyroscopeIntrinsicsModel GetType() const final
Getter for gyroscope model type.
Definition: gyroscope_models.h:292
int NumberOfParameters() const final
Getter for the number of parameters for this model.
Definition: gyroscope_models.h:296
static absl::StatusOr< Eigen::Vector3< T > > Project(const Eigen::VectorX< T > &intrinsics, const Eigen::Vector3< T > &omega_sensor_world)
Definition: gyroscope_models.h:208
Sensors namespace.
Definition: accelerometer.cpp:8
GyroscopeIntrinsicsModel
Gyroscope model types.
Definition: gyroscope_models.h:16
@ kGyroscopeScaleOnly
Isotropic scale without bias.
@ kGyroscopeVectorNav
VectorNav model.
@ kGyroscopeScaleAndBias
Isotropic scale with bias.