aboutsummaryrefslogtreecommitdiff
path: root/apps/systemlib/mixer/mixer.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/systemlib/mixer/mixer.h')
-rw-r--r--apps/systemlib/mixer/mixer.h358
1 files changed, 358 insertions, 0 deletions
diff --git a/apps/systemlib/mixer/mixer.h b/apps/systemlib/mixer/mixer.h
new file mode 100644
index 000000000..5a3857a00
--- /dev/null
+++ b/apps/systemlib/mixer/mixer.h
@@ -0,0 +1,358 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2012 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.
+ *
+ ****************************************************************************/
+
+/**
+ * @file mixer.h
+ *
+ * Generic, programmable, procedural control signal mixers.
+ *
+ * This library implements a generic mixer interface that can be used
+ * by any driver or subsytem that wants to combine several control signals
+ * into a single output.
+ *
+ * Terminology
+ * ===========
+ *
+ * control value
+ * A mixer input value, typically provided by some controlling
+ * component of the system.
+ *
+ * control group
+ * A collection of controls provided by a single controlling component.
+ *
+ * actuator
+ * The mixer output value.
+ *
+ *
+ * Mixing basics
+ * =============
+ *
+ * An actuator derives its value from the combination of one or more
+ * control values. Each of the control values is scaled according to
+ * the actuator's configuration and then combined to produce the
+ * actuator value, which may then be further scaled to suit the specific
+ * output type.
+ *
+ * Internally, all scaling is performed using floating point values.
+ * Inputs and outputs are clamped to the range -1.0 to 1.0.
+ *
+ * control control control
+ * | | |
+ * v v v
+ * scale scale scale
+ * | | |
+ * | v |
+ * +-------> mix <------+
+ * |
+ * scale
+ * |
+ * v
+ * out
+ *
+ * Scaling
+ * -------
+ *
+ * Each scaler allows the input value to be scaled independently for
+ * inputs greater/less than zero. An offset can be applied to the output,
+ * as well as lower and upper boundary constraints.
+ * Negative scaling factors cause the output to be inverted (negative input
+ * produces positive output).
+ *
+ * Scaler pseudocode:
+ *
+ * if (input < 0)
+ * output = (input * NEGATIVE_SCALE) + OFFSET
+ * else
+ * output = (input * POSITIVE_SCALE) + OFFSET
+ *
+ * if (output < LOWER_LIMIT)
+ * output = LOWER_LIMIT
+ * if (output > UPPER_LIMIT)
+ * output = UPPER_LIMIT
+ *
+ *
+ * Mixing
+ * ------
+ *
+ * Mixing behaviour varies based on the specific mixer class; each
+ * mixer class describes its behaviour in more detail.
+ *
+ *
+ * Controls
+ * --------
+ *
+ * The precise assignment of controls may vary depending on the
+ * application, but the following assignments should be used
+ * when appropriate. Some mixer classes have specific assumptions
+ * about the assignment of controls.
+ *
+ * control | standard meaning
+ * --------+-----------------------
+ * 0 | roll
+ * 1 | pitch
+ * 2 | yaw
+ * 3 | primary thrust
+ */
+
+
+#ifndef _SYSTEMLIB_MIXER_MIXER_H
+#define _SYSTEMLIB_MIXER_MIXER_H value
+
+#include "drivers/drv_mixer.h"
+
+/**
+ * Abstract class defining a mixer mixing zero or more inputs to
+ * one or more outputs.
+ */
+class __EXPORT Mixer
+{
+public:
+ /** next mixer in a list */
+ Mixer *_next;
+
+ /**
+ * Fetch a control value.
+ *
+ * @param handle Token passed when the callback is registered.
+ * @param control_group The group to fetch the control from.
+ * @param control_index The group-relative index to fetch the control from.
+ * @param control The returned control
+ * @return Zero if the value was fetched, nonzero otherwise.
+ */
+ typedef int (* ControlCallback)(uintptr_t handle,
+ uint8_t control_group,
+ uint8_t control_index,
+ float &control);
+
+ /**
+ * Constructor.
+ *
+ * @param control_cb Callback invoked when reading controls.
+ */
+ Mixer(ControlCallback control_cb, uintptr_t cb_handle);
+ ~Mixer() {};
+
+ /**
+ * Perform the mixing function.
+ *
+ * @param outputs Array into which mixed output(s) should be placed.
+ * @param space The number of available entries in the output array;
+ * @return The number of entries in the output array that were populated.
+ */
+ virtual unsigned mix(float *outputs, unsigned space) = 0;
+
+ /**
+ * Analyses the mix configuration and updates a bitmask of groups
+ * that are required.
+ *
+ * @param groups A bitmask of groups (0-31) that the mixer requires.
+ */
+ virtual void groups_required(uint32_t &groups) = 0;
+
+protected:
+ /** client-supplied callback used when fetching control values */
+ ControlCallback _control_cb;
+ uintptr_t _cb_handle;
+
+ /**
+ * Perform simpler linear scaling.
+ *
+ * @param scaler The scaler configuration.
+ * @param input The value to be scaled.
+ * @return The scaled value.
+ */
+ static float scale(const mixer_scaler_s &scaler, float input);
+
+ /**
+ * Validate a scaler
+ *
+ * @param scaler The scaler to be validated.
+ * @return Zero if good, nonzero otherwise.
+ */
+ static int scale_check(struct mixer_scaler_s &scaler);
+
+private:
+};
+
+/**
+ * Group of mixers, built up from single mixers and processed
+ * in order when mixing.
+ */
+class __EXPORT MixerGroup : public Mixer
+{
+public:
+ MixerGroup(ControlCallback control_cb, uintptr_t cb_handle);
+ ~MixerGroup();
+
+ virtual unsigned mix(float *outputs, unsigned space);
+ virtual void groups_required(uint32_t &groups);
+
+ /**
+ * Add a mixer to the group.
+ *
+ * @param mixer The mixer to be added.
+ */
+ void add_mixer(Mixer *mixer);
+
+ /**
+ * Reads a mixer definition from a file and configures a corresponding
+ * group.
+ *
+ * The mixer group must be empty when this function is called.
+ *
+ * A mixer definition is a text representation of the configuration of a
+ * mixer. Definition lines begin with a capital letter followed by a colon.
+ *
+ * Null Mixer:
+ *
+ * Z:
+ *
+ * This mixer generates a constant zero output, and is normally used to
+ * skip over outputs that are not in use.
+ *
+ * Simple Mixer:
+ *
+ * M: <scaler count>
+ * S: <control group> <control index> <negative_scale*> <positive_scale*> <offset*> <lower_limit*> <upper_limit*>
+ * S: ...
+ *
+ * The definition consists of a single-line header indicating the
+ * number of scalers and then one line defining each scaler. The first
+ * scaler in the file is always the output scaler, followed by the input
+ * scalers.
+ *
+ * The <control ...> values for the output scaler are ignored by the mixer.
+ *
+ *
+ *
+ * Values marked * are integers representing floating point values; values are
+ * scaled by 10000 on load/save.
+ *
+ * Multiple mixer definitions may be stored in a single file; it is assumed that
+ * the reader will know how many to expect and read accordingly.
+ *
+ * A mixer entry with a scaler count of zero indicates a disabled mixer. This
+ * will return NULL for the mixer when processed by this function, and will be
+ * generated by passing NULL as the mixer to mixer_save.
+ *
+ * @param path The mixer configuration file to read.
+ * @return Zero on successful load, nonzero otherwise.
+ */
+ int load_from_file(const char *path);
+
+private:
+ Mixer *_first; /**< linked list of mixers */
+};
+
+/**
+ * Null mixer; returns zero.
+ *
+ * Used as a placeholder for output channels that are unassigned in groups.
+ */
+class __EXPORT NullMixer : public Mixer
+{
+public:
+ NullMixer();
+ ~NullMixer() {};
+
+ virtual unsigned mix(float *outputs, unsigned space);
+ virtual void groups_required(uint32_t &groups);
+};
+
+/**
+ * Simple summing mixer.
+ *
+ * Collects zero or more inputs and mixes them to a single output.
+ */
+class __EXPORT SimpleMixer : public Mixer
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param mixinfo Mixer configuration. The pointer passed
+ * becomes the property of the mixer and
+ * will be freed when the mixer is deleted.
+ */
+ SimpleMixer(ControlCallback control_cb,
+ uintptr_t cb_handle,
+ mixer_simple_s *mixinfo);
+ ~SimpleMixer();
+
+ virtual unsigned mix(float *outputs, unsigned space);
+ virtual void groups_required(uint32_t &groups);
+
+ /**
+ * Check that the mixer configuration as loaded is sensible.
+ *
+ * Note that this function will call control_cb, but only cares about
+ * error returns, not the input value.
+ *
+ * @return Zero if the mixer makes sense, nonzero otherwise.
+ */
+ int check();
+protected:
+
+private:
+ mixer_simple_s *_info;
+};
+
+/**
+ * Multi-rotor mixer.
+ *
+ * Collects four inputs (roll, pitch, yaw, thrust) and mixes them to
+ * a set of outputs based on the configured geometry.
+ */
+class __EXPORT MultirotorMixer : public Mixer
+{
+public:
+ enum Geometry
+ {
+ MULTIROTOR_QUAD_PLUS,
+ MULTIROTOR_QUAD_X
+ /* XXX add more here */
+ };
+
+ MultirotorMixer(ControlCallback control_cb,
+ uintptr_t cb_handle,
+ Geometry geom);
+ ~MultirotorMixer();
+
+ virtual unsigned mix(float *outputs, unsigned space);
+ virtual void groups_required(uint32_t &groups);
+
+private:
+ Geometry _geometry;
+};
+
+#endif