1 #ifndef CALICO_SENSORS_ACCELEROMETER_COST_FUNCTOR_H_
2 #define CALICO_SENSORS_ACCELEROMETER_COST_FUNCTOR_H_
4 #include "calico/geometry.h"
5 #include "calico/sensors/accelerometer_models.h"
6 #include "calico/trajectory.h"
7 #include "ceres/cost_function.h"
13 enum class AccelerometerParameterIndices : int {
17 kExtrinsicsRotationIndex = 1,
18 kExtrinsicsTranslationIndex = 2,
25 kSensorRigPoseSplineControlPointsIndex = 5
32 static constexpr
int kAccelerometerResidualSize = 3;
35 const Eigen::Vector3d& measurement,
double sigma,
double stamp,
39 static ceres::CostFunction* CreateCostFunction(
40 const Eigen::Vector3d& measurement,
double sigma,
42 Eigen::VectorXd& intrinsics,
Pose3d& extrinsics,
double& latency,
43 Eigen::Vector3d& gravity,
Trajectory& trajectory_world_sensorrig,
44 double stamp, std::vector<double*>& parameters);
63 bool operator()(T
const*
const* parameters, T* residual) {
65 const T* intrinsics_ptr =
66 static_cast<const T*
>(&(parameters[
static_cast<int>(
67 AccelerometerParameterIndices::kIntrinsicsIndex)][0]));
68 const int parameter_size = accelerometer_model_->NumberOfParameters();
69 const Eigen::VectorX<T> intrinsics = Eigen::Map<const Eigen::VectorX<T>>(
70 intrinsics_ptr, parameter_size);
72 const Eigen::Map<const Eigen::Quaternion<T>> q_sensorrig_accelerometer(
73 &(parameters[
static_cast<int>(
74 AccelerometerParameterIndices::kExtrinsicsRotationIndex)][0]));
75 const Eigen::Map<const Eigen::Vector3<T>> t_sensorrig_accelerometer(
76 &(parameters[
static_cast<int>(
77 AccelerometerParameterIndices::kExtrinsicsTranslationIndex)][0]));
80 parameters[
static_cast<int>(
81 AccelerometerParameterIndices::kLatencyIndex)][0];
83 const Eigen::Map<const Eigen::Vector3<T>> gravity(
84 &(parameters[
static_cast<int>(
85 AccelerometerParameterIndices::kGravityIndex)][0]));
87 const int num_rotation_control_points =
88 rotation_trajectory_evaluation_params_.num_control_points;
89 Eigen::MatrixX<T> rotation_control_points(num_rotation_control_points, 3);
90 for (
int i = 0; i < num_rotation_control_points; ++i) {
91 rotation_control_points.row(i) = Eigen::Map<const Eigen::Vector3<T>>(
92 &(parameters[
static_cast<int>(
93 AccelerometerParameterIndices::kSensorRigPoseSplineControlPointsIndex)
97 const int num_position_control_points =
98 position_trajectory_evaluation_params_.num_control_points;
99 Eigen::MatrixX<T> position_control_points(num_position_control_points, 3);
100 for (
int i = 0; i < num_position_control_points; ++i) {
101 position_control_points.row(i) = Eigen::Map<const Eigen::Vector3<T>>(
102 &(parameters[
static_cast<int>(
103 AccelerometerParameterIndices::kSensorRigPoseSplineControlPointsIndex)
104 + i + num_rotation_control_points
108 const Eigen::MatrixX<T> rotation_basis_matrix =
109 rotation_trajectory_evaluation_params_.basis_matrix.template cast<T>();
110 const T rotation_knot0 =
static_cast<T
>(
111 rotation_trajectory_evaluation_params_.knot0);
112 const T rotation_knot1 =
static_cast<T
>(
113 rotation_trajectory_evaluation_params_.knot1);
114 const T rotation_stamp =
115 static_cast<T
>(rotation_trajectory_evaluation_params_.stamp) - latency;
117 const Eigen::MatrixX<T> position_basis_matrix =
118 position_trajectory_evaluation_params_.basis_matrix.template cast<T>();
119 const T position_knot0 =
static_cast<T
>(
120 position_trajectory_evaluation_params_.knot0);
121 const T position_knot1 =
static_cast<T
>(
122 position_trajectory_evaluation_params_.knot1);
123 const T position_stamp =
124 static_cast<T
>(position_trajectory_evaluation_params_.stamp) - latency;
128 rotation_control_points, rotation_knot0, rotation_knot1,
129 rotation_basis_matrix, rotation_stamp, 0);
130 T q_sensorrig_world_array[4];
131 ceres::AngleAxisToQuaternion(
132 phi_sensorrig_world.data(), q_sensorrig_world_array);
133 const Eigen::Quaternion<T> q_sensorrig_world(
134 q_sensorrig_world_array[0], q_sensorrig_world_array[1],
135 q_sensorrig_world_array[2], q_sensorrig_world_array[3]);
137 position_control_points, position_knot0, position_knot1,
138 position_basis_matrix, position_stamp, 0);
140 rotation_control_points, rotation_knot0, rotation_knot1,
141 rotation_basis_matrix, rotation_stamp, 1);
143 rotation_control_points, rotation_knot0, rotation_knot1,
144 rotation_basis_matrix, rotation_stamp, 2);
146 position_control_points, position_knot0, position_knot1,
147 position_basis_matrix, position_stamp, 2);
150 const Eigen::Matrix3<T> J_sensorrig_world =
152 const Eigen::Matrix3<T> J_dot_sensorrig_world =
154 const Eigen::Vector3<T> omega_sensorrig_world =
155 J_sensorrig_world * phi_dot_sensorrig_world;
156 const Eigen::Vector3<T> alpha_sensorrig_world =
157 J_dot_sensorrig_world * phi_dot_sensorrig_world +
158 J_sensorrig_world * phi_ddot_sensorrig_world;
159 const Eigen::Matrix3<T> Alpha = -
Skew(alpha_sensorrig_world);
160 const Eigen::Matrix3<T> Omega = -
Skew(omega_sensorrig_world);
161 const Eigen::Vector3<T> ddt_accelerometer_world_accelerometer =
162 q_sensorrig_accelerometer.inverse() *
163 (q_sensorrig_world * (ddt_world_sensorrig - gravity) +
164 (Omega * Omega + Alpha) * t_sensorrig_accelerometer);
166 const absl::StatusOr<Eigen::Vector3<T>> projection =
167 accelerometer_model_->Project(
168 intrinsics, ddt_accelerometer_world_accelerometer);
169 if (projection.ok()) {
170 Eigen::Map<Eigen::Vector3<T>> error(residual);
171 const Eigen::Vector3<T> measurement = measurement_.template cast<T>();
172 error = (measurement - *projection) *
static_cast<T
>(information_);
179 Eigen::Vector3d measurement_;
181 std::unique_ptr<AccelerometerModel> accelerometer_model_;
Definition: trajectory.h:25
Definition: accelerometer_cost_functor.h:30
Sensors namespace.
Definition: accelerometer.cpp:8
AccelerometerIntrinsicsModel
Accelerometer model types.
Definition: accelerometer_models.h:16
Eigen::Matrix3< T > Skew(const Eigen::Vector3< T > &v)
Convert a 3-vector to a skew-symmetric cross-product matrix.
Definition: geometry.h:12
Eigen::Matrix3< T > ExpSO3Jacobian(const Eigen::Vector3< T > &phi)
Definition: geometry.h:138
Eigen::Matrix3< T > ExpSO3JacobianDot(const Eigen::Vector3< T > &phi, const Eigen::Vector3< T > &phi_dot)
Compute the time derivative of the Rodrigues formula manifold Jacobian.
Definition: geometry.h:214
Definition: trajectory.h:14