shorten parameter values
parent
224af650bb
commit
937cdcf4d9
|
@ -0,0 +1,236 @@
|
|||
/**
|
||||
* @file ISAM2_SmartFactorStereo_IMU.cpp
|
||||
* @brief test of iSAM2 with smart stereo factors and IMU preintegration,
|
||||
* originally used to debug valgrind invalid reads with Eigen
|
||||
* @author Nghia Ho
|
||||
*
|
||||
* Setup is a stationary stereo camera with an IMU attached.
|
||||
* The data file is at examples/Data/ISAM2_SmartFactorStereo_IMU.txt
|
||||
* It contains 5 frames of stereo matches and IMU data.
|
||||
*/
|
||||
#include <gtsam/navigation/CombinedImuFactor.h>
|
||||
#include <gtsam/nonlinear/ISAM2.h>
|
||||
#include <gtsam_unstable/slam/SmartStereoProjectionPoseFactor.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
using symbol_shorthand::X;
|
||||
using symbol_shorthand::V;
|
||||
using symbol_shorthand::B;
|
||||
|
||||
struct IMUHelper {
|
||||
IMUHelper() {
|
||||
{
|
||||
auto gaussian = noiseModel::Diagonal::Sigmas(
|
||||
(Vector(6) << Vector3::Constant(5.0e-2), Vector3::Constant(5.0e-3))
|
||||
.finished());
|
||||
|
||||
auto huber = noiseModel::Robust::Create(
|
||||
noiseModel::mEstimator::Huber::Create(1.345), gaussian);
|
||||
|
||||
biasNoiseModel = huber;
|
||||
}
|
||||
|
||||
{
|
||||
auto gaussian = noiseModel::Isotropic::Sigma(3, 0.01);
|
||||
auto huber = noiseModel::Robust::Create(
|
||||
noiseModel::mEstimator::Huber::Create(1.345), gaussian);
|
||||
|
||||
velocityNoiseModel = huber;
|
||||
}
|
||||
|
||||
// expect IMU to be rotated in image space co-ords
|
||||
auto p = boost::make_shared<PreintegratedCombinedMeasurements::Params>(
|
||||
Vector3(0.0, 9.8, 0.0));
|
||||
|
||||
p->accelerometerCovariance =
|
||||
I_3x3 * pow(0.0565, 2.0); // acc white noise in continuous
|
||||
p->integrationCovariance =
|
||||
I_3x3 * 1e-9; // integration uncertainty continuous
|
||||
p->gyroscopeCovariance =
|
||||
I_3x3 * pow(4.0e-5, 2.0); // gyro white noise in continuous
|
||||
p->biasAccCovariance = I_3x3 * pow(0.00002, 2.0); // acc bias in continuous
|
||||
p->biasOmegaCovariance =
|
||||
I_3x3 * pow(0.001, 2.0); // gyro bias in continuous
|
||||
p->biasAccOmegaInt = Matrix::Identity(6, 6) * 1e-5;
|
||||
|
||||
// body to IMU rotation
|
||||
Rot3 iRb(
|
||||
0.036129, -0.998727, 0.035207,
|
||||
0.045417, -0.033553, -0.99840,4
|
||||
0.998315, 0.037670, 0.044147);
|
||||
|
||||
// body to IMU translation (meters)
|
||||
Point3 iTb(0.03, -0.025, -0.06);
|
||||
|
||||
// body in this example is the left camera
|
||||
p->body_P_sensor = Pose3(iRb, iTb);
|
||||
|
||||
Rot3 prior_rotation = Rot3(I_3x3);
|
||||
Pose3 prior_pose(prior_rotation, Point3(0, 0, 0));
|
||||
|
||||
Vector3 acc_bias(0.0, -0.0942015, 0.0); // in camera frame
|
||||
Vector3 gyro_bias(-0.00527483, -0.00757152, -0.00469968);
|
||||
|
||||
priorImuBias = imuBias::ConstantBias(acc_bias, gyro_bias);
|
||||
|
||||
prevState = NavState(prior_pose, Vector3(0, 0, 0));
|
||||
propState = prevState;
|
||||
prevBias = priorImuBias;
|
||||
|
||||
preintegrated = new PreintegratedCombinedMeasurements(p, priorImuBias);
|
||||
}
|
||||
|
||||
imuBias::ConstantBias priorImuBias; // assume zero initial bias
|
||||
noiseModel::Robust::shared_ptr velocityNoiseModel;
|
||||
noiseModel::Robust::shared_ptr biasNoiseModel;
|
||||
NavState prevState;
|
||||
NavState propState;
|
||||
imuBias::ConstantBias prevBias;
|
||||
PreintegratedCombinedMeasurements* preintegrated;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "./main [data.txt]\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
ifstream in(argv[1]);
|
||||
|
||||
if (!in) {
|
||||
cerr << "error opening: " << argv[1] << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Camera parameters
|
||||
double fx = 822.37;
|
||||
double fy = 822.37;
|
||||
double cx = 538.73;
|
||||
double cy = 579.10;
|
||||
double baseline = 0.372; // meters
|
||||
|
||||
Cal3_S2Stereo::shared_ptr K(new Cal3_S2Stereo(fx, fy, 0.0, cx, cy, baseline));
|
||||
|
||||
ISAM2Params parameters;
|
||||
parameters.relinearizeThreshold = 0.1;
|
||||
ISAM2 isam(parameters);
|
||||
|
||||
// Create a factor graph
|
||||
std::map<size_t, SmartStereoProjectionPoseFactor::shared_ptr> smartFactors;
|
||||
NonlinearFactorGraph graph;
|
||||
Values initialEstimate;
|
||||
IMUHelper imu;
|
||||
|
||||
// Pose prior - at identity
|
||||
auto priorPoseNoise = noiseModel::Diagonal::Sigmas(
|
||||
(Vector(6) << Vector3::Constant(0.1), Vector3::Constant(0.1)).finished());
|
||||
graph.emplace_shared<PriorFactor<Pose3>>(X(1), Pose3::identity(),
|
||||
priorPoseNoise);
|
||||
initialEstimate.insert(X(0), Pose3::identity());
|
||||
|
||||
// Bias prior
|
||||
graph.add(PriorFactor<imuBias::ConstantBias>(B(1), imu.priorImuBias,
|
||||
imu.biasNoiseModel));
|
||||
initialEstimate.insert(B(0), imu.priorImuBias);
|
||||
|
||||
// Velocity prior - assume stationary
|
||||
graph.add(
|
||||
PriorFactor<Vector3>(V(1), Vector3(0, 0, 0), imu.velocityNoiseModel));
|
||||
initialEstimate.insert(V(0), Vector3(0, 0, 0));
|
||||
|
||||
int lastFrame = 1;
|
||||
int frame;
|
||||
|
||||
while (true) {
|
||||
char line[1024];
|
||||
|
||||
in.getline(line, sizeof(line));
|
||||
stringstream ss(line);
|
||||
char type;
|
||||
|
||||
ss >> type;
|
||||
ss >> frame;
|
||||
|
||||
if (frame != lastFrame || in.eof()) {
|
||||
cout << "Running iSAM for frame: " << lastFrame << "\n";
|
||||
|
||||
initialEstimate.insert(X(lastFrame), Pose3::identity());
|
||||
initialEstimate.insert(V(lastFrame), Vector3(0, 0, 0));
|
||||
initialEstimate.insert(B(lastFrame), imu.prevBias);
|
||||
|
||||
CombinedImuFactor imuFactor(X(lastFrame - 1), V(lastFrame - 1),
|
||||
X(lastFrame), V(lastFrame), B(lastFrame - 1),
|
||||
B(lastFrame), *imu.preintegrated);
|
||||
|
||||
graph.add(imuFactor);
|
||||
|
||||
isam.update(graph, initialEstimate);
|
||||
|
||||
Values currentEstimate = isam.calculateEstimate();
|
||||
|
||||
imu.propState = imu.preintegrated->predict(imu.prevState, imu.prevBias);
|
||||
imu.prevState = NavState(currentEstimate.at<Pose3>(X(lastFrame)),
|
||||
currentEstimate.at<Vector3>(V(lastFrame)));
|
||||
imu.prevBias = currentEstimate.at<imuBias::ConstantBias>(B(lastFrame));
|
||||
imu.preintegrated->resetIntegrationAndSetBias(imu.prevBias);
|
||||
|
||||
graph.resize(0);
|
||||
initialEstimate.clear();
|
||||
|
||||
if (in.eof()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 'i') { // Process IMU measurement
|
||||
double ax, ay, az;
|
||||
double gx, gy, gz;
|
||||
double dt = 1 / 800.0; // IMU at ~800Hz
|
||||
|
||||
ss >> ax;
|
||||
ss >> ay;
|
||||
ss >> az;
|
||||
|
||||
ss >> gx;
|
||||
ss >> gy;
|
||||
ss >> gz;
|
||||
|
||||
Vector3 acc(ax, ay, az);
|
||||
Vector3 gyr(gx, gy, gz);
|
||||
|
||||
imu.preintegrated->integrateMeasurement(acc, gyr, dt);
|
||||
} else if (type == 's') { // Process stereo measurement
|
||||
int landmark;
|
||||
double xl, xr, y;
|
||||
|
||||
ss >> landmark;
|
||||
ss >> xl;
|
||||
ss >> xr;
|
||||
ss >> y;
|
||||
|
||||
if (smartFactors.count(landmark) == 0) {
|
||||
auto gaussian = noiseModel::Isotropic::Sigma(3, 1.0);
|
||||
|
||||
SmartProjectionParams params(HESSIAN, ZERO_ON_DEGENERACY);
|
||||
|
||||
smartFactors[landmark] = SmartStereoProjectionPoseFactor::shared_ptr(
|
||||
new SmartStereoProjectionPoseFactor(gaussian, params));
|
||||
graph.push_back(smartFactors[landmark]);
|
||||
}
|
||||
|
||||
smartFactors[landmark]->add(StereoPoint2(xl, xr, y), X(frame), K);
|
||||
} else {
|
||||
throw runtime_error("unexpected data type: " + type);
|
||||
}
|
||||
|
||||
lastFrame = frame;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,222 +0,0 @@
|
|||
#include <gtsam/nonlinear/ISAM2.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
#include <gtsam_unstable/slam/SmartStereoProjectionPoseFactor.h>
|
||||
#include <gtsam/navigation/CombinedImuFactor.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
using symbol_shorthand::X;
|
||||
using symbol_shorthand::V;
|
||||
using symbol_shorthand::B;
|
||||
|
||||
struct IMUHelper
|
||||
{
|
||||
IMUHelper()
|
||||
{
|
||||
gtsam::Matrix33 measured_acc_cov = gtsam::Matrix33::Identity(3,3) * pow(0.113, 2.0);
|
||||
gtsam::Matrix33 measured_omega_cov = gtsam::Matrix33::Identity(3,3) * pow(4.0e-5, 2.0);
|
||||
gtsam::Matrix33 bias_acc_cov = gtsam::Matrix33::Identity(3,3) * pow( 0.00002, 2.0);
|
||||
gtsam::Matrix33 bias_omega_cov = gtsam::Matrix33::Identity(3,3) * pow(0.001, 2.0);
|
||||
gtsam::Matrix33 integration_error_cov = gtsam::Matrix33::Identity(3,3)*1e-9; // error committed in integrating position from velocities
|
||||
gtsam::Matrix bias_acc_omega_int = gtsam::Matrix::Identity(6,6)*1e-5; // error in the bias used for preintegration
|
||||
|
||||
{
|
||||
auto gaussian = gtsam::noiseModel::Diagonal::Sigmas(
|
||||
(gtsam::Vector(6) <<
|
||||
gtsam::Vector3::Constant(5.0e-2),
|
||||
gtsam::Vector3::Constant(5.0e-3)).finished());
|
||||
|
||||
auto huber = gtsam::noiseModel::Robust::Create(gtsam::noiseModel::mEstimator::Huber::Create(1.345), gaussian);
|
||||
|
||||
bias_noise_model = huber;
|
||||
}
|
||||
|
||||
{
|
||||
auto gaussian = gtsam::noiseModel::Isotropic::Sigma(3,0.01);
|
||||
auto huber = gtsam::noiseModel::Robust::Create(gtsam::noiseModel::mEstimator::Huber::Create(1.345), gaussian);
|
||||
|
||||
velocity_noise_model = huber;
|
||||
}
|
||||
|
||||
// expect IMU to be rotated in image space co-ords
|
||||
auto p = boost::make_shared<gtsam::PreintegratedCombinedMeasurements::Params>(gtsam::Vector3(0.0, 9.8, 0.0));
|
||||
|
||||
p->accelerometerCovariance = measured_acc_cov; // acc white noise in continuous
|
||||
p->integrationCovariance = integration_error_cov; // integration uncertainty continuous
|
||||
p->gyroscopeCovariance = measured_omega_cov; // gyro white noise in continuous
|
||||
p->biasAccCovariance = bias_acc_cov; // acc bias in continuous
|
||||
p->biasOmegaCovariance = bias_omega_cov; // gyro bias in continuous
|
||||
p->biasAccOmegaInt = bias_acc_omega_int;
|
||||
|
||||
// from SVD comparing gyro and vision estimates, no bias modelled
|
||||
gtsam::Rot3 body_to_imu_rot(
|
||||
3.612861008216737e-02, -9.987267865568920e-01, 3.520695026944293e-02,
|
||||
4.541686330383411e-02, -3.355264881270600e-02, -9.984044913186698e-01,
|
||||
9.983145957368207e-01, 3.766995581886975e-02, 4.414682737675374e-02);
|
||||
|
||||
gtsam::Point3 body_to_imu_trans(0.03, -0.025, -0.06);
|
||||
|
||||
p->body_P_sensor = gtsam::Pose3(body_to_imu_rot, body_to_imu_trans);
|
||||
|
||||
gtsam::Rot3 prior_rotation = gtsam::Rot3(gtsam::Matrix33::Identity());
|
||||
gtsam::Pose3 prior_pose(prior_rotation, gtsam::Point3(0,0,0));
|
||||
|
||||
gtsam::Vector3 acc_bias(2.05998e-18, -0.0942015, 1.17663e-16);
|
||||
gtsam::Vector3 gyro_bias(0,0,0);
|
||||
|
||||
prior_imu_bias = gtsam::imuBias::ConstantBias(acc_bias, gyro_bias);
|
||||
|
||||
prev_state = gtsam::NavState(prior_pose, gtsam::Vector3(0,0,0));
|
||||
prop_state = prev_state;
|
||||
prev_bias = prior_imu_bias;
|
||||
|
||||
preintegrated = new gtsam::PreintegratedCombinedMeasurements(p, prior_imu_bias);
|
||||
}
|
||||
|
||||
gtsam::imuBias::ConstantBias prior_imu_bias; // assume zero initial bias
|
||||
gtsam::noiseModel::Robust::shared_ptr velocity_noise_model;
|
||||
gtsam::noiseModel::Robust::shared_ptr bias_noise_model;
|
||||
gtsam::NavState prev_state;
|
||||
gtsam::NavState prop_state;
|
||||
gtsam::imuBias::ConstantBias prev_bias;
|
||||
gtsam::PreintegratedCombinedMeasurements *preintegrated;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "./main [data.txt]\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
double fx = 8.2237229542137766e+02;
|
||||
double fy = fx;
|
||||
double cx = 5.3872524261474609e+02;
|
||||
double cy = 5.7909587860107422e+02;
|
||||
double baseline = 7.4342307430851651e-01;
|
||||
|
||||
Cal3_S2Stereo::shared_ptr K(new Cal3_S2Stereo(fx, fy, 0.0, cx, cy, baseline));
|
||||
|
||||
ISAM2Params parameters;
|
||||
parameters.relinearizeThreshold = 0.1;
|
||||
ISAM2 isam(parameters);
|
||||
|
||||
// Create a factor graph
|
||||
std::map<size_t, gtsam::SmartStereoProjectionPoseFactor::shared_ptr> smartFactors;
|
||||
NonlinearFactorGraph graph;
|
||||
Values initialEstimate;
|
||||
IMUHelper imu;
|
||||
|
||||
// Pose prior
|
||||
auto priorPoseNoise = noiseModel::Diagonal::Sigmas((Vector(6) << Vector3::Constant(0.1), Vector3::Constant(0.1)).finished());
|
||||
graph.emplace_shared<PriorFactor<Pose3>>(X(1), Pose3::identity(), priorPoseNoise);
|
||||
initialEstimate.insert(X(0), Pose3::identity());
|
||||
|
||||
// Bias prior
|
||||
graph.add(PriorFactor<imuBias::ConstantBias>(B(1), imu.prior_imu_bias, imu.bias_noise_model));
|
||||
initialEstimate.insert(B(0), imu.prior_imu_bias);
|
||||
|
||||
// Velocity prior
|
||||
graph.add(PriorFactor<Vector3>(V(1), Vector3(0,0,0), imu.velocity_noise_model));
|
||||
initialEstimate.insert(V(0), Vector3(0,0,0));
|
||||
|
||||
ifstream in(argv[1]);
|
||||
|
||||
if (!in) {
|
||||
cerr << "error opening: " << argv[1] << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int last_frame = 1;
|
||||
int frame;
|
||||
|
||||
while (true) {
|
||||
char line[1024];
|
||||
|
||||
in.getline(line, sizeof(line));
|
||||
stringstream ss(line);
|
||||
char type;
|
||||
|
||||
ss >> type;
|
||||
ss >> frame;
|
||||
|
||||
if (frame != last_frame || in.eof()) {
|
||||
cout << "Running isam for frame: " << last_frame << "\n";
|
||||
|
||||
initialEstimate.insert(X(last_frame), Pose3::identity());
|
||||
initialEstimate.insert(V(last_frame), Vector3(0,0,0));
|
||||
initialEstimate.insert(B(last_frame), imu.prev_bias);
|
||||
|
||||
CombinedImuFactor imu_factor(
|
||||
X(last_frame-1), V(last_frame-1),
|
||||
X(last_frame), V(last_frame),
|
||||
B(last_frame-1), B(last_frame),
|
||||
*imu.preintegrated);
|
||||
|
||||
graph.add(imu_factor);
|
||||
|
||||
isam.update(graph, initialEstimate);
|
||||
|
||||
Values currentEstimate = isam.calculateEstimate();
|
||||
//currentEstimate.print("Current estimate: ");
|
||||
|
||||
imu.prop_state = imu.preintegrated->predict(imu.prev_state, imu.prev_bias);
|
||||
imu.prev_state = NavState(currentEstimate.at<Pose3>(X(last_frame)), currentEstimate.at<Vector3>(V(last_frame)));
|
||||
imu.prev_bias = currentEstimate.at<imuBias::ConstantBias>(B(last_frame));
|
||||
imu.preintegrated->resetIntegrationAndSetBias(imu.prev_bias);
|
||||
|
||||
graph.resize(0);
|
||||
initialEstimate.clear();
|
||||
|
||||
if (in.eof()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 'i') {
|
||||
double ax, ay, az;
|
||||
double gx, gy, gz;
|
||||
double dt = 1/800.0;
|
||||
|
||||
ss >> ax;
|
||||
ss >> ay;
|
||||
ss >> az;
|
||||
|
||||
ss >> gx;
|
||||
ss >> gy;
|
||||
ss >> gz;
|
||||
|
||||
Vector3 acc(ax, ay, az);
|
||||
Vector3 gyr(gx, gy, gz);
|
||||
|
||||
imu.preintegrated->integrateMeasurement(acc, gyr, dt);
|
||||
} else if (type == 's') {
|
||||
int landmark;
|
||||
double xl, xr, y;
|
||||
|
||||
ss >> landmark;
|
||||
ss >> xl;
|
||||
ss >> xr;
|
||||
ss >> y;
|
||||
|
||||
if (smartFactors.count(landmark) == 0) {
|
||||
auto gaussian = noiseModel::Isotropic::Sigma(3, 1.0);
|
||||
|
||||
SmartProjectionParams params(HESSIAN, ZERO_ON_DEGENERACY);
|
||||
|
||||
smartFactors[landmark] = SmartStereoProjectionPoseFactor::shared_ptr(new SmartStereoProjectionPoseFactor(gaussian, params));
|
||||
graph.push_back(smartFactors[landmark]);
|
||||
}
|
||||
|
||||
smartFactors[landmark]->add(StereoPoint2(xl, xr, y), X(frame), K);
|
||||
}
|
||||
|
||||
last_frame = frame;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue