Paparazzi UAS  v6.2_unstable
Paparazzi is a free software Unmanned Aircraft System.
cloud_sensor.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Gautier Hattenberger <gautier.hattenberger@enac.fr>
3  * Titouan Verdu <titouan.verdu@enac.fr>
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
34 
35 #include "generated/airframe.h"
36 #include "state.h"
37 #include "modules/core/abi.h"
38 #include "pprzlink/messages.h"
41 #include "math/pprz_stat.h"
42 #include "modules/gps/gps.h"
44 
45 #ifndef SITL
48 #endif
49 
50 // log to flight recorder by default
51 #ifndef CLOUD_SENSOR_LOG_FILE
52 #define CLOUD_SENSOR_LOG_FILE flightrecorder_sdlog
53 #endif
54 
55 // max number of values received from cloud sensor
56 #ifndef CLOUD_SENSOR_RAW_MAX
57 #define CLOUD_SENSOR_RAW_MAX 16
58 #endif
59 
60 // number of actual cloud sensor channels
61 #ifndef CLOUD_SENSOR_NB
62 #define CLOUD_SENSOR_NB 4
63 #endif
64 
65 // offset inside the raw value array to get cloud sensor channels
66 #ifndef CLOUD_SENSOR_OFFSET
67 #define CLOUD_SENSOR_OFFSET 4
68 #endif
69 
70 // threshold for cloud border
71 #ifndef CLOUD_SENSOR_BORDER_THRESHOLD
72 #define CLOUD_SENSOR_BORDER_THRESHOLD 0.05
73 #endif
74 
75 // histeresis for cloud border
76 #ifndef CLOUD_SENSOR_BORDER_HYSTERESIS
77 #define CLOUD_SENSOR_BORDER_HYSTERESIS 0.01
78 #endif
79 
80 // default cloud sensor channel for single detection
81 #ifndef CLOUD_SENSOR_SINGLE_CHANNEL
82 #define CLOUD_SENSOR_SINGLE_CHANNEL 1
83 #endif
84 
85 // default coef for auto-threshold from background data
86 #ifndef CLOUD_SENSOR_BACKGROUND_THRESHOLD_COEF
87 #define CLOUD_SENSOR_BACKGROUND_THRESHOLD_COEF 2.f
88 #endif
89 
90 // default coef for auto-hysteresis from background data
91 #ifndef CLOUD_SENSOR_BACKGROUND_HYSTERESIS_COEF
92 #define CLOUD_SENSOR_BACKGROUND_HYSTERESIS_COEF 0.5f
93 #endif
94 
95 #ifndef CLOUD_SENSOR_CALIB_ALPHA
96 #define CLOUD_SENSOR_CALIB_ALPHA 1.f
97 #endif
98 
99 #ifndef CLOUD_SENSOR_CALIB_BETA
100 #define CLOUD_SENSOR_CALIB_BETA 1.f
101 #endif
102 
103 #ifndef CLOUD_SENSOR_CHANNEL_SCALE
104 #define CLOUD_SENSOR_CHANNEL_SCALE 1.f
105 #endif
106 
107 #ifndef CLOUD_SENSOR_TAU
108 #define CLOUD_SENSOR_TAU 0.f
109 #endif
110 
111 // Type of data
112 #define CLOUD_RAW 0 // LWC value
113 #define CLOUD_BORDER 1 // crossing border
114 
115 // don't report border detection by default
116 #ifndef CLOUD_SENSOR_REPORT_BORDER_CROSSING
117 #define CLOUD_SENSOR_REPORT_BORDER_CROSSING FALSE
118 #endif
119 
120 // default frequencies of cloud sensor leds
121 // blue, orange, iri1, iri2
122 #ifndef CLOUD_SENSOR_LAMBDA
123 #define CLOUD_SENSOR_LAMBDA { 505.f, 590.f, 840.f, 840.f }
124 #endif
125 static float lambdas[] = CLOUD_SENSOR_LAMBDA;
126 
127 // default calibration coefficient for Angstrom coef
128 #ifndef CLOUD_SENSOR_ANGSTROM_COEF
129 #define CLOUD_SENSOR_ANGSTROM_COEF { 1.f, 1.f, 1.f, 1.f }
130 #endif
132 
133 // default calibration offset for Angstrom coef
134 #ifndef CLOUD_SENSOR_ANGSTROM_OFFSET
135 #define CLOUD_SENSOR_ANGSTROM_OFFSET { 1.f, 1.f, 1.f, 1.f }
136 #endif
138 
145 struct LinReg {
147  float var_lambda;
148 };
149 
150 // number of samples to compute the background caracteristics
151 #ifndef CLOUD_SENSOR_BACKGROUND_NB
152 #define CLOUD_SENSOR_BACKGROUND_NB 30
153 #endif
154 
159 struct Background {
164 };
165 
168 struct CloudSensor {
171  float coef;
173  struct LinReg reg;
176 };
177 
181 struct MedianFilter {
182  int length; // init to 0
183  int current; // init to 0
184  float values[3]; // is a circular buffer size MUST be 3
185 };
186 
189 static struct CloudSensor cloud_sensor;
190 static bool log_tagged;
193 
205 
206 // handle precomputed LWC
207 static float lwc_from_buffer(uint8_t *buf)
208 {
209  int res = 0;
210  for (int i = 0; i < DL_PAYLOAD_COMMAND_command_length(buf); i++) {
211  res = res * 10 + DL_PAYLOAD_COMMAND_command(buf)[i];
212  }
213  float lwc = (float) res;
214  return lwc;
215 }
216 
217 // send CLOUD_SENSOR message
218 static void send_cloud_sensor_data(struct transport_tx *trans, struct link_device *dev)
219 {
220  uint8_t nb = 1;
221  float * val = cloud_sensor.raw;
222  if (cloud_sensor.nb_raw > 0) {
223  nb = cloud_sensor.nb_raw;
224  }
225  pprz_msg_send_CLOUD_SENSOR(trans, dev, AC_ID,
226  &stateGetPositionLla_i()->lat,
227  &stateGetPositionLla_i()->lon,
228  &gps.hmsl,
229  &gps.tow,
231  nb, val);
232 }
233 
234 #if CLOUD_SENSOR_REPORT_BORDER_CROSSING
235 // send DC_SHOT message when crossing border
236 static void border_send_shot_position(void)
237 {
238  static int16_t border_point_nr = 0;
239  // angles in decideg
240  int16_t phi = DegOfRad(stateGetNedToBodyEulers_f()->phi * 10.0f);
241  int16_t theta = DegOfRad(stateGetNedToBodyEulers_f()->theta * 10.0f);
242  int16_t psi = DegOfRad(stateGetNedToBodyEulers_f()->psi * 10.0f);
243  // course in decideg
244  int16_t course = DegOfRad(stateGetHorizontalSpeedDir_f()) * 10;
245  // ground speed in cm/s
247 
248  DOWNLINK_SEND_DC_SHOT(DefaultChannel, DefaultDevice,
249  &border_point_nr,
250  &stateGetPositionLla_i()->lat,
251  &stateGetPositionLla_i()->lon,
252  &stateGetPositionLla_i()->alt,
253  &gps.hmsl,
254  &phi,
255  &theta,
256  &psi,
257  &course,
258  &speed,
259  &gps.tow);
260 
261  border_point_nr++;
262 }
263 #endif
264 
265 // test border crossing
266 static void check_border(void)
267 {
269 #if CLOUD_SENSOR_REPORT_BORDER_CROSSING
270  border_send_shot_position();
271 #endif
272  cloud_sensor.inside_cloud = true;
274 #if CLOUD_SENSOR_REPORT_BORDER_CROSSING
275  border_send_shot_position();
276 #endif
277  cloud_sensor.inside_cloud = false;
278  }
279 }
280 
281 // send ABI message
282 static void send_data(uint32_t stamp)
283 {
284  AbiSendMsgPAYLOAD_DATA(CLOUD_SENSOR_ID, stamp, CLOUD_RAW, sizeof(float), (uint8_t *)(&cloud_sensor.coef));
286  AbiSendMsgPAYLOAD_DATA(CLOUD_SENSOR_ID, stamp, CLOUD_BORDER, 1, &inside);
287 }
288 
289 // init
291 {
292  for (int i = 0; i < CLOUD_SENSOR_NB; i++) {
293  cloud_sensor.values[i] = 0.f;
294  cloud_sensor.reg.lambda[i] = logf(lambdas[i]);
295  cloud_sensor.background.mean[i] = 0.f;
296  cloud_sensor.background.std[i] = -1.f; // means invalid data or not ready
298  }
299  cloud_sensor.coef = 0.f;
300  cloud_sensor.inside_cloud = false;
302 
303  cloud_sensor.nb_raw = 0;
304 
305  cloud_sensor_compute_coef = CLOUD_SENSOR_COEF_SINGLE; // coef from single channel by default
312  cloud_sensor_background = 0.f; // this should be found during the flight
313 
314  // Inittializing median filter
315  medianFilter0.length = 0;
317 
318  // Initializing low-pass filter (tau is in samples, not seconds)
320 
321  log_tagged = false;
322 }
323 
324 void cloud_sensor_update_tau(float tau)
325 {
326  cloud_sensor_tau = tau;
328 }
329 
332 float median_filter_update(float new_sample, struct MedianFilter* filter) {
333 
334  // Updating filter state
335  filter->values[filter->current] = new_sample;
336  filter->current++;
337  filter->current %= 3; // looping on 3 indexes
338 
339  if (filter->length < 3) {
340  // Here we are still in an initialization step (we need at least 3
341  // sample to process a median value.
342  filter->length++;
343  return new_sample; // returning here bypassing the nominal process.
344  }
345 
346  // Here we are in nominal processing. Finding the median value in
347  // filter.values.
348 
349  if (filter->values[0] >= filter->values[1]) {
350  if (filter->values[0] < filter->values[2]) {
351  return filter->values[0];
352  }
353  else {
354  // here values[0] is the greatest value->
355  if (filter->values[1] >= filter->values[2]) {
356  return filter->values[1];
357  }
358  else {
359  return filter->values[2];
360  }
361  }
362  }
363  else {
364  if (filter->values[0] >= filter->values[2]) {
365  return filter->values[0];
366  }
367  else {
368  // here values[0] is the lowest value->
369  if (filter->values[1] <= filter->values[2]) {
370  return filter->values[1];
371  }
372  else {
373  return filter->values[2];
374  }
375  }
376  }
377 
378  // we should never get here
379  return new_sample; // always return something just in case.
380 }
381 
382 float cloud_sensor_filtering(float new_sample, struct MedianFilter* medianFilter, struct FirstOrderLowPass* lowPassFilter) {
383  // Applying median filter
384  new_sample = median_filter_update(new_sample, medianFilter);
385 
386  // Applying battery voltage correction and scaling
387  float battery_voltage = PowerVoltage();
388  new_sample = (new_sample - cloud_sensor_calib_alpha*battery_voltage - cloud_sensor_calib_beta) / cloud_sensor_channel_scale;
389 
390  new_sample = update_first_order_low_pass(lowPassFilter, new_sample);
391 
392  return new_sample;
393 }
398 {
399  uint8_t nb = pprzlink_get_PAYLOAD_FLOAT_values_length(buf);
401 
402  if (nb > 0) {
403  // new data
404  //float *values = pprzlink_get_DL_PAYLOAD_FLOAT_values(buf);
405  float values[nb];
406  //store values from Cloud_sensor
407  memcpy(values, pprzlink_get_DL_PAYLOAD_FLOAT_values(buf), nb*sizeof(float));
408  // copy raw values in cloud_sensor.raw
409  memcpy(cloud_sensor.raw, values, cloud_sensor.nb_raw * sizeof(float));
410  uint32_t stamp = get_sys_time_usec();
411 
413  const uint8_t channel = CLOUD_SENSOR_SINGLE_CHANNEL; // short name for single channel
414  //Use values to make the filter processing
416  //copy filtered values in unused cloud_sensor.raw channel for feedback in GCS in rela time
417  cloud_sensor.raw[cloud_sensor.nb_raw -1] = values[CLOUD_SENSOR_OFFSET + channel];
418 
419  // first check that frame is long enough
420  if (nb > CLOUD_SENSOR_OFFSET + channel) {
422  if (values[CLOUD_SENSOR_OFFSET + channel] > 1.f) { // FIXME stupid ack to remove 0 values during calibration
423  // store a list of raw values
425  cloud_sensor.background.raw[channel][idx++] = values[CLOUD_SENSOR_OFFSET + channel];
427  // raw value buffer is full
428  // compute the background as the mean of the list
429  // compute threshold as n-times the std of the list
431  cloud_sensor.background.std[channel] = sqrtf(variance_f(cloud_sensor.background.raw[channel], idx));
432  // use the copy to be able to change the value by hand from settings
434  // set the threshold
437  // reset index
439  // end procedure
441  }
442  else {
443  cloud_sensor.background.idx = idx; // increment index
444  }
445  }
446  }
447  else {
448  // normal run
449  // compute coef from a single channel
451  // test border crossing and send data over ABI
452  check_border();
453  send_data(stamp);
454  }
455  }
456  }
458  // compute angstrom coef from available channels
459  // first check that frame is long enough
460  if ((nb >= CLOUD_SENSOR_OFFSET + CLOUD_SENSOR_NB)) {
463  // store a list of raw values for all channels
464  for (int i = 0; i < CLOUD_SENSOR_NB; i++) {
466  }
467  idx++;
469  // raw value buffer is full
470  // compute the background as the mean of the list
471  for (int i = 0; i < CLOUD_SENSOR_NB; i++) {
474  }
475  // TODO compute some threshold and hysteresis
476  // reset index
478  // end procedure
480  }
481  else {
482  cloud_sensor.background.idx = idx; // increment index
483  }
484  }
485  else {
486  // normal run
487  for (int i = 0; i < CLOUD_SENSOR_NB; i++) {
488  float scaled = (values[CLOUD_SENSOR_OFFSET + i] - cloud_sensor.background.mean[i]) * angstrom_coef[i] + angstrom_offset[i];
489  cloud_sensor.values[i] = logf(scaled);
490  }
491 
492  // compute coef with a linear regression from cloud sensor raw data
494  float angstrom = cov / cloud_sensor.reg.var_lambda;
495  cloud_sensor.coef = angstrom; // That's it ????
496 
497  // test border crossing and send data over ABI
498  check_border();
499  send_data(stamp);
500  }
501  }
502  }
503  // else don't check border from sensor
504 
505 
506 #if (defined CLOUD_SENSOR_LOG_FILE) && !(defined SITL)
507  // Log on SD card in flight recorder
508  if (CLOUD_SENSOR_LOG_FILE.file != NULL && *(CLOUD_SENSOR_LOG_FILE.file) != -1) {
509  if (log_tagged == false && GpsFixValid()) {
510  // write at least once ALIVE and GPS messages
511  // to log for correct extraction of binary data
512  DOWNLINK_SEND_ALIVE(pprzlog_tp, CLOUD_SENSOR_LOG_FILE, 16, MD5SUM);
513  // Log GPS for time reference
514  uint8_t foo_u8 = 0;
515  int16_t foo_16 = 0;
516  uint16_t foo_u16 = 0;
517  struct UtmCoor_f utm = *stateGetPositionUtm_f();
518  int32_t east = utm.east * 100;
519  int32_t north = utm.north * 100;
520  DOWNLINK_SEND_GPS(pprzlog_tp, CLOUD_SENSOR_LOG_FILE, &gps.fix,
521  &east, &north, &foo_16, &gps.hmsl, &foo_u16, &foo_16,
522  &gps.week, &gps.tow, &utm.zone, &foo_u8);
523  log_tagged = true;
524  }
526  }
527 #endif
528 
529  }
530 }
531 
533 {
534  if (DL_PAYLOAD_COMMAND_ac_id(dl_buffer) == AC_ID) {
535  uint32_t stamp = get_sys_time_usec();
536 
537  // get LWC from ground or external computer and apply filters
538  //cloud_sensor.coef = cloud_sensor_filtering(lwc_from_buffer(buf), &medianFilter0, &lowPassFilter0);
540 
541  // test border crossing and send data over ABI
542  check_border();
543  send_data(stamp);
544  }
545 }
546 
548 {
549  send_cloud_sensor_data(&(DefaultChannel).trans_tx, &(DefaultDevice).device);
550 }
551 
552 
CLOUD_SENSOR_CALIB_ALPHA
#define CLOUD_SENSOR_CALIB_ALPHA
Definition: cloud_sensor.c:96
send_cloud_sensor_data
static void send_cloud_sensor_data(struct transport_tx *trans, struct link_device *dev)
Definition: cloud_sensor.c:218
dl_buffer
uint8_t dl_buffer[MSG_SIZE]
Definition: main_demo5.c:63
uint32_t
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
uint8_t
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
stateGetHorizontalSpeedDir_f
static float stateGetHorizontalSpeedDir_f(void)
Get dir of horizontal ground speed (float).
Definition: state.h:944
CLOUD_SENSOR_OFFSET
#define CLOUD_SENSOR_OFFSET
Definition: cloud_sensor.c:67
val
uint16_t val[TCOUPLE_NB]
Definition: temp_tcouple_adc.c:49
cloud_sensor_calib_beta
float cloud_sensor_calib_beta
Definition: cloud_sensor.c:202
median_filter_update
float median_filter_update(float new_sample, struct MedianFilter *filter)
Median filter function.
Definition: cloud_sensor.c:332
CLOUD_RAW
#define CLOUD_RAW
Definition: cloud_sensor.c:112
UtmCoor_f::north
float north
in meters
Definition: pprz_geodetic_float.h:82
abi.h
GpsState::tow
uint32_t tow
GPS time of week in ms.
Definition: gps.h:109
cloud_sensor_callback
void cloud_sensor_callback(uint8_t *buf)
End median filter function.
Definition: cloud_sensor.c:397
lowPassFilter0
static struct FirstOrderLowPass lowPassFilter0
Definition: cloud_sensor.c:192
cloud_sensor_update_tau
void cloud_sensor_update_tau(float tau)
Definition: cloud_sensor.c:324
Background::mean
float mean[CLOUD_SENSOR_NB]
mean of the lists
Definition: cloud_sensor.c:161
CloudSensor::raw
float raw[CLOUD_SENSOR_RAW_MAX]
raw cloud sensor values
Definition: cloud_sensor.c:169
stateGetNedToBodyEulers_f
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
Definition: state.h:1143
stateGetPositionLla_i
static struct LlaCoor_i * stateGetPositionLla_i(void)
Get position in LLA coordinates (int).
Definition: state.h:683
init_first_order_low_pass
static void init_first_order_low_pass(struct FirstOrderLowPass *filter, float tau, float sample_time, float value)
Init first order low pass filter.
Definition: low_pass_filter.h:57
update_first_order_low_pass
static float update_first_order_low_pass(struct FirstOrderLowPass *filter, float value)
Update first order low pass filter state with a new value.
Definition: low_pass_filter.h:71
UtmCoor_f::east
float east
in meters
Definition: pprz_geodetic_float.h:83
CLOUD_SENSOR_BACKGROUND_NB
#define CLOUD_SENSOR_BACKGROUND_NB
Definition: cloud_sensor.c:152
cloud_sensor_background
float cloud_sensor_background
Definition: cloud_sensor.c:200
pprzlog_tp.h
Initialize pprzlog transport.
CLOUD_SENSOR_COEF_SINGLE
#define CLOUD_SENSOR_COEF_SINGLE
Definition: cloud_sensor.h:39
CloudSensor::values
float values[CLOUD_SENSOR_NB]
preprocessed cloud sensor values
Definition: cloud_sensor.c:170
CloudSensor::nb_raw
uint8_t nb_raw
number of raw data in array
Definition: cloud_sensor.c:175
CLOUD_SENSOR_ANGSTROM_COEF
#define CLOUD_SENSOR_ANGSTROM_COEF
Definition: cloud_sensor.c:129
CloudSensor::reg
struct LinReg reg
linear regression parameters
Definition: cloud_sensor.c:173
stateGetPositionUtm_f
static struct UtmCoor_f * stateGetPositionUtm_f(void)
Get position in UTM coordinates (float).
Definition: state.h:692
MedianFilter::length
int length
Definition: cloud_sensor.c:182
cloud_sensor_compute_background
uint8_t cloud_sensor_compute_background
Definition: cloud_sensor.c:197
CLOUD_SENSOR_SINGLE_CHANNEL
#define CLOUD_SENSOR_SINGLE_CHANNEL
Definition: cloud_sensor.c:82
CloudSensor::background
struct Background background
structure for background parameters
Definition: cloud_sensor.c:174
cloud_sensor_report
void cloud_sensor_report(void)
Report function.
Definition: cloud_sensor.c:547
idx
static uint32_t idx
Definition: nps_radio_control_spektrum.c:105
CLOUD_SENSOR_CALIB_BETA
#define CLOUD_SENSOR_CALIB_BETA
Definition: cloud_sensor.c:100
sdlog_chibios.h
CLOUD_SENSOR_LOG_FILE
#define CLOUD_SENSOR_LOG_FILE
Definition: cloud_sensor.c:52
CLOUD_SENSOR_BORDER_THRESHOLD
#define CLOUD_SENSOR_BORDER_THRESHOLD
Definition: cloud_sensor.c:72
cloud_sensor_filtering
float cloud_sensor_filtering(float new_sample, struct MedianFilter *medianFilter, struct FirstOrderLowPass *lowPassFilter)
Definition: cloud_sensor.c:382
get_sys_time_usec
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:75
cloud_sensor_channel_scale
float cloud_sensor_channel_scale
Definition: cloud_sensor.c:203
CloudSensor
Cloud sensor structure.
Definition: cloud_sensor.c:168
int16_t
short int16_t
Typedef defining 16 bit short type.
Definition: vl53l1_types.h:93
CloudSensor::coef
float coef
scalar coeff related to cloud parameter (LWC, angstrom, extinction,...)
Definition: cloud_sensor.c:171
angstrom_offset
static float angstrom_offset[]
Definition: cloud_sensor.c:137
pprz_geodetic_float.h
Paparazzi floating point math for geodetic calculations.
medianFilter0
static struct MedianFilter medianFilter0
Definition: cloud_sensor.c:191
LWC_callback
void LWC_callback(uint8_t *buf)
Definition: cloud_sensor.c:532
CLOUD_SENSOR_NB
#define CLOUD_SENSOR_NB
Definition: cloud_sensor.c:62
cloud_sensor_compute_coef
uint8_t cloud_sensor_compute_coef
Extern variables.
Definition: cloud_sensor.c:196
gps.h
Device independent GPS code (interface)
GpsState::fix
uint8_t fix
status of fix
Definition: gps.h:107
UtmCoor_f::zone
uint8_t zone
UTM zone number.
Definition: pprz_geodetic_float.h:85
GpsState::week
uint16_t week
GPS week.
Definition: gps.h:108
dev
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
PowerVoltage
#define PowerVoltage()
Definition: nav.h:56
CLOUD_SENSOR_CHANNEL_SCALE
#define CLOUD_SENSOR_CHANNEL_SCALE
Definition: cloud_sensor.c:104
CLOUD_SENSOR_LAMBDA
#define CLOUD_SENSOR_LAMBDA
Definition: cloud_sensor.c:123
cloud_sensor_calib_alpha
float cloud_sensor_calib_alpha
Definition: cloud_sensor.c:201
lambdas
static float lambdas[]
Definition: cloud_sensor.c:125
lwc_from_buffer
static float lwc_from_buffer(uint8_t *buf)
Definition: cloud_sensor.c:207
pprz_stat.h
Statistics functions.
Background
Structure used to compute the background and the threshold which is a list of raw data,...
Definition: cloud_sensor.c:159
check_border
static void check_border(void)
Definition: cloud_sensor.c:266
CLOUD_SENSOR_BACKGROUND_HYSTERESIS_COEF
#define CLOUD_SENSOR_BACKGROUND_HYSTERESIS_COEF
Definition: cloud_sensor.c:92
Background::raw
float raw[CLOUD_SENSOR_NB][CLOUD_SENSOR_BACKGROUND_NB]
lists of raw values
Definition: cloud_sensor.c:160
CLOUD_SENSOR_ANGSTROM_OFFSET
#define CLOUD_SENSOR_ANGSTROM_OFFSET
Definition: cloud_sensor.c:135
covariance_f
float covariance_f(float *arr1, float *arr2, uint32_t n_elements)
Compute the covariance of two arrays V(X) = E[(X-E[X])(Y-E[Y])] = E[XY] - E[X]E[Y] where E[X] is the ...
Definition: pprz_stat.c:152
f
uint16_t f
Camera baseline, in meters (i.e. horizontal distance between the two cameras of the stereo setup)
Definition: wedgebug.c:204
mean_f
float mean_f(float *array, uint32_t n_elements)
Compute the mean value of an array (float)
Definition: pprz_stat.c:122
cloud_sensor_tau
float cloud_sensor_tau
Definition: cloud_sensor.c:204
CLOUD_SENSOR_RAW_MAX
#define CLOUD_SENSOR_RAW_MAX
Definition: cloud_sensor.c:57
GpsFixValid
#define GpsFixValid()
Definition: gps.h:43
Background::idx
uint8_t idx
current index
Definition: cloud_sensor.c:163
MedianFilter
Median Filter structure.
Definition: cloud_sensor.c:181
cloud_sensor.h
course
static int16_t course[3]
Definition: airspeed_uADC.c:58
int32_t
int int32_t
Typedef defining 32 bit int type.
Definition: vl53l1_types.h:83
LinReg::lambda
float lambda[CLOUD_SENSOR_NB]
list of sensor LED frequencies
Definition: cloud_sensor.c:146
stateGetHorizontalSpeedNorm_f
static float stateGetHorizontalSpeedNorm_f(void)
Get norm of horizontal ground speed (float).
Definition: state.h:935
variance_f
float variance_f(float *array, uint32_t n_elements)
Compute the variance of an array of values (float).
Definition: pprz_stat.c:139
CLOUD_SENSOR_BACKGROUND_THRESHOLD_COEF
#define CLOUD_SENSOR_BACKGROUND_THRESHOLD_COEF
Definition: cloud_sensor.c:87
cloud_sensor_init
void cloud_sensor_init(void)
Init function.
Definition: cloud_sensor.c:290
UtmCoor_f
position in UTM coordinates Units: meters
Definition: pprz_geodetic_float.h:81
log_tagged
static bool log_tagged
Definition: cloud_sensor.c:190
Background::std
float std[CLOUD_SENSOR_NB]
std of the lists
Definition: cloud_sensor.c:162
GpsState::hmsl
int32_t hmsl
height above mean sea level (MSL) in mm
Definition: gps.h:94
pprzlog_tp
struct pprzlog_transport pprzlog_tp
PPRZLOG transport structure.
Definition: pprzlog_tp.c:29
CLOUD_SENSOR_ID
#define CLOUD_SENSOR_ID
Definition: abi_sender_ids.h:538
LinReg
Structure used to compute the linear regression that provides the angstrom coefficient.
Definition: cloud_sensor.c:145
cloud_sensor
static struct CloudSensor cloud_sensor
Local variables.
Definition: cloud_sensor.c:189
MedianFilter::current
int current
Definition: cloud_sensor.c:183
CloudSensor::inside_cloud
bool inside_cloud
in/out status flag
Definition: cloud_sensor.c:172
cloud_sensor_threshold
float cloud_sensor_threshold
Definition: cloud_sensor.c:198
CLOUD_SENSOR_BORDER_HYSTERESIS
#define CLOUD_SENSOR_BORDER_HYSTERESIS
Definition: cloud_sensor.c:77
state.h
LinReg::var_lambda
float var_lambda
variance of lambda
Definition: cloud_sensor.c:147
uint16_t
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
MedianFilter::values
float values[3]
Definition: cloud_sensor.c:184
send_data
static void send_data(uint32_t stamp)
Definition: cloud_sensor.c:282
gps
struct GpsState gps
global GPS state
Definition: gps.c:69
CLOUD_SENSOR_COEF_ANGSTROM
#define CLOUD_SENSOR_COEF_ANGSTROM
Definition: cloud_sensor.h:40
FirstOrderLowPass
First order low pass filter structure.
Definition: low_pass_filter.h:39
cloud_sensor_hysteresis
float cloud_sensor_hysteresis
Definition: cloud_sensor.c:199
angstrom_coef
static float angstrom_coef[]
Definition: cloud_sensor.c:131
update_first_order_low_pass_tau
static void update_first_order_low_pass_tau(struct FirstOrderLowPass *filter, float tau, float sample_time)
Update time constant (tau parameter) for first order low pass filter.
Definition: low_pass_filter.h:95
CLOUD_SENSOR_TAU
#define CLOUD_SENSOR_TAU
Definition: cloud_sensor.c:108
Min
#define Min(x, y)
Definition: esc_dshot.c:85
low_pass_filter.h
Simple first order low pass filter with bilinear transform.
CLOUD_BORDER
#define CLOUD_BORDER
Definition: cloud_sensor.c:113