-
Notifications
You must be signed in to change notification settings - Fork 789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding lever-arm to GPS factors #1975
Conversation
I see the macos-14-xcode-15.4 Release Python 3 check failed. This I have very little experience with, but in hindsight I see the serialization and interfacing were not appropriately updated. Perhaps I should ask the following questions
|
I’ll take a look and then answer your questions. If it can be done easily with another state then probably that is preferred. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is great, and I think it should be added to a factor. But I propose to add a GpsFactor2 or GpsFactorArm in the same file, because the Jacobians are more expensive. Adding documentation of the nature I suggested in both the old and the new factor would make it easier to see the difference.
PS we will soon start adding notebooks to document factors in the source tree itself. Consider authoring a small colab that demonstrates both factors that we could include :-) That’s not needed for this PR to merge, though.
gtsam/navigation/GPSFactor.cpp
Outdated
} | ||
|
||
//*************************************************************************** | ||
Vector GPSFactor2::evaluateError(const NavState& p, | ||
OptionalMatrixType H) const { | ||
return p.position(H) -nT_; | ||
const Matrix3 rot = p.attitude().matrix(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use aRb
naming convention, where R transforms b coordinates into a coordinates.
gtsam/navigation/GPSFactor.h
Outdated
@@ -39,6 +39,7 @@ class GTSAM_EXPORT GPSFactor: public NoiseModelFactorN<Pose3> { | |||
typedef NoiseModelFactorN<Pose3> Base; | |||
|
|||
Point3 nT_; ///< Position measurement in cartesian coordinates | |||
Point3 B_t_BG_; ///< Lever arm between GPS and BODY frame |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming convention ‘nT_’ says that T is in the navigation frame. I think if you want to include a lever arm in this factor you need to include more documentation about the frames involved.
@@ -61,10 +64,12 @@ TEST( GPSFactor, Constructor ) { | |||
// Factor | |||
Key key(1); | |||
SharedNoiseModel model = noiseModel::Isotropic::Sigma(3, 0.25); | |||
GPSFactor factor(key, Point3(E, N, U), model); | |||
GPSFactor factor(key, Point3(E, N, U), model, leverArm); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not expect you to change an existing test, but rather add an additional test with a non-zero lever arm.
gtsam/navigation/GPSFactor.cpp
Outdated
H->block<3, 3>(0, 6).setZero(); | ||
} | ||
|
||
return p.position() - (nT_ - rot * B_t_BG_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This formula is a bit counter-intuitive to me. I would expect to see
h(x) = p.position() + rot * B_t_BG_
From which I deduce that rot==nRb
which matches my definition of NavState, and B_t_BG_==bL_
, a lever arm in the body frame. So, I think the documentation/notation I’m looking for is
bL_ is a lever arm in the body frame, denoting the 3D position of the GPS antenna in the body frame. Because the actual location of the antenna depends on both position and attitude, providing a lever arm makes components of the attitude observable in turns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lever arm is definitely in body frame, will adapt this to GTSAM format.
I think I have addressed all your points in the review with new factors I had some follow-up questions
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great ! You could probably save a bit of copy/pasta by inheriting from the non-arm factors, but that's entirely optional.
I would say that is a different factor, one that would incur a lot of computation, actually: this new state variable would connect all GPS factors. It would be useful in a calibration setting, but not for everyday use, if you already have a calibrated lever arm.
Sure: https://www.roboticsbook.org/S64_driving_perception.html, open in colab :-)
I don't quite understand this :-) |
Thanks! I had considered inheritance, but I had some trouble with base classes and indirect bases. Plus I think inheritance only saves copy-pasting
I'll try to explain it differently, suppose aPab is the position of {b} with respect to {a}, expressed in coordinate frame {a} (for coordinate frames {a} and {b}). If there is a lever arm, the measurement is really wPwg instead of wPwb for world frame {w}, GPS antenna {g}, and body frame {b}. Therefore This is what I was trying to say. I hope this makes a little more sense. |
Agreed !
Yep, I think so :-) So, this is ready to merge after CI succeeds, yes? I propose we do a notebook in a follow-up PR, if you're game. In fact, we're soon going to add a mechanism to GTSAM to check these in and they will be automatically served. And, we can featsure them as blog posts on gtsam.org, as well. |
Sorry about that, I was a bit slow but I added a factor with the lever arm as a state as well. Ended up calling it
Otherwise yes, should be all good from my side.
Yeah I am down for that. The model for this is a numerical example and a bit of description/story-telling? |
Thanks @mnissov !!! Will be quite useful, makes orientation observable if you have two receivers, as well :-) |
I noticed the GPS factors had no option for a non-zero lever arm, the feature became necessary for me so I figured I would make this PR.
Of course similar behavior is possible with
setBodyPSensor
but this comes at the cost of additional linearization error I believe (ref). As a result the performance is actually different.