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

Failure detector / Failsafe (Parachute) triggering #10179

Merged
merged 32 commits into from
Jun 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a8fba74
IOFirmware - Properly clear the alarm flags
bresch Jul 30, 2018
32bdd22
Circuit Breaker - Disable flight termination circuit breaker by defau…
bresch Aug 7, 2018
54f5927
Px4io Driver - Remove unimplemented prototype
bresch Aug 9, 2018
bbe552e
FailureDetector - Update failure detector logic in commander.
bresch Jul 25, 2018
e05fdb3
PX4ioFirmware - Clean should_arm, should_arm_nothrottle and should_al…
bresch Aug 21, 2018
a439c35
PX4IO driver - use "curcuit_breaker_enabled" function instead of manu…
bresch Aug 21, 2018
5e50745
IO - Send flight termination circuit breaker state to IO through PX4I…
bresch Aug 21, 2018
e34802a
IO mixer - Change default mixer to DISARMED and allow to set outputs …
bresch Aug 21, 2018
6582bda
Failure Detector - Play TONE_PARACHUTE_RELEASE_TUNE when force failsa…
bresch Aug 22, 2018
cf342a7
PWM - Remove unused MIXERADDSIMPLE
bresch Aug 29, 2018
c152a7a
quad x mixer - Add null mixer for parachute triggering
bresch Aug 29, 2018
bf809a8
Failure Detector - Add Failure Detector check to preflight checks
bresch Aug 29, 2018
0488d7b
Failure detector - Disable flight termination by default. Modify FD_F…
bresch Dec 20, 2018
4bbb2de
FailureDetector - Add roll and pitch failures hysteresis
bresch Jan 7, 2019
a07670e
MC Lnd detector - Remove double include
bresch Jan 7, 2019
1170f8c
FailureDetector - Increase min value of FD_FAIL_P/R to 60 degrees
bresch Jan 7, 2019
8f3574f
Failure detector - Add flight termination comments, make format
bresch Jan 30, 2019
9942d87
Flight termination - Always send flag to IO without checking the circ…
bresch Jan 30, 2019
a41bb72
quad_x_main - rename parachute output to failsafe output
bresch Mar 8, 2019
c91f7de
flight termination - rename in_flight_termination to flight_terminati…
bresch Mar 8, 2019
f1c4151
FailureDetector - Add is_failure() function to simplify the interface…
bresch Mar 8, 2019
246ab89
px4io - rename safety_param_val to circuit_breaker_io_enabled and cha…
bresch Mar 8, 2019
1405a0e
Failure detector - change snake_case function names to camelCase
bresch Mar 27, 2019
42a8a8e
Failure detector - in failure detector preflight check, get
bresch Mar 27, 2019
87a1686
Flight termination - Rename "flightterm" variables and defines to "fl…
bresch Mar 27, 2019
182568f
Flight termination IO - reword flight termination flag description
bresch Apr 1, 2019
cf2cd0b
protocol.h - comment style update
bresch Apr 1, 2019
7b3cf8c
IO mixer - cleanup FMU timeout check (comments and indentation)
bresch Apr 1, 2019
c99ba1c
Failsafe - cosmetic changes
bresch Apr 1, 2019
7eecd70
IO failsafe - apply failsafe values to outputs when in failsafe.
bresch Apr 26, 2019
ff85321
IO driver - Recover flight termination state from IO after FMU reboot…
bresch Apr 26, 2019
c850c75
FailureDetector - update hysteresis to comply with new interface
bresch Jun 5, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ROMFS/px4fmu_common/mixers/quad_x.main.mix
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
R: 4x 10000 10000 10000 0

AUX1 Passthrough
M: 1
S: 3 5 10000 10000 0 -10000 10000

AUX2 Passthrough
M: 1
S: 3 6 10000 10000 0 -10000 10000

Failsafe outputs
The following outputs are set to their disarmed value
during normal operation and to their failsafe falue in case
of flight termination.
Z:
Z:
5 changes: 0 additions & 5 deletions src/drivers/drv_mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,6 @@
/** reset (clear) the mixer configuration */
#define MIXERIOCRESET _MIXERIOC(1)

/**
* add a simple mixer in (struct mixer_simple_s *)arg
*/
#define MIXERIOCADDSIMPLE _MIXERIOC(2)

julianoes marked this conversation as resolved.
Show resolved Hide resolved
/* _MIXERIOC(3) was deprecated */
/* _MIXERIOC(4) was deprecated */

