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
AC_PrecLand: Use sensor timestamp to match inertial frame corrections #18548
base: master
Are you sure you want to change the base?
Conversation
I like the idea of this PR! |
No testing has been done yet. I would like to get feedback though. |
93dc96d
to
4c88919
Compare
Thanks @amilcarlucas for rebasing this and pushing it forward, I had given up hope :) |
66148e1
to
b3248ed
Compare
Rebased and solved conflicts again. Any feedback? |
@rishabsingh3003 need your input on this one |
if (los_meas_time_us != 0) { | ||
// Search through inertial history for the nearest frame to the measurement timestamp | ||
for (uint8_t i=0; i<_inertial_history->available(); i++) { | ||
uint64_t delta_usec = labs((*_inertial_history)[i]->time_usec - los_meas_time_us); |
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 there a time wrap issue 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.
los_meas_time_ms will wrap after 71 days, and time_usec does not wrap, so there is a wrap issue
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 solved that now and unit tested it with the script below.
if (los_meas_time_us != 0) { | ||
// Search through inertial history for the nearest frame to the measurement timestamp | ||
for (uint8_t i=0; i<_inertial_history->available(); i++) { | ||
uint64_t delta_usec = labs((*_inertial_history)[i]->time_usec - los_meas_time_us); |
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.
los_meas_time_ms will wrap after 71 days, and time_usec does not wrap, so there is a wrap issue
bd23044
to
7f1c877
Compare
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 assume you will remove all the commits that will go with #26238. That will make this PR much simpler.
Specifically the "sync_frame" changes look correct and will help the companion computer backend most likely. However, some amount of testing, atleast in SITL, is warranted before we add more complexity. Also the time-wrap bit looks mostly okay, but I would want to double check if that is being handled correctly.
We can potentially modify the SITL prec land backend to trivially test this PR.
for (uint8_t i=0; i<_inertial_history->available(); i++) { | ||
uint64_t delta_us; | ||
uint64_t ih_point_us = (*_inertial_history)[i]->time_usec; // overflows after approximately 584 554.531 years | ||
while (ih_point_us >= (UINT32_MAX + 1UL) * 1000UL) { |
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.
A comment explaining that this is needed because of the comparison with "ms" time stamp given by the backend would be helpful
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.
Why does the timestamp of the companion Computer Precision landing Vision messages has a half a second delay when compared with the IMU timestamps? It causes problems when comparing the timestamps in the precision landing companion autotest.
I would like to fix that, but I need help. Does this have to do with TIME_SYNC messages? Is the delay in there purposeful?
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.
Yes, this is a followup of #26238. I moved the NFCish things into that one.
I added the comment that you asked.
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 wrap code has been tested with this:
#!/bin/env python
UINT32_MAX = 2**32 - 1
def compare_timestamps(los_meas_time_ms, ih_point_us):
"""
Compare two timestamps and calculate the difference in microseconds,
accounting for 32-bit wrap-around.
Args:
los_meas_time_ms (int): The first timestamp in milliseconds.
ih_point_us (int): The second timestamp in microseconds.
Returns:
int: The difference between the two timestamps in microseconds.
Note:
This function assumes that the timestamps are close to each other and
handles the case where the difference exceeds the maximum value of a
32-bit unsigned integer.
"""
# simulate 32bit wrap in python
while los_meas_time_ms >= (UINT32_MAX + 1):
los_meas_time_ms -= (UINT32_MAX + 1)
los_meas_time_us = los_meas_time_ms * 1000
while ih_point_us >= (UINT32_MAX + 1) * 1000:
ih_point_us -= (UINT32_MAX + 1) * 1000
if ih_point_us > los_meas_time_us:
delta_us = ih_point_us - los_meas_time_us
else:
delta_us = los_meas_time_us - ih_point_us
if delta_us > UINT32_MAX * 1000 / 2:
delta_us = (UINT32_MAX + 1) * 1000 - delta_us
print(delta_us)
return delta_us
assert compare_timestamps(0, 0) == 0
assert compare_timestamps(1, 0) == 1000
assert compare_timestamps(0, 1) == 1
assert compare_timestamps(2, 0) == 2000
assert compare_timestamps(0, 2) == 2
assert compare_timestamps(2, 0) == 2000
assert compare_timestamps(UINT32_MAX, UINT32_MAX*1000) == 0
assert compare_timestamps(UINT32_MAX, UINT32_MAX*1000+1) == 1
assert compare_timestamps((UINT32_MAX+1)+0, (UINT32_MAX+1)*1000+0) == 0
assert compare_timestamps((UINT32_MAX+1)+0, (UINT32_MAX+1)*1000-1) == 1
assert compare_timestamps((UINT32_MAX+1)+0, (UINT32_MAX+1)*1000-2) == 2
assert compare_timestamps((UINT32_MAX+1)+0, (UINT32_MAX+1)*1000+1) == 1
assert compare_timestamps((UINT32_MAX+1)+0, (UINT32_MAX+1)*1000+2) == 2
assert compare_timestamps((UINT32_MAX+1)+0, 2*(UINT32_MAX+1)*1000+2) == 2
assert compare_timestamps((UINT32_MAX+1)+0, 3*(UINT32_MAX+1)*1000+4) == 4
assert compare_timestamps((UINT32_MAX+0)+0, 3*(UINT32_MAX+1)*1000+4) == 1004
assert compare_timestamps((UINT32_MAX+1)+7, 3*(UINT32_MAX+1)*1000+4) == 6996
I have updated the size comparison on top of this PR |
53fc196
to
8eace96
Compare
6a5a5f9
to
8f0f4e3
Compare
This PR was started by @khancyr , later picked up by @fnoop and later on by me. It has been around by many years, but it is now a lot shorter and easier to review. Unfortunately right now I do not have a vehicle that I can test this with, so it would be nice if someone with a companion computer and visual fiducial markers would test this. |
Co-authored-by: Dr.-Ing. Amilcar do Carmo Lucas <amilcar.lucas@iav.de> If the sensor sets the timestamp with the sensor frame then it attempts to match it against inertial frame timestamps. Sensor frames can have widely varying latencies so this is essential to safely correlate the attitude compensation against any given sensor reading. This effectively auto-detects the sensor latency and makes the PLND_LAG manual setting unnecessary. The only caveat is that PLND_LAG must be set large enough to hold the biggest sensor latency. So if used with a sensor that supports time-stamping PLND_LAG should be set to something large like 0.250 (s). - Separate out sync_frames logic, make _inertial_data_delayed class struct - Run forward prediction from synced frame
8f0f4e3
to
5c965c2
Compare
@rishabsingh3003 the other 2 precland PRs from me got merged, only this one remains and it got a lot smaller now. Can you review this? |
This is a rebase and cleanup of @fnoop #9020
If the sensor sets the timestamp with the sensor frame then it attempts to match it against inertial frame timestamps.
Sensor frames can have widely varying latencies so this is essential to safely correlate the attitude compensation against any given sensor reading.
This effectively auto-detects the sensor latency and makes the PLND_LAG manual setting unnecessary.
The only caveat is that PLND_LAG must be set large enough to hold the biggest sensor latency.
So if used with a sensor that supports timestamping PLND_LAG should be set to something large like 0.250 (s).