36void HolisticFusion::setup(
const std::shared_ptr<GraphConfig> graphConfigPtr,
const std::shared_ptr<StaticTransforms> staticTransformsPtr) {
40 if (graphConfigPtr ==
nullptr || staticTransformsPtr ==
nullptr) {
41 throw std::runtime_error(
"setup() of inheriting classes did not has not been called before.");
49 throw std::logic_error(
"HolisticFusion: initialization_params.static_at_startup=false: in-motion initialization is not implemented.");
53 throw std::invalid_argument(
"HolisticFusion: additionalOptimizationIterations must be nonnegative.");
56 throw std::invalid_argument(
"HolisticFusion: createStateEveryNthImuMeasurement must be positive.");
64 std::cout <<
"HolisticFusion: Creating GraphManager." << std::endl;
67 std::cout <<
"HolisticFusion: GraphManager created." << std::endl;
71 REGULAR_COUT <<
" Initialized thread for optimizing the graph in parallel." << std::endl;
110 const std::string& frame1,
const std::string& frame2) {
124 const gtsam::Rot3 yawR_W_frame1 = gtsam::Rot3::Yaw(yaw_fixedFrame_frame1);
127 const double yaw_W_I0_ =
137 Eigen::Vector3d W_t_W_I0 =
148 REGULAR_COUT <<
GREEN_START <<
" Initial global yaw of from world frame to imu frame has been set to (deg) " << 180.0 * yaw_W_I0_ / M_PI
150 REGULAR_COUT <<
GREEN_START <<
" Initial global position of imu frame in world frame has been set to (m) " << W_t_W_I0.transpose()
155 REGULAR_COUT <<
GREEN_START <<
" Initial global yaw of from odom frame to imu frame has been set to (deg) " << 180.0 * yaw_O_I0 / M_PI
183 const Eigen::Vector3d& linearAcc,
const Eigen::Vector3d& angularVel,
double imuTimeK,
184 std::shared_ptr<SafeIntegratedNavState>& returnPreIntegratedNavStatePtr,
185 std::shared_ptr<SafeNavStateWithCovarianceAndBias>& returnOptimizedStateWithCovarianceAndBiasPtr,
186 Eigen::Matrix<double, 6, 1>& returnAddedImuMeasurements) {
207 Eigen::Vector3d linearAccInMps2 = linearAcc;
209 constexpr double gravityConst = 9.80665;
210 linearAccInMps2 *= gravityConst;
214 const double accNorm = linearAccInMps2.norm();
218 }
else if (accNorm > 90) {
237 returnAddedImuMeasurements =
coreImuBufferPtr_->addToImuBuffer(imuTimeK, linearAccInMps2, angularVel);
245 double imuAttitudeRoll, imuAttitudePitch = 0.0;
246 if (!
alignImu_(imuAttitudeRoll, imuAttitudePitch)) {
249 REGULAR_COUT <<
" NOT ENOUGH IMU MESSAGES TO INITIALIZE POSE. WAITING FOR MORE..." << std::endl;
253 Eigen::Matrix3d R_W_I0_attitude = gtsam::Rot3::Ypr(0.0, imuAttitudePitch, imuAttitudeRoll).matrix();
254 gtsam::Rot3 R_W_Init0_attitude(
261 R_W_Init0_attitude = gtsam::Rot3::Ypr(0.0, R_W_Init0_attitude.pitch(), R_W_Init0_attitude.roll());
263 R_W_Init0_attitude.matrix() *
267 Eigen::Isometry3d T_O_Ik_attitude = Eigen::Isometry3d::Identity();
268 T_O_Ik_attitude.matrix().block<3, 3>(0, 0) = R_W_I0_attitude;
269 Eigen::Vector3d O_t_O_Ik =
270 Eigen::Vector3d(0, 0, 0) -
274 T_O_Ik_attitude.matrix().block<3, 1>(0, 3) = O_t_O_Ik;
276 <<
", hence iniital position of IMU is: " << O_t_O_Ik.transpose() << std::endl;
277 Eigen::Vector3d zeroPVeloctiy = Eigen::Vector3d(0, 0, 0);
278 preIntegratedNavStatePtr_ = std::make_shared<SafeIntegratedNavState>(T_O_Ik_attitude, zeroPVeloctiy, zeroPVeloctiy, imuTimeK);
288 REGULAR_COUT <<
" IMU callback waiting for initialization of global yaw and initial position." << std::endl;
304 initGraph_(imuTimeK, returnAddedImuMeasurements.tail<3>());
315 imuTimeK, createNewStateFlag);
329 static_cast<void>(
graphMgrPtr_->addPoseBetweenFactor(gtsam::Pose3::Identity(), noiseDensity * Eigen::Matrix<double, 6, 1>::Ones(),
331 graphMgrPtr_->addUnaryClassicFactor<gtsam::Vector3, 3, gtsam::PriorFactor<gtsam::Vector3>, gtsam::symbol_shorthand::V>(
332 gtsam::Vector3::Zero(), noiseDensity * Eigen::Matrix<double, 3, 1>::Ones(), timeK);
348 gtsam::Rot3 R_W_I_rollPitch;
349 static int alignImuCounter__ = -1;
351 double estimatedGravityMagnitude;
353 imuAttitudeRoll = R_W_I_rollPitch.roll();
354 imuAttitudePitch = R_W_I_rollPitch.pitch();
357 REGULAR_COUT <<
" Attitude of IMU is initialized. Determined Gravity Magnitude: " << estimatedGravityMagnitude << std::endl;
359 REGULAR_COUT <<
" Estimated gravity magnitude from IMU is: " << estimatedGravityMagnitude << std::endl;
360 REGULAR_COUT <<
" This gravity is not used, because estimateGravityFromImu is set to false. Gravity set to "
362 gtsam::Vector3 gravityVector = gtsam::Vector3(0, 0,
graphConfigPtr_->gravityMagnitude_);
363 gtsam::Vector3 estimatedGravityVector = gtsam::Vector3(0, 0, estimatedGravityMagnitude);
364 gtsam::Vector3 gravityVectorError = estimatedGravityVector - gravityVector;
365 gtsam::Vector3 gravityVectorErrorInImuFrame = R_W_I_rollPitch.inverse().rotate(gravityVectorError);
366 graphMgrPtr_->getInitAccBiasReference() = gravityVectorErrorInImuFrame;
367 std::cout <<
YELLOW_START <<
"GMsf" <<
COLOR_END <<
" Gravity error in IMU frame is: " << gravityVectorErrorInImuFrame.transpose()
382 REGULAR_COUT <<
GREEN_START <<
" Total initial IMU attitude is RPY (deg): " << T_W_I0.rotation().rpy().transpose() * (180.0 / M_PI)
389 graphMgrPtr_->initPoseVelocityBiasGraph(timeStamp_k, T_W_I0, T_O_I0, imuAngularVelocity);
392 gtsam::Pose3 T_W_I0_opt =
graphMgrPtr_->getOptimizedGraphState().navState().pose();
394 <<
" INITIAL POSE of IMU in world frame after first optimization, x,y,z (m): " << T_W_I0_opt.translation().transpose()
395 <<
", RPY (deg): " << T_W_I0_opt.rotation().rpy().transpose() * (180.0 / M_PI) <<
COLOR_END << std::endl;
406 REGULAR_COUT <<
" Thread for updating graph is ready." << std::endl;
407 double lastOptimizedTime = std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count();
408 double currentTime = std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count();
409 bool optimizedAtLeastOnce =
false;
411 bool optimizeGraphFlag =
false;
416 currentTime = std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count();
419 ((currentTime - lastOptimizedTime) > (1.0 /
graphConfigPtr_->minOptimizationFrequency_) && optimizedAtLeastOnce)) {
420 optimizeGraphFlag =
true;
421 lastOptimizedTime = currentTime;
422 optimizedAtLeastOnce =
true;
428 if (optimizeGraphFlag) {
432 std::this_thread::sleep_for(std::chrono::milliseconds(1));
439 const std::string& frame2,
const Eigen::Matrix3d& R_W_frame2) {
441 const Eigen::Isometry3d& T_frame2_frame1 =
staticTransformsPtr_->rv_T_frame1_frame2(frame2, frame1);
442 const Eigen::Vector3d& frame1_t_frame1_frame2 =
staticTransformsPtr_->rv_T_frame1_frame2(frame1, frame2).translation();
445 Eigen::Matrix3d R_W_frame1 = R_W_frame2 * T_frame2_frame1.rotation();
448 Eigen::Vector3d W_t_frame1_frame2 = R_W_frame1 * frame1_t_frame1_frame2;
451 return W_t_W_frame1 + W_t_frame1_frame2;
bool addCoreImuMeasurementAndGetState(const Eigen::Vector3d &linearAcc, const Eigen::Vector3d &angularVel, const double imuTimeK, std::shared_ptr< SafeIntegratedNavState > &returnPreIntegratedNavStatePtr, std::shared_ptr< SafeNavStateWithCovarianceAndBias > &returnOptimizedStateWithCovarianceAndBiasPtr, Eigen::Matrix< double, 6, 1 > &returnAddedImuMeasurements)
Main: IMU --------------------—.