Expand Down
21 changes: 0 additions & 21 deletions src/drivers/mkblctrl/mkblctrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1052,27 +1052,6 @@ MK::pwm_ioctl(file *filp, int cmd, unsigned long arg)

break;

case MIXERIOCADDSIMPLE: {
mixer_simple_s *mixinfo = (mixer_simple_s *)arg;

SimpleMixer *mixer = new SimpleMixer(control_callback,
(uintptr_t)&_controls, mixinfo);

if (mixer->check()) {
delete mixer;
ret = -EINVAL;

} else {
if (_mixers == nullptr)
_mixers = new MixerGroup(control_callback,
(uintptr_t)&_controls);

_mixers->add_mixer(mixer);
}

break;
}

case MIXERIOCLOADBUF: {
const char *buf = (const char *)arg;
unsigned buflen = strnlen(buf, 1024);
Expand Down
22 changes: 0 additions & 22 deletions src/drivers/pwm_out_sim/PWMSim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,28 +517,6 @@ PWMSim::ioctl(device::file_t *filp, int cmd, unsigned long arg)

break;

case MIXERIOCADDSIMPLE: {
mixer_simple_s *mixinfo = (mixer_simple_s *)arg;

SimpleMixer *mixer = new SimpleMixer(control_callback, (uintptr_t)&_controls, mixinfo);

if (mixer->check()) {
delete mixer;
_groups_required = 0;
ret = -EINVAL;

} else {
if (_mixers == nullptr) {
_mixers = new MixerGroup(control_callback, (uintptr_t)&_controls);
}

_mixers->add_mixer(mixer);
_mixers->groups_required(_groups_required);
}

break;
}

case MIXERIOCLOADBUF: {
const char *buf = (const char *)arg;
unsigned buflen = strnlen(buf, 1024);
Expand Down
22 changes: 0 additions & 22 deletions src/drivers/px4fmu/fmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2152,28 +2152,6 @@ PX4FMU::pwm_ioctl(file *filp, int cmd, unsigned long arg)

break;

case MIXERIOCADDSIMPLE: {
mixer_simple_s *mixinfo = (mixer_simple_s *)arg;

SimpleMixer *mixer = new SimpleMixer(control_callback, (uintptr_t)_controls, mixinfo);

if (mixer->check()) {
delete mixer;
_groups_required = 0;
ret = -EINVAL;

} else {
if (_mixers == nullptr) {
_mixers = new MixerGroup(control_callback, (uintptr_t)_controls);
}

_mixers->add_mixer(mixer);
_mixers->groups_required(_groups_required);
}

break;
}

case MIXERIOCLOADBUF: {
const char *buf = (const char *)arg;
unsigned buflen = strnlen(buf, 1024);
Expand Down
78 changes: 51 additions & 27 deletions src/drivers/px4io/px4io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,6 @@ class PX4IO : public cdev::CDev
*/
int set_update_rate(int rate);

/**
* Push failsafe values to IO.
*
* @param[in] vals Failsafe control inputs: in us PPM (900 for zero, 1500 for centered, 2100 for full)
* @param[in] len Number of channels, could up to 8
*/
int set_failsafe_values(const uint16_t *vals, unsigned len);

/**
* Disable RC input handling
*/
Expand Down Expand Up @@ -734,17 +726,56 @@ PX4IO::init()
errx(1, "PRM CMPID");
}

/* send command to arm system via command API */
/* prepare vehicle command */
vehicle_command_s vcmd = {};
vcmd.timestamp = hrt_absolute_time();
vcmd.param1 = 1.0f; /* request arming */
vcmd.command = vehicle_command_s::VEHICLE_CMD_COMPONENT_ARM_DISARM;
vcmd.target_system = (uint8_t)sys_id;
vcmd.target_component = (uint8_t)comp_id;
vcmd.source_system = (uint8_t)sys_id;
vcmd.source_component = (uint8_t)comp_id;
vcmd.confirmation = true; /* ask to confirm command */

if (reg & PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE) {
mavlink_log_emergency(&_mavlink_log_pub, "IO is in failsafe, force failsafe");
/* send command to terminate flight via command API */
vcmd.timestamp = hrt_absolute_time();
vcmd.param1 = 1.0f; /* request flight termination */
vcmd.command = vehicle_command_s::VEHICLE_CMD_DO_FLIGHTTERMINATION;

/* send command once */
orb_advert_t pub = orb_advertise_queue(ORB_ID(vehicle_command), &vcmd, vehicle_command_s::ORB_QUEUE_LENGTH);

/* spin here until IO's state has propagated into the system */
do {
orb_check(safety_sub, &updated);

if (updated) {
orb_copy(ORB_ID(actuator_armed), safety_sub, &safety);
}

/* wait 50 ms */
px4_usleep(50000);

/* abort after 5s */
if ((hrt_absolute_time() - try_start_time) / 1000 > 2000) {
mavlink_log_emergency(&_mavlink_log_pub, "Failed to recover from in-air restart (3), abort");
return 1;
}

/* re-send if necessary */
if (!safety.force_failsafe) {
orb_publish(ORB_ID(vehicle_command), pub, &vcmd);
PX4_WARN("re-sending flight termination cmd");
}

/* keep waiting for state change for 2 s */
} while (!safety.force_failsafe);
}

/* send command to arm system via command API */
vcmd.timestamp = hrt_absolute_time();
vcmd.param1 = 1.0f; /* request arming */
vcmd.command = vehicle_command_s::VEHICLE_CMD_COMPONENT_ARM_DISARM;

/* send command once */
orb_advert_t pub = orb_advertise_queue(ORB_ID(vehicle_command), &vcmd, vehicle_command_s::ORB_QUEUE_LENGTH);

Expand Down Expand Up @@ -1031,21 +1062,15 @@ PX4IO::task_main()
}
}

