46 #include <mathlib/mathlib.h>    48 #ifdef MIXER_MULTIROTOR_USE_MOCK_GEOMETRY    56     { -0.707107,  0.707107,  1.000000,  1.000000 },
    57     {  0.707107, -0.707107,  1.000000,  1.000000 },
    58     {  0.707107,  0.707107, -1.000000,  1.000000 },
    59     { -0.707107, -0.707107, -1.000000,  1.000000 },
    64 const unsigned _config_rotor_count[] = {4};
    65 const char *_config_key[] = {
"4x"};
    72 #include "mixer_multirotor_normalized.generated.h"    77 #define debug(fmt, args...) do { } while(0)    83                  float roll_scale, 
float pitch_scale, 
float yaw_scale, 
float idle_speed) :
    84     MultirotorMixer(control_cb, cb_handle, _config_index[(int)geometry], _config_rotor_count[(int)geometry])
    93                  unsigned rotor_count) :
    94     Mixer(control_cb, cb_handle),
   114     MultirotorGeometry geometry = MultirotorGeometry::MAX_GEOMETRY;
   124     if (sscanf(buf, 
"R: %7s %d %d %d %d%n", geomname, &s[0], &s[1], &s[2], &s[3], &used) != 5) {
   125         debug(
"multirotor parse failed on '%s'", buf);
   129     if (used > (
int)buflen) {
   130         debug(
"OVERFLOW: multirotor spec used %d of %u", used, buflen);
   136     if (buf == 
nullptr) {
   137         debug(
"no line ending, line is incomplete");
   141     debug(
"remaining in buf: %d, first char: %c", buflen, buf[0]);
   145         if (!strcmp(geomname, _config_key[i])) {
   146             geometry = (MultirotorGeometry)i;
   151     if (geometry == MultirotorGeometry::MAX_GEOMETRY) {
   152         debug(
"unrecognised geometry '%s'", geomname);
   156     debug(
"adding multirotor mixer '%s'", geomname);
   181         if (outputs[i] < min_output) {
   182             float k = (min_output - outputs[i]) / desaturation_vector[i];
   184             if (k < k_min) { k_min = k; }
   186             if (k > k_max) { k_max = k; }
   191         if (outputs[i] > max_output) {
   192             float k = (max_output - outputs[i]) / desaturation_vector[i];
   194             if (k < k_min) { k_min = k; }
   196             if (k > k_max) { k_max = k; }
   203     return k_min + k_max;
   208                      saturation_status &sat_status, 
float min_output, 
float max_output, 
bool reduce_only)
 const   212     if (reduce_only && k1 > 0.
f) {
   217         outputs[i] += k1 * desaturation_vector[i];
   226         outputs[i] += k2 * desaturation_vector[i];
   374                     (1.0
f - _thrust_factor) / (4.0
f * _thrust_factor * _thrust_factor) + (outputs[i] < 0.0
f ? 0.0
f : outputs[i] /
   383         bool clipping_high = 
false;
   384         bool clipping_low_roll_pitch = 
false;
   385         bool clipping_low_yaw = 
false;
   394                 clipping_low_roll_pitch = 
true;
   395                 clipping_low_yaw = 
true;
   398                 clipping_low_yaw = 
true;
   408                 clipping_high = 
true;
   412                 clipping_low_roll_pitch = 
true;
   413                 clipping_low_yaw = 
true;
   439         bool clipping_low_yaw)
   444         if (
_rotors[index].roll_scale > 0.0
f) {
   448         } 
else if (
_rotors[index].roll_scale < 0.0
f) {
   454         if (
_rotors[index].pitch_scale > 0.0
f) {
   458         } 
else if (
_rotors[index].pitch_scale < 0.0
f) {
   464         if (
_rotors[index].yaw_scale > 0.0
f) {
   468         } 
else if (
_rotors[index].yaw_scale < 0.0
f) {
   479     if (clipping_low_roll_pitch) {
   481         if (
_rotors[index].roll_scale > 0.0
f) {
   485         } 
else if (
_rotors[index].roll_scale < 0.0
f) {
   491         if (
_rotors[index].pitch_scale > 0.0
f) {
   495         } 
else if (
_rotors[index].pitch_scale < 0.0
f) {
   504     if (clipping_low_yaw) {
   506         if (
_rotors[index].yaw_scale > 0.0
f) {
   510         } 
else if (
_rotors[index].yaw_scale < 0.0
f) {
 
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
 
float thrust_scale
scales thrust for this rotor 
 
void update_saturation_status(unsigned index, bool clipping_high, bool clipping_low_roll_pitch, bool clipping_low_yaw)
 
void minimize_saturation(const float *desaturation_vector, float *outputs, saturation_status &sat_status, float min_output=0.f, float max_output=1.f, bool reduce_only=false) const
Minimize the saturation of the actuators by adding or substracting a fraction of desaturation_vector...
 
static const char * skipline(const char *buf, unsigned &buflen)
Skip a line. 
 
static MultirotorMixer * from_text(Mixer::ControlCallback control_cb, uintptr_t cb_handle, const char *buf, unsigned &buflen)
Factory method. 
 
void mix_yaw(float yaw, float *outputs)
Mix yaw by updating an existing output vector (that already contains roll/pitch/thrust). 
 
uint8_t MultirotorGeometryUnderlyingType
Supported multirotor geometries. 
 
void mix_airmode_rpy(float roll, float pitch, float yaw, float thrust, float *outputs)
Mix roll, pitch, yaw, thrust and set the outputs vector. 
 
int(* ControlCallback)(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &control)
Fetch a control value. 
 
float compute_desaturation_gain(const float *desaturation_vector, const float *outputs, saturation_status &sat_status, float min_output, float max_output) const
Computes the gain k by which desaturation_vector has to be multiplied in order to unsaturate the outp...
 
static bool string_well_formed(const char *buf, unsigned &buflen)
Check wether the string is well formed and suitable for parsing. 
 
saturation_status _saturation_status
 
void mix_airmode_rp(float roll, float pitch, float yaw, float thrust, float *outputs)
Mix roll, pitch, yaw, thrust and set the outputs vector. 
 
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
 
#define debug(fmt, args...)
 
virtual ~MultirotorMixer()
 
float get_control(uint8_t group, uint8_t index)
Invoke the client callback to fetch a control value. 
 
MultirotorMixer(ControlCallback control_cb, uintptr_t cb_handle, MultirotorGeometry geometry, float roll_scale, float pitch_scale, float yaw_scale, float idle_speed)
Constructor. 
 
float pitch_scale
scales pitch for this rotor 
 
void mix_airmode_disabled(float roll, float pitch, float yaw, float thrust, float *outputs)
Mix roll, pitch, yaw, thrust and set the outputs vector. 
 
unsigned mix(float *outputs, unsigned space) override
Perform the mixing function. 
 
float roll_scale
scales roll for this rotor 
 
Multi-rotor mixer for pre-defined vehicle geometries. 
 
float yaw_scale
scales yaw for this rotor 
 
Abstract class defining a mixer mixing zero or more inputs to one or more outputs. 
 
struct MultirotorMixer::saturation_status::@66 flags