37 bool StaticInitializer::initialize(
double ×tamp, Eigen::MatrixXd &covariance, std::vector<std::shared_ptr<Type>> &order,
38 std::shared_ptr<IMU> t_imu,
bool wait_for_jerk) {
41 if (imu_data->size() < 2) {
46 double newesttime = imu_data->at(imu_data->size() - 1).timestamp;
47 double oldesttime = imu_data->at(0).timestamp;
50 if (newesttime - oldesttime < params.init_window_time) {
56 std::vector<ImuData> window_1to0, window_2to1;
57 for (
const ImuData &data : *imu_data) {
58 if (data.timestamp > newesttime - 0.5 * params.init_window_time && data.timestamp <= newesttime - 0.0 * params.init_window_time) {
59 window_1to0.push_back(data);
61 if (data.timestamp > newesttime - 1.0 * params.init_window_time && data.timestamp <= newesttime - 0.5 * params.init_window_time) {
62 window_2to1.push_back(data);
67 if (window_1to0.size() < 2 || window_2to1.size() < 2) {
73 Eigen::Vector3d a_avg_1to0 = Eigen::Vector3d::Zero();
74 for (
const ImuData &data : window_1to0) {
75 a_avg_1to0 += data.am;
77 a_avg_1to0 /= (int)window_1to0.size();
78 double a_var_1to0 = 0;
79 for (
const ImuData &data : window_1to0) {
80 a_var_1to0 += (data.am - a_avg_1to0).dot(data.am - a_avg_1to0);
82 a_var_1to0 = std::sqrt(a_var_1to0 / ((
int)window_1to0.size() - 1));
85 Eigen::Vector3d a_avg_2to1 = Eigen::Vector3d::Zero();
86 Eigen::Vector3d w_avg_2to1 = Eigen::Vector3d::Zero();
87 for (
const ImuData &data : window_2to1) {
88 a_avg_2to1 += data.am;
89 w_avg_2to1 += data.wm;
91 a_avg_2to1 = a_avg_2to1 / window_2to1.size();
92 w_avg_2to1 = w_avg_2to1 / window_2to1.size();
93 double a_var_2to1 = 0;
94 for (
const ImuData &data : window_2to1) {
95 a_var_2to1 += (data.am - a_avg_2to1).dot(data.am - a_avg_2to1);
97 a_var_2to1 = std::sqrt(a_var_2to1 / ((
int)window_2to1.size() - 1));
101 if (a_var_1to0 < params.init_imu_thresh && wait_for_jerk) {
102 PRINT_INFO(
YELLOW "[init-s]: no IMU excitation, below threshold %.3f < %.3f\n" RESET, a_var_1to0, params.init_imu_thresh);
108 if (a_var_2to1 > params.init_imu_thresh && wait_for_jerk) {
109 PRINT_INFO(
YELLOW "[init-s]: to much IMU excitation, above threshold %.3f > %.3f\n" RESET, a_var_2to1, params.init_imu_thresh);
115 if ((a_var_1to0 > params.init_imu_thresh || a_var_2to1 > params.init_imu_thresh) && !wait_for_jerk) {
116 PRINT_INFO(
YELLOW "[init-s]: to much IMU excitation, above threshold %.3f,%.3f > %.3f\n" RESET, a_var_2to1, a_var_1to0,
117 params.init_imu_thresh);
122 Eigen::Vector3d z_axis = a_avg_2to1 / a_avg_2to1.norm();
124 InitializerHelper::gram_schmidt(z_axis, Ro);
128 Eigen::Vector3d gravity_inG;
129 gravity_inG << 0.0, 0.0, params.gravity_mag;
130 Eigen::Vector3d bg = w_avg_2to1;
131 Eigen::Vector3d ba = a_avg_2to1 -
quat_2_Rot(q_GtoI) * gravity_inG;
134 timestamp = window_2to1.at(window_2to1.size() - 1).timestamp;
135 Eigen::VectorXd imu_state = Eigen::VectorXd::Zero(16);
136 imu_state.block(0, 0, 4, 1) = q_GtoI;
137 imu_state.block(10, 0, 3, 1) = bg;
138 imu_state.block(13, 0, 3, 1) = ba;
139 assert(t_imu !=
nullptr);
140 t_imu->set_value(imu_state);
141 t_imu->set_fej(imu_state);
145 order.push_back(t_imu);
146 covariance = std::pow(0.02, 2) * Eigen::MatrixXd::Identity(t_imu->size(), t_imu->size());
147 covariance.block(0, 0, 3, 3) = std::pow(0.02, 2) * Eigen::Matrix3d::Identity();
148 covariance.block(3, 3, 3, 3) = std::pow(0.05, 2) * Eigen::Matrix3d::Identity();
149 covariance.block(6, 6, 3, 3) = std::pow(0.01, 2) * Eigen::Matrix3d::Identity();