1717
1818#include < gtsam_unstable/navigation/EqVIOFilter.h>
1919
20+ #include < algorithm>
2021#include < cassert>
22+ #include < map>
23+ #include < numeric>
24+ #include < set>
2125#include < stdexcept>
2226#include < tuple>
2327
@@ -41,6 +45,7 @@ EqVIOFilter::EqVIOFilter(const EqVIOFilterParams& params)
4145 xi0.sensor .velocity .setZero ();
4246 xi0.sensor .cameraOffset = Pose3::Identity ();
4347 resetReferenceAndGroup (xi0, defaultCovariance (0 ), makeVioGroupIdentity ());
48+ landmarkKeys_.clear ();
4449}
4550
4651/* *
@@ -53,6 +58,8 @@ EqVIOFilter::EqVIOFilter(const State& xi_ref, const Matrix& Sigma,
5358 : Base(State(), defaultCovariance(0 ), makeVioGroupIdentity()),
5459 params_(params) {
5560 resetReferenceAndGroup (xi_ref, Sigma, makeVioGroupIdentity (xi_ref.n ()));
61+ landmarkKeys_.resize (xi_ref.n ());
62+ std::iota (landmarkKeys_.begin (), landmarkKeys_.end (), 0 );
5663 initialized_ = true ;
5764}
5865
@@ -192,9 +199,9 @@ void EqVIOFilter::innovationUpdate(
192199 if (measurement.empty ()) return ;
193200
194201 const VisionMeasurement estimatedMeasurement =
195- measureSystemState (state (), camera);
196- const Matrix Ct = EqFoutputMatrixC (referenceState (), groupEstimate () ,
197- measurement, camera, true );
202+ measureSystemState (state (), landmarkKeys_, camera);
203+ const Matrix Ct = EqFoutputMatrixC (referenceState (), landmarkKeys_ ,
204+ groupEstimate (), measurement, camera, true );
198205 const Matrix Rused = (outputGainMatrix.rows () == Ct.rows () &&
199206 outputGainMatrix.cols () == Ct.rows ())
200207 ? outputGainMatrix
@@ -222,13 +229,15 @@ void EqVIOFilter::addNewLandmarks(
222229 if (!camera) throw std::invalid_argument (" EqVIOFilter::addNewLandmarks: camera is null" );
223230
224231 std::vector<Landmark> newLandmarks;
225- const std::vector<Key> existingIds = referenceState ().ids ();
232+ std::vector<Key> newKeys;
233+ const std::vector<Key> existingIds = landmarkKeys_;
226234 for (const auto & [id, coord] : measurement) {
227235 if (std::find (existingIds.begin (), existingIds.end (), id) != existingIds.end ()) {
228236 continue ;
229237 }
230238 const Vector3 bearing = undistortPoint (*camera, coord);
231- newLandmarks.push_back (Landmark{bearing, id});
239+ newLandmarks.push_back (Landmark{bearing});
240+ newKeys.push_back (id);
232241 }
233242
234243 if (newLandmarks.empty ()) return ;
@@ -244,6 +253,7 @@ void EqVIOFilter::addNewLandmarks(
244253 State xi_ref = referenceState ();
245254 xi_ref.cameraLandmarks .insert (xi_ref.cameraLandmarks .end (), newLandmarks.begin (),
246255 newLandmarks.end ());
256+ landmarkKeys_.insert (landmarkKeys_.end (), newKeys.begin (), newKeys.end ());
247257
248258 const auto & [A, Beta, B, Q] = decompose (groupEstimate ());
249259 std::vector<SOT3> q;
@@ -270,7 +280,7 @@ void EqVIOFilter::addNewLandmarks(
270280
271281// / Remove any landmarks that are absent from the current measurement id list.
272282void EqVIOFilter::removeOldLandmarks (const std::vector<Key>& measurementIds) {
273- const std::vector<Key> existingIds = referenceState (). ids () ;
283+ const std::vector<Key> existingIds = landmarkKeys_ ;
274284 std::vector<int > lostIndices (existingIds.size ());
275285 std::iota (lostIndices.begin (), lostIndices.end (), 0 );
276286 if (lostIndices.empty ()) return ;
@@ -295,6 +305,7 @@ void EqVIOFilter::removeOldLandmarks(const std::vector<Key>& measurementIds) {
295305void EqVIOFilter::removeLandmarkByIndex (int idx) {
296306 State xi_ref = referenceState ();
297307 xi_ref.cameraLandmarks .erase (xi_ref.cameraLandmarks .begin () + idx);
308+ landmarkKeys_.erase (landmarkKeys_.begin () + idx);
298309
299310 const auto & [A, Beta, B, Q] = decompose (groupEstimate ());
300311
@@ -316,22 +327,16 @@ void EqVIOFilter::removeLandmarkByIndex(int idx) {
316327
317328// / Remove landmark with matching key id.
318329void EqVIOFilter::removeLandmarkById (Key id) {
319- const auto it = std::find_if (
320- referenceState ().cameraLandmarks .begin (), referenceState ().cameraLandmarks .end (),
321- [&id](const Landmark& lm) { return lm.id == id; });
322- assert (it != referenceState ().cameraLandmarks .end ());
323- removeLandmarkByIndex (
324- static_cast <int >(std::distance (referenceState ().cameraLandmarks .begin (), it)));
330+ const auto it = std::find (landmarkKeys_.begin (), landmarkKeys_.end (), id);
331+ assert (it != landmarkKeys_.end ());
332+ removeLandmarkByIndex (static_cast <int >(std::distance (landmarkKeys_.begin (), it)));
325333}
326334
327335// / Return 3x3 landmark-state covariance block for the specified id.
328336Matrix3 EqVIOFilter::getLandmarkCovById (Key id) const {
329- const auto it = std::find_if (
330- referenceState ().cameraLandmarks .begin (), referenceState ().cameraLandmarks .end (),
331- [&id](const Landmark& lm) { return lm.id == id; });
332- assert (it != referenceState ().cameraLandmarks .end ());
333- const int i =
334- static_cast <int >(std::distance (referenceState ().cameraLandmarks .begin (), it));
337+ const auto it = std::find (landmarkKeys_.begin (), landmarkKeys_.end (), id);
338+ assert (it != landmarkKeys_.end ());
339+ const int i = static_cast <int >(std::distance (landmarkKeys_.begin (), it));
335340 return errorCovariance ().block <3 , 3 >(SensorState::CompDim + 3 * i,
336341 SensorState::CompDim + 3 * i);
337342}
@@ -340,17 +345,15 @@ Matrix3 EqVIOFilter::getLandmarkCovById(Key id) const {
340345Matrix2 EqVIOFilter::outputCovarianceById (
341346 Key id, const std::shared_ptr<const CameraModel>& camera) const {
342347 const Matrix3 lmCov = getLandmarkCovById (id);
343- const auto it = std::find_if (
344- referenceState ().cameraLandmarks .begin (), referenceState ().cameraLandmarks .end (),
345- [&id](const Landmark& lm) { return lm.id == id; });
346- assert (it != referenceState ().cameraLandmarks .end ());
348+ const auto it = std::find (landmarkKeys_.begin (), landmarkKeys_.end (), id);
349+ assert (it != landmarkKeys_.end ());
347350
348- const size_t i =
349- static_cast <size_t >(std::distance (referenceState ().cameraLandmarks .begin (), it));
351+ const size_t i = static_cast <size_t >(std::distance (landmarkKeys_.begin (), it));
350352 const LandmarkGroup& Q = std::get<3 >(decompose (groupEstimate ()));
351353 const SOT3& Q_i = Q[i];
354+ const Point3& q0 = referenceState ().cameraLandmarks [i].p ;
352355
353- const Matrix23 C0i = EqFoutputMatrixCi (it-> p , Q_i, camera);
356+ const Matrix23 C0i = EqFoutputMatrixCi (q0 , Q_i, camera);
354357 return C0i * lmCov * C0i.transpose ();
355358}
356359
@@ -361,7 +364,7 @@ void EqVIOFilter::removeInvalidLandmarks() {
361364 for (size_t i = 0 ; i < Q.size (); ++i) {
362365 const double a = SOT3Scale (Q[i]);
363366 if (!std::isfinite (a) || a <= 1e-8 || a > 1e8 ) {
364- invalidIds.insert (referenceState (). cameraLandmarks [i]. id );
367+ invalidIds.insert (landmarkKeys_ [i]);
365368 }
366369 }
367370 for (const Key id : invalidIds) {
@@ -382,7 +385,7 @@ void EqVIOFilter::removeOutliers(
382385 (1.0 - params_.featureRetention ) * measurement.size ());
383386 if (!camera) return ;
384387
385- const VisionMeasurement yHat = measureSystemState (state (), camera);
388+ const VisionMeasurement yHat = measureSystemState (state (), landmarkKeys_, camera);
386389
387390 std::vector<Key> proposedOutliers;
388391 std::map<Key, double > absoluteOutliers;
0 commit comments