-
Notifications
You must be signed in to change notification settings - Fork 13.6k
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
Move GPS aggregation and blending to sensors #14447
Conversation
@dakejahl the correct way of rebasing work is to rebase commits. Not to pick up commits from another developer and bring it together as your own. That removes the credit and effort from the other developer. |
Rebasing was a mess, this was much quicker, cleaner and easier. I am working with @dagar on this. I could care less about credit so if that matters we can close this and dagar can unstage and reopen... |
Cleaner it isn't. Easier probably is for sure. Well done rebasing takes effort and it's the right thing to do. Anyway if @dagar is fine with it, I don't oppose as it's not my work. |
d0c3171
to
a6237ba
Compare
Tested successfully using Neo V2 GPS connected to a Pixhawk4 and a UBX GPS connected to a pixracer configured as a CAN node connected to the Pixhawk4 over CAN.
|
Hmm looks like we don't publish hdop, vdop or s_variance_m_s over uavcan from the cannode gps, the uavcan What should we do about this? @dagar @JacobCrabill
|
My simple solution was just to use pdop for both hdop and vdop; I believe they're similar enough quantites that it works ok (if you're only using CAN GPS units, then it's totally fine). Definitely not perfect if you have another GPS with real hdop/vdop data, but I don't know of a better solution. |
Tested successfully! After a days worth of debugging (mostly cannode side) this finally works.
@JacobCrabill would you mind testing this on your end as well? |
@mhkabir I'm on a critical path right now. Would you mind making the changes you are requesting and just pushing up the commit? Otherwise I'd like to get this merged and keep chugging along with CAN stuff. |
10bdb4e
to
d4f89ca
Compare
@dakejahl If you care about your commits, please interactively rebase. Otherwise I will squash and merge your PRs as colloquial commits like "thanks clang" do not belong into an upstream open source project. I would recommend to run I will squash this PR since it seems appropriate to have single commit. |
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 architecturally correct to me (moving this into the work queue and "cleaning up" the resulting message flow from GPS -> fused estimate -> estimator), but I'd like to get the review of @CarlOlsson and @bresch on it.
c3a0696
to
243a919
Compare
This log is less helpful than I thought it would be, but here it is.
https://review.px4.io/plot_app?log=4b8998a9-428a-448c-b9bc-b4bdd722b8b9 |
243a919
to
89e785b
Compare
@@ -52,7 +52,7 @@ using namespace time_literals; | |||
const char *const UavcanGnssBridge::NAME = "gnss"; | |||
|
|||
UavcanGnssBridge::UavcanGnssBridge(uavcan::INode &node) : | |||
UavcanCDevSensorBridgeBase("uavcan_gnss", "/dev/uavcan/gnss", "/dev/gnss", ORB_ID(vehicle_gps_position)), | |||
UavcanCDevSensorBridgeBase("uavcan_gnss", "/dev/uavcan/gnss", "/dev/gnss", ORB_ID(sensor_gps)), |
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.
In the future we should consider removing the use of CDev as a base class for UavcanSensorBridge; I don't think the CDev interfaces are used anymore. If they are, then ideally those sensor types would have a generic interface class like PX4Barometer / PX4Magnetometer.
if ((gps1_updated && _gps_select_index == 0) || (gps2_updated && _gps_select_index == 1)) { | ||
_gps_new_output_data = true; | ||
// Second, compare GPS's with best fix and take the one with most satellites | ||
uint8_t max_sats = 0; |
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 was just the quickest/simplest heuristic I came up with for picking which GPS was best; we could also use an accuracy measurement if all GPSs are publishing compatible quantities.
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.
Is it possible for a GPS unit to report "No fix" (fix_type == 0) while still reporting some number of satellites?
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.
And vice versa, reporting "3D fix" while having zero satellites?
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.
If one GPS doesn't have a fix while another does, this will automatically discard the GPS without the fix (only the GPSs with the "best fix" will be sorted through).
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.
And as to 0 satellites... I doubt that would happen, but I could see a case where two different units both have a 3D fix with multiple satellites, but the one with fewer satellites could have a better speed/position accuracy estimate than the one with more satellites. Unlikely perhaps, but plausible.
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.
@dakejahl could you add me as a co-author on this commit, seeing as I did the original blending modifications here?
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've likely already made a mess of things with squashed commits. Happy to restore credit.
Hi all, While working with rovers with GPS RTK precision it turned out that 1E-7 degrees precision for lat and long was not enough in several specific cases. I suppose it's worst (at least in this PR) to discuss proposal to make lat and lon as double (and alt as float) in sensor_gps.msg:
Yes, I understand that 1e-7 precision is quite good (1.11 cm at equator) and enough for many general drones use cases, but I believe that losing precision in gps drivers straight away on parsing is not good thing for px4 framework and mitigates its universality and customization potential! Another argument - that in different calculations (especially in ekf) px4 internally already use lat, lon as doubles converting them on input and output every time back and forward from deg/1e-7deg (and m/mm for alt). I don't know how much, but I suppose CPU will be reduced a little, just by increasing RAM usage for 8 bytes * (GPS receivers number). Most disadvantage - it will break all log analyzes that use vehicle_gps_position (but anyway finally they have to correct parser to sensor_gps anyway, right?) Also I would like to suggest here to add dgps_age field to sensor_gps.msg (and fill it in MavlinkStreamGPS2Raw) and parsed it in drivers where available (for example in @bys1123 PR GpsDrivers #58 NMEA-0183) |
Time to finally bring this in! |
@lukegluke I haven't reviewed the various GPS receivers, but from a PX4 message standpoint I don't currently see a reason to be opposed to moving latitude and longitude to double precision floating point. Computationally we're already working with lat/lon in double and the difference in message size is pretty minor for a relatively low rate message like this. I would propose we get this PR safely into master and do an immediate followup pass. |
6d57642
to
27e4597
Compare
Rebased on current master and GPSDrivers submodule updated to latest. |
I've added parameter migration for the changes.
|
bc1dca8
to
07ff168
Compare
Later we should move the GPS position offset configuration to out of EKF2 and into the sensors module handled per instance.
One question is if we actually shift the sensor_gps data before publishing (vehicle_gps_position) or publish it as metadata for the estimator to handle. @CarlOlsson I believe this is how we should properly handle your GPS offset issue. |
We don't have to do it in this PR, but ideally we'd finally get some unit testing for the actual GPS blending logic here after another incremental refactor. |
- N x sensor_gps => vehicle_gps_position - blending is now configurable with SENS_GPS_MASK and SENS_GPS_TAU
07ff168
to
ee42faf
Compare
I'm in favor of sending the gps measurements without any modification and send the metadata such that the estimator can perform all the required corrections: removing tangential velocity requires gyro data. |
Me too, otherwise we get a strong coupling between the health of the estimator and the "raw" gps data |
double lat_deg_now = (double)_gps_state[i].lat * 1.0e-7; | ||
double lon_deg_now = (double)_gps_state[i].lon * 1.0e-7; | ||
double lat_deg_res, lon_deg_res; | ||
add_vector_to_global_position(lat_deg_now, lon_deg_now, _NE_pos_offset_m[i](0), _NE_pos_offset_m[i](1), &lat_deg_res, |
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 don't think we should modify the GPS individual readings; IMO, the blending logic should create a blended output from all the receivers but not adjust each GPS solution, why do we do that?
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.
@dakejahl @JacobCrabill any comment here? I don't believe I modified any of the logic when I did the original extraction in #13584, although obviously it's been a while...
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.
Ok, looks like this isn't modified from what ekf2 is currently doing.
I don't think we should modify the GPS individual readings; IMO, the blending logic should create a blended output from all the receivers but not adjust each GPS solution
I agree, storing some of this incremental state was one of my criticisms of the original gps blending work in ekf2, but it was a bit more confusing going between uORB vehicle_gps_position
-> ecl/EKF gps_message
and then back to ekf_gps_position
(nearly identical to vehicle_gps_position
). Let me see if I can eliminate it this time.
// Convert each GPS position to a local NEU offset relative to the reference position | ||
// which is defined as the positon of the blended solution calculated from non offset corrected data | ||
Vector2f blended_NE_offset_m; | ||
blended_NE_offset_m.zero(); | ||
float blended_alt_offset_mm = 0.0f; | ||
|
||
for (uint8_t i = 0; i < GPS_MAX_RECEIVERS; i++) { | ||
if (_blend_weights[i] > 0.0f) { | ||
// calculate the horizontal offset | ||
Vector2f horiz_offset{}; | ||
get_vector_to_next_waypoint((_gps_blended_state.lat / 1.0e7), | ||
(_gps_blended_state.lon / 1.0e7), | ||
(_gps_output[i].lat / 1.0e7), | ||
(_gps_output[i].lon / 1.0e7), | ||
&horiz_offset(0), | ||
&horiz_offset(1)); | ||
|
||
// sum weighted offsets | ||
blended_NE_offset_m += horiz_offset * _blend_weights[i]; | ||
|
||
// calculate vertical offset | ||
float vert_offset = (float)(_gps_output[i].alt - _gps_blended_state.alt); | ||
|
||
// sum weighted offsets | ||
blended_alt_offset_mm += vert_offset * _blend_weights[i]; | ||
} | ||
} |
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.
Are we not already doing the correction here: https://github.com/PX4/Firmware/pull/14447/files#diff-5c37c83ace9fdd92b81d362d265d2f21R503-R525 ?
Co-authored-by: Mathieu Bresciani <brescianimathieu@gmail.com>
25ff582
to
614facf
Compare
I'll give this a review soon |
In order to prevent this from dragging out even longer I'm going to revert this branch to the last "good" tested state and get it rebased and merged immediately. Having it merged unblocks further GpsDriver updates and helps with multi-ekf. I'll then restore the cleanup fixes in a new PR we can test incrementally. |
614facf
to
ab0217b
Compare
ab0217b
to
9575815
Compare
Brought the work from this PR #13584 up to date with current
master
Need to test still.
FYI @dagar @JacobCrabill