mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-03 14:58:53 +08:00
control_allocator: add helicopter mixer
Same logic as the existing mixer. Untested.
This commit is contained in:
@@ -73,6 +73,15 @@ public:
|
|||||||
static constexpr int NUM_ACTUATORS = 16;
|
static constexpr int NUM_ACTUATORS = 16;
|
||||||
static constexpr int NUM_AXES = 6;
|
static constexpr int NUM_AXES = 6;
|
||||||
|
|
||||||
|
enum ControlAxis {
|
||||||
|
ROLL = 0,
|
||||||
|
PITCH,
|
||||||
|
YAW,
|
||||||
|
THRUST_X,
|
||||||
|
THRUST_Y,
|
||||||
|
THRUST_Z
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr int MAX_NUM_MATRICES = 2;
|
static constexpr int MAX_NUM_MATRICES = 2;
|
||||||
|
|
||||||
using EffectivenessMatrix = matrix::Matrix<float, NUM_AXES, NUM_ACTUATORS>;
|
using EffectivenessMatrix = matrix::Matrix<float, NUM_AXES, NUM_ACTUATORS>;
|
||||||
|
|||||||
+143
@@ -0,0 +1,143 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "ActuatorEffectivenessHelicopter.hpp"
|
||||||
|
#include <lib/mathlib/mathlib.h>
|
||||||
|
|
||||||
|
using namespace matrix;
|
||||||
|
|
||||||
|
ActuatorEffectivenessHelicopter::ActuatorEffectivenessHelicopter(ModuleParams *parent)
|
||||||
|
: ModuleParams(parent)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_SWASH_PLATE_SERVOS_MAX; ++i) {
|
||||||
|
char buffer[17];
|
||||||
|
snprintf(buffer, sizeof(buffer), "CA_SP0_ANG%u", i);
|
||||||
|
_param_handles.swash_plate_servos[i].angle = param_find(buffer);
|
||||||
|
snprintf(buffer, sizeof(buffer), "CA_SP0_ARM_L%u", i);
|
||||||
|
_param_handles.swash_plate_servos[i].arm_length = param_find(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
_param_handles.num_swash_plate_servos = param_find("CA_SP0_COUNT");
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_CURVE_POINTS; ++i) {
|
||||||
|
char buffer[17];
|
||||||
|
snprintf(buffer, sizeof(buffer), "CA_HELI_THR_C%u", i);
|
||||||
|
_param_handles.throttle_curve[i] = param_find(buffer);
|
||||||
|
snprintf(buffer, sizeof(buffer), "CA_HELI_PITCH_C%u", i);
|
||||||
|
_param_handles.pitch_curve[i] = param_find(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActuatorEffectivenessHelicopter::updateParams()
|
||||||
|
{
|
||||||
|
ModuleParams::updateParams();
|
||||||
|
|
||||||
|
int32_t count = 0;
|
||||||
|
|
||||||
|
if (param_get(_param_handles.num_swash_plate_servos, &count) != 0) {
|
||||||
|
PX4_ERR("param_get failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_geometry.num_swash_plate_servos = math::constrain((int)count, 3, NUM_SWASH_PLATE_SERVOS_MAX);
|
||||||
|
|
||||||
|
for (int i = 0; i < _geometry.num_swash_plate_servos; ++i) {
|
||||||
|
float angle_deg{};
|
||||||
|
param_get(_param_handles.swash_plate_servos[i].angle, &angle_deg);
|
||||||
|
_geometry.swash_plate_servos[i].angle = math::radians(angle_deg);
|
||||||
|
param_get(_param_handles.swash_plate_servos[i].arm_length, &_geometry.swash_plate_servos[i].arm_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_CURVE_POINTS; ++i) {
|
||||||
|
param_get(_param_handles.throttle_curve[i], &_geometry.throttle_curve[i]);
|
||||||
|
param_get(_param_handles.pitch_curve[i], &_geometry.pitch_curve[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ActuatorEffectivenessHelicopter::getEffectivenessMatrix(Configuration &configuration,
|
||||||
|
EffectivenessUpdateReason external_update)
|
||||||
|
{
|
||||||
|
if (external_update == EffectivenessUpdateReason::NO_EXTERNAL_UPDATE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As the allocation is non-linear, we use updateSetpoint() instead of the matrix
|
||||||
|
configuration.addActuator(ActuatorType::MOTORS, Vector3f{}, Vector3f{});
|
||||||
|
|
||||||
|
// Tail (yaw) servo
|
||||||
|
configuration.addActuator(ActuatorType::SERVOS, Vector3f{0.f, 0.f, 1.f}, Vector3f{});
|
||||||
|
|
||||||
|
// N swash plate servos
|
||||||
|
_first_swash_plate_servo_index = configuration.num_actuators_matrix[0];
|
||||||
|
|
||||||
|
for (int i = 0; i < _geometry.num_swash_plate_servos; ++i) {
|
||||||
|
configuration.addActuator(ActuatorType::SERVOS, Vector3f{}, Vector3f{});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActuatorEffectivenessHelicopter::updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp,
|
||||||
|
int matrix_index, ActuatorVector &actuator_sp)
|
||||||
|
{
|
||||||
|
// Find index to use for curves
|
||||||
|
float thrust_cmd = -control_sp(ControlAxis::THRUST_Z);
|
||||||
|
float num_intervals = NUM_CURVE_POINTS - 1;
|
||||||
|
// We access idx + 1 below, so max legal index is (size - 2)
|
||||||
|
int idx = math::constrain((int)(thrust_cmd * num_intervals), 0, NUM_CURVE_POINTS - 2);
|
||||||
|
|
||||||
|
// Local throttle curve gradient and offset
|
||||||
|
float tg = (_geometry.throttle_curve[idx + 1] - _geometry.throttle_curve[idx]) * num_intervals;
|
||||||
|
float to = (_geometry.throttle_curve[idx]) - (tg * idx / num_intervals);
|
||||||
|
float throttle = math::constrain(tg * thrust_cmd + to, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Local pitch curve gradient and offset
|
||||||
|
float pg = (_geometry.pitch_curve[idx + 1] - _geometry.pitch_curve[idx]) * num_intervals;
|
||||||
|
float po = (_geometry.pitch_curve[idx]) - (pg * idx / num_intervals);
|
||||||
|
float collective_pitch = math::constrain((pg * thrust_cmd + po), -0.5f, 0.5f);
|
||||||
|
|
||||||
|
float roll_cmd = control_sp(ControlAxis::ROLL);
|
||||||
|
float pitch_cmd = control_sp(ControlAxis::PITCH);
|
||||||
|
|
||||||
|
actuator_sp(0) = throttle;
|
||||||
|
|
||||||
|
for (int i = 0; i < _geometry.num_swash_plate_servos; i++) {
|
||||||
|
actuator_sp(_first_swash_plate_servo_index + i) = collective_pitch
|
||||||
|
+ cosf(_geometry.swash_plate_servos[i].angle) * pitch_cmd * _geometry.swash_plate_servos[i].arm_length
|
||||||
|
- sinf(_geometry.swash_plate_servos[i].angle) * roll_cmd * _geometry.swash_plate_servos[i].arm_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ActuatorEffectiveness.hpp"
|
||||||
|
|
||||||
|
#include <px4_platform_common/module_params.h>
|
||||||
|
|
||||||
|
class ActuatorEffectivenessHelicopter : public ModuleParams, public ActuatorEffectiveness
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static constexpr int NUM_SWASH_PLATE_SERVOS_MAX = 4;
|
||||||
|
static constexpr int NUM_CURVE_POINTS = 5;
|
||||||
|
|
||||||
|
struct SwashPlateGeometry {
|
||||||
|
float angle;
|
||||||
|
float arm_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Geometry {
|
||||||
|
SwashPlateGeometry swash_plate_servos[NUM_SWASH_PLATE_SERVOS_MAX];
|
||||||
|
int num_swash_plate_servos{0};
|
||||||
|
float throttle_curve[NUM_CURVE_POINTS];
|
||||||
|
float pitch_curve[NUM_CURVE_POINTS];
|
||||||
|
};
|
||||||
|
|
||||||
|
ActuatorEffectivenessHelicopter(ModuleParams *parent);
|
||||||
|
virtual ~ActuatorEffectivenessHelicopter() = default;
|
||||||
|
|
||||||
|
bool getEffectivenessMatrix(Configuration &configuration, EffectivenessUpdateReason external_update) override;
|
||||||
|
|
||||||
|
const char *name() const override { return "Helicopter"; }
|
||||||
|
|
||||||
|
|
||||||
|
const Geometry &geometry() const { return _geometry; }
|
||||||
|
|
||||||
|
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index,
|
||||||
|
ActuatorVector &actuator_sp) override;
|
||||||
|
private:
|
||||||
|
void updateParams() override;
|
||||||
|
|
||||||
|
struct ParamHandlesSwashPlate {
|
||||||
|
param_t angle;
|
||||||
|
param_t arm_length;
|
||||||
|
};
|
||||||
|
struct ParamHandles {
|
||||||
|
ParamHandlesSwashPlate swash_plate_servos[NUM_SWASH_PLATE_SERVOS_MAX];
|
||||||
|
param_t num_swash_plate_servos;
|
||||||
|
param_t throttle_curve[NUM_CURVE_POINTS];
|
||||||
|
param_t pitch_curve[NUM_CURVE_POINTS];
|
||||||
|
};
|
||||||
|
ParamHandles _param_handles{};
|
||||||
|
|
||||||
|
Geometry _geometry{};
|
||||||
|
|
||||||
|
int _first_swash_plate_servo_index{};
|
||||||
|
};
|
||||||
@@ -40,6 +40,8 @@ px4_add_library(ActuatorEffectiveness
|
|||||||
ActuatorEffectivenessCustom.hpp
|
ActuatorEffectivenessCustom.hpp
|
||||||
ActuatorEffectivenessFixedWing.cpp
|
ActuatorEffectivenessFixedWing.cpp
|
||||||
ActuatorEffectivenessFixedWing.hpp
|
ActuatorEffectivenessFixedWing.hpp
|
||||||
|
ActuatorEffectivenessHelicopter.cpp
|
||||||
|
ActuatorEffectivenessHelicopter.hpp
|
||||||
ActuatorEffectivenessMCTilt.cpp
|
ActuatorEffectivenessMCTilt.cpp
|
||||||
ActuatorEffectivenessMCTilt.hpp
|
ActuatorEffectivenessMCTilt.hpp
|
||||||
ActuatorEffectivenessMultirotor.cpp
|
ActuatorEffectivenessMultirotor.cpp
|
||||||
|
|||||||
@@ -254,6 +254,10 @@ ControlAllocator::update_effectiveness_source()
|
|||||||
tmp = new ActuatorEffectivenessCustom(this);
|
tmp = new ActuatorEffectivenessCustom(this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EffectivenessSource::HELICOPTER:
|
||||||
|
tmp = new ActuatorEffectivenessHelicopter(this);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PX4_ERR("Unknown airframe");
|
PX4_ERR("Unknown airframe");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include <ActuatorEffectivenessFixedWing.hpp>
|
#include <ActuatorEffectivenessFixedWing.hpp>
|
||||||
#include <ActuatorEffectivenessMCTilt.hpp>
|
#include <ActuatorEffectivenessMCTilt.hpp>
|
||||||
#include <ActuatorEffectivenessCustom.hpp>
|
#include <ActuatorEffectivenessCustom.hpp>
|
||||||
|
#include <ActuatorEffectivenessHelicopter.hpp>
|
||||||
|
|
||||||
#include <ControlAllocation.hpp>
|
#include <ControlAllocation.hpp>
|
||||||
#include <ControlAllocationPseudoInverse.hpp>
|
#include <ControlAllocationPseudoInverse.hpp>
|
||||||
@@ -148,6 +149,7 @@ private:
|
|||||||
MOTORS_6DOF = 7,
|
MOTORS_6DOF = 7,
|
||||||
MULTIROTOR_WITH_TILT = 8,
|
MULTIROTOR_WITH_TILT = 8,
|
||||||
CUSTOM = 9,
|
CUSTOM = 9,
|
||||||
|
HELICOPTER = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
EffectivenessSource _effectiveness_source_id{EffectivenessSource::NONE};
|
EffectivenessSource _effectiveness_source_id{EffectivenessSource::NONE};
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ parameters:
|
|||||||
7: Motors (6DOF)
|
7: Motors (6DOF)
|
||||||
8: Multirotor with Tilt
|
8: Multirotor with Tilt
|
||||||
9: Custom
|
9: Custom
|
||||||
|
10: Helicopter
|
||||||
default: 0
|
default: 0
|
||||||
|
|
||||||
CA_METHOD:
|
CA_METHOD:
|
||||||
@@ -378,6 +379,62 @@ parameters:
|
|||||||
instance_start: 0
|
instance_start: 0
|
||||||
default: 0
|
default: 0
|
||||||
|
|
||||||
|
# helicopter
|
||||||
|
CA_SP0_COUNT:
|
||||||
|
description:
|
||||||
|
short: Number of swash plates servos
|
||||||
|
type: enum
|
||||||
|
values:
|
||||||
|
3: '3'
|
||||||
|
4: '4'
|
||||||
|
default: 3
|
||||||
|
CA_SP0_ANG${i}:
|
||||||
|
description:
|
||||||
|
short: Angle for swash plate servo ${i}
|
||||||
|
type: float
|
||||||
|
decimal: 0
|
||||||
|
increment: 10
|
||||||
|
unit: deg
|
||||||
|
num_instances: 4
|
||||||
|
min: 0
|
||||||
|
max: 360
|
||||||
|
default: [0, 140, 220, 0]
|
||||||
|
CA_SP0_ARM_L${i}:
|
||||||
|
description:
|
||||||
|
short: Arm length for swash plate servo ${i}
|
||||||
|
long: |
|
||||||
|
This is relative to the other arm lengths.
|
||||||
|
type: float
|
||||||
|
decimal: 3
|
||||||
|
increment: 0.1
|
||||||
|
num_instances: 4
|
||||||
|
min: 0
|
||||||
|
max: 10
|
||||||
|
default: 1.0
|
||||||
|
CA_HELI_THR_C${i}:
|
||||||
|
description:
|
||||||
|
short: Throttle curve at position ${i}
|
||||||
|
long: |
|
||||||
|
Defines the output throttle at the interval position ${i}.
|
||||||
|
type: float
|
||||||
|
decimal: 3
|
||||||
|
increment: 0.1
|
||||||
|
num_instances: 5
|
||||||
|
min: 0
|
||||||
|
max: 1
|
||||||
|
default: [0, 0.3, 0.6, 0.8, 1]
|
||||||
|
CA_HELI_PITCH_C${i}:
|
||||||
|
description:
|
||||||
|
short: Collective pitch curve at position ${i}
|
||||||
|
long: |
|
||||||
|
Defines the collective pitch at the interval position ${i} for a given thrust setpoint.
|
||||||
|
type: float
|
||||||
|
decimal: 3
|
||||||
|
increment: 0.1
|
||||||
|
num_instances: 5
|
||||||
|
min: 0
|
||||||
|
max: 1
|
||||||
|
default: [0.05, 0.15, 0.25, 0.35, 0.45]
|
||||||
|
|
||||||
# Mixer
|
# Mixer
|
||||||
mixer:
|
mixer:
|
||||||
@@ -767,3 +824,20 @@ mixer:
|
|||||||
- name: 'CA_SV_CS${i}_TRIM'
|
- name: 'CA_SV_CS${i}_TRIM'
|
||||||
label: 'Trim'
|
label: 'Trim'
|
||||||
|
|
||||||
|
10: # Helicopter
|
||||||
|
actuators:
|
||||||
|
- actuator_type: 'motor'
|
||||||
|
count: 1
|
||||||
|
item_label_prefix: ['Rotor']
|
||||||
|
- actuator_type: 'servo'
|
||||||
|
item_label_prefix: ['Yaw tail servo']
|
||||||
|
count: 1
|
||||||
|
- actuator_type: 'servo'
|
||||||
|
group_label: 'Swash plate servos'
|
||||||
|
count: 'CA_SP0_COUNT'
|
||||||
|
per_item_parameters:
|
||||||
|
extra:
|
||||||
|
- name: 'CA_SP0_ANG${i}'
|
||||||
|
label: 'Angle'
|
||||||
|
- name: 'CA_SP0_ARM_L${i}'
|
||||||
|
label: 'Arm Length (relative)'
|
||||||
|
|||||||
Reference in New Issue
Block a user