1 #ifndef CALICO_SENSORS_GYROSCOPE_COST_FUNCTOR_H_
2 #define CALICO_SENSORS_GYROSCOPE_COST_FUNCTOR_H_
4 #include "calico/geometry.h"
5 #include "calico/sensors/gyroscope_models.h"
6 #include "calico/trajectory.h"
7 #include "ceres/cost_function.h"
13 enum class GyroscopeParameterIndices : int {
17 kExtrinsicsRotationIndex = 1,
18 kExtrinsicsTranslationIndex = 2,
23 kSensorRigPoseSplineControlPointsIndex = 4
30 static constexpr
int kGyroscopeResidualSize = 3;
33 const Eigen::Vector3d& measurement,
double sigma,
double stamp,
37 static ceres::CostFunction* CreateCostFunction(
38 const Eigen::Vector3d& measurement,
double sigma,
40 Pose3d& extrinsics,
double& latency,
41 Trajectory& trajectory_world_sensorrig,
double stamp,
42 std::vector<double*>& parameters);
59 bool operator()(T
const*
const* parameters, T* residual) {
61 const T* intrinsics_ptr =
62 static_cast<const T*
>(&(parameters[
static_cast<int>(
63 GyroscopeParameterIndices::kIntrinsicsIndex)][0]));
64 const int parameter_size = gyroscope_model_->NumberOfParameters();
65 const Eigen::VectorX<T> intrinsics = Eigen::Map<const Eigen::VectorX<T>>(
66 intrinsics_ptr, parameter_size);
68 const Eigen::Map<const Eigen::Quaternion<T>> q_sensorrig_gyroscope(
69 &(parameters[
static_cast<int>(
70 GyroscopeParameterIndices::kExtrinsicsRotationIndex)][0]));
71 const Eigen::Map<const Eigen::Vector3<T>> t_sensorrig_gyroscope(
72 &(parameters[
static_cast<int>(
73 GyroscopeParameterIndices::kExtrinsicsTranslationIndex)][0]));
76 parameters[
static_cast<int>(
77 GyroscopeParameterIndices::kLatencyIndex)][0];
79 const int num_rotation_control_points =
80 rotation_trajectory_evaluation_params_.num_control_points;
81 Eigen::MatrixX<T> rotation_control_points(num_rotation_control_points, 3);
82 for (
int i = 0; i < num_rotation_control_points; ++i) {
83 rotation_control_points.row(i) = Eigen::Map<const Eigen::Vector3<T>>(
84 &(parameters[
static_cast<int>(
85 GyroscopeParameterIndices::kSensorRigPoseSplineControlPointsIndex)
89 const int num_position_control_points =
90 position_trajectory_evaluation_params_.num_control_points;
91 Eigen::MatrixX<T> position_control_points(num_position_control_points, 3);
92 for (
int i = 0; i < num_position_control_points; ++i) {
93 position_control_points.row(i) = Eigen::Map<const Eigen::Vector3<T>>(
94 &(parameters[
static_cast<int>(
95 GyroscopeParameterIndices::kSensorRigPoseSplineControlPointsIndex)
96 + i + num_rotation_control_points
100 const Eigen::MatrixX<T> rotation_basis_matrix =
101 rotation_trajectory_evaluation_params_.basis_matrix.template cast<T>();
102 const T rotation_knot0 =
static_cast<T
>(
103 rotation_trajectory_evaluation_params_.knot0);
104 const T rotation_knot1 =
static_cast<T
>(
105 rotation_trajectory_evaluation_params_.knot1);
106 const T rotation_stamp =
107 static_cast<T
>(rotation_trajectory_evaluation_params_.stamp) - latency;
109 const Eigen::MatrixX<T> position_basis_matrix =
110 position_trajectory_evaluation_params_.basis_matrix.template cast<T>();
111 const T position_knot0 =
static_cast<T
>(
112 position_trajectory_evaluation_params_.knot0);
113 const T position_knot1 =
static_cast<T
>(
114 position_trajectory_evaluation_params_.knot1);
115 const T position_stamp =
116 static_cast<T
>(position_trajectory_evaluation_params_.stamp) - latency;
120 rotation_control_points, rotation_knot0, rotation_knot1,
121 rotation_basis_matrix, rotation_stamp, 0);
122 T q_sensorrig_world_array[4];
123 ceres::AngleAxisToQuaternion(
124 phi_sensorrig_world.data(), q_sensorrig_world_array);
125 const Eigen::Quaternion<T> q_sensorrig_world(
126 q_sensorrig_world_array[0], q_sensorrig_world_array[1],
127 q_sensorrig_world_array[2], q_sensorrig_world_array[3]);
129 position_control_points, position_knot0, position_knot1,
130 position_basis_matrix, position_stamp, 0);
132 rotation_control_points, rotation_knot0, rotation_knot1,
133 rotation_basis_matrix, rotation_stamp, 1);
136 const Eigen::Vector3<T> omega_sensorrig_world = J * phi_dot_sensorrig_world;
137 const Eigen::Vector3<T> omega_gyroscope_world =
138 -(q_sensorrig_gyroscope.inverse() * omega_sensorrig_world);
140 const absl::StatusOr<Eigen::Vector3<T>> projection =
141 gyroscope_model_->Project(intrinsics, omega_gyroscope_world);
142 if (projection.ok()) {
143 Eigen::Map<Eigen::Vector3<T>> error(residual);
144 const Eigen::Vector3<T> measurement = measurement_.template cast<T>();
145 error = (measurement - *projection) *
static_cast<T
>(information_);
152 Eigen::Vector3d measurement_;
154 std::unique_ptr<GyroscopeModel> gyroscope_model_;
Definition: trajectory.h:25
Definition: gyroscope_cost_functor.h:28
Sensors namespace.
Definition: accelerometer.cpp:8
GyroscopeIntrinsicsModel
Gyroscope model types.
Definition: gyroscope_models.h:16
Eigen::Matrix3< T > ExpSO3Jacobian(const Eigen::Vector3< T > &phi)
Definition: geometry.h:138
Definition: trajectory.h:14