22 #include "Eigen/Geometry" 27 #include "ceres/jet.h" 31 namespace optimization {
34 class SpaCostFunction2D {
36 explicit SpaCostFunction2D(
37 const PoseGraphInterface::Constraint::Pose& observed_relative_pose)
41 bool operator()(
const T*
const start_pose,
const T*
const end_pose,
43 const std::array<T, 3> error =
46 start_pose, end_pose),
49 std::copy(std::begin(error), std::end(error), e);
57 class AnalyticalSpaCostFunction2D
58 :
public ceres::SizedCostFunction<3 ,
62 explicit AnalyticalSpaCostFunction2D(
63 const PoseGraphInterface::Constraint::Pose& constraint_pose)
67 virtual ~AnalyticalSpaCostFunction2D() {}
69 bool Evaluate(
double const*
const* parameters,
double* residuals,
70 double** jacobians)
const override {
71 double const* start = parameters[0];
72 double const* end = parameters[1];
74 const double cos_start_rotation = cos(start[2]);
75 const double sin_start_rotation = sin(start[2]);
76 const double delta_x = end[0] - start[0];
77 const double delta_y = end[1] - start[1];
82 (cos_start_rotation * delta_x + sin_start_rotation * delta_y));
86 (-sin_start_rotation * delta_x + cos_start_rotation * delta_y));
91 if (jacobians == NULL)
return true;
93 const double weighted_cos_start_rotation =
95 const double weighted_sin_start_rotation =
100 if (jacobians[0] != NULL) {
101 jacobians[0][0] = weighted_cos_start_rotation;
102 jacobians[0][1] = weighted_sin_start_rotation;
103 jacobians[0][2] = weighted_sin_start_rotation * delta_x -
104 weighted_cos_start_rotation * delta_y;
105 jacobians[0][3] = -weighted_sin_start_rotation;
106 jacobians[0][4] = weighted_cos_start_rotation;
107 jacobians[0][5] = weighted_cos_start_rotation * delta_x +
108 weighted_sin_start_rotation * delta_y;
113 if (jacobians[1] != NULL) {
114 jacobians[1][0] = -weighted_cos_start_rotation;
115 jacobians[1][1] = -weighted_sin_start_rotation;
117 jacobians[1][3] = weighted_sin_start_rotation;
118 jacobians[1][4] = -weighted_cos_start_rotation;
137 return new ceres::AutoDiffCostFunction<SpaCostFunction2D, 3 ,
140 new SpaCostFunction2D(observed_relative_pose));
145 return new AnalyticalSpaCostFunction2D(observed_relative_pose);
const PoseGraphInterface::Constraint::Pose observed_relative_pose_
ceres::CostFunction * CreateAutoDiffSpaCostFunction(const PoseGraphInterface::Constraint::Pose &observed_relative_pose)
const double translation_weight_
const double rotation_weight_
ceres::CostFunction * CreateAnalyticalSpaCostFunction(const PoseGraphInterface::Constraint::Pose &observed_relative_pose)
std::array< T, 3 > ScaleError(const std::array< T, 3 > &error, double translation_weight, double rotation_weight)
T NormalizeAngleDifference(T difference)
static std::array< T, 3 > ComputeUnscaledError(const transform::Rigid2d &relative_pose, const T *const start, const T *const end)