Skip to content
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

Merged
merged 22 commits into from
Apr 17, 2018

Conversation

dagar
Copy link
Member

@dagar dagar commented Mar 30, 2018

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.

@dagar
Copy link
Member Author

dagar commented Mar 30, 2018

@PX4/testflights please bench test on a couple different systems.

Verify things like...

  • safety button works as expected for arming or preventing arming
  • low battery prevents arming
  • test the COM_ARM_WO_GPS parameter
  • test the COM_ARM_MIS_REQ parameter
  • try to arm with a bogus compass setup (uncalibrated, external rotated 90 degrees, etc)
  • try to arm with USB connected

@dagar dagar force-pushed the pr-commander_state_machine_preflight branch 3 times, most recently from 7164ae2 to 7c6c0ca Compare March 30, 2018 15:31
@dagar dagar requested a review from LorenzMeier March 30, 2018 15:31
@dagar dagar force-pushed the pr-commander_state_machine_preflight branch 2 times, most recently from b6452f6 to e81f370 Compare April 2, 2018 15:11
@dagar
Copy link
Member Author

dagar commented Apr 3, 2018

TODO (possibly after this PR):

  • review preflight, prearm, and all the state machines in general with respect to calibration. I believe there are currently some holes.
  • review HIL and try to extract and centralize all HIL specific behaviour changes. The state machines themselves (and eventually all of commander) could be completely oblivious to HIL.

@Avysuarez
Copy link

Test with pixhawk 2.1:
1; safety button works as expected for arming or preventing arming.
Not arming.
2;low battery prevents arming.
Not arming, low battery message.
3; test the COM_ARM_WO_GPS parameter.
Not arming. position reject message
4;test the COM_ARM_MIS_REQ parameter.
Not arming
5; try to arm with a bogus compass setup (uncalibrated, external rotated 90 degrees, etc)
Not arming.
6; try to arm with USB connected.
Not arming.

Copy link
Contributor

@julianoes julianoes left a 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) {
Copy link
Contributor

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.

Copy link
Member Author

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) {
Copy link
Contributor

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;
}
...

Copy link
Member Author

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)
Copy link
Contributor

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.

Copy link
Member Author

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;
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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.

Copy link
Member Author

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();
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.

@dagar
Copy link
Member Author

dagar commented Apr 5, 2018

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?

@dagar dagar force-pushed the pr-commander_state_machine_preflight branch 2 times, most recently from 281e595 to b89e407 Compare April 5, 2018 01:25
@AlexisTM
Copy link
Contributor

AlexisTM commented Apr 5, 2018

NOTE: With the 1.7.2 release, I sometimes cannot arm because of the following error: PREFLIGHT FAIL: ACCEL SENSORS INCONSISTENT - CHECK CALIBRATION.

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.

@Avysuarez
Copy link

@dagar

Did you see any situations where arming was blocked and no explanation was given?

No, I didn't see any, in all tests when there were no conditions to arm I received messages with the explanation.

Did you see any situations where there was a mavlink critical message (pop up in the yellow box), but arming was allowed to complete?

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.

@AlexisTM
Copy link
Contributor

AlexisTM commented Apr 6, 2018

@dagar

With this PR, we should as well check if the target_local_ned module is initialized and publishing before allowing the OFFBOARD mode (or any other mode?). Aka the PX4 publisher for the following MAVLink handler:

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.

dagar added 19 commits April 16, 2018 16:33
 - 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
 - this is needed for the unit tests
@dagar dagar force-pushed the pr-commander_state_machine_preflight branch from e4b050b to 43160d3 Compare April 16, 2018 20:35
@dagar
Copy link
Member Author

dagar commented Apr 16, 2018

Rebased on master again. Last call for testing.

@dagar dagar merged commit 7bc3a12 into master Apr 17, 2018
@dagar
Copy link
Member Author

dagar commented Apr 17, 2018

Thanks everyone.

@potaito
Copy link
Contributor

potaito commented May 4, 2018

@dagar
I am a bit late to the party, but can you clarify something? Before, the power check would only run if the 3.3V and 5.0V power rails were above 0.0V:
https://github.com/PX4/Firmware/blob/c679703da49528cedbbf31766dfffdcb0f5c2863/src/modules/commander/state_machine_helper.cpp#L227-L244

In the new preflight check, this >0.0 condition has been removed:
https://github.com/PX4/Firmware/blob/df042ab20e5ab1df43a322eacdb0e189c1b01652/src/modules/commander/PreflightCheck.cpp#L496-L513

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 >0.0 check was probably a hack in the first place. So I understand if it should be removed.

@dagar
Copy link
Member Author

dagar commented May 4, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants