Robot Control Library
filter.h
Go to the documentation of this file.
1/**
2 * <rc/math/filter.h>
3 *
4 * @brief Functions for generating and implementing discrete SISO filters.
5 *
6 * This discrete filter implementation allows for easy implementation of
7 * arbitrary transfer functions in code. It keeps track of all previous inputs
8 * and outputs in ring buffers for efficiency. All computation is done using
9 * single-precision doubleing point values.
10 *
11 * Several functions are providing for generating filter coefficients for the
12 * most common functions such as low/high pass filters, moving average filters,
13 * PID, and integrators.
14 *
15 * See the rc_test_filter.c example for use case.
16 *
17 * @author James Strawson
18 * @date 2016
19 *
20 * @addtogroup SISO_Filter
21 * @ingroup Math
22 * @{
23 */
24
25#ifndef RC_FILTER_H
26#define RC_FILTER_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include <stdint.h>
33#include <rc/math/vector.h>
34#include <rc/math/ring_buffer.h>
35
36/**
37 * @brief Struct containing configuration and state of a SISO filter.
38 *
39 * Also points to dynamically allocated memory which make it necessary to use
40 * the allocation and free function in this API for proper use. The user can
41 * read and modify values directly from ths struct.
42 */
43typedef struct rc_filter_t{
44 /** @name transfer function properties */
45 ///@{
46 int order; ///< transfer function order
47 double dt; ///< timestep in seconds
48 double gain; ///< Additional gain multiplier, usually 1.0
49 rc_vector_t num; ///< numerator coefficients
50 rc_vector_t den; ///< denominator coefficients
51 ///@}
52
53 /** @name saturation settings */
54 ///@{
55 int sat_en; ///< set to 1 by enable_saturation()
56 double sat_min; ///< lower saturation limit
57 double sat_max; ///< upper saturation limit
58 int sat_flag; ///< 1 if saturated on the last step
59 ///@}
60
61 /** @name soft start settings */
62 ///@{
63 int ss_en; ///< set to 1 by enbale_soft_start()
64 double ss_steps; ///< steps before full output allowed
65 ///@}
66
67 /** @name dynamically allocated ring buffers */
68 ///@{
71 ///@}
72
73 /** @name other */
74 ///@{
75 double newest_input; ///< shortcut for the most recent input
76 double newest_output; ///< shortcut for the most recent output
77 uint64_t step; ///< steps since last reset
78 int initialized; ///< initialization flag
79 ///@}
81
82#define RC_FILTER_INITIALIZER {\
83 .order = 0,\
84 .dt = 0.0,\
85 .gain = 1.0,\
86 .num = RC_VECTOR_INITIALIZER,\
87 .den = RC_VECTOR_INITIALIZER,\
88 .sat_en = 0,\
89 .sat_min = 0.0,\
90 .sat_max = 0.0,\
91 .sat_flag = 0,\
92 .ss_en = 0,\
93 .ss_steps = 0,\
94 .in_buf = RC_RINGBUF_INITIALIZER,\
95 .out_buf = RC_RINGBUF_INITIALIZER,\
96 .newest_input = 0.0,\
97 .newest_output = 0.0,\
98 .step = 0,\
99 .initialized = 0}
100
101/**
102 * @brief Critical function for initializing rc_filter_t structs.
103 *
104 * This is a very important function. If your rc_filter_t struct is not a global
105 * variable, then its initial contents cannot be guaranteed to be anything in
106 * particular. Therefore it could contain problematic contents which could
107 * interfere with functions in this library. Therefore, you should always
108 * initialize your filters with rc_filter_empty before using with any other
109 * function in this library such as rc_filter_alloc. This serves the same
110 * purpose as rc_matrix_empty, rc_vector_empty, and rc_ringbuf_empty.
111 *
112 * @return Empty zero-filled rc_filter_t struct
113 */
115
116/**
117 * @brief Allocate memory for a discrete-time filter & populates it with
118 * the transfer function coefficients provided in vectors num and den.
119 *
120 * The memory in num and den is duplicated so those vectors can be reused or
121 * freed after allocating a filter without fear of disturbing the function of
122 * the filter. Argument dt is the timestep in seconds at which the user expects
123 * to operate the filter. The length of demonimator den must be at least as
124 * large as numerator num to avoid describing an improper transfer function. If
125 * rc_filter_t pointer f points to an existing filter then the old filter's
126 * contents are freed safely to avoid memory leaks. We suggest initializing
127 * filter f with rc_filter_empty before calling this function if it is not a
128 * global variable to ensure it does not accidentally contain invlaid contents
129 * such as null pointers. The filter's order is derived from the length of the
130 * denominator polynomial.
131 *
132 * @param[out] f Pointer to user's rc_filter_t struct
133 * @param[in] num The numerator vector
134 * @param[in] den The denomenator vector
135 * @param[in] dt Timestep in seconds
136 *
137 * @return 0 on success or -1 on failure.
138 */
140
141/**
142 * @brief Like rc_filter_alloc(), but takes arrays for the numerator and
143 * denominator coefficients instead of vectors.
144 *
145 * Arrays num and den must have lengths that form a proper or semi-proper
146 * transfer function.
147 *
148 * @param[out] f Pointer to user's rc_filter_t struct
149 * @param[in] dt Timestep in seconds
150 * @param[in] num pointer to numerator array
151 * @param[in] numlen The numerator length
152 * @param[in] den pointer to denominator array
153 * @param[in] denlen The denominator length
154 *
155 * @return 0 on success or -1 on failure.
156 */
157int rc_filter_alloc_from_arrays(rc_filter_t* f,double dt,double* num,int numlen,\
158 double* den,int denlen);
159
160/**
161 * @brief duplicates a filter
162 *
163 * This allocates new memory in filter f so it can be used independently from
164 * the old filter but with the same configuration.
165 *
166 * @param f new filter to allocate
167 * @param[in] old old filter to copy
168 *
169 * @return { description_of_the_return_value }
170 */
172
173/**
174 * @brief Frees the memory allocated by a filter's buffers and coefficient
175 * vectors. Also resets all filter properties back to 0.
176 *
177 * @param f Pointer to user's rc_filter_t struct
178 *
179 * @return Returns 0 on success or -1 on failure.
180 */
182
183/**
184 * @brief Prints the transfer function and other statistic of a filter to
185 * the screen.
186 *
187 * Only works on filters up to order 9.
188 *
189 * @param f Pointer to user's rc_filter_t struct
190 *
191 * @return Returns 0 on success or -1 on failure.
192 */
194
195/**
196 * @brief March a filter forward one step with new input provided as an
197 * argument.
198 *
199 * If saturation or soft-start are enabled then the output will automatically be
200 * bound appropriately. The steps counter is incremented by one and internal
201 * ring buffers are updated accordingly. Once a filter is created, this is
202 * typically the only function required afterwards.
203 *
204 * @param f Pointer to user's rc_filter_t struct
205 * @param[in] new_input The new input
206 *
207 * @return Returns the new output which could also be accessed with the
208 * newest_output field in the filter struct.
209 */
210double rc_filter_march(rc_filter_t* f, double new_input);
211
212/**
213 * @brief Resets all previous inputs and outputs to 0. Also resets the step
214 * counter & saturation flag.
215 *
216 * This is sufficient to start the filter again as if it were just created.
217 *
218 * @param f Pointer to user's rc_filter_t struct
219 *
220 * @return Returns 0 on success or -1 on failure.
221 */
223
224/**
225 * @brief Enables saturation between bounds min and max.
226 *
227 * If saturation is enabled for a specified filter, the filter will
228 * automatically bound the output between min and max. You may ignore this
229 * function if you wish the filter to run unbounded. Max must be greater than or
230 * equal to min. If max==min, the output will be fixed at that value. Any
231 * double-precision floating point value is allowed, positive or negative.
232 *
233 * @param f Pointer to user's rc_filter_t struct
234 * @param[in] min The lower bound
235 * @param[in] max The upper bound
236 *
237 * @return Returns 0 on success or -1 on failure.
238 */
239int rc_filter_enable_saturation(rc_filter_t* f, double min, double max);
240
241/**
242 * @brief Checks if the filter saturated the last time step.
243 *
244 * This information could also be retrieved by looking at the 'sat_flag' value
245 * in the filter struct.
246 *
247 * @param f Pointer to user's rc_filter_t struct
248 *
249 * @return Returns 1 if the filter saturated the last time step. Returns 0
250 * otherwise.
251 */
253
254/**
255 * @brief Enables soft start functionality where the output bound is
256 * gradually opened linearly from 0 to the normal saturation range.
257 *
258 * This occurs over the time specified from argument 'seconds' from when the
259 * filter is first created or reset. Saturation must already be enabled for this
260 * to work. This assumes that the user does indeed call rc_filter_march at
261 * roughly the same time interval as the 'dt' variable in the filter struct
262 * which is set at creation time. The soft-start property is maintained through
263 * a call to rc_filter_reset so the filter will soft-start again after each
264 * reset. This feature should only really be used for feedback controllers to
265 * prevent jerky starts. The saturation flag will not be set during this period
266 * as the output is usually expected to be bounded and we don't want to falsely
267 * trigger alarms or saturation counters.
268 *
269 * @param f Pointer to user's rc_filter_t struct
270 * @param[in] seconds Time in seconds
271 *
272 * @return Returns 0 on success or -1 on failure.
273 */
275
276/**
277 * @brief Returns the input 'steps' back in time. Steps=0 returns most
278 * recent input.
279 *
280 * 'steps' must be between 0 and order inclusively as those are the only steps
281 * retained in memory for normal filter operation. To record values further back
282 * in time we suggest creating your own rc_ringbuf_t ring buffer.
283 *
284 * @param f Pointer to user's rc_filter_t struct
285 * @param[in] steps The steps back in time, steps=0 returns most recent input.
286 *
287 * @return Returns the requested previous input. If there is an error,
288 * returns -1.0f and prints an error message.
289 */
291
292/**
293 * @brief Returns the output 'steps' back in time. Steps = 0 returns most
294 * recent output.
295 *
296 * 'steps' must be between 0 and order inclusively as those are the only steps
297 * retained in memory for normal filter operation. To record values further back
298 * in time we suggest creating your own rc_ringbuf_t ring buffer.
299 *
300 * @param f Pointer to user's rc_filter_t struct
301 * @param[in] steps The steps back in time, steps=0 returns most recent
302 * output.
303 *
304 * @return Returns the requested previous output. If there is an error,
305 * returns -1.0f and prints an error message.
306 */
308
309/**
310 * @brief Fills all previous inputs to the filter as if they had been equal
311 * to 'in'
312 *
313 * Most useful when starting high-pass filters to prevent unwanted jumps in the
314 * output when starting with non-zero input.
315 *
316 * @param f Pointer to user's rc_filter_t struct
317 * @param[in] in Input value to fill
318 *
319 * @return Returns 0 on success or -1 on failure.
320 */
322
323/**
324 * @brief Fills all previous outputs of the filter as if they had been
325 * equal to 'out'.
326 *
327 * Most useful when starting low-pass filters to prevent unwanted settling time
328 * when starting with non-zero input.
329 *
330 * @param f Pointer to user's rc_filter_t struct
331 * @param[in] out output value to fill
332 *
333 * @return Returns 0 on success or -1 on failure.
334 */
336
337/**
338 * @brief Creates a new filter 'out' by multiplying f1*f2.
339 *
340 * The contents of f3 are freed safely if necessary and new memory is allocated
341 * to avoid memory leaks.
342 *
343 * @param[in] f1 Pointer to user's rc_filter_t struct to be multiplied
344 * @param[in] f2 Pointer to user's rc_filter_t struct to be multiplied
345 * @param[out] out Pointer to newly created filter struct
346 *
347 * @return Returns 0 on success or -1 on failure.
348 */
350/**
351 * @brief Creates a new filter 'out' by multiplying f1*f2*f3
352 *
353 * The contents of f3 are freed safely if necessary and new memory is allocated
354 * to avoid memory leaks.
355 *
356 * @param[in] f1 Pointer to user's rc_filter_t struct to be multiplied
357 * @param[in] f2 Pointer to user's rc_filter_t struct to be multiplied
358 * @param[in] f3 Pointer to user's rc_filter_t struct to be multiplied
359 * @param[out] out Pointer to newly created filter struct
360 *
361 * @return Returns 0 on success or -1 on failure.
362 */
364
365/**
366 * @brief Creates a discrete time filter with similar dynamics to a
367 * provided continuous time transfer function using tustin's approximation with
368 * prewarping about a frequency of interest 'w' in radians per second.
369 *
370 * Any existing memory allocated for f is freed is necessary to prevent memory
371 * leaks. Returns 0 on success or -1 on failure.
372 *
373 * @param[out] f Pointer to user's rc_filter_t struct
374 * @param[in] dt desired timestep of discrete filter in seconds
375 * @param[in] num continuous time numerator coefficients
376 * @param[in] den continuous time denominator coefficients
377 * @param[in] w prewarping frequency in rad/s
378 *
379 * @return Returns 0 on success or -1 on failure.
380 */
381int rc_filter_c2d_tustin(rc_filter_t* f, double dt,rc_vector_t num,rc_vector_t den,double w);
382
383/**
384 * @brief Normalizes a discrete time filter so that the leading demoninator
385 * coefficient is 1
386 *
387 * @param f Pointer to user's rc_filter_t struct
388 *
389 * @return Returns 0 on success or -1 on failure.
390 */
392
393/**
394 * @brief Creates a first order low pass filter.
395 *
396 * Any existing memory allocated for f is freed safely to avoid memory leaks and
397 * new memory is allocated for the new filter. dt is in units of seconds and
398 * time_constant is the number of seconds it takes to rise to 63.4% of a
399 * steady-state input. This can be used alongside rc_first_order_highpass to
400 * make a complementary filter pair.
401 *
402 * @param[out] f Pointer to user's rc_filter_t struct
403 * @param[in] dt desired timestep of discrete filter in seconds
404 * @param[in] tc time constant: Seconds it takes to rise to 63.4% of a
405 * steady-state input
406 *
407 * @return Returns 0 on success or -1 on failure.
408 */
409int rc_filter_first_order_lowpass(rc_filter_t* f, double dt, double tc);
410
411/**
412 * @brief Creates a first order high pass filter.
413 *
414 * Any existing memory allocated for f is freed safely to avoid memory leaks and
415 * new memory is allocated for the new filter. dt is in units of seconds and
416 * time_constant is the number of seconds it takes to decay by 63.4% of a
417 * steady-state input. This can be used alongside rc_first_order_highpass to
418 * make a complementary filter pair.
419 *
420 * @param[out] f Pointer to user's rc_filter_t struct
421 * @param[in] dt desired timestep of discrete filter in seconds
422 * @param[in] tc time constant: Seconds it takes to decay by 63.4% of a
423 * steady-state input
424 *
425 * @return Returns 0 on success or -1 on failure.
426 */
427int rc_filter_first_order_highpass(rc_filter_t* f, double dt, double tc);
428
429/**
430 * @brief Creates a Butterworth low pass filter of specified order and
431 * cutoff frequency.
432 *
433 * Any existing memory allocated for f is freed safely to avoid memory leaks and
434 * new memory is allocated for the new filter.
435 *
436 * @param[out] f Pointer to user's rc_filter_t struct
437 * @param[in] order The order (>=1)
438 * @param[in] dt desired timestep of discrete filter in seconds
439 * @param[in] wc Cuttoff freqauency in rad/s
440 *
441 * @return Returns 0 on success or -1 on failure.
442 */
443int rc_filter_butterworth_lowpass(rc_filter_t* f, int order, double dt, double wc);
444
445/**
446 * @brief Creates a Butterworth high pass filter of specified order and
447 * cutoff frequency.
448 *
449 * Any existing memory allocated for f is freed safely to avoid memory leaks and
450 * new memory is allocated for the new filter.
451 *
452 * @param[out] f Pointer to user's rc_filter_t struct
453 * @param[in] order The order (>=1)
454 * @param[in] dt desired timestep of discrete filter in seconds
455 * @param[in] wc Cuttoff freqauency in rad/s
456 *
457 * @return Returns 0 on success or -1 on failure.
458 */
459int rc_filter_butterworth_highpass(rc_filter_t* f, int order, double dt, double wc);
460
461/**
462 * @brief Makes a FIR moving average filter that averages over specified
463 * number of samples.
464 *
465 * Any existing memory allocated for f is freed safely to avoid memory leaks and
466 * new memory is allocated for the new filter.
467 *
468 * Note that the timestep dt does not effect the dynamics of the produced
469 * filter. It is simply copied into the 'dt' field of the rc_filter_t struct.
470 * However, it is necessary for creation of this filter for compatability with
471 * the soft-start feature and any other user codepaths that may be dependent on
472 * a filter's timestep.
473 *
474 * @param[out] f Pointer to user's rc_filter_t struct
475 * @param[in] samples The samples to average over (>=2)
476 * @param[in] dt desired timestep of discrete filter in seconds
477 *
478 * @return Returns 0 on success or -1 on failure.
479 */
480int rc_filter_moving_average(rc_filter_t* f, int samples, double dt);
481
482/**
483 * @brief Creates a first order integrator.
484 *
485 * Like most functions here, the dynamics are only accurate if the filter is
486 * called with a timestep corresponding to dt. Any existing memory allocated for
487 * f is freed safely to avoid memory leaks and new memory is allocated for the
488 * new filter.
489 *
490 * @param[out] f Pointer to user's rc_filter_t struct
491 * @param[in] dt desired timestep of discrete filter in seconds
492 *
493 * @return Returns 0 on success or -1 on failure.
494 */
496
497/**
498 * @brief Creates a second order double integrator.
499 *
500 * Like most functions here, the dynamics are only accurate if the filter is
501 * called with a timestep corresponding to dt. Any existing memory allocated for
502 * f is freed safely to avoid memory leaks and new memory is allocated for the
503 * new filter.
504 *
505 * @param[out] f Pointer to user's rc_filter_t struct
506 * @param[in] dt desired timestep of discrete filter in seconds
507 *
508 * @return Returns 0 on success or -1 on failure.
509 */
511
512/**
513 * @brief Creates a discrete-time implementation of a parallel PID
514 * controller with high-frequency rolloff using the forward-Euler integration
515 * method.
516 *
517 * This is equivalent to the Matlab function: C = pid(Kp,Ki,Kd,Tf,Ts)
518 *
519 * It is not possible to implement a pure differentiator with a discrete
520 * transfer function so this filter has high frequency rolloff with time
521 * constant Tf. Smaller Tf results in less rolloff, but Tf must be greater than
522 * dt/2 for stability. Returns 0 on success or -1 on failure.
523 *
524 * @param f Pointer to user's rc_filter_t struct
525 * @param[in] kp Proportional constant
526 * @param[in] ki Integration constant
527 * @param[in] kd Derivative constant
528 * @param[in] Tf High Frequency rolloff time constant (seconds)
529 * @param[in] dt desired timestep of discrete filter in seconds
530 *
531 * @return Returns 0 on success or -1 on failure.
532 */
533int rc_filter_pid(rc_filter_t* f,double kp,double ki,double kd,double Tf,double dt);
534
535
536/**
537 * @brief Creates a third order symmetric complementary pair of high/low
538 * pass filters
539 *
540 * @param lp lowpass filter to be populated
541 * @param hp highpass filter to be populated
542 * @param[in] freq crossover frequency in rad/s
543 * @param[in] damp Damping ratio >0, 1 is critically damped, lower than that
544 * gets wobbly
545 * @param[in] dt desired timestep of discrete filter in seconds
546 *
547 * @return 0 on success or -1 on failure.
548 */
549int rc_filter_third_order_complement(rc_filter_t* lp, rc_filter_t* hp, double freq, double damp, double dt);
550
551
552#ifdef __cplusplus
553}
554#endif
555
556#endif // RC_FILTER_H
557
558/** @} end ingroup math*/
double rc_filter_previous_output(rc_filter_t *f, int steps)
Returns the output 'steps' back in time. Steps = 0 returns most recent output.
int rc_filter_pid(rc_filter_t *f, double kp, double ki, double kd, double Tf, double dt)
Creates a discrete-time implementation of a parallel PID controller with high-frequency rolloff using...
int rc_filter_alloc_from_arrays(rc_filter_t *f, double dt, double *num, int numlen, double *den, int denlen)
Like rc_filter_alloc(), but takes arrays for the numerator and denominator coefficients instead of ve...
int rc_filter_prefill_outputs(rc_filter_t *f, double out)
Fills all previous outputs of the filter as if they had been equal to 'out'.
int rc_filter_double_integrator(rc_filter_t *f, double dt)
Creates a second order double integrator.
int rc_filter_reset(rc_filter_t *f)
Resets all previous inputs and outputs to 0. Also resets the step counter & saturation flag.
int rc_filter_normalize(rc_filter_t *f)
Normalizes a discrete time filter so that the leading demoninator coefficient is 1.
int rc_filter_third_order_complement(rc_filter_t *lp, rc_filter_t *hp, double freq, double damp, double dt)
Creates a third order symmetric complementary pair of high/low pass filters.
double rc_filter_march(rc_filter_t *f, double new_input)
March a filter forward one step with new input provided as an argument.
struct rc_filter_t rc_filter_t
Struct containing configuration and state of a SISO filter.
int rc_filter_first_order_highpass(rc_filter_t *f, double dt, double tc)
Creates a first order high pass filter.
int rc_filter_enable_soft_start(rc_filter_t *f, double seconds)
Enables soft start functionality where the output bound is gradually opened linearly from 0 to the no...
int rc_filter_duplicate(rc_filter_t *f, rc_filter_t old)
duplicates a filter
rc_filter_t rc_filter_empty(void)
Critical function for initializing rc_filter_t structs.
int rc_filter_prefill_inputs(rc_filter_t *f, double in)
Fills all previous inputs to the filter as if they had been equal to 'in'.
int rc_filter_c2d_tustin(rc_filter_t *f, double dt, rc_vector_t num, rc_vector_t den, double w)
Creates a discrete time filter with similar dynamics to a provided continuous time transfer function ...
int rc_filter_first_order_lowpass(rc_filter_t *f, double dt, double tc)
Creates a first order low pass filter.
int rc_filter_get_saturation_flag(rc_filter_t *f)
Checks if the filter saturated the last time step.
int rc_filter_alloc(rc_filter_t *f, rc_vector_t num, rc_vector_t den, double dt)
Allocate memory for a discrete-time filter & populates it with the transfer function coefficients pro...
int rc_filter_integrator(rc_filter_t *f, double dt)
Creates a first order integrator.
int rc_filter_print(rc_filter_t f)
Prints the transfer function and other statistic of a filter to the screen.
int rc_filter_butterworth_lowpass(rc_filter_t *f, int order, double dt, double wc)
Creates a Butterworth low pass filter of specified order and cutoff frequency.
int rc_filter_free(rc_filter_t *f)
Frees the memory allocated by a filter's buffers and coefficient vectors. Also resets all filter prop...
int rc_filter_multiply_three(rc_filter_t f1, rc_filter_t f2, rc_filter_t f3, rc_filter_t *out)
Creates a new filter 'out' by multiplying f1*f2*f3.
int rc_filter_enable_saturation(rc_filter_t *f, double min, double max)
Enables saturation between bounds min and max.
int rc_filter_multiply(rc_filter_t f1, rc_filter_t f2, rc_filter_t *out)
Creates a new filter 'out' by multiplying f1*f2.
double rc_filter_previous_input(rc_filter_t *f, int steps)
Returns the input 'steps' back in time. Steps=0 returns most recent input.
int rc_filter_moving_average(rc_filter_t *f, int samples, double dt)
Makes a FIR moving average filter that averages over specified number of samples.
int rc_filter_butterworth_highpass(rc_filter_t *f, int order, double dt, double wc)
Creates a Butterworth high pass filter of specified order and cutoff frequency.
#define min(a, b)
Definition: rc_usefulincludes.h:73
Struct containing configuration and state of a SISO filter.
Definition: filter.h:43
double dt
timestep in seconds
Definition: filter.h:47
uint64_t step
steps since last reset
Definition: filter.h:77
int sat_flag
1 if saturated on the last step
Definition: filter.h:58
rc_ringbuf_t in_buf
Definition: filter.h:69
rc_vector_t num
numerator coefficients
Definition: filter.h:49
double newest_output
shortcut for the most recent output
Definition: filter.h:76
double sat_min
lower saturation limit
Definition: filter.h:56
int sat_en
set to 1 by enable_saturation()
Definition: filter.h:55
rc_ringbuf_t out_buf
Definition: filter.h:70
double gain
Additional gain multiplier, usually 1.0.
Definition: filter.h:48
int order
transfer function order
Definition: filter.h:46
double ss_steps
steps before full output allowed
Definition: filter.h:64
int initialized
initialization flag
Definition: filter.h:78
double newest_input
shortcut for the most recent input
Definition: filter.h:75
double sat_max
upper saturation limit
Definition: filter.h:57
int ss_en
set to 1 by enbale_soft_start()
Definition: filter.h:63
rc_vector_t den
denominator coefficients
Definition: filter.h:50
Struct containing state of a ringbuffer and pointer to dynamically allocated memory.
Definition: ring_buffer.h:34
Struct containing the state of a vector and a pointer to dynamically allocated memory to hold its con...
Definition: vector.h:41