-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
Gsof bitmask flexible parser #28802
Gsof bitmask flexible parser #28802
Conversation
2d00160
to
b469160
Compare
b469160
to
6fcb9a1
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.
It looks ok to me but the logic of the changes is a little hard to follow
Thanks for the review! I'm open to changes to improve readability too - if you had any recommendations, I'm happy to implement. |
The code looks okay. But it's not clear that the original problem exists, or that this solves it properly? The links have rotted but I looked through Trimble's documentation and this is what I surmise happens each "epoch" (assuming all the messages come at the same rate which we do configure):
The documentation says "There can be various records in one GENOUT packet. There could be multiple GENOUT packets per epoch. Records may be split over two consecutive packets.". I'm further assuming that one "transmission number" is used for each time through this loop. The current code assumes the above loop, but it only assumes 1 GENOUT packet. Can the transmitter put multiple messages of the same type into one packet? I assume the problematic case would fail because it should, according to my model, get 5 different GENOUT packets with 1 message each. The new code still assumes this model is true, because it won't work if the receiver chooses to send 3 messages in one packet and 2 in the next, and it also will have problems if the receiver chooses to send the 5 correct messages, then duplicate one of them again in the same packet. This also will fall apart if the set of requested messages ever exceeds 248 bytes (one GENOUT packet). I think this needs a deeper rework. The memory overflows should be fixed too. |
New plan:
class GsofParser {
public:
bool OnData(char c, ) // returns true if you got a message
bool run_parser( MsgTypes& types_parsed)
next_msg(&id, uint8 len) // uses packet_ptr to parse the buffer
parse_gsof1(len, GSOF1& msg)
parse_gsof2(len, GSOF2& msg)
private:
int* packet_ptr
)
} |
5926311
to
986c5af
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've reworked the PR a bit to make it a bit simpler and functionally robust to extranneous data. I tested it by enabling a few extra packets, and verified the parser still is happy.
I also tested disabling one of the required packets, and it was no longer healthy as designed.
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.
LGTM
// https://receiverhelp.trimble.com/oem-gnss/index.html#GSOFmessages_Overview.html?TocPath=Output%2520Messages%257CGSOF%2520Messages%257COverview%257C_____0 | ||
static_assert(ARRAY_SIZE(gsofmsgreq) <= 10, "The maximum number of outputs allowed with GSOF is 10."); |
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.
prefer compile time assert if possible, happy to have new constructor for AP_Bitmask that takes const array
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.
Done!
I understood that the desire was to call static_assert on the array rather than bitmask.count(). You also don't necessarily need to add a constructor to AP_Bitmask, that could be done in a followup though. |
You can't do a static assert if you don't have a constexpr constructor, unless I'm missing something. |
I think the idea was to keep the array and static_assert like they were before this PR, then add a little loop in the GSOF constructor which reads that array and sets up the bitmask. |
Signed-off-by: Ryan Friedman <25047695+Ryanf55@users.noreply.github.com>
Signed-off-by: Ryan Friedman <25047695+Ryanf55@users.noreply.github.com>
Signed-off-by: Ryan Friedman <25047695+Ryanf55@users.noreply.github.com>
986c5af
to
01614e8
Compare
Got it, sorry, was being dense. Take a look now. |
Purpose
Refactor the GSOF parser to instead return a bitmask of which packets were parsed. Compared to before, where we used a counter for packets, which was not robust to duplicate packets, or flexible to different sets of packets. It now mirrors more commonly accepted ways of parsing such as in the inertial labs EAHRS by using a Bitmask to keep track of received packets.
The upcoming EAHRS uses this to keep track of the time_ms of each required packet, and only reports
healthy
when all tracked packets have arrived recently.Details
Behavioral changes
The GSOF GPS driver expects packets 1,2,8,9,12 enabled.
Previously, if it received packets [1,1,1,1,1] all in a row, the parser would return success, which is terrible behavior because it's missing important data. Now, it fails. This is the main improvement.
Previously, if received packets [1,2,8,9,12, 18] (ie, unexpected unparsed data), the parser would fail. It still fails, but now we can easily change the behavior.
Because the driver is in control of configuration, we only expect data that was configured.
Next Up
The upcoming Trimble External AHRS will re-use this parser, but with different packets.
See https://github.com/ArduPilot/ardupilot/compare/master...Ryanf55:ardupilot:27033-gsof-add-eahrs-driver?expand=1 for a preview.
Testing Performed
Run the unit test, uncommenting the skip line.