17 #ifndef CARTOGRAPHER_MAPPING_INTERNAL_OPTIMIZATION_COST_FUNCTIONS_COST_HELPERS_IMPL_H_ 18 #define CARTOGRAPHER_MAPPING_INTERNAL_OPTIMIZATION_COST_FUNCTIONS_COST_HELPERS_IMPL_H_ 26 namespace optimization {
32 const T cos_theta_i = cos(start[2]);
33 const T sin_theta_i = sin(start[2]);
34 const T delta_x = end[0] - start[0];
35 const T delta_y = end[1] - start[1];
36 const T h[3] = {cos_theta_i * delta_x + sin_theta_i * delta_y,
37 -sin_theta_i * delta_x + cos_theta_i * delta_y,
42 T(relative_pose.
rotation().angle()) - h[2])}};
46 std::array<T, 3>
ScaleError(
const std::array<T, 3>& error,
47 double translation_weight,
double rotation_weight) {
50 error[0] * translation_weight,
51 error[1] * translation_weight,
52 error[2] * rotation_weight
60 const T*
const start_translation,
const T*
const end_rotation,
61 const T*
const end_translation) {
62 const Eigen::Quaternion<T> R_i_inverse(start_rotation[0], -start_rotation[1],
66 const Eigen::Matrix<T, 3, 1> delta(end_translation[0] - start_translation[0],
67 end_translation[1] - start_translation[1],
68 end_translation[2] - start_translation[2]);
69 const Eigen::Matrix<T, 3, 1> h_translation = R_i_inverse * delta;
71 const Eigen::Quaternion<T> h_rotation_inverse =
72 Eigen::Quaternion<T>(end_rotation[0], -end_rotation[1], -end_rotation[2],
74 Eigen::Quaternion<T>(start_rotation[0], start_rotation[1],
75 start_rotation[2], start_rotation[3]);
77 const Eigen::Matrix<T, 3, 1> angle_axis_difference =
79 h_rotation_inverse * relative_pose.
rotation().cast<T>());
81 return {{T(relative_pose.
translation().x()) - h_translation[0],
82 T(relative_pose.
translation().y()) - h_translation[1],
83 T(relative_pose.
translation().z()) - h_translation[2],
84 angle_axis_difference[0], angle_axis_difference[1],
85 angle_axis_difference[2]}};
89 std::array<T, 6>
ScaleError(
const std::array<T, 6>& error,
90 double translation_weight,
double rotation_weight) {
93 error[0] * translation_weight,
94 error[1] * translation_weight,
95 error[2] * translation_weight,
96 error[3] * rotation_weight,
97 error[4] * rotation_weight,
98 error[5] * rotation_weight
105 template <
typename T>
110 const T cos_theta = start[0] * end[0] + start[1] * end[1] +
111 start[2] * end[2] + start[3] * end[3];
113 const T abs_cos_theta = ceres::abs(cos_theta);
116 T prev_scale(1. - factor);
117 T next_scale(factor);
118 if (abs_cos_theta < T(1. - 1e-5)) {
119 const T theta = acos(abs_cos_theta);
120 const T sin_theta = sin(theta);
121 prev_scale = sin((1. - factor) * theta) / sin_theta;
122 next_scale = sin(factor * theta) / sin_theta;
124 if (cos_theta < T(0.)) {
125 next_scale = -next_scale;
127 return {{prev_scale * start[0] + next_scale * end[0],
128 prev_scale * start[1] + next_scale * end[1],
129 prev_scale * start[2] + next_scale * end[2],
130 prev_scale * start[3] + next_scale * end[3]}};
133 template <
typename T>
134 std::tuple<std::array<T, 4> , std::array<T, 3> >
136 const T*
const prev_node_translation,
137 const T*
const next_node_rotation,
138 const T*
const next_node_translation,
139 const double interpolation_parameter) {
140 return std::make_tuple(
142 interpolation_parameter),
144 {prev_node_translation[0] +
145 interpolation_parameter *
146 (next_node_translation[0] - prev_node_translation[0]),
147 prev_node_translation[1] +
148 interpolation_parameter *
149 (next_node_translation[1] - prev_node_translation[1]),
150 prev_node_translation[2] +
151 interpolation_parameter *
152 (next_node_translation[2] - prev_node_translation[2])}});
155 template <
typename T>
156 std::tuple<std::array<T, 4> , std::array<T, 3> >
158 const Eigen::Quaterniond& prev_node_gravity_alignment,
159 const T*
const next_node_pose,
160 const Eigen::Quaterniond& next_node_gravity_alignment,
161 const double interpolation_parameter) {
164 const Eigen::Quaternion<T> prev_quaternion(
165 (Eigen::AngleAxis<T>(prev_node_pose[2], Eigen::Matrix<T, 3, 1>::UnitZ()) *
166 prev_node_gravity_alignment.cast<T>())
168 const std::array<T, 4> prev_node_rotation = {
169 {prev_quaternion.w(), prev_quaternion.x(), prev_quaternion.y(),
170 prev_quaternion.z()}};
174 const Eigen::Quaternion<T> next_quaternion(
175 (Eigen::AngleAxis<T>(next_node_pose[2], Eigen::Matrix<T, 3, 1>::UnitZ()) *
176 next_node_gravity_alignment.cast<T>())
178 const std::array<T, 4> next_node_rotation = {
179 {next_quaternion.w(), next_quaternion.x(), next_quaternion.y(),
180 next_quaternion.z()}};
182 return std::make_tuple(
184 interpolation_parameter),
186 {prev_node_pose[0] + interpolation_parameter *
187 (next_node_pose[0] - prev_node_pose[0]),
188 prev_node_pose[1] + interpolation_parameter *
189 (next_node_pose[1] - prev_node_pose[1]),
197 #endif // CARTOGRAPHER_MAPPING_INTERNAL_OPTIMIZATION_COST_FUNCTIONS_COST_HELPERS_IMPL_H_
std::tuple< std::array< T, 4 >, std::array< T, 3 > > InterpolateNodes3D(const T *const prev_node_rotation, const T *const prev_node_translation, const T *const next_node_rotation, const T *const next_node_translation, const double interpolation_parameter)
std::array< T, 3 > ScaleError(const std::array< T, 3 > &error, double translation_weight, double rotation_weight)
std::tuple< std::array< T, 4 >, std::array< T, 3 > > InterpolateNodes2D(const T *const prev_node_pose, const Eigen::Quaterniond &prev_node_gravity_alignment, const T *const next_node_pose, const Eigen::Quaterniond &next_node_gravity_alignment, const double interpolation_parameter)
T NormalizeAngleDifference(T difference)
static std::array< T, 3 > ComputeUnscaledError(const transform::Rigid2d &relative_pose, const T *const start, const T *const end)
std::array< T, 4 > SlerpQuaternions(const T *const start, const T *const end, double factor)