@@ -48,9 +48,51 @@ bool State_JPLQuatLocal::Plus(const double *x, const double *delta, double *x_pl
4848 return true ;
4949}
5050
51+ #if CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 2
52+ bool State_JPLQuatLocal::PlusJacobian (const double *x, double *jacobian) const {
53+ Eigen::Map<Eigen::Matrix<double , 4 , 3 , Eigen::RowMajor>> j (jacobian);
54+ j.topRows <3 >().setIdentity ();
55+ j.bottomRows <1 >().setZero ();
56+ return true ;
57+ }
58+
59+ bool State_JPLQuatLocal::Minus (const double *y, const double *x, double *delta) const {
60+ Eigen::Map<const Eigen::Vector4d> q1 (x);
61+ Eigen::Map<const Eigen::Vector4d> q2 (y);
62+ Eigen::Vector4d q_rel = ov_core::quat_multiply (q2, ov_core::Inv (q1));
63+ Eigen::Vector3d omega;
64+
65+ double qw = q_rel (3 );
66+ Eigen::Vector3d qv = q_rel.head <3 >();
67+
68+ double norm_qv = qv.norm ();
69+ if (norm_qv < 1e-8 ) {
70+ omega.setZero ();
71+ } else {
72+ double angle = 2.0 * std::atan2 (norm_qv, qw);
73+ omega = angle * (qv / norm_qv);
74+ }
75+
76+ Eigen::Map<Eigen::Vector3d> d_out (delta);
77+ d_out = omega;
78+ return true ;
79+ }
80+
81+ bool State_JPLQuatLocal::MinusJacobian (const double *x, double *jacobian) const {
82+ // This is an approximation: ∂delta/∂x ≈ [I; 0]
83+ Eigen::Map<Eigen::Matrix<double , 3 , 4 , Eigen::RowMajor>> j (jacobian);
84+ j.setZero ();
85+ j.leftCols <3 >().setIdentity ();
86+ return true ;
87+ }
88+
89+ #else
90+
5191bool State_JPLQuatLocal::ComputeJacobian (const double *x, double *jacobian) const {
5292 Eigen::Map<Eigen::Matrix<double , 4 , 3 , Eigen::RowMajor>> j (jacobian);
5393 j.topRows <3 >().setIdentity ();
5494 j.bottomRows <1 >().setZero ();
5595 return true ;
5696}
97+
98+ #endif
0 commit comments