37 #include <boost/program_options.hpp> 54 using namespace gtsam;
61 namespace po = boost::program_options;
64 po::options_description desc;
65 desc.add_options()(
"help,h",
"produce help message")(
66 "data_csv_path", po::value<string>()->default_value(
"imuAndGPSdata.csv"),
67 "path to the CSV file with the IMU data")(
69 po::value<string>()->default_value(
"imuFactorExampleResults.csv"),
70 "path to the result file to use")(
"use_isam", po::bool_switch(),
71 "use ISAM as the optimizer");
74 po::store(po::parse_command_line(argc, argv, desc), vm);
76 if (vm.count(
"help")) {
84 boost::shared_ptr<PreintegratedCombinedMeasurements::Params>
imuParams() {
86 double accel_noise_sigma = 0.0003924;
87 double gyro_noise_sigma = 0.000205689024915;
88 double accel_bias_rw_sigma = 0.004905;
89 double gyro_bias_rw_sigma = 0.000001454441043;
90 Matrix33 measured_acc_cov = I_3x3 *
pow(accel_noise_sigma, 2);
91 Matrix33 measured_omega_cov = I_3x3 *
pow(gyro_noise_sigma, 2);
92 Matrix33 integration_error_cov =
94 Matrix33 bias_acc_cov = I_3x3 *
pow(accel_bias_rw_sigma, 2);
95 Matrix33 bias_omega_cov = I_3x3 *
pow(gyro_bias_rw_sigma, 2);
96 Matrix66 bias_acc_omega_int =
101 p->accelerometerCovariance =
103 p->integrationCovariance =
104 integration_error_cov;
107 p->gyroscopeCovariance =
110 p->biasAccCovariance = bias_acc_cov;
111 p->biasOmegaCovariance = bias_omega_cov;
112 p->biasAccOmegaInt = bias_acc_omega_int;
117 int main(
int argc,
char* argv[]) {
120 bool use_isam =
false;
125 output_filename = var_map[
"output_filename"].as<
string>();
126 use_isam = var_map[
"use_isam"].as<
bool>();
130 printf(
"Using ISAM2\n");
134 isam2 =
new ISAM2(parameters);
137 printf(
"Using Levenberg Marquardt Optimizer\n");
141 FILE* fp_out = fopen(output_filename.c_str(),
"w+");
143 "#time(s),x(m),y(m),z(m),qx,qy,qz,qw,gt_x(m),gt_y(m),gt_z(m),gt_qx," 144 "gt_qy,gt_qz,gt_qw\n");
149 ifstream
file(data_filename.c_str());
153 Vector10 initial_state;
154 getline(
file, value,
',');
155 for (
int i = 0;
i < 9;
i++) {
156 getline(
file, value,
',');
157 initial_state(
i) = stof(value.c_str());
159 getline(
file, value,
'\n');
160 initial_state(9) = stof(value.c_str());
161 cout <<
"initial state:\n" << initial_state.transpose() <<
"\n\n";
166 initial_state(4), initial_state(5));
167 Point3 prior_point(initial_state.head<3>());
168 Pose3 prior_pose(prior_rotation, prior_point);
169 Vector3 prior_velocity(initial_state.tail<3>());
173 int correction_count = 0;
174 initial_values.
insert(
X(correction_count), prior_pose);
175 initial_values.
insert(
V(correction_count), prior_velocity);
176 initial_values.
insert(
B(correction_count), prior_imu_bias);
180 (
Vector(6) << 0.01, 0.01, 0.01, 0.5, 0.5, 0.5)
187 graph->
addPrior(
X(correction_count), prior_pose, pose_noise_model);
188 graph->
addPrior(
V(correction_count), prior_velocity, velocity_noise_model);
189 graph->
addPrior(
B(correction_count), prior_imu_bias, bias_noise_model);
193 std::shared_ptr<PreintegrationType> preintegrated =
194 std::make_shared<PreintegratedImuMeasurements>(
p, prior_imu_bias);
196 assert(preintegrated);
199 NavState prev_state(prior_pose, prior_velocity);
204 double current_position_error = 0.0, current_orientation_error = 0.0;
206 double output_time = 0.0;
211 while (
file.good()) {
213 getline(
file, value,
',');
214 int type = stoi(value.c_str());
218 for (
int i = 0;
i < 5; ++
i) {
219 getline(
file, value,
',');
220 imu(
i) = stof(value.c_str());
222 getline(
file, value,
'\n');
223 imu(5) = stof(value.c_str());
226 preintegrated->integrateMeasurement(imu.head<3>(), imu.tail<3>(), dt);
228 }
else if (type == 1) {
230 for (
int i = 0;
i < 6; ++
i) {
231 getline(
file, value,
',');
232 gps(
i) = stof(value.c_str());
234 getline(
file, value,
'\n');
235 gps(6) = stof(value.c_str());
242 ImuFactor imu_factor(
X(correction_count - 1),
V(correction_count - 1),
243 X(correction_count),
V(correction_count),
244 B(correction_count - 1), preint_imu);
245 graph->
add(imu_factor);
248 B(correction_count - 1),
B(correction_count), zero_bias,
257 graph->
add(gps_factor);
260 prop_state = preintegrated->predict(prev_state, prev_bias);
261 initial_values.
insert(
X(correction_count), prop_state.
pose());
262 initial_values.
insert(
V(correction_count), prop_state.
v());
263 initial_values.
insert(
B(correction_count), prev_bias);
268 isam2->
update(*graph, initial_values);
270 result = isam2->calculateEstimate();
274 initial_values.
clear();
287 preintegrated->resetIntegrationAndSetBias(prev_bias);
291 Vector3 position_error = gtsam_position - gps.head<3>();
292 current_position_error = position_error.norm();
298 Vector3 euler_angle_error(quat_error.
x() * 2, quat_error.
y() * 2,
300 current_orientation_error = euler_angle_error.norm();
303 cout <<
"Position error:" << current_position_error <<
"\t " 304 <<
"Angular error:" << current_orientation_error <<
"\n";
306 fprintf(fp_out,
"%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",
307 output_time, gtsam_position(0), gtsam_position(1),
308 gtsam_position(2), gtsam_quat.
x(), gtsam_quat.
y(), gtsam_quat.
z(),
309 gtsam_quat.
w(),
gps(0),
gps(1),
gps(2), gps_quat.
x(),
310 gps_quat.
y(), gps_quat.
z(), gps_quat.
w());
315 cerr <<
"ERROR parsing file\n";
320 cout <<
"Complete, results written to " << output_filename <<
"\n\n";
virtual const Values & optimize()
EIGEN_DEVICE_FUNC CoeffReturnType x() const
const Vector3 & v() const
Return velocity as Vector3. Computation-free.
Factor Graph consisting of non-linear factors.
void insert(Key j, const Value &val)
EIGEN_DEVICE_FUNC CoeffReturnType y() const
const Point3 & translation(OptionalJacobian< 3, 6 > Hself=boost::none) const
get translation
IsDerived< DERIVEDFACTOR > add(boost::shared_ptr< DERIVEDFACTOR > factor)
add is a synonym for push_back.
NonlinearFactorGraph graph
EIGEN_DEVICE_FUNC Quaternion< Scalar > inverse() const
void addPrior(Key key, const T &prior, const SharedNoiseModel &model=nullptr)
EIGEN_DEVICE_FUNC CoeffReturnType w() const
boost::shared_ptr< PreintegratedCombinedMeasurements::Params > imuParams()
EIGEN_DEVICE_FUNC CoeffReturnType z() const
string findExampleDataFile(const string &name)
const string output_filename
static Rot3 Quaternion(double w, double x, double y, double z)
Header file for GPS factor.
EIGEN_DEVICE_FUNC void normalize()
const ValueType at(Key j) const
Incremental update functionality (ISAM2) for BayesTree, with fluid relinearization.
A nonlinear optimizer that uses the Levenberg-Marquardt trust-region scheme.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
po::variables_map parseOptions(int argc, char *argv[])
static ConjugateGradientParameters parameters
RelinearizationThreshold relinearizeThreshold
static shared_ptr Sigmas(const Vector &sigmas, bool smart=true)
The quaternion class used to represent 3D orientations and rotations.
void update(Key j, const Value &val)
Jet< T, N > pow(const Jet< T, N > &f, double g)
static boost::shared_ptr< PreintegrationCombinedParams > MakeSharedD(double g=9.81)
utility functions for loading datasets
gtsam::Quaternion toQuaternion() const
const Rot3 & rotation(OptionalJacobian< 3, 6 > Hself=boost::none) const
get rotation
int main(int argc, char *argv[])
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)