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
29 extern "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  */
43 typedef 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  ///@}
80 } rc_filter_t;
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  */
157 int 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  */
210 double 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  */
239 int 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  */
274 int rc_filter_enable_soft_start(rc_filter_t* f, double seconds);
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  */
290 double rc_filter_previous_input(rc_filter_t* f, int steps);
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  */
307 double rc_filter_previous_output(rc_filter_t* f, int steps);
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  */
321 int rc_filter_prefill_inputs(rc_filter_t* f, double in);
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  */
335 int rc_filter_prefill_outputs(rc_filter_t* f, double out);
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  */
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  */
409 int 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  */
427 int 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  */
443 int 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  */
459 int 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  */
480 int 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  */
495 int rc_filter_integrator(rc_filter_t *f, double dt);
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  */
533 int 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  */
549 int 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*/
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_first_order_lowpass(rc_filter_t *f, double dt, double tc)
Creates a first order low pass filter.
rc_vector_t den
denominator coefficients
Definition: filter.h:50
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 &#39;out&#39; by multiplying f1*f2*f3.
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 sat_flag
1 if saturated on the last step
Definition: filter.h:58
int ss_en
set to 1 by enbale_soft_start()
Definition: filter.h:63
double rc_filter_march(rc_filter_t *f, double new_input)
March a filter forward one step with new input provided as an argument.
int rc_filter_enable_saturation(rc_filter_t *f, double min, double max)
Enables saturation between bounds min and max.
double gain
Additional gain multiplier, usually 1.0.
Definition: filter.h:48
int rc_filter_multiply(rc_filter_t f1, rc_filter_t f2, rc_filter_t *out)
Creates a new filter &#39;out&#39; by multiplying f1*f2.
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_prefill_outputs(rc_filter_t *f, double out)
Fills all previous outputs of the filter as if they had been equal to &#39;out&#39;.
int rc_filter_duplicate(rc_filter_t *f, rc_filter_t old)
duplicates a filter
int rc_filter_integrator(rc_filter_t *f, double dt)
Creates a first order integrator.
double sat_max
upper saturation limit
Definition: filter.h:57
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 ss_steps
steps before full output allowed
Definition: filter.h:64
int initialized
initialization flag
Definition: filter.h:78
Struct containing the state of a vector and a pointer to dynamically allocated memory to hold its con...
Definition: vector.h:41
rc_ringbuf_t in_buf
Definition: filter.h:69
Struct containing configuration and state of a SISO filter.
Definition: filter.h:43
int sat_en
set to 1 by enable_saturation()
Definition: filter.h:55
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 ...
uint64_t step
steps since last reset
Definition: filter.h:77
Struct containing state of a ringbuffer and pointer to dynamically allocated memory.
Definition: ring_buffer.h:34
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...
struct rc_filter_t rc_filter_t
Struct containing configuration and state of a SISO filter.
int rc_filter_normalize(rc_filter_t *f)
Normalizes a discrete time filter so that the leading demoninator coefficient is 1.
int rc_filter_print(rc_filter_t f)
Prints the transfer function and other statistic of a filter to the screen.
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 &#39;in&#39;.
rc_filter_t rc_filter_empty(void)
Critical function for initializing rc_filter_t structs.
#define min(a, b)
Definition: rc_usefulincludes.h:73
double rc_filter_previous_output(rc_filter_t *f, int steps)
Returns the output &#39;steps&#39; back in time. Steps = 0 returns most recent output.
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...
double sat_min
lower saturation limit
Definition: filter.h:56
int rc_filter_free(rc_filter_t *f)
Frees the memory allocated by a filter&#39;s buffers and coefficient vectors. Also resets all filter prop...
int order
transfer function order
Definition: filter.h:46
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_first_order_highpass(rc_filter_t *f, double dt, double tc)
Creates a first order high pass filter.
double dt
timestep in seconds
Definition: filter.h:47
rc_vector_t num
numerator coefficients
Definition: filter.h:49
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.
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.
double newest_input
shortcut for the most recent input
Definition: filter.h:75
int rc_filter_get_saturation_flag(rc_filter_t *f)
Checks if the filter saturated the last time step.
rc_ringbuf_t out_buf
Definition: filter.h:70
double newest_output
shortcut for the most recent output
Definition: filter.h:76
double rc_filter_previous_input(rc_filter_t *f, int steps)
Returns the input &#39;steps&#39; back in time. Steps=0 returns most recent input.