Larus glider flight sensor system 3.9.2024
Software-In-The-Loop test and validation system
Loading...
Searching...
No Matches
soaring_flight_averager.h
Go to the documentation of this file.
1/***********************************************************************/
25#ifndef SMART_AVERAGER_H_
26#define SMART_AVERAGER_H_
27
28#include <AHRS.h>
29#define SQR(x) ((x)*(x))
30#include "pt2.h"
31#include "embedded_math.h"
32
33#define ONE_DIV_2PI 0.159155f
34#define PI_TIMES_2 6.2832f
35
37template<class value_t, bool CLAMP_OUTPUT_FIRST_CIRCLE = false, bool SOFT_TAKEOFF = true>
39 {
40 public:
42 active_state (STRAIGHT_FLIGHT),
44 present_output(0),
45 old_sector(0)
46 {
47 for (unsigned index = 0; index < N_SECTORS; ++index)
48 {
49 sector_averages[index] = {0};
50 sector_sample_count[index] = 0;
51 }
52 };
53
54 const value_t & get_output (void) const
55 {
56 return present_output;
57 }
58
59 void
62 {
63 if (heading < ZERO)
65
66 switch (active_state)
67 {
68 case STRAIGHT_FLIGHT:
69 if (new_state == CIRCLING)
70 {
71 active_state = CIRCLING;
72
73 // use a little trick to provide a smooth transition
74 if( SOFT_TAKEOFF)
75 fill_recordings_with_value (averager.get_output());
76 else
78
80 present_output = get_boxcar_average();
81 }
82 else
83 {
84 present_output = averager.respond (current_value);
85 }
86 break;
87 case CIRCLING:
89 {
90 active_state = STRAIGHT_FLIGHT;
91 reset( get_boxcar_average());
92 }
93
95
97 {
98 if( circle_completed())
99 present_output = get_boxcar_average();
100 }
101 else
102 present_output = get_boxcar_average();
103
104 break;
105 case TRANSITION: // impossible, just to keep the compiler calm
106 default:
107 assert( 0);
108 break;
109 }
110 }
111
113 {
114 unsigned index = find_sector_index( heading);
115
116 if( old_sector != index) // on sector change
117 {
118 old_sector = index;
119 if( sector_sample_count[index] > 1) // if sector has been used in the circle before
120 {
121 // reset sector
122 sector_sample_count[index] = 0;
123 sector_averages[index] = {0};
124 }
125 }
126
127 sector_averages[index] += current_value;
128 ++ sector_sample_count[index];
129 }
130
131 void reset( value_t value)
132 {
133 averager.settle(value);
134 for (unsigned i = 0; i < N_SECTORS; ++i)
135 {
136 sector_averages[i] = {0};
137 sector_sample_count[i] = 0;
138 }
139 present_output = value;
140 }
141
142 bool circle_completed (void) const
143 {
144 for (unsigned index = 0; index < N_SECTORS; ++index)
145 if( sector_sample_count[index] == 0)
146 return false;
147 return true;
148 }
149
150 void relax( void)
151 {
152 averager.settle({0});
153 }
154
155 private:
156
157 value_t get_boxcar_average( void)
158 {
159 value_t average = { 0 };
160
161 unsigned number_of_used_sectors = 0;
162 for (unsigned index = 0; index < N_SECTORS; ++index)
163 if( sector_sample_count[index] > 0)
164 {
165 average = average + sector_averages[index] * ( ONE / sector_sample_count[index]);
167 }
168 if( number_of_used_sectors == 0)
169 return {0};
170 else
171 return average * (1.0f / (float) number_of_used_sectors); // as division may not be implemented
172 }
173
174 unsigned find_sector_index( float heading)
175 {
176 unsigned retv = (unsigned) (heading * ONE_DIV_2PI * N_SECTORS);
177 if( retv >= N_SECTORS) // prevent rounding errors
178 retv = N_SECTORS -1;
179 return retv;
180 }
181
182 void fill_recordings_with_value ( value_t value)
183 {
184 for (unsigned i = 0; i < N_SECTORS; ++i)
185 {
186 sector_averages[i] = value;
187 sector_sample_count[i] = 1;
188 }
189 }
190
191 enum { N_SECTORS = 16};
192
193 circle_state_t active_state;
194 pt2<value_t, float> averager; // IIR-averager for straight flight
195 value_t present_output; // maintained to save computing time
196 value_t sector_averages[N_SECTORS]; // boxcar averager for circling flight
197 unsigned sector_sample_count[N_SECTORS]; // boxcar averager for circling flight
198 unsigned old_sector;
199 };
200
201
202
203
204#endif /* SMART_AVERAGER_H_ */
attitude and heading reference system (interface)
circle_state_t
Definition AHRS.h:44
@ TRANSITION
Definition AHRS.h:44
@ STRAIGHT_FLIGHT
Definition AHRS.h:44
@ CIRCLING
Definition AHRS.h:44
void settle(const datatype &present_input)
Definition pt2.h:73
datatype get_output(void) const
Definition pt2.h:88
datatype respond(const datatype &input)
Definition pt2.h:79
template for an average filter for circling and straight flight
soaring_flight_averager(float normalized_stop_frequency)
void record_input(value_t current_value, volatile float heading)
void update(const value_t &current_value, float heading, circle_state_t new_state)
const value_t & get_output(void) const
mathematical vector of arbitrary type and size
Definition vector.h:40
defines platform-dependent algorithms and constants
#define ONE
#define ZERO
tunable second order IIR lowpass filter (butterworth)
#define ONE_DIV_2PI
#define PI_TIMES_2
#define assert(x)
Definition vector.h:29