-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
Add validation to initialization configuration commands #27459
Changes from all commits
3207d2f
d4722b1
884a889
51db6eb
9611503
a8370f3
93673c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -286,28 +286,35 @@ bool AP_ExternalAHRS_VectorNav::check_uart() | |
return true; | ||
} | ||
|
||
// Send command to read given register number and wait for response | ||
// Only run from thread! This blocks until a response is received | ||
// Send command and wait for response | ||
// Only run from thread! This blocks and retries until a non-error response is received | ||
#define READ_REQUEST_RETRY_MS 500 | ||
void AP_ExternalAHRS_VectorNav::wait_register_responce(const uint8_t register_num) | ||
void AP_ExternalAHRS_VectorNav::run_command(const char * fmt, ...) | ||
{ | ||
nmea.register_number = register_num; | ||
va_list ap; | ||
|
||
va_start(ap, fmt); | ||
hal.util->vsnprintf(message_to_send, sizeof(message_to_send), fmt, ap); | ||
va_end(ap); | ||
|
||
uint32_t request_sent = 0; | ||
while (true) { | ||
hal.scheduler->delay(1); | ||
|
||
const uint32_t now = AP_HAL::millis(); | ||
if (now - request_sent > READ_REQUEST_RETRY_MS) { | ||
// Send request to read | ||
nmea_printf(uart, "$%s%u", "VNRRG,", nmea.register_number); | ||
nmea_printf(uart, "$%s", message_to_send); | ||
request_sent = now; | ||
} | ||
|
||
int16_t nbytes = uart->available(); | ||
while (nbytes-- > 0) { | ||
char c = uart->read(); | ||
if (decode(c)) { | ||
if (nmea.error_response && nmea.sentence_done) { | ||
// Received a valid VNERR. Try to resend after the timeout length | ||
break; | ||
} | ||
return; | ||
} | ||
} | ||
|
@@ -356,6 +363,7 @@ bool AP_ExternalAHRS_VectorNav::decode(char c) | |
nmea.checksum = 0; | ||
nmea.term_is_checksum = false; | ||
nmea.sentence_done = false; | ||
nmea.error_response = false; | ||
return false; | ||
} | ||
|
||
|
@@ -371,57 +379,60 @@ bool AP_ExternalAHRS_VectorNav::decode(char c) | |
} | ||
|
||
// decode the most recently consumed term | ||
// returns true if new sentence has just passed checksum test and is validated | ||
// returns true if new term is valid | ||
bool AP_ExternalAHRS_VectorNav::decode_latest_term() | ||
{ | ||
// Check the first two terms (In most cases header + reg number) that they match the sent | ||
// message. If not, the response is invalid. | ||
switch (nmea.term_number) { | ||
case 0: | ||
if (strcmp(nmea.term, "VNRRG") != 0) { | ||
if (strncmp(nmea.term, "VNERR", nmea.term_offset) == 0) { | ||
nmea.error_response = true; // Message will be printed on next term | ||
} else if (strncmp(nmea.term, message_to_send, nmea.term_offset) != 0) { | ||
return false; | ||
} | ||
break; | ||
|
||
case 1: | ||
if (nmea.register_number != strtoul(nmea.term, nullptr, 10)) { | ||
return true; | ||
case 1: | ||
if (nmea.error_response) { | ||
GCS_SEND_TEXT(MAV_SEVERITY_CRITICAL, "VectorNav received VNERR code: %s", nmea.term); | ||
} else if (strlen(message_to_send) > 6 && | ||
strncmp(nmea.term, &message_to_send[6], nmea.term_offset != 0)) { // Start after "VNXXX," | ||
return false; | ||
} | ||
break; | ||
|
||
case 2: | ||
strncpy(model_name, nmea.term, sizeof(model_name)); | ||
break; | ||
|
||
return true; | ||
case 2: | ||
if (strncmp(nmea.term, "VN-", 3) == 0) { | ||
// This term is the model number | ||
strncpy(model_name, nmea.term, sizeof(model_name)); | ||
} | ||
return true; | ||
default: | ||
return false; | ||
return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This deserves a comment - we ignore any terms past the third? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The prior iteration of this driver only received responses up to 3 terms, meaning it should mark any response it saw above 3 as invalid. This will now receive 5 or 6 term responses, so it shouldn't invalidate the responses longer than 3 terms. |
||
} | ||
return true; | ||
} | ||
|
||
void AP_ExternalAHRS_VectorNav::update_thread() | ||
{ | ||
void AP_ExternalAHRS_VectorNav::initialize() { | ||
// Open port in the thread | ||
uart->begin(baudrate, 1024, 512); | ||
|
||
// Reset and wait for module to reboot | ||
// VN_100 takes 1.25 seconds | ||
//nmea_printf(uart, "$VNRST"); | ||
//hal.scheduler->delay(3000); | ||
// Pause asynchronous communications to simplify packet finding | ||
run_command("VNASY,0"); | ||
|
||
// Stop NMEA Async Outputs (this UART only) | ||
nmea_printf(uart, "$VNWRG,6,0"); | ||
// Stop ASCII async outputs for both UARTs. If only active UART is disabled, we get a baudrate | ||
// overflow on the other UART when configuring binary outputs (reg 75 and 76) to both UARTs | ||
run_command("VNWRG,06,0,1"); | ||
run_command("VNWRG,06,0,2"); | ||
|
||
// Detect version | ||
// Read Model Number Register, ID 1 | ||
wait_register_responce(1); | ||
run_command("VNRRG,01"); | ||
|
||
// Setup for messages respective model types (on both UARTs) | ||
if (strncmp(model_name, "VN-1", 4) == 0) { | ||
// VN-100 | ||
// VN-1X0 | ||
type = TYPE::VN_AHRS; | ||
|
||
// This assumes unit is still configured at its default rate of 800hz | ||
nmea_printf(uart, "$VNWRG,75,3,%u,14,073E,0004", unsigned(800/get_rate())); | ||
|
||
run_command("VNWRG,75,3,%u,14,073E,0004", unsigned(800 / get_rate())); | ||
} else { | ||
// Default to setup for sensors other than VN-100 or VN-110 | ||
// This assumes unit is still configured at its default IMU rate of 400hz for VN-300, 800hz for others | ||
|
@@ -432,11 +443,17 @@ void AP_ExternalAHRS_VectorNav::update_thread() | |
if (strncmp(model_name, "VN-3", 4) == 0) { | ||
has_dual_gnss = true; | ||
} | ||
nmea_printf(uart, "$VNWRG,75,3,%u,34,072E,0106,0612", unsigned(imu_rate/get_rate())); | ||
nmea_printf(uart, "$VNWRG,76,3,%u,4E,0002,0010,20B8,0018", unsigned(imu_rate/5)); | ||
run_command("VNWRG,75,3,%u,34,072E,0106,0612", unsigned(imu_rate / get_rate())); | ||
run_command("VNWRG,76,3,%u,4E,0002,0010,20B8,0018", unsigned(imu_rate / 5)); | ||
} | ||
|
||
// Resume asynchronous communications | ||
run_command("VNASY,1"); | ||
setup_complete = true; | ||
} | ||
|
||
void AP_ExternalAHRS_VectorNav::update_thread() { | ||
initialize(); | ||
while (true) { | ||
if (!check_uart()) { | ||
hal.scheduler->delay(1); | ||
|
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 might be problematic as the driver evolves. There's an assumption in here that whatever is in the pipeline to/from the device is the command we're currently trying to execute.
That may not be the case outside of the initialisation phase of the driver.
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.
@peterbarker
I don't think I understand this comment.
I agree that the driver assumes that a blocking call doesn't have an interrupting call. Is that what you mean?
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.
What I was getting at here is that your UART might contain incoming data that isn't related to the command you just sent. If you parse a message out of that buffer you may attribute it to the command you sent rather than a previous command.
It's not an easy thing to resolve (flushing the input buffer isn't actually sufficient as there may be outstanding commands on the way t into the VectorNav.
If you're not fussed with this I don't particular mind; it's not a major safety issue for the vehicle.