1 #ifndef CALICO_SENSORS_IMAGER_COST_FUNCTOR_H_
2 #define CALICO_SENSORS_IMAGER_COST_FUNCTOR_H_
8 #include "calico/sensors/camera_models.h"
9 #include "calico/trajectory.h"
10 #include "ceres/cost_function.h"
15 enum class ImagerParameterIndices : int {
19 kImagerExtrinsicsRotationIndex = 1,
20 kImagerExtrinsicsTranslationIndex = 2,
22 kSensorExtrinsicsRotationIndex = 3,
23 kSensorExtrinsicsTranslationIndex = 4,
33 kModelRotationIndex = 7,
34 kModelTranslationIndex = 8,
37 kSensorRigPoseSplineControlPointsIndex = 9,
44 static constexpr
int kCameraResidualSize = 2;
46 const Eigen::Vector2d& pixel,
double sigma,
double stamp,
50 static ceres::CostFunction* CreateCostFunction(
51 const Eigen::Vector2d& pixel,
double sigma,
53 Pose3d& imager_extrinsics,
Pose3d& sensor_extrinsics,
double& latency,
54 Eigen::Vector3d& t_model_point,
Pose3d& T_world_model,
55 Trajectory& trajectory_world_sensorrig,
double stamp,
56 std::vector<double*>& parameters);
84 bool operator()(T
const*
const* parameters, T* residual) {
86 const T* intrinsics_ptr =
static_cast<const T*
>(
87 &(parameters[
static_cast<int>(ImagerParameterIndices::kIntrinsicsIndex)]
89 const int parameter_size = camera_model_->NumberOfParameters();
90 const Eigen::VectorX<T> intrinsics =
91 Eigen::Map<const Eigen::VectorX<T>>(intrinsics_ptr, parameter_size);
93 const Eigen::Map<const Eigen::Quaternion<T>> q_sensor_imager(
94 &(parameters[
static_cast<int>(
95 ImagerParameterIndices::kImagerExtrinsicsRotationIndex)][0]));
96 const Eigen::Map<const Eigen::Vector3<T>> t_sensor_imager(
97 &(parameters[
static_cast<int>(
98 ImagerParameterIndices::kImagerExtrinsicsTranslationIndex)][0]));
100 const Eigen::Map<const Eigen::Quaternion<T>> q_sensorrig_sensor(
101 &(parameters[
static_cast<int>(
102 ImagerParameterIndices::kSensorExtrinsicsRotationIndex)][0]));
103 const Eigen::Map<const Eigen::Vector3<T>> t_sensorrig_sensor(
104 &(parameters[
static_cast<int>(
105 ImagerParameterIndices::kSensorExtrinsicsTranslationIndex)][0]));
108 parameters[
static_cast<int>(ImagerParameterIndices::kLatencyIndex)][0];
110 const Eigen::Map<const Eigen::Vector3<T>> t_model_point(
111 &(parameters[
static_cast<int>(ImagerParameterIndices::kModelPointIndex)]
113 const Eigen::Map<const Eigen::Quaternion<T>> q_world_model(
114 &(parameters[
static_cast<int>(
115 ImagerParameterIndices::kModelRotationIndex)][0]));
116 const Eigen::Map<const Eigen::Vector3<T>> t_world_model(
117 &(parameters[
static_cast<int>(
118 ImagerParameterIndices::kModelTranslationIndex)][0]));
120 const int num_rotation_control_points =
121 rotation_trajectory_evaluation_params_.num_control_points;
122 Eigen::MatrixX<T> rotation_control_points(num_rotation_control_points, 3);
123 for (
int i = 0; i < num_rotation_control_points; ++i) {
124 rotation_control_points.row(i) = Eigen::Map<const Eigen::Vector3<T>>(
125 &(parameters[
static_cast<int>(
126 ImagerParameterIndices::
127 kSensorRigPoseSplineControlPointsIndex) +
130 const int num_position_control_points =
131 position_trajectory_evaluation_params_.num_control_points;
132 Eigen::MatrixX<T> position_control_points(num_position_control_points, 3);
133 for (
int i = 0; i < num_position_control_points; ++i) {
134 position_control_points.row(i) = Eigen::Map<const Eigen::Vector3<T>>(
135 &(parameters[
static_cast<int>(
136 ImagerParameterIndices::
137 kSensorRigPoseSplineControlPointsIndex) +
138 i + num_rotation_control_points][0]));
141 const Eigen::MatrixX<T> rotation_basis_matrix =
142 rotation_trajectory_evaluation_params_.basis_matrix.template cast<T>();
143 const T rotation_knot0 =
144 static_cast<T
>(rotation_trajectory_evaluation_params_.knot0);
145 const T rotation_knot1 =
146 static_cast<T
>(rotation_trajectory_evaluation_params_.knot1);
147 const T rotation_stamp =
148 static_cast<T
>(rotation_trajectory_evaluation_params_.stamp) - latency;
150 const Eigen::MatrixX<T> position_basis_matrix =
151 position_trajectory_evaluation_params_.basis_matrix.template cast<T>();
152 const T position_knot0 =
153 static_cast<T
>(position_trajectory_evaluation_params_.knot0);
154 const T position_knot1 =
155 static_cast<T
>(position_trajectory_evaluation_params_.knot1);
156 const T position_stamp =
157 static_cast<T
>(position_trajectory_evaluation_params_.stamp) - latency;
160 rotation_control_points, rotation_knot0, rotation_knot1,
161 rotation_basis_matrix, rotation_stamp, 0);
162 T q_sensorrig_world_array[4];
163 ceres::AngleAxisToQuaternion(phi_sensorrig_world.data(),
164 q_sensorrig_world_array);
165 const Eigen::Quaternion<T> q_sensorrig_world(
166 q_sensorrig_world_array[0], q_sensorrig_world_array[1],
167 q_sensorrig_world_array[2], q_sensorrig_world_array[3]);
169 position_control_points, position_knot0, position_knot1,
170 position_basis_matrix, position_stamp, 0);
173 const Eigen::Quaternion<T> q_sensorrig_imager =
174 q_sensorrig_sensor * q_sensor_imager;
175 const Eigen::Vector3<T> t_sensorrig_imager =
176 t_sensorrig_sensor + q_sensorrig_sensor * t_sensor_imager;
177 const Eigen::Quaternion<T> q_imager_model =
178 q_sensorrig_imager.inverse() * q_sensorrig_world * q_world_model;
179 const Eigen::Vector3<T> t_world_imager =
180 t_world_sensorrig + q_sensorrig_world.inverse() * t_sensorrig_imager;
181 const Eigen::Vector3<T> t_model_imager =
182 q_world_model.inverse() * (t_world_imager - t_world_model);
183 const Eigen::Vector3<T> t_camera_point =
184 q_imager_model * (t_model_point - t_model_imager);
186 const absl::StatusOr<Eigen::Vector2<T>> projection =
187 camera_model_->ProjectPoint(intrinsics, t_camera_point);
189 if (projection.ok()) {
190 Eigen::Map<Eigen::Vector2<T>> error(residual);
191 const Eigen::Vector2<T> pixel = pixel_.template cast<T>();
192 error = (pixel - *projection) *
static_cast<T
>(information_);
199 Eigen::Vector2d pixel_;
201 std::unique_ptr<CameraModel> camera_model_;
Definition: trajectory.h:25
Definition: imager_cost_functor.h:42
Sensors namespace.
Definition: accelerometer.cpp:8
CameraIntrinsicsModel
Camera model types.
Definition: camera_models.h:16
Definition: trajectory.h:14