PX4 Firmware
PX4 Autopilot Software http://px4.io
Mixer.hpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (C) 2012-2019 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file Mixer.hpp
36  *
37  * Generic, programmable, procedural control signal mixers.
38  *
39  * This library implements a generic mixer interface that can be used
40  * by any driver or subsytem that wants to combine several control signals
41  * into a single output.
42  *
43  * Terminology
44  * ===========
45  *
46  * control value
47  * A mixer input value, typically provided by some controlling
48  * component of the system.
49  *
50  * control group
51  * A collection of controls provided by a single controlling component.
52  *
53  * actuator
54  * The mixer output value.
55  *
56  *
57  * Mixing basics
58  * =============
59  *
60  * An actuator derives its value from the combination of one or more
61  * control values. Each of the control values is scaled according to
62  * the actuator's configuration and then combined to produce the
63  * actuator value, which may then be further scaled to suit the specific
64  * output type.
65  *
66  * Internally, all scaling is performed using floating point values.
67  * Inputs and outputs are clamped to the range -1.0 to 1.0.
68  *
69  * control control control
70  * | | |
71  * v v v
72  * scale scale scale
73  * | | |
74  * | v |
75  * +-------> mix <------+
76  * |
77  * scale
78  * |
79  * v
80  * out
81  *
82  * Scaling
83  * -------
84  *
85  * Each scaler allows the input value to be scaled independently for
86  * inputs greater/less than zero. An offset can be applied to the output,
87  * as well as lower and upper boundary constraints.
88  * Negative scaling factors cause the output to be inverted (negative input
89  * produces positive output).
90  *
91  * Scaler pseudocode:
92  *
93  * if (input < 0)
94  * output = (input * NEGATIVE_SCALE) + OFFSET
95  * else
96  * output = (input * POSITIVE_SCALE) + OFFSET
97  *
98  * if (output < LOWER_LIMIT)
99  * output = LOWER_LIMIT
100  * if (output > UPPER_LIMIT)
101  * output = UPPER_LIMIT
102  *
103  *
104  * Mixing
105  * ------
106  *
107  * Mixing behaviour varies based on the specific mixer class; each
108  * mixer class describes its behaviour in more detail.
109  *
110  *
111  * Controls
112  * --------
113  *
114  * The precise assignment of controls may vary depending on the
115  * application, but the following assignments should be used
116  * when appropriate. Some mixer classes have specific assumptions
117  * about the assignment of controls.
118  *
119  * control | standard meaning
120  * --------+-----------------------
121  * 0 | roll
122  * 1 | pitch
123  * 2 | yaw
124  * 3 | primary thrust
125  */
126 
127 #pragma once
128 
129 #include <containers/List.hpp>
130 #include <mathlib/mathlib.h>
131 
132 /**
133  * Abstract class defining a mixer mixing zero or more inputs to
134  * one or more outputs.
135  */
136 class Mixer : public ListNode<Mixer *>
137 {
138 public:
139  enum class Airmode : int32_t {
140  disabled = 0,
141  roll_pitch = 1,
142  roll_pitch_yaw = 2
143  };
144 
145  /**
146  * Fetch a control value.
147  *
148  * @param handle Token passed when the callback is registered.
149  * @param control_group The group to fetch the control from.
150  * @param control_index The group-relative index to fetch the control from.
151  * @param control The returned control
152  * @return Zero if the value was fetched, nonzero otherwise.
153  */
154  typedef int (* ControlCallback)(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &control);
155 
156  /**
157  * Constructor.
158  *
159  * @param control_cb Callback invoked when reading controls.
160  */
161  Mixer(ControlCallback control_cb, uintptr_t cb_handle) : _control_cb(control_cb), _cb_handle(cb_handle) {}
162  virtual ~Mixer() = default;
163 
164  // no copy, assignment, move, move assignment
165  Mixer(const Mixer &) = delete;
166  Mixer &operator=(const Mixer &) = delete;
167  Mixer(Mixer &&) = delete;
168  Mixer &operator=(Mixer &&) = delete;
169 
170  /**
171  * Perform the mixing function.
172  *
173  * @param outputs Array into which mixed output(s) should be placed.
174  * @param space The number of available entries in the output array;
175  * @return The number of entries in the output array that were populated.
176  */
177  virtual unsigned mix(float *outputs, unsigned space) = 0;
178 
179  /**
180  * Get the saturation status.
181  *
182  * @return Integer bitmask containing saturation_status from multirotor_motor_limits.msg.
183  */
184  virtual uint16_t get_saturation_status() { return 0; }
185 
186  /**
187  * Analyses the mix configuration and updates a bitmask of groups
188  * that are required.
189  *
190  * @param groups A bitmask of groups (0-31) that the mixer requires.
191  */
192  virtual void groups_required(uint32_t &groups) {};
193 
194  /**
195  * @brief Empty method, only implemented for MultirotorMixer and MixerGroup class.
196  *
197  * @param[in] delta_out_max Maximum delta output.
198  *
199  */
200  virtual void set_max_delta_out_once(float delta_out_max) {}
201 
202  /**
203  * @brief Set trim offset for this mixer
204  *
205  * @return the number of outputs this mixer feeds to
206  */
207  virtual unsigned set_trim(float trim) { return 0; }
208 
209  /**
210  * @brief Get trim offset for this mixer
211  *
212  * @return the number of outputs this mixer feeds to
213  */
214  virtual unsigned get_trim(float *trim) { return 0; }
215 
216  /*
217  * @brief Sets the thrust factor used to calculate mapping from desired thrust to motor control signal output.
218  *
219  * @param[in] val The value
220  */
221  virtual void set_thrust_factor(float val) {}
222 
223  /**
224  * @brief Set airmode. Airmode allows the mixer to increase the total thrust in order to unsaturate the motors.
225  *
226  * @param[in] airmode Select airmode type (0 = disabled, 1 = roll/pitch, 2 = roll/pitch/yaw)
227  */
228  virtual void set_airmode(Airmode airmode) {};
229 
230  virtual unsigned get_multirotor_count() { return 0; }
231 
232 protected:
233 
234  /** client-supplied callback used when fetching control values */
236  uintptr_t _cb_handle;
237 
238  /**
239  * Invoke the client callback to fetch a control value.
240  *
241  * @param group Control group to fetch from.
242  * @param index Control index to fetch.
243  * @return The control value.
244  */
245  float get_control(uint8_t group, uint8_t index);
246 
247  /**
248  * Find a tag
249  *
250  * @param buf The buffer to operate on.
251  * @param buflen length of the buffer.
252  * @param tag character to search for.
253  */
254  static const char *findtag(const char *buf, unsigned &buflen, char tag);
255 
256  /**
257  * Find next tag and return it (0 is returned if no tag is found)
258  *
259  * @param buf The buffer to operate on.
260  * @param buflen length of the buffer.
261  */
262  static char findnexttag(const char *buf, unsigned buflen);
263 
264  /**
265  * Skip a line
266  *
267  * @param buf The buffer to operate on.
268  * @param buflen length of the buffer.
269  * @return 0 / OK if a line could be skipped, 1 else
270  */
271  static const char *skipline(const char *buf, unsigned &buflen);
272 
273  /**
274  * Check wether the string is well formed and suitable for parsing
275  */
276  static bool string_well_formed(const char *buf, unsigned &buflen);
277 };
static char findnexttag(const char *buf, unsigned buflen)
Find next tag and return it (0 is returned if no tag is found)
Definition: Mixer.cpp:75
virtual unsigned get_multirotor_count()
Definition: Mixer.hpp:230
static const char * skipline(const char *buf, unsigned &buflen)
Skip a line.
Definition: Mixer.cpp:90
ControlCallback _control_cb
client-supplied callback used when fetching control values
Definition: Mixer.hpp:235
An intrusive linked list.
virtual void set_max_delta_out_once(float delta_out_max)
Empty method, only implemented for MultirotorMixer and MixerGroup class.
Definition: Mixer.hpp:200
Mixer(ControlCallback control_cb, uintptr_t cb_handle)
Constructor.
Definition: Mixer.hpp:161
int(* ControlCallback)(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &control)
Fetch a control value.
Definition: Mixer.hpp:154
virtual uint16_t get_saturation_status()
Get the saturation status.
Definition: Mixer.hpp:184
static bool string_well_formed(const char *buf, unsigned &buflen)
Check wether the string is well formed and suitable for parsing.
Definition: Mixer.cpp:105
virtual void set_airmode(Airmode airmode)
Set airmode.
Definition: Mixer.hpp:228
uintptr_t _cb_handle
Definition: Mixer.hpp:236
Mixer & operator=(const Mixer &)=delete
virtual unsigned mix(float *outputs, unsigned space)=0
Perform the mixing function.
Airmode
Definition: Mixer.hpp:139
float get_control(uint8_t group, uint8_t index)
Invoke the client callback to fetch a control value.
Definition: Mixer.cpp:50
virtual ~Mixer()=default
static const char * findtag(const char *buf, unsigned &buflen, char tag)
Find a tag.
Definition: Mixer.cpp:60
virtual unsigned get_trim(float *trim)
Get trim offset for this mixer.
Definition: Mixer.hpp:214
virtual void groups_required(uint32_t &groups)
Analyses the mix configuration and updates a bitmask of groups that are required. ...
Definition: Mixer.hpp:192
virtual void set_thrust_factor(float val)
Definition: Mixer.hpp:221
Abstract class defining a mixer mixing zero or more inputs to one or more outputs.
Definition: Mixer.hpp:136
virtual unsigned set_trim(float trim)
Set trim offset for this mixer.
Definition: Mixer.hpp:207