int32_t safety_param_val;
param_t safety_param = param_find("CBRK_IO_SAFETY");

if (safety_param != PARAM_INVALID) {

param_get(safety_param, &safety_param_val);

if (safety_param_val == PX4IO_FORCE_SAFETY_MAGIC) {
/* disable IO safety if circuit breaker asked for it */
(void)io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FORCE_SAFETY_OFF, safety_param_val);
}
}
/* Check if the IO safety circuit breaker has been updated */
bool circuit_breaker_io_safety_enabled = circuit_breaker_enabled("CBRK_IO_SAFETY", CBRK_IO_SAFETY_KEY);
/* Bypass IO safety switch logic by setting FORCE_SAFETY_OFF */
(void)io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FORCE_SAFETY_OFF, circuit_breaker_io_safety_enabled);

/* Check if the flight termination circuit breaker has been updated */
_cb_flighttermination = circuit_breaker_enabled("CBRK_FLIGHTTERM", CBRK_FLIGHTTERM_KEY);
/* Tell IO that it can terminate the flight if FMU is not responding or if a failure has been reported by the FailureDetector logic */
(void)io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ENABLE_FLIGHTTERMINATION, !_cb_flighttermination);

param_get(param_find("RC_RSSI_PWM_CHAN"), &_rssi_pwm_chan);
param_get(param_find("RC_RSSI_PWM_MAX"), &_rssi_pwm_max);
Expand Down Expand Up @@ -1385,8 +1410,7 @@ PX4IO::io_set_arming_state()
_lockdown_override = false;
}

