@@ -38,48 +38,55 @@ std::shared_ptr<Keyframe> MapDB::insertNewKeyframeCandidate(
3838 const std::vector<slam::Pose> &poseTrail,
3939 const odometry::ParametersSlam ¶meters)
4040{
41- Eigen::Matrix4d pose;
41+ Eigen::Matrix4d pose, smoothPose ;
4242 std::shared_ptr<Keyframe> keyframe = std::move (keyframeUniq);
4343 Keyframe *previousKf = latestKeyframe ();
4444 // debugPrintPoseTrail(poseTrail);
4545
46+ smoothPose = poseTrail[0 ].pose ;
47+ // TODO: to be more accurate, should uncertainty "deltas" over pose trail
48+ Eigen::Matrix<double , 3 , 6 > curUncertainty = poseTrail[0 ].uncertainty * parameters.keyframeCandidateInterval ;
49+ // assert(curUncertainty.squaredNorm() > 1e-20); // matters only if used
50+
4651 if (prevPoseKfId.v < 0 ) {
47- pose = keyframe->origPoseCW ;
52+ // First KF (or something bad happened): use odometry pose as-is
53+ pose = poseTrail[0 ].pose ;
4854 // Tip: Use this to change direction of SLAM map and debug transform issues.
4955 // pose.topLeftCorner<3, 3>() = pose.topLeftCorner<3, 3>() * Eigen::AngleAxisd(0.5 * M_PI, Vector3d::UnitZ());
5056 // pose.block<3, 1>(0, 3) << 4, 1, -2;
5157 }
5258 else {
5359 assert (previousKf);
54- // this "two-step" mechanism may be required to handle loop closures correctly
5560 Eigen::Matrix4d refPose = prevPose;
56- if (parameters.useVariableLengthDeltas ) {
57- refPose = prevPoseToPrevKeyframeDelta * previousKf->poseCW ;
58- }
5961
60- Eigen::Matrix4d poseTilted, refPrevPose;
61- refPrevPose = prevInputPose;
62+ // Could update prevPose to previousKf->poseCW here, but this does not play nice
63+ // with loop closures or non-keyframes and the practical difference is very small
64+
6265 if (parameters.useOdometryPoseTrailDelta ) {
6366 // note that this can fail if in certain cases with long
6467 // stationarity and no new keyframes unless special care is taken
6568 const auto *prevPoseInPoseTrail = findInPoseTrail (poseTrail, prevPoseKfId);
6669 if (prevPoseInPoseTrail == nullptr ) {
67- log_debug (" keyframe %d not found in pose trail" , prevPoseKfId.v );
70+ log_warn (" keyframe %d not found in pose trail" , prevPoseKfId.v );
6871 } else {
6972 assert (KfId (prevPoseInPoseTrail->frameNumber ) != keyframe->id );
70- refPrevPose = prevPoseInPoseTrail->pose ;
73+ smoothPose = poseTrail[0 ].pose * prevPoseInPoseTrail->pose .inverse () * prevSmoothPose;
74+ // No need to remove Z-axis tilt here. "smoothPose" should only be used for computing
75+ // odometry priors between consecutive keyframes but never as an absolute pose
7176 }
7277 }
73- poseTilted = keyframe->origPoseCW * refPrevPose.inverse () * refPose;
7478
79+ Eigen::Matrix4d poseTilted = poseTrail[0 ].pose * prevInputPose.inverse () * refPose;
7580 if (parameters.removeOdometryTransformZAxisTilt ) {
76- pose = removeZAxisTiltComparedToReference (poseTilted, keyframe-> origPoseCW );
81+ pose = removeZAxisTiltComparedToReference (poseTilted, smoothPose );
7782 } else {
7883 pose = poseTilted;
7984 }
8085 }
8186
8287 keyframe->poseCW = pose;
88+ keyframe->smoothPoseCW = smoothPose;
89+ keyframe->uncertainty = prevUncertainty + curUncertainty;
8390
8491 if (previousKf) {
8592 keyframe->previousKfId = previousKf->id ;
@@ -106,7 +113,8 @@ MapDB::MapDB(const MapDB &mapDB) {
106113
107114 prevPose = mapDB.prevPose ;
108115 prevInputPose = mapDB.prevInputPose ;
109- discardedUncertainty = mapDB.discardedUncertainty ;
116+ prevSmoothPose = mapDB.prevSmoothPose ;
117+ prevUncertainty = mapDB.prevUncertainty ;
110118
111119 nextMp = mapDB.nextMp ;
112120 lastKfCandidateId = mapDB.lastKfCandidateId ;
@@ -149,8 +157,8 @@ MapDB::MapDB(const MapDB &mapDB, const std::set<KfId> &activeKeyframes) {
149157
150158 prevPose = mapDB.prevPose ;
151159 prevInputPose = mapDB.prevInputPose ;
152- prevPoseToPrevKeyframeDelta = mapDB.prevPoseToPrevKeyframeDelta ;
153- discardedUncertainty = mapDB.discardedUncertainty ;
160+ prevSmoothPose = mapDB.prevSmoothPose ;
161+ prevUncertainty = mapDB.prevUncertainty ;
154162
155163 nextMp = mapDB.nextMp ;
156164 prevPoseKfId = mapDB.prevPoseKfId ;
@@ -225,45 +233,20 @@ Eigen::Matrix4d MapDB::poseDifference(KfId kfId1, KfId kfId2) const {
225233 assert (kfId1 <= kfId2);
226234 const Keyframe &kf1 = *keyframes.at (kfId1);
227235 const Keyframe &kf2 = *keyframes.at (kfId2);
228- return kf1.origPoseCW * kf2.origPoseCW .inverse ();
236+ return kf1.smoothPoseCW * kf2.smoothPoseCW .inverse ();
229237}
230238
231- void MapDB::updatePrevPose (
232- const Keyframe ¤tKeyframe,
233- bool keyframeDecision,
234- const std::vector<slam::Pose> &poseTrail,
235- const odometry::Parameters ¶meters)
239+ void MapDB::updatePrevPose (const Keyframe ¤tKeyframe, const Eigen::Matrix4d &inputPose)
236240{
237- if (!keyframeDecision && parameters.slam .useVariableLengthDeltas && findInPoseTrail (poseTrail, prevPoseKfId) == nullptr ) {
238- log_debug (" prevPoseKfId %d lost in pose trail: must update" , prevPoseKfId.v );
239- // TODO: could rather try to update to an older pose isn the trail
240- // TODO: such odometry non-keyframes should also be removed from the map
241- keyframeDecision = true ;
242- }
243-
244- if (!keyframeDecision && parameters.slam .useVariableLengthDeltas ) {
245- // TODO: this is overly complex
246- const int nextKfCandidateAge = currentKeyframe.id .v - prevPoseKfId.v + parameters.slam .keyframeCandidateInterval ;
247- assert (nextKfCandidateAge > 0 );
248- // TODO: +1? (not so serious here)
249- const int maxPoseTrailSize = parameters.odometry .cameraTrailLength - std::max (0 , parameters.slam .delayIntervalMultiplier ) * parameters.slam .keyframeCandidateInterval ;
250- // log_debug("next %d/%d", nextKfCandidateAge, maxPoseTrailSize);
251- if (parameters.slam .useOdometryPoseTrailDelta && nextKfCandidateAge >= maxPoseTrailSize) {
252- log_debug (" storing prevPose of non-KF %d: max pose trail length will be reached" , currentKeyframe.id .v );
253- } else {
254- // log_debug(" skipping non-keyframe %d as prev pose", currentKeyframe.id.v);
255- return ;
256- }
257- }
258-
259241 // log_debug("storing keyframe %d as prev pose", currentKeyframe.id.v);
260242 prevPoseKfId = currentKeyframe.id ;
261- prevInputPose = currentKeyframe.origPoseCW ;
243+ prevInputPose = inputPose;
244+ prevSmoothPose = currentKeyframe.smoothPoseCW ;
262245 prevPose = currentKeyframe.poseCW ;
246+ prevUncertainty = currentKeyframe.uncertainty ;
263247
264248 const auto *prevKf = latestKeyframe ();
265249 assert (prevKf);
266- prevPoseToPrevKeyframeDelta = prevPose * prevKf->poseCW .inverse ();
267250}
268251
269252const MapDB& getMapWithId (MapId mapId, const MapDB &mapDB, const Atlas &atlas) {
0 commit comments