-
Notifications
You must be signed in to change notification settings - Fork 13.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
commander state machine fix preflight and prearm error #9193
Conversation
830d7b1
to
7d75ccd
Compare
@PX4/testflights please bench test on a couple different systems. Verify things like...
|
7164ae2
to
7c6c0ca
Compare
b6452f6
to
e81f370
Compare
TODO (possibly after this PR):
|
Test with pixhawk 2.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.
Nice cleanup! I made some inline comments.
|
||
system_power_s system_power = {}; | ||
|
||
if (orb_copy(ORB_ID(system_power), system_power_sub, &system_power) == PX4_OK) { |
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 there is no system power update, this check will just pass. As I understand it, there will always be one orb_copy
and therefore we would copy an avionics_power_rail_voltage
of 0
and fail anyway.
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 added a time elapsed check as a workaround, which should be fine for now, but still isn't ideal. After this PR I was thinking about centralizing the arming requirements checks. We can make system_power explicitly required or not.
{ | ||
bool success = true; // start with a pass and change to a fail if any test fails | ||
|
||
if (prearm) { |
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'd prefer the structure like this:
if (!prearm) {
// Ignore power check after arming.
return true;
}
...
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.
Sure, that works for me.
@@ -570,12 +612,12 @@ static bool ekf2Check(orb_advert_t *mavlink_log_pub, bool optional, bool report_ | |||
} | |||
|
|||
bool preflightCheck(orb_advert_t *mavlink_log_pub, bool checkSensors, bool checkAirspeed, bool checkRC, bool checkGNSS, | |||
bool checkDynamic, bool isVTOL, bool reportFailures, bool prearm, hrt_abstime time_since_boot) | |||
bool checkDynamic, bool checkPower, bool isVTOL, bool reportFailures, bool prearm, const hrt_abstime &time_since_boot) |
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 list of bools needs to go away in the future, that's super error-prone. A struct
containing the bools would already be better.
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.
Completely agree. I was going to start using vehicle_status_flags and vehicle_status after this PR.
failed = true; | ||
mag_fail_reported = true; |
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 mag_fail_reported
flag doesn't do anything as I understand it. Since max_mandatory_mag_count
is 1, only the first check is required. After that (reportFailures && !mag_fail_reported)) && required
evaluates to false
anyway.
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 should prevent the repetition of
PREFLIGHT FAIL: MAG 0 UNCALIBRATED
PREFLIGHT FAIL: MAG 1 UNCALIBRATED
PREFLIGHT FAIL: MAG 2 UNCALIBRATED
Since you can only calibrate them in bulk, I didn't see the point in reporting more than a single line.
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.
But if you only report for mandatory devices then you don't need the reported flag, required
should be enough.
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 still reports uncalibrated for optional devices. I find the entire thing more convoluted than necessary. It could almost be refactored into a template for all types.
* Perform an atomic state update | ||
*/ | ||
#ifdef __PX4_NUTTX | ||
irqstate_t flags = px4_enter_critical_section(); |
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's the reason that all this is removed?
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 is it needed? The state machine isn't grabbing new system data in this section. If it was important we'd also need an equivalent on Linux and QuRT.
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 know. But ok makes sense then.
if (reportFailures && !prearm_ok) { | ||
status_flags->condition_system_prearm_error_reported = true; | ||
// Arm Requirements: authorization | ||
// check last, and only if everything else has passed |
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.
Makes sense.
Thanks @Avysuarez. Did you see any situations where arming was blocked and no explanation was given? Did you see any situations where there was a mavlink critical message (pop up in the yellow box), but arming was allowed to complete? |
281e595
to
b89e407
Compare
NOTE: With the 1.7.2 release, I sometimes cannot arm because of the following error: This is on a Pixhawk 1, with only one IMU. This does not happen on 1.6.5. EDIT: It actually has the MPU6000 as main accel and gyro and a ST Micro 14-bit accelerometer/compass. |
No, I didn't see any, in all tests when there were no conditions to arm I received messages with the explanation.
No, I didn't see any. When I got mavlink critical messages such as low battery, gps not ready to takeoff, etc, arming was not allowed. |
With this PR, we should as well check if the handle_position_target_local_ned(const mavlink::mavlink_message_t *msg, mavlink::common::msg::POSITION_TARGET_LOCAL_NED &tgt) NOTE: I don't know where this is located in the PX4 Firmware. |
- only call prearm if preflight passes - prearm always provide feedback
- this flag often results in hiding useful information, or adding useless information to the mavlink console
- add preflight_check helper
- this is needed for the unit tests
e4b050b
to
43160d3
Compare
Rebased on master again. Last call for testing. |
Thanks everyone. |
@dagar In the new preflight check, this Is there a specific reason for that? I am asking because I have a system here that is always showing 0.0V on both rails and now the preflight check fails obviously. That |
The structure is a bit different now because the avionics power rail voltage is no longer passed into the arming state machine directly as a float. Now it's only checked after the system_power message publishes, so we don't need the > 0.0 hack. There's also the power circuit breaker that can be used to explicitly ignore these checks. |
There were many issues. The most important immediate issue is that preflight checks haven't been blocking arming. Additionally many little annoying edge cases I've experienced finally make sense to me where you might not be provided appropriate (or any) feedback trying to arm.
There's still a lot more to do here, but this restores a level of sanity. The next steps from my perspective would be removing the actual sensor check calls from the state machine and centralizing all of it on the commander side. Then commander would simple pass the appropriate flags into a much simpler generated (and documented) state machine.