/* Do not set failsafe if circuit breaker is enabled */
if (armed.force_failsafe && !_cb_flighttermination) {
if (armed.force_failsafe) {
set |= PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE;

} else {
Expand Down Expand Up @@ -2217,7 +2241,7 @@ PX4IO::print_status(bool extended_status)
((alarms & PX4IO_P_STATUS_ALARMS_PWM_ERROR) ? " PWM_ERROR" : ""),
((alarms & PX4IO_P_STATUS_ALARMS_VSERVO_FAULT) ? " VSERVO_FAULT" : ""));
/* now clear alarms */
io_reg_set(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_ALARMS, 0xFFFF);
io_reg_set(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_ALARMS, 0x0000);
julianoes marked this conversation as resolved.
Show resolved Hide resolved

if (_hardware == 2) {
printf("vservo %u mV vservo scale %u\n",
Expand Down
6 changes: 3 additions & 3 deletions src/lib/circuit_breaker/circuit_breaker_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ PARAM_DEFINE_INT32(CBRK_AIRSPD_CHK, 0);
/**
* Circuit breaker for flight termination
*
* Setting this parameter to 121212 will disable the flight termination action.
* --> The IO driver will not do flight termination if requested by the FMU
* WARNING: ENABLING THIS CIRCUIT BREAKER IS AT OWN RISK
* Setting this parameter to 121212 will disable the flight termination action if triggered
* by the FailureDetector logic or if FMU is lost.
bkueng marked this conversation as resolved.
Show resolved Hide resolved
* This circuit breaker does not affect the RC loss, data link loss and geofence safety logic.
*
* @reboot_required true
* @min 0
Expand Down
33 changes: 19 additions & 14 deletions src/modules/commander/Commander.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2206,27 +2206,32 @@ Commander::run()
}

/* Check for failure detector status */
if (armed.armed) {
const bool failure_detector_updated = _failure_detector.update();

if (_failure_detector.update()) {
if (failure_detector_updated) {

const uint8_t failure_status = _failure_detector.get_status();
const uint8_t failure_status = _failure_detector.getStatus();

if (failure_status != status.failure_detector_status) {
status.failure_detector_status = failure_status;
status_changed = true;
}
if (failure_status != status.failure_detector_status) {
status.failure_detector_status = failure_status;
status_changed = true;
}
}

if (failure_status != 0 && !status_flags.circuit_breaker_flight_termination_disabled) {
if (armed.armed &&
failure_detector_updated &&
!_flight_termination_triggered &&
!status_flags.circuit_breaker_flight_termination_disabled) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Next time try to make a separate commit for formatting only.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wow so many negations 😄, let me try wrap my head around this:

So if the circuit breaker is enabled which is the default then the variable circuit_breaker_flight_termination_disabled is true meaning the flight termination is "disabled", so nothing is happening. Now if the circuit breaker is disabled (set to 0), the flight termination is "enabled", so "no disabled", and therefore this block is called.

I think that's correct.


// TODO: set force_failsafe flag
if (_failure_detector.isFailure()) {

if (!_failure_detector_termination_printed) {
mavlink_log_critical(&mavlink_log_pub, "Attitude failure detected! Enforcing failsafe");
_failure_detector_termination_printed = true;
}
armed.force_failsafe = true;
status_changed = true;

}
_flight_termination_triggered = true;

mavlink_log_critical(&mavlink_log_pub, "Critical failure detected: terminate flight");
set_tune_override(TONE_PARACHUTE_RELEASE_TUNE);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/modules/commander/Commander.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class Commander : public ModuleBase<Commander>, public ModuleParams
bool _geofence_violated_prev{false};

FailureDetector _failure_detector;
bool _failure_detector_termination_printed{false};
bool _flight_termination_triggered{false};

bool handle_command(vehicle_status_s *status, const vehicle_command_s &cmd, actuator_armed_s *armed,
orb_advert_t *command_ack_pub, bool *changed);
Expand Down
40 changes: 40 additions & 0 deletions src/modules/commander/PreflightCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,38 @@ static bool ekf2Check(orb_advert_t *mavlink_log_pub, vehicle_status_s &vehicle_s
return success;
}

static bool failureDetectorCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status, bool report_fail,
bool prearm)
{
bool success = true;

if (!prearm) {
// Ignore failure detector check after arming.
return true;

}

if (status.failure_detector_status != vehicle_status_s::FAILURE_NONE) {
success = false;

if (report_fail) {
if (status.failure_detector_status & vehicle_status_s::FAILURE_ROLL) {
mavlink_log_critical(mavlink_log_pub, "Preflight Fail: Roll failure detected");
}

if (status.failure_detector_status & vehicle_status_s::FAILURE_PITCH) {
mavlink_log_critical(mavlink_log_pub, "Preflight Fail: Pitch failure detected");
}

if (status.failure_detector_status & vehicle_status_s::FAILURE_ALT) {
mavlink_log_critical(mavlink_log_pub, "Preflight Fail: Altitude failure detected");
}
}
}

return success;
}

bool preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status,
vehicle_status_flags_s &status_flags, bool checkGNSS, bool reportFailures, bool prearm,
const hrt_abstime &time_since_boot)
Expand All @@ -689,6 +721,7 @@ bool preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status,
const bool checkRC = (status.rc_input_mode == vehicle_status_s::RC_IN_MODE_DEFAULT);
const bool checkDynamic = !hil_enabled;
const bool checkPower = (status_flags.condition_power_input_valid && !status_flags.circuit_breaker_engaged_power_check);
const bool checkFailureDetector = true;

bool checkAirspeed = false;

Expand Down Expand Up @@ -944,6 +977,13 @@ bool preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status,
}
}

/* ---- Failure Detector ---- */
if (checkFailureDetector) {
if (!failureDetectorCheck(mavlink_log_pub, status, (reportFailures && !failed), prearm)) {
failed = true;
}
}

/* Report status */
return !failed;
}
Expand Down
Loading