38 #include <boost/program_options.hpp>
56 using namespace gtsam;
63 namespace po = boost::program_options;
66 po::options_description
desc;
67 desc.add_options()(
"help,h",
"produce help message")(
68 "data_csv_path", po::value<string>()->default_value(
"imuAndGPSdata.csv"),
69 "path to the CSV file with the IMU data")(
71 po::value<string>()->default_value(
"imuFactorExampleResults.csv"),
72 "path to the result file to use")(
"use_isam", po::bool_switch(),
73 "use ISAM as the optimizer");
76 po::store(po::parse_command_line(argc, argv,
desc), vm);
78 if (vm.count(
"help")) {
86 std::shared_ptr<PreintegratedCombinedMeasurements::Params>
imuParams() {
88 double accel_noise_sigma = 0.0003924;
89 double gyro_noise_sigma = 0.000205689024915;
90 double accel_bias_rw_sigma = 0.004905;
91 double gyro_bias_rw_sigma = 0.000001454441043;
92 Matrix33 measured_acc_cov = I_3x3 *
pow(accel_noise_sigma, 2);
93 Matrix33 measured_omega_cov = I_3x3 *
pow(gyro_noise_sigma, 2);
94 Matrix33 integration_error_cov =
96 Matrix33 bias_acc_cov = I_3x3 *
pow(accel_bias_rw_sigma, 2);
97 Matrix33 bias_omega_cov = I_3x3 *
pow(gyro_bias_rw_sigma, 2);
98 Matrix66 bias_acc_omega_init =
103 p->accelerometerCovariance =
105 p->integrationCovariance =
106 integration_error_cov;
109 p->gyroscopeCovariance =
112 p->biasAccCovariance = bias_acc_cov;
113 p->biasOmegaCovariance = bias_omega_cov;
114 p->biasAccOmegaInt = bias_acc_omega_init;
119 int main(
int argc,
char* argv[]) {
122 bool use_isam =
false;
128 use_isam = var_map[
"use_isam"].as<
bool>();
132 printf(
"Using ISAM2\n");
139 printf(
"Using Levenberg Marquardt Optimizer\n");
145 "#time(s),x(m),y(m),z(m),qx,qy,qz,qw,gt_x(m),gt_y(m),gt_z(m),gt_qx,"
146 "gt_qy,gt_qz,gt_qw\n");
151 ifstream
file(data_filename.c_str());
155 Vector10 initial_state;
157 for (
int i = 0;
i < 9;
i++) {
159 initial_state(
i) = stof(
value.c_str());
162 initial_state(9) = stof(
value.c_str());
163 cout <<
"initial state:\n" << initial_state.transpose() <<
"\n\n";
168 initial_state(4), initial_state(5));
169 Point3 prior_point(initial_state.head<3>());
170 Pose3 prior_pose(prior_rotation, prior_point);
171 Vector3 prior_velocity(initial_state.tail<3>());
175 int correction_count = 0;
176 initial_values.
insert(
X(correction_count), prior_pose);
177 initial_values.
insert(
V(correction_count), prior_velocity);
178 initial_values.
insert(
B(correction_count), prior_imu_bias);
182 (
Vector(6) << 0.01, 0.01, 0.01, 0.5, 0.5, 0.5)
189 graph->
addPrior(
X(correction_count), prior_pose, pose_noise_model);
190 graph->
addPrior(
V(correction_count), prior_velocity, velocity_noise_model);
191 graph->
addPrior(
B(correction_count), prior_imu_bias, bias_noise_model);
195 std::shared_ptr<PreintegrationType> preintegrated =
196 std::make_shared<PreintegratedImuMeasurements>(
p, prior_imu_bias);
198 assert(preintegrated);
201 NavState prev_state(prior_pose, prior_velocity);
206 double current_position_error = 0.0, current_orientation_error = 0.0;
208 double output_time = 0.0;
213 while (
file.good()) {
220 for (
int i = 0;
i < 5; ++
i) {
222 imu(
i) = stof(
value.c_str());
225 imu(5) = stof(
value.c_str());
228 preintegrated->integrateMeasurement(imu.head<3>(), imu.tail<3>(),
dt);
230 }
else if (
type == 1) {
232 for (
int i = 0;
i < 6; ++
i) {
234 gps(
i) = stof(
value.c_str());
237 gps(6) = stof(
value.c_str());
244 ImuFactor imu_factor(
X(correction_count - 1),
V(correction_count - 1),
245 X(correction_count),
V(correction_count),
246 B(correction_count - 1), preint_imu);
250 B(correction_count - 1),
B(correction_count), zero_bias,
262 prop_state = preintegrated->predict(prev_state, prev_bias);
263 initial_values.
insert(
X(correction_count), prop_state.
pose());
264 initial_values.
insert(
V(correction_count), prop_state.
v());
265 initial_values.
insert(
B(correction_count), prev_bias);
271 result = isam2->calculateEstimate();
275 initial_values.
clear();
288 preintegrated->resetIntegrationAndSetBias(prev_bias);
292 Vector3 position_error = gtsam_position - gps.head<3>();
293 current_position_error = position_error.norm();
296 Quaternion gps_quat(gps(6), gps(3), gps(4), gps(5));
297 Quaternion quat_error = gtsam_quat * gps_quat.inverse();
298 quat_error.normalize();
299 Vector3 euler_angle_error(quat_error.x() * 2, quat_error.y() * 2,
301 current_orientation_error = euler_angle_error.norm();
304 cout <<
"Position error:" << current_position_error <<
"\t "
305 <<
"Angular error:" << current_orientation_error <<
"\n";
307 fprintf(fp_out,
"%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",
308 output_time, gtsam_position(0), gtsam_position(1),
309 gtsam_position(2), gtsam_quat.x(), gtsam_quat.y(), gtsam_quat.z(),
310 gtsam_quat.w(), gps(0), gps(1), gps(2), gps_quat.x(),
311 gps_quat.y(), gps_quat.z(), gps_quat.w());
316 cerr <<
"ERROR parsing file\n";