39 #ifndef INCLUDE_OKVIS_CERES_ODE_ODE_HPP_
40 #define INCLUDE_OKVIS_CERES_ODE_ODE_HPP_
58 __inline__
double sinc(
double x) {
62 static const double c_2 = 1.0 / 6.0;
63 static const double c_4 = 1.0 / 120.0;
64 static const double c_6 = 1.0 / 5040.0;
65 const double x_2 = x * x;
66 const double x_4 = x_2 * x_2;
67 const double x_6 = x_2 * x_2 * x_2;
68 return 1.0 - c_2 * x_2 + c_4 * x_4 - c_6 * x_6;
74 const Eigen::Vector3d& p_WS_W,
const Eigen::Quaterniond& q_WS,
77 Eigen::Matrix<double, 15, 15>* F_c_ptr = 0){
79 const Eigen::Vector3d omega_S = gyr - sb.segment<3>(3);
80 const Eigen::Vector3d acc_S = acc - sb.tail<3>();
84 p_WS_W_dot = sb.head<3>();
88 q_WS_dot.head<3>() = 0.5 * omega_S;
90 Eigen::Matrix3d C_WS = q_WS.toRotationMatrix();
95 Eigen::Vector3d G = -p_WS_W - Eigen::Vector3d(0, 0, 6371009);
96 sb_dot.head<3>() = (C_WS * acc_S + g * G.normalized());
98 sb_dot.tail<6>().setZero();
103 F_c_ptr->block<3, 3>(0, 6) += Eigen::Matrix3d::Identity();
104 F_c_ptr->block<3, 3>(3, 9) -= C_WS;
106 F_c_ptr->block<3, 3>(6, 12) -= C_WS;
161 const Eigen::Vector3d& gyr_0,
const Eigen::Vector3d& acc_0,
162 const Eigen::Vector3d& gyr_1,
const Eigen::Vector3d& acc_1,
double g,
163 double sigma_g_c,
double sigma_a_c,
double sigma_gw_c,
double sigma_aw_c,
164 double dt, Eigen::Vector3d& p_WS_W, Eigen::Quaterniond& q_WS,
166 Eigen::Matrix<double, 15, 15>* F_tot_ptr = 0) {
168 Eigen::Vector3d k1_p_WS_W_dot;
169 Eigen::Vector4d k1_q_WS_dot;
171 Eigen::Matrix<double, 15, 15> k1_F_c;
173 k1_q_WS_dot, k1_sb_dot, &k1_F_c);
175 Eigen::Vector3d p_WS_W1 = p_WS_W;
176 Eigen::Quaterniond q_WS1 = q_WS;
179 p_WS_W1 += k1_p_WS_W_dot * 0.5 * dt;
180 Eigen::Quaterniond dq;
181 double theta_half = k1_q_WS_dot.head<3>().norm() * 0.5 * dt;
182 double sinc_theta_half =
sinc(theta_half);
183 double cos_theta_half = cos(theta_half);
184 dq.vec() = sinc_theta_half * k1_q_WS_dot.head<3>() * 0.5 * dt;
185 dq.w() = cos_theta_half;
187 sb1 += k1_sb_dot * 0.5 * dt;
189 Eigen::Vector3d k2_p_WS_W_dot;
190 Eigen::Vector4d k2_q_WS_dot;
192 Eigen::Matrix<double, 15, 15> k2_F_c;
194 p_WS_W1, q_WS1, sb1, k2_p_WS_W_dot, k2_q_WS_dot,
197 Eigen::Vector3d p_WS_W2 = p_WS_W;
198 Eigen::Quaterniond q_WS2 = q_WS;
201 p_WS_W2 += k2_p_WS_W_dot * dt;
202 theta_half = k2_q_WS_dot.head<3>().norm() * dt;
203 sinc_theta_half =
sinc(theta_half);
204 cos_theta_half = cos(theta_half);
205 dq.vec() = sinc_theta_half * k2_q_WS_dot.head<3>() * dt;
206 dq.w() = cos_theta_half;
209 sb2 += k1_sb_dot * dt;
211 Eigen::Vector3d k3_p_WS_W_dot;
212 Eigen::Vector4d k3_q_WS_dot;
214 Eigen::Matrix<double, 15, 15> k3_F_c;
216 p_WS_W2, q_WS2, sb2, k3_p_WS_W_dot, k3_q_WS_dot,
219 Eigen::Vector3d p_WS_W3 = p_WS_W;
220 Eigen::Quaterniond q_WS3 = q_WS;
223 p_WS_W3 += k3_p_WS_W_dot * dt;
224 theta_half = k3_q_WS_dot.head<3>().norm() * dt;
225 sinc_theta_half =
sinc(theta_half);
226 cos_theta_half = cos(theta_half);
227 dq.vec() = sinc_theta_half * k3_q_WS_dot.head<3>() * dt;
228 dq.w() = cos_theta_half;
231 sb3 += k3_sb_dot * dt;
233 Eigen::Vector3d k4_p_WS_W_dot;
234 Eigen::Vector4d k4_q_WS_dot;
236 Eigen::Matrix<double, 15, 15> k4_F_c;
238 k4_q_WS_dot, k4_sb_dot, &k4_F_c);
242 (k1_p_WS_W_dot + 2 * (k2_p_WS_W_dot + k3_p_WS_W_dot) + k4_p_WS_W_dot) * dt
244 Eigen::Vector3d theta_half_vec = (k1_q_WS_dot.head<3>()
245 + 2 * (k2_q_WS_dot.head<3>() + k3_q_WS_dot.head<3>())
246 + k4_q_WS_dot.head<3>()) * dt / 6.0;
247 theta_half = theta_half_vec.norm();
248 sinc_theta_half =
sinc(theta_half);
249 cos_theta_half = cos(theta_half);
250 dq.vec() = sinc_theta_half * theta_half_vec;
251 dq.w() = cos_theta_half;
253 sb += (k1_sb_dot + 2 * (k2_sb_dot + k3_sb_dot) + k4_sb_dot) * dt / 6.0;
259 Eigen::Matrix<double, 15, 15>& F_tot = *F_tot_ptr;
260 const Eigen::Matrix<double, 15, 15>& J1 = k1_F_c;
261 const Eigen::Matrix<double, 15, 15> J2=k2_F_c*(Eigen::Matrix<double, 15, 15>::Identity()+0.5*dt*J1);
262 const Eigen::Matrix<double, 15, 15> J3=k3_F_c*(Eigen::Matrix<double, 15, 15>::Identity()+0.5*dt*J2);
263 const Eigen::Matrix<double, 15, 15> J4=k4_F_c*(Eigen::Matrix<double, 15, 15>::Identity()+dt*J3);
264 Eigen::Matrix<double, 15, 15> F = Eigen::Matrix<double, 15, 15>::Identity()
265 + dt * (J1+2*(J2+J3)+J4) / 6.0;
268 F_tot = (F * F_tot).eval();
271 Eigen::Matrix<double, 15, 15>& cov = *P_ptr;
272 cov = F * (cov * F.transpose()).eval();
275 const double Q_g = sigma_g_c * sigma_g_c * dt;
276 const double Q_a = sigma_a_c * sigma_a_c * dt;
277 const double Q_gw = sigma_gw_c * sigma_gw_c * dt;
278 const double Q_aw = sigma_aw_c * sigma_aw_c * dt;
__inline__ void evaluateContinuousTimeOde(const Eigen::Vector3d &gyr, const Eigen::Vector3d &acc, double g, const Eigen::Vector3d &p_WS_W, const Eigen::Quaterniond &q_WS, const okvis::SpeedAndBias &sb, Eigen::Vector3d &p_WS_W_dot, Eigen::Vector4d &q_WS_dot, okvis::SpeedAndBias &sb_dot, Eigen::Matrix< double, 15, 15 > *F_c_ptr=0)
Definition: ode.hpp:73
Eigen::Matrix< Scalar_T, 3, 3 > crossMx(Scalar_T x, Scalar_T y, Scalar_T z)
Cross matrix of a vector [x,y,z]. Adopted from Schweizer-Messer by Paul Furgale.
Definition: operators.hpp:62
__inline__ void integrateOneStep_RungeKutta(const Eigen::Vector3d &gyr_0, const Eigen::Vector3d &acc_0, const Eigen::Vector3d &gyr_1, const Eigen::Vector3d &acc_1, double g, double sigma_g_c, double sigma_a_c, double sigma_gw_c, double sigma_aw_c, double dt, Eigen::Vector3d &p_WS_W, Eigen::Quaterniond &q_WS, okvis::SpeedAndBias &sb, Eigen::Matrix< double, 15, 15 > *P_ptr=0, Eigen::Matrix< double, 15, 15 > *F_tot_ptr=0)
Definition: ode.hpp:160
Eigen::Matrix< double, 9, 1 > SpeedAndBias
Definition: FrameTypedefs.hpp:234
This file contains the templated measurement structs, structs encapsulating Sensor data and related t...
__inline__ double sinc(double x)
Definition: ode.hpp:58
This file contains some useful assert macros.
This file contains some typedefs related to state variables.
File with some helper functions related to matrix/vector operations.
This file contains useful typedefs and structs related to frames.