mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
Enable directly injecting motor failures using e.g. failure motor off -i 1
Only if SYS_FAILURE_EN is enabled and CA_FAILURE_MODE is > 0.
This commit is contained in:
parent
786e0a12c2
commit
e59afce5db
@ -19,3 +19,4 @@ int8[16] actuator_saturation # Indicates actuator saturation status.
|
|||||||
# Note 2: an actuator with limited dynamics can be indicated as upper-saturated even if it as not reached its maximum value.
|
# Note 2: an actuator with limited dynamics can be indicated as upper-saturated even if it as not reached its maximum value.
|
||||||
|
|
||||||
uint16 handled_motor_failure_mask # Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector
|
uint16 handled_motor_failure_mask # Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector
|
||||||
|
uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection
|
||||||
|
|||||||
@ -12,3 +12,4 @@ bool fd_motor
|
|||||||
|
|
||||||
float32 imbalanced_prop_metric # Metric of the imbalanced propeller check (low-passed)
|
float32 imbalanced_prop_metric # Metric of the imbalanced propeller check (low-passed)
|
||||||
uint16 motor_failure_mask # Bit-mask with motor indices, indicating critical motor failures
|
uint16 motor_failure_mask # Bit-mask with motor indices, indicating critical motor failures
|
||||||
|
uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection
|
||||||
|
|||||||
@ -1956,6 +1956,7 @@ void Commander::run()
|
|||||||
fd_status.fd_motor = _failure_detector.getStatusFlags().motor;
|
fd_status.fd_motor = _failure_detector.getStatusFlags().motor;
|
||||||
fd_status.imbalanced_prop_metric = _failure_detector.getImbalancedPropMetric();
|
fd_status.imbalanced_prop_metric = _failure_detector.getImbalancedPropMetric();
|
||||||
fd_status.motor_failure_mask = _failure_detector.getMotorFailures();
|
fd_status.motor_failure_mask = _failure_detector.getMotorFailures();
|
||||||
|
fd_status.motor_stop_mask = _failure_detector.getMotorStopMask();
|
||||||
fd_status.timestamp = hrt_absolute_time();
|
fd_status.timestamp = hrt_absolute_time();
|
||||||
_failure_detector_status_pub.publish(fd_status);
|
_failure_detector_status_pub.publish(fd_status);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,6 +89,7 @@ public:
|
|||||||
const decltype(failure_detector_status_u::flags) &getStatusFlags() const { return _status.flags; }
|
const decltype(failure_detector_status_u::flags) &getStatusFlags() const { return _status.flags; }
|
||||||
float getImbalancedPropMetric() const { return _imbalanced_prop_lpf.getState(); }
|
float getImbalancedPropMetric() const { return _imbalanced_prop_lpf.getState(); }
|
||||||
uint16_t getMotorFailures() const { return _motor_failure_esc_timed_out_mask | _motor_failure_esc_under_current_mask; }
|
uint16_t getMotorFailures() const { return _motor_failure_esc_timed_out_mask | _motor_failure_esc_under_current_mask; }
|
||||||
|
uint16_t getMotorStopMask() { return _failure_injector.getMotorStopMask(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateAttitudeStatus(const vehicle_status_s &vehicle_status);
|
void updateAttitudeStatus(const vehicle_status_s &vehicle_status);
|
||||||
|
|||||||
@ -33,10 +33,23 @@
|
|||||||
|
|
||||||
#include "FailureInjector.hpp"
|
#include "FailureInjector.hpp"
|
||||||
|
|
||||||
|
#include <parameters/param.h>
|
||||||
#include <uORB/topics/actuator_motors.h>
|
#include <uORB/topics/actuator_motors.h>
|
||||||
|
|
||||||
|
FailureInjector::FailureInjector()
|
||||||
|
{
|
||||||
|
int32_t param_sys_failure_en = 0;
|
||||||
|
|
||||||
|
if ((param_get(param_find("SYS_FAILURE_EN"), ¶m_sys_failure_en) == PX4_OK)
|
||||||
|
&& (param_sys_failure_en == 1)) {
|
||||||
|
_failure_injection_enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FailureInjector::update()
|
void FailureInjector::update()
|
||||||
{
|
{
|
||||||
|
if (!_failure_injection_enabled) { return; }
|
||||||
|
|
||||||
vehicle_command_s vehicle_command;
|
vehicle_command_s vehicle_command;
|
||||||
|
|
||||||
while (_vehicle_command_sub.update(&vehicle_command)) {
|
while (_vehicle_command_sub.update(&vehicle_command)) {
|
||||||
@ -59,14 +72,21 @@ void FailureInjector::update()
|
|||||||
switch (failure_type) {
|
switch (failure_type) {
|
||||||
case vehicle_command_s::FAILURE_TYPE_OK:
|
case vehicle_command_s::FAILURE_TYPE_OK:
|
||||||
supported = true;
|
supported = true;
|
||||||
PX4_INFO("CMD_INJECT_FAILURE, motor %d ok", i);
|
PX4_INFO("CMD_INJECT_FAILURE, motor %d ok", i + 1);
|
||||||
|
_motor_stop_mask &= ~(1 << i);
|
||||||
_esc_telemetry_blocked_mask &= ~(1 << i);
|
_esc_telemetry_blocked_mask &= ~(1 << i);
|
||||||
_esc_telemetry_wrong_mask &= ~(1 << i);
|
_esc_telemetry_wrong_mask &= ~(1 << i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vehicle_command_s::FAILURE_TYPE_OFF:
|
case vehicle_command_s::FAILURE_TYPE_OFF:
|
||||||
supported = true;
|
supported = true;
|
||||||
PX4_INFO("CMD_INJECT_FAILURE, motor %d no esc telemetry", i);
|
PX4_INFO("CMD_INJECT_FAILURE, motor %d off", i + 1);
|
||||||
|
_motor_stop_mask |= 1 << i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vehicle_command_s::FAILURE_TYPE_STUCK:
|
||||||
|
supported = true;
|
||||||
|
PX4_INFO("CMD_INJECT_FAILURE, motor %d no esc telemetry", i + 1);
|
||||||
_esc_telemetry_blocked_mask |= 1 << i;
|
_esc_telemetry_blocked_mask |= 1 << i;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -91,6 +111,8 @@ void FailureInjector::update()
|
|||||||
|
|
||||||
void FailureInjector::manipulateEscStatus(esc_status_s &status)
|
void FailureInjector::manipulateEscStatus(esc_status_s &status)
|
||||||
{
|
{
|
||||||
|
if (!_failure_injection_enabled) { return; }
|
||||||
|
|
||||||
if (_esc_telemetry_blocked_mask != 0 || _esc_telemetry_wrong_mask != 0) {
|
if (_esc_telemetry_blocked_mask != 0 || _esc_telemetry_wrong_mask != 0) {
|
||||||
for (int i = 0; i < status.esc_count; i++) {
|
for (int i = 0; i < status.esc_count; i++) {
|
||||||
const unsigned i_esc = status.esc[i].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1;
|
const unsigned i_esc = status.esc[i].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1;
|
||||||
|
|||||||
@ -42,13 +42,18 @@
|
|||||||
class FailureInjector
|
class FailureInjector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
FailureInjector();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
void manipulateEscStatus(esc_status_s &status);
|
void manipulateEscStatus(esc_status_s &status);
|
||||||
|
uint32_t getMotorStopMask() { return _motor_stop_mask; }
|
||||||
private:
|
private:
|
||||||
uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)};
|
uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)};
|
||||||
uORB::Publication<vehicle_command_ack_s> _command_ack_pub{ORB_ID(vehicle_command_ack)};
|
uORB::Publication<vehicle_command_ack_s> _command_ack_pub{ORB_ID(vehicle_command_ack)};
|
||||||
|
|
||||||
|
bool _failure_injection_enabled = false;
|
||||||
|
uint32_t _motor_stop_mask{};
|
||||||
uint32_t _esc_telemetry_blocked_mask{};
|
uint32_t _esc_telemetry_blocked_mask{};
|
||||||
uint32_t _esc_telemetry_wrong_mask{};
|
uint32_t _esc_telemetry_wrong_mask{};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -641,6 +641,7 @@ ControlAllocator::publish_control_allocator_status(int matrix_index)
|
|||||||
|
|
||||||
// Handled motor failures
|
// Handled motor failures
|
||||||
control_allocator_status.handled_motor_failure_mask = _handled_motor_failure_bitmask;
|
control_allocator_status.handled_motor_failure_mask = _handled_motor_failure_bitmask;
|
||||||
|
control_allocator_status.motor_stop_mask = _motor_stop_mask;
|
||||||
|
|
||||||
_control_allocator_status_pub[matrix_index].publish(control_allocator_status);
|
_control_allocator_status_pub[matrix_index].publish(control_allocator_status);
|
||||||
}
|
}
|
||||||
@ -665,7 +666,9 @@ ControlAllocator::publish_actuator_controls()
|
|||||||
int actuator_idx = 0;
|
int actuator_idx = 0;
|
||||||
int actuator_idx_matrix[ActuatorEffectiveness::MAX_NUM_MATRICES] {};
|
int actuator_idx_matrix[ActuatorEffectiveness::MAX_NUM_MATRICES] {};
|
||||||
|
|
||||||
uint32_t stopped_motors = _actuator_effectiveness->getStoppedMotors() | _handled_motor_failure_bitmask;
|
uint32_t stopped_motors = _actuator_effectiveness->getStoppedMotors()
|
||||||
|
| _handled_motor_failure_bitmask
|
||||||
|
| _motor_stop_mask;
|
||||||
|
|
||||||
// motors
|
// motors
|
||||||
int motors_idx;
|
int motors_idx;
|
||||||
@ -716,8 +719,13 @@ ControlAllocator::check_for_motor_failures()
|
|||||||
|
|
||||||
if ((FailureMode)_param_ca_failure_mode.get() > FailureMode::IGNORE
|
if ((FailureMode)_param_ca_failure_mode.get() > FailureMode::IGNORE
|
||||||
&& _failure_detector_status_sub.update(&failure_detector_status)) {
|
&& _failure_detector_status_sub.update(&failure_detector_status)) {
|
||||||
if (failure_detector_status.fd_motor) {
|
|
||||||
|
|
||||||
|
if (_motor_stop_mask != failure_detector_status.motor_stop_mask) {
|
||||||
|
_motor_stop_mask = failure_detector_status.motor_stop_mask;
|
||||||
|
PX4_WARN("Stopping motors (%d)", _motor_stop_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failure_detector_status.fd_motor) {
|
||||||
if (_handled_motor_failure_bitmask != failure_detector_status.motor_failure_mask) {
|
if (_handled_motor_failure_bitmask != failure_detector_status.motor_failure_mask) {
|
||||||
// motor failure bitmask changed
|
// motor failure bitmask changed
|
||||||
switch ((FailureMode)_param_ca_failure_mode.get()) {
|
switch ((FailureMode)_param_ca_failure_mode.get()) {
|
||||||
|
|||||||
@ -201,6 +201,7 @@ private:
|
|||||||
// Reflects motor failures that are currently handled, not motor failures that are reported.
|
// Reflects motor failures that are currently handled, not motor failures that are reported.
|
||||||
// For example, the system might report two motor failures, but only the first one is handled by CA
|
// For example, the system might report two motor failures, but only the first one is handled by CA
|
||||||
uint16_t _handled_motor_failure_bitmask{0};
|
uint16_t _handled_motor_failure_bitmask{0};
|
||||||
|
uint16_t _motor_stop_mask{0};
|
||||||
|
|
||||||
perf_counter_t _loop_perf; /**< loop duration performance counter */
|
perf_counter_t _loop_perf; /**< loop duration performance counter */
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user