17 <<
" Waiting for setup() with graphConfiguration and staticTransforms." << std::endl;
19 globalGraphKeysTimestampsMapBufferPtr_ = std::make_shared<std::map<gtsam::Key, double>>();
20 fallbackGraphKeysTimestampsMapBufferPtr_ = std::make_shared<std::map<gtsam::Key, double>>();
24 activeSmootherPtr_ = globalSmootherPtr_;
25 activeFactorsBufferPtr_ = globalFactorsBufferPtr_;
26 activeImuBufferPreintegratorPtr_ = globalImuBufferPreintegratorPtr_;
27 activeGraphValuesBufferPtr_ = globalGraphValuesBufferPtr_;
28 activeGraphKeysTimestampsMapBufferPtr_ = globalGraphKeysTimestampsMapBufferPtr_;
31std::shared_ptr<SafeNavState> HolisticFusion::addDualOdometryMeasurementAndReturnNavState(
const UnaryMeasurement6D& odometryKm1,
32 const UnaryMeasurement6D& odometryK,
33 const Eigen::Matrix<double, 6, 1>& poseBetweenNoise) {
35 const Eigen::Isometry3d T_M_Lj = odometryK.measurementPose();
38 if (!validFirstMeasurementReceivedFlag_) {
39 Eigen::Isometry3d T_M_Ij =
40 Eigen::Isometry3d(T_M_Lj) * staticTransformsPtr_->rv_T_frame1_frame2(odometryK.frameName(), staticTransformsPtr_->getImuFrame());
41 preIntegratedNavStatePtr_->updatePoseInMap(T_M_Ij);
43 validFirstMeasurementReceivedFlag_ =
true;
47 if (!initedGraphFlag_) {
52 const Eigen::Isometry3d T_Lkm1_Lk(odometryKm1.measurementPose().inverse() * odometryK.measurementPose());
53 const Eigen::Isometry3d T_Ikm1_Ik =
54 staticTransformsPtr_->rv_T_frame1_frame2(staticTransformsPtr_->getImuFrame(), odometryKm1.frameName()) * T_Lkm1_Lk *
55 staticTransformsPtr_->rv_T_frame1_frame2(odometryK.frameName(), staticTransformsPtr_->getImuFrame());
56 const gtsam::Key keyAtMeasurementK =
57 graphMgrPtr_->addPoseBetweenFactorToGlobalGraph(odometryKm1.timeK(), odometryK.timeK(), odometryK.measurementRate(), poseBetweenNoise,
58 gtsam::Pose3(T_Ikm1_Ik.matrix()), odometryK.measurementName());
63 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
64 optimizeGraphFlag_ =
true;
69 if (graphMgrPtr_->globalGraphActiveFlag()) {
71 bool computeSuccessfulFlag =
false;
72 Eigen::Isometry3d T_W_Ij_Graph(graphMgrPtr_->calculateActiveStateAtKey(computeSuccessfulFlag, keyAtMeasurementK).pose().matrix());
73 if (computeSuccessfulFlag) {
74 Eigen::Isometry3d T_M_Ij =
75 Eigen::Isometry3d(T_M_Lj) * staticTransformsPtr_->rv_T_frame1_frame2(odometryK.frameName(), staticTransformsPtr_->getImuFrame());
76 preIntegratedNavStatePtr_->updateWorldToMap(T_W_Ij_Graph * T_M_Ij.inverse());
78 }
else if (graphMgrPtr_->fallbackGraphActiveFlag()) {
80 gtsam::Pose3 pseudo_T_W_Ik(
81 preIntegratedNavStatePtr_->getT_W_M() * T_M_Lj *
82 staticTransformsPtr_->rv_T_frame1_frame2(odometryK.frameName(), staticTransformsPtr_->getImuFrame()).matrix());
83 graphMgrPtr_->addPoseUnaryFactorToFallbackGraph(odometryK.timeK(), odometryK.measurementRate(), odometryK.measurementNoise(),
90 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
91 optimizeGraphFlag_ =
true;
94 return std::make_shared<SafeNavState>(*preIntegratedNavStatePtr_);
98void HolisticFusion::addDualGnssPositionMeasurement(
const UnaryMeasurement3D& W_t_W_frame,
const Eigen::Vector3d& W_t_W_frame_km1,
99 const Eigen::Vector3d& gnssCovarianceXYZ,
const bool attemptGraphSwitching,
100 const bool addedYawBefore) {
102 bool gnssCovarianceViolatedFlagThisTimestep = isGnssCovarianceViolated_(gnssCovarianceXYZ);
104 if (gnssCovarianceViolatedFlagThisTimestep) {
106 if (!gnssCovarianceViolatedFlag_) {
111 gnssCovarianceViolatedFlag_ =
true;
112 gnssNotJumpingCounter_ = 0;
115 if (!validFirstMeasurementReceivedFlag_) {
116 validFirstMeasurementReceivedFlag_ =
true;
119 if (gnssCovarianceViolatedFlag_) {
124 gnssCovarianceViolatedFlag_ =
false;
128 if (!initedGraphFlag_) {
133 if (!gnssCovarianceViolatedFlag_ &&
134 (W_t_W_frame_km1 - W_t_W_frame.measurementVector()).norm() < graphConfigPtr_->poseMotionOutlierThresold) {
135 ++gnssNotJumpingCounter_;
140 }
else if ((W_t_W_frame_km1 - W_t_W_frame.measurementVector()).norm() >= graphConfigPtr_->poseMotionOutlierThresold) {
142 std::cout <<
YELLOW_START <<
"GMsf" <<
RED_START <<
" Gnss was jumping more than the allowed distance of "
143 << graphConfigPtr_->poseMotionOutlierThresold <<
"m. Reset outlier counter." <<
COLOR_END << std::endl;
145 gnssNotJumpingCounter_ = 0;
149 if (!gnssCovarianceViolatedFlag_) {
150 gtsam::Rot3 R_W_I_meas(preIntegratedNavStatePtr_->getT_W_Ik().rotation());
151 Eigen::Vector3d W_T_W_I = W_t_W_frame.measurementVector();
153 if (addedYawBefore) {
154 R_W_I_meas = gtsam::Rot3::Ypr(lastGnssYaw_W_I_, R_W_I_meas.pitch(), R_W_I_meas.roll());
155 W_T_W_I = W_t_W_Frame1_to_W_t_W_Frame2_(W_T_W_I, W_t_W_frame.frameName(), staticTransformsPtr_->getImuFrame(), R_W_I_meas.matrix());
160 graphMgrPtr_->activateGlobalGraph(W_T_W_I, R_W_I_meas, W_t_W_frame.timeK());
164 addGnssPositionMeasurement(W_t_W_frame);
166 }
else if (graphConfigPtr_->usingFallbackGraphFlag) {
168 graphMgrPtr_->activateFallbackGraph();
172void GraphManager::activateGlobalGraph(
const gtsam::Vector3& imuPosition,
const gtsam::Rot3& imuRotation,
const double measurementTime) {
174 const std::lock_guard<std::mutex> swappingActiveGraphLock(swappingActiveGraphMutex_);
175 if (activeSmootherPtr_ != globalSmootherPtr_) {
177 int smootherNumberStates = int(graphConfigPtr_->smootherLag * graphConfigPtr_->imuRate);
178 gtsam::NonlinearFactorGraph globalFactorsBuffer;
179 gtsam::Values globalGraphValues;
180 std::map<gtsam::Key, double> globalGraphKeysTimestampsMap;
181 bool optimizeGraphFlag =
false;
182 gtsam::Key currentPropagatedKey;
183 double currentPropagatedTime;
187 const std::lock_guard<std::mutex> operateOnGraphDataLock(operateOnGraphDataMutex_);
188 currentPropagatedKey = propagatedStateKey_;
189 currentPropagatedTime = propagatedImuSampleTime_;
190 int lastKeyInSmoother = (--globalSmootherPtr_->timestamps().end())->first;
192 std::cout <<
YELLOW_START <<
"GMsf-GraphManager" <<
GREEN_START <<
" Last Key in Smoother is: " << lastKeyInSmoother
193 <<
", current key is: " << currentPropagatedKey <<
COLOR_END << std::endl;
194 if (lastKeyInSmoother < (
int(currentPropagatedKey) - smootherNumberStates)) {
195 optimizeGraphFlag =
true;
198 <<
" Hence, previous global graph is too old --> previously optimized graph can not be used --> shrinking and re-optimizing..."
202 globalFactorsBuffer = *globalFactorsBufferPtr_;
203 globalGraphValues = *globalGraphValuesBufferPtr_;
204 globalGraphKeysTimestampsMap = *globalGraphKeysTimestampsMapBufferPtr_;
205 globalFactorsBufferPtr_->resize(0);
206 globalGraphValuesBufferPtr_->clear();
207 globalGraphKeysTimestampsMapBufferPtr_->clear();
208 if (graphConfigPtr_->usingBiasForPreIntegrationFlag) {
209 globalImuBufferPreintegratorPtr_->resetIntegrationAndSetBias(optimizedGraphState_.imuBias());
211 globalImuBufferPreintegratorPtr_->resetIntegrationAndSetBias(gtsam::imuBias::ConstantBias());
219 if (optimizeGraphFlag) {
221 double closestGraphTimeToGnssMeasurement;
222 gtsam::Key closestKeyToGnssMeasurement;
223 timeToKeyBuffer_.getClosestKeyAndTimestamp(closestGraphTimeToGnssMeasurement, closestKeyToGnssMeasurement,
"GnssUnary",
224 graphConfigPtr_->maxSearchDeviation, measurementTime);
228 std::cout <<
YELLOW_START <<
"GMsf-GraphManager" <<
GREEN_START <<
" Adding prior factor for GNSS key " << closestKeyToGnssMeasurement
234 gtsam::Pose3 providedPose(globalGraphValues.at<gtsam::Pose3>(gtsam::symbol_shorthand::X(currentPropagatedKey)).rotation(),
237 gtsam::PriorFactor<gtsam::Pose3> posePrior(
238 gtsam::symbol_shorthand::X(closestKeyToGnssMeasurement), providedPose,
239 gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-05, 1e-05, 1e-02, 1e02, 1e02, 1e02).finished()));
240 globalFactorsBuffer.add(posePrior);
242 gtsam::PriorFactor<gtsam::Vector3> velPrior(gtsam::symbol_shorthand::V(currentPropagatedKey),
243 globalGraphValues.at<gtsam::Vector3>(gtsam::symbol_shorthand::V(currentPropagatedKey)),
244 gtsam::noiseModel::Isotropic::Sigma(3, 1e-03));
245 globalFactorsBuffer.add(velPrior);
247 gtsam::PriorFactor<gtsam::imuBias::ConstantBias> biasPrior(
248 gtsam::symbol_shorthand::B(currentPropagatedKey), optimizedGraphState_.imuBias(),
249 gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-03, 1e-03, 1e-03, 1e-03, 1e-03, 1e-03).finished()));
250 globalFactorsBuffer.add(biasPrior);
253 globalSmootherPtr_ = std::make_shared<gtsam::IncrementalFixedLagSmoother>(
254 graphConfigPtr_->smootherLag, isamParams_);
255 addFactorsToSmootherAndOptimize(globalSmootherPtr_, globalFactorsBuffer, globalGraphValues, globalGraphKeysTimestampsMap,
260 const std::lock_guard<std::mutex> activelyUSingActiveGraphLock(activelyUsingActiveGraphMutex_);
263 activeSmootherPtr_ = globalSmootherPtr_;
264 activeFactorsBufferPtr_ = globalFactorsBufferPtr_;
265 activeImuBufferPreintegratorPtr_ = globalImuBufferPreintegratorPtr_;
266 activeGraphValuesBufferPtr_ = globalGraphValuesBufferPtr_;
267 activeGraphKeysTimestampsMapBufferPtr_ = globalGraphKeysTimestampsMapBufferPtr_;
269 const std::lock_guard<std::mutex> operateOnGraphDataLock(operateOnGraphDataMutex_);
270 sentRelocalizationCommandAlready_ =
false;
271 numOptimizationsSinceGraphSwitching_ = 0;
279void GraphManager::activateFallbackGraph() {
281 const std::lock_guard<std::mutex> swappingActiveGraphLock(swappingActiveGraphMutex_);
282 if (activeSmootherPtr_ != fallbackSmootherPtr_) {
284 const std::lock_guard<std::mutex> activelyUsingActiveGraphLock(activelyUsingActiveGraphMutex_);
285 *fallbackSmootherPtr_ = *globalSmootherPtr_;
287 activeSmootherPtr_ = fallbackSmootherPtr_;
288 activeFactorsBufferPtr_ = fallbackFactorsBufferPtr_;
289 activeImuBufferPreintegratorPtr_ = fallbackImuBufferPreintegratorPtr_;
290 activeGraphValuesBufferPtr_ = fallbackGraphValuesBufferPtr_;
291 activeGraphKeysTimestampsMapBufferPtr_ = fallbackGraphKeysTimestampsMapBufferPtr_;
293 numOptimizationsSinceGraphSwitching_ = 0;
299void HolisticFusion::activateFallbackGraph() {
300 if (graphConfigPtr_->usingFallbackGraphFlag) {
301 graphMgrPtr_->activateFallbackGraph();
#define REQUIRED_GNSS_NUM_NOT_JUMPED