preflight check: replace uOrb msg with argument

Previously, the approach to modify collective tilt control was to send
the corresponding tiltrotor_extra_control uOrb message from
ControlAllocator, which then influences
ActuatorEffectivenessTiltrotorVTOL with minimal changes.

This was a bit hacky and introduced potentially conflicting uOrb
messages. So, with this new approach we pass the same information via
argument.

Specifically, the class ActuatorEffectiveness now declares
updateSetpoint with an extra argument, preflight_check_running. It is
only used in ActuatorEffectivenessTiltrotorVTOL, but has to be included
as a "dummy" in all other classes inheriting from ActuatorEffectiveness.

The argument can be used to bypass the collective tilt/thrust setpoints,
instead replacing them with values from public class member variables
which can be set from outside just before calling updateSetpoints.

Also, slight refactor in ControlAllocator by splitting up the functions
related to the preflight check into smaller parts
This commit is contained in:
Balduin
2025-02-18 15:42:28 +01:00
parent 96fc4a0673
commit c28d015d9c
23 changed files with 81 additions and 60 deletions
@@ -198,7 +198,7 @@ public:
*/
virtual void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) {}
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) {}
/**
* Get a bitmask of motors to be stopped
@@ -61,8 +61,6 @@ ControlAllocator::ControlAllocator() :
_actuator_servos_pub.advertise();
_actuator_servos_trim_pub.advertise();
_tiltrotor_extra_controls_pub.advertise();
for (int i = 0; i < MAX_NUM_MOTORS; ++i) {
char buffer[17];
snprintf(buffer, sizeof(buffer), "CA_R%u_SLEW", i);
@@ -347,7 +345,6 @@ ControlAllocator::Run()
if (_vehicle_status_sub.update(&vehicle_status)) {
_armed = vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED;
_preflight_check_running = vehicle_status.nav_state == vehicle_status_s::NAVIGATION_STATE_CS_PREFLIGHT_CHECK;
ActuatorEffectiveness::FlightPhase flight_phase{ActuatorEffectiveness::FlightPhase::HOVER_FLIGHT};
@@ -442,25 +439,34 @@ ControlAllocator::Run()
}
if (_preflight_check_running) {
preflight_check_update_state();
preflight_check_overwrite_torque_sp(c);
}
for (int i = 0; i < _num_control_allocation; ++i) {
ActuatorEffectivenessTiltrotorVTOL *casted = dynamic_cast<ActuatorEffectivenessTiltrotorVTOL *>
(_actuator_effectiveness);
if (casted != nullptr) {
casted->_preflight_check_running = _preflight_check_running;
}
_control_allocation[i]->setControlSetpoint(c[i]);
// Do allocation
_control_allocation[i]->allocate();
if (_preflight_check_running) {
// alternative: specify these member variables in the general ActuatorEffectiveness,
// and just don't use them anywhere except TiltrotorVTOL
auto actuator_effectiveness_tiltrotor_vtol = dynamic_cast<ActuatorEffectivenessTiltrotorVTOL*>(_actuator_effectiveness);
if (actuator_effectiveness_tiltrotor_vtol) {
float collective_tilt_sp = preflight_check_get_tilt_control();
actuator_effectiveness_tiltrotor_vtol->_collective_tilt_normalized_setpoint = collective_tilt_sp;
actuator_effectiveness_tiltrotor_vtol->_collective_thrust_normalized_setpoint = 0.0f;
}
}
_actuator_effectiveness->allocateAuxilaryControls(dt, i, _control_allocation[i]->_actuator_sp); //flaps and spoilers
_actuator_effectiveness->updateSetpoint(c[i], i, _control_allocation[i]->_actuator_sp,
_control_allocation[i]->getActuatorMin(), _control_allocation[i]->getActuatorMax());
_control_allocation[i]->getActuatorMin(), _control_allocation[i]->getActuatorMax(),
_preflight_check_running);
if (_has_slew_rate) {
_control_allocation[i]->applySlewRateLimit(dt);
@@ -502,15 +508,13 @@ ControlAllocator::Run()
// }
void ControlAllocator::preflight_check_overwrite_torque_sp(matrix::Vector<float, NUM_AXES> (&c)[ActuatorEffectiveness::MAX_NUM_MATRICES]) {
void ControlAllocator::preflight_check_update_state() {
bool tiltrotor = dynamic_cast<ActuatorEffectivenessTiltrotorVTOL*>(_actuator_effectiveness) != nullptr;
// cycle through roll, pitch, yaw, and for each one inject positive and
// negative torque setpoints.
// is this the proper way to do it?
// bool tiltrotor = _effectiveness_source_id == EffectivenessSource::TILTROTOR_VTOL;
bool tiltrotor = dynamic_cast<ActuatorEffectivenessTiltrotorVTOL*>(_actuator_effectiveness) != nullptr;
int n_axes = 3;
if (tiltrotor) {
n_axes = 4;
@@ -524,12 +528,13 @@ void ControlAllocator::preflight_check_overwrite_torque_sp(matrix::Vector<float,
_preflight_check_phase %= max_phase; // or quit once we did the whole thing once?
_last_preflight_check_update = now;
}
}
void ControlAllocator::preflight_check_overwrite_torque_sp(matrix::Vector<float, NUM_AXES> (&c)[ActuatorEffectiveness::MAX_NUM_MATRICES]) {
int axis = _preflight_check_phase / 2;
int negative = _preflight_check_phase % 2;
float modified_tilt_control = 0.5f;
if (axis < 3) {
c[0](0) = 0.;
c[0](1) = 0.;
@@ -543,24 +548,24 @@ void ControlAllocator::preflight_check_overwrite_torque_sp(matrix::Vector<float,
c[1](axis) = negative ? -1.f : 1.f;
}
} else {
// axis 4 = tiltrotor.
}
}
float ControlAllocator::preflight_check_get_tilt_control() {
int axis = _preflight_check_phase / 2;
int negative = _preflight_check_phase % 2;
float modified_tilt_control = 0.5f;
if (axis == 3) {
// axis 3 = tiltrotor.
// collective tilt normalised control goes from 0 to 1.
modified_tilt_control = negative ? 0.f : 1.f;
}
tiltrotor_extra_controls_s tiltrotor_extra_controls;
if (!_tiltrotor_extra_controls_sub.copy(&tiltrotor_extra_controls)) {
// got no message, make up thrust setpoint
tiltrotor_extra_controls.collective_thrust_normalized_setpoint = 0.;
}
tiltrotor_extra_controls.collective_tilt_normalized_setpoint = modified_tilt_control;
tiltrotor_extra_controls.timestamp = hrt_absolute_time();
_tiltrotor_extra_controls_pub.publish(tiltrotor_extra_controls);
// PX4_INFO("_torque_sp: %f, %f, %f", (double) _torque_sp(0), (double) _torque_sp(1), (double) _torque_sp(2));
return modified_tilt_control;
}
@@ -139,6 +139,8 @@ private:
void publish_actuator_controls();
void preflight_check_overwrite_torque_sp(matrix::Vector<float, NUM_AXES> (&c)[ActuatorEffectiveness::MAX_NUM_MATRICES]);
void preflight_check_update_state();
float preflight_check_get_tilt_control();
AllocationMethod _allocation_method_id{AllocationMethod::NONE};
ControlAllocation *_control_allocation[ActuatorEffectiveness::MAX_NUM_MATRICES] {}; ///< class for control allocation calculations
@@ -181,7 +183,6 @@ private:
uORB::Subscription _vehicle_torque_setpoint1_sub{ORB_ID(vehicle_torque_setpoint), 1}; /**< vehicle torque setpoint subscription (2. instance) */
uORB::Subscription _vehicle_thrust_setpoint1_sub{ORB_ID(vehicle_thrust_setpoint), 1}; /**< vehicle thrust setpoint subscription (2. instance) */
uORB::Subscription _tiltrotor_extra_controls_sub{ORB_ID(tiltrotor_extra_controls)};
// Outputs
uORB::PublicationMulti<control_allocator_status_s> _control_allocator_status_pub[2] {ORB_ID(control_allocator_status), ORB_ID(control_allocator_status)};
@@ -190,8 +191,6 @@ private:
uORB::Publication<actuator_servos_s> _actuator_servos_pub{ORB_ID(actuator_servos)};
uORB::Publication<actuator_servos_trim_s> _actuator_servos_trim_pub{ORB_ID(actuator_servos_trim)};
uORB::Publication<tiltrotor_extra_controls_s> _tiltrotor_extra_controls_pub{ORB_ID(tiltrotor_extra_controls)};
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
@@ -61,7 +61,7 @@ ActuatorEffectivenessCustom::getEffectivenessMatrix(Configuration &configuration
void ActuatorEffectivenessCustom::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
stopMaskedMotorsWithZeroThrust(_motors_mask, actuator_sp);
}
@@ -47,7 +47,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
const char *name() const override { return "Custom"; }
@@ -63,7 +63,7 @@ ActuatorEffectivenessFixedWing::getEffectivenessMatrix(Configuration &configurat
void ActuatorEffectivenessFixedWing::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
stopMaskedMotorsWithZeroThrust(_forwards_motors_mask, actuator_sp);
}
@@ -53,7 +53,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
private:
ActuatorEffectivenessRotors _rotors;
@@ -130,7 +130,7 @@ bool ActuatorEffectivenessHelicopter::getEffectivenessMatrix(Configuration &conf
void ActuatorEffectivenessHelicopter::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
_saturation_flags = {};
@@ -80,7 +80,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
void getUnallocatedControl(int matrix_index, control_allocator_status_s &status) override;
private:
@@ -104,7 +104,7 @@ bool ActuatorEffectivenessHelicopterCoaxial::getEffectivenessMatrix(Configuratio
void ActuatorEffectivenessHelicopterCoaxial::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
_saturation_flags = {};
@@ -71,7 +71,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
void getUnallocatedControl(int matrix_index, control_allocator_status_s &status) override;
private:
@@ -78,7 +78,7 @@ ActuatorEffectivenessMCTilt::getEffectivenessMatrix(Configuration &configuration
void ActuatorEffectivenessMCTilt::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
actuator_sp += _tilt_offsets;
// TODO: dynamic matrix update
@@ -57,7 +57,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
const char *name() const override { return "MC Tilt"; }
@@ -51,7 +51,7 @@ ActuatorEffectivenessRoverAckermann::getEffectivenessMatrix(Configuration &confi
void ActuatorEffectivenessRoverAckermann::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
stopMaskedMotorsWithZeroThrust(_motors_mask, actuator_sp);
}
@@ -45,7 +45,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
const char *name() const override { return "Rover (Ackermann)"; }
private:
@@ -85,7 +85,7 @@ void ActuatorEffectivenessStandardVTOL::allocateAuxilaryControls(const float dt,
void ActuatorEffectivenessStandardVTOL::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
if (matrix_index == 0) {
stopMaskedMotorsWithZeroThrust(_forwards_motors_mask, actuator_sp);
@@ -77,7 +77,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
void setFlightPhase(const FlightPhase &flight_phase) override;
@@ -90,7 +90,7 @@ void ActuatorEffectivenessTailsitterVTOL::allocateAuxilaryControls(const float d
void ActuatorEffectivenessTailsitterVTOL::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
if (matrix_index == 0) {
stopMaskedMotorsWithZeroThrust(_forwards_motors_mask, actuator_sp);
@@ -74,7 +74,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
void setFlightPhase(const FlightPhase &flight_phase) override;
@@ -126,14 +126,30 @@ void ActuatorEffectivenessTiltrotorVTOL::allocateAuxilaryControls(const float dt
void ActuatorEffectivenessTiltrotorVTOL::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
// apply tilt
// if preflight_check_running, we alter the behaviour in these two ways:
// - collective tilt and thrust setpoints are NOT taken from uOrb
// message, but from class member variable, which we can arbitrarily set
// before calling this function
// - collective tilt is added to actuator_sp even if
// (throttleSpoolupFinished() || _flight_phase != FlightPhase::HOVER_FLIGHT)
// evaluates to false
if (matrix_index == 0) {
tiltrotor_extra_controls_s tiltrotor_extra_controls;
if (_tiltrotor_extra_controls_sub.copy(&tiltrotor_extra_controls)) {
if (_tiltrotor_extra_controls_sub.copy(&tiltrotor_extra_controls) || preflight_check_running) {
float control_collective_tilt = tiltrotor_extra_controls.collective_tilt_normalized_setpoint * 2.f - 1.f;
float control_collective_thrust = tiltrotor_extra_controls.collective_thrust_normalized_setpoint;
if (preflight_check_running) {
control_collective_tilt = _collective_tilt_normalized_setpoint * 2.f - 1.f;
control_collective_thrust = _collective_thrust_normalized_setpoint;
}
// set control_collective_tilt to exactly -1 or 1 if close to these end points
control_collective_tilt = control_collective_tilt < -0.99f ? -1.f : control_collective_tilt;
@@ -166,7 +182,7 @@ void ActuatorEffectivenessTiltrotorVTOL::updateSetpoint(const matrix::Vector<flo
if (_tilts.config(i).tilt_direction == ActuatorEffectivenessTilts::TiltDirection::TowardsFront) {
// as long as throttle spoolup is not completed, leave the tilts in the disarmed position (in hover)
if (throttleSpoolupFinished() || _flight_phase != FlightPhase::HOVER_FLIGHT || _preflight_check_running) {
if (throttleSpoolupFinished() || _flight_phase != FlightPhase::HOVER_FLIGHT || preflight_check_running) {
actuator_sp(i + _first_tilt_idx) += control_collective_tilt;
} else {
@@ -202,7 +218,7 @@ void ActuatorEffectivenessTiltrotorVTOL::updateSetpoint(const matrix::Vector<flo
// in FW directly use throttle sp
if (_flight_phase == FlightPhase::FORWARD_FLIGHT) {
for (int i = 0; i < _first_tilt_idx; ++i) {
actuator_sp(i) = tiltrotor_extra_controls.collective_thrust_normalized_setpoint;
actuator_sp(i) = control_collective_thrust;
}
}
}
@@ -82,13 +82,14 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
const char *name() const override { return "VTOL Tiltrotor"; }
void getUnallocatedControl(int matrix_index, control_allocator_status_s &status) override;
bool _preflight_check_running{false};
float _collective_tilt_normalized_setpoint{0.5f};
float _collective_thrust_normalized_setpoint{0.0f};
protected:
bool _collective_tilt_updated{true};
@@ -57,7 +57,7 @@ bool ActuatorEffectivenessUUV::getEffectivenessMatrix(Configuration &configurati
void ActuatorEffectivenessUUV::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
int matrix_index, ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max)
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running)
{
stopMaskedMotorsWithZeroThrust(_motors_mask, actuator_sp);
}
@@ -56,7 +56,7 @@ public:
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
ActuatorVector &actuator_sp, const matrix::Vector<float, NUM_ACTUATORS> &actuator_min,
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max) override;
const matrix::Vector<float, NUM_ACTUATORS> &actuator_max, bool preflight_check_running) override;
const char *name() const override { return "UUV"; }