dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
flightstatsmodule.c
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, see <http://www.gnu.org/licenses/>
28  */
29 
30 #include "openpilot.h"
31 #include "modulesettings.h"
32 #include "pios_thread.h"
33 
34 #include "misc_math.h"
35 
36 #include "airspeedactual.h"
37 #include "flightbatterystate.h"
38 #include "flightstatus.h"
39 #include "flightstats.h"
40 #include "flightstatssettings.h"
41 #include "gyros.h"
42 #include "positionactual.h"
43 #include "velocityactual.h"
44 
45 // Private constants
46 #define STACK_SIZE_BYTES 600
47 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
48 
49 // Private types
50 
51 // Private variables
52 static bool module_enabled;
53 static struct pios_thread *flightStatsTaskHandle;
54 static volatile FlightStatsSettingsData settings;
55 static PositionActualData lastPositionActual;
58 
59 // Private functions
60 static void flightStatsTask(void *parameters);
61 static bool isArmed();
62 static void resetStats(FlightStatsData *stats);
63 static void collectStats(FlightStatsData *stats);
64 
65 // Local variables
66 
67 // External variables
68 
75 {
76 #ifdef MODULE_FLIGHTSTATS_BUILTIN
77  module_enabled = true;
78 #else
79  uint8_t module_state[MODULESETTINGS_ADMINSTATE_NUMELEM];
80  ModuleSettingsAdminStateGet(module_state);
81  if (module_state[MODULESETTINGS_ADMINSTATE_FLIGHTSTATS] == MODULESETTINGS_ADMINSTATE_ENABLED) {
82  module_enabled = true;
83  } else {
84  module_enabled = false;
85  }
86 #endif
87 
88  if (!module_enabled)
89  return -1;
90 
91  if (FlightStatsInitialize() == -1 || FlightStatsSettingsInitialize() == -1) {
92  module_enabled = false;
93  return -1;
94  }
95 
96  // Get settings and connect
97  FlightStatsSettingsConnectCopy(&settings);
98 
99  return 0;
100 }
101 
108 {
109  //Check if module is enabled or not
110  if (module_enabled == false) {
111  return -1;
112  }
113 
114  // Start flight stats task
116 
117  TaskMonitorAdd(TASKINFO_RUNNING_FLIGHTSTATS, flightStatsTaskHandle);
118 
119  return 0;
120 }
121 
123 
124 static void flightStatsTask(void *parameters)
125 {
126  FlightStatsData flightStatsData;
127  bool first_run = true;
128 
129  resetStats(&flightStatsData);
130  flightStatsData.State = FLIGHTSTATS_STATE_IDLE;
131 
132  // Loop forever
133  while (1) {
134  // Update stats at about 10Hz
135  PIOS_Thread_Sleep(100);
136  switch (flightStatsData.State) {
137  case FLIGHTSTATS_STATE_IDLE:
138  if (isArmed()) {
139  switch (settings.StatsBehavior) {
140  case FLIGHTSTATSSETTINGS_STATSBEHAVIOR_RESETONBOOT:
141  flightStatsData.State = FLIGHTSTATS_STATE_COLLECTING;
142  break;
143  case FLIGHTSTATSSETTINGS_STATSBEHAVIOR_RESETONARM:
144  flightStatsData.State = FLIGHTSTATS_STATE_RESET;
145  break;
146  }
147  first_run = true;
148  }
149  break;
150  case FLIGHTSTATS_STATE_RESET:
151  resetStats(&flightStatsData);
152  flightStatsData.State = FLIGHTSTATS_STATE_COLLECTING;
153  break;
154  case FLIGHTSTATS_STATE_COLLECTING:
155  if (first_run) { // get some initial values
156  // initial position
157  PositionActualGet(&lastPositionActual);
158 
159  // get the initial battery voltage and consumed energy
160  if (FlightBatteryStateHandle()) {
161  FlightBatteryStateConsumedEnergyGet(&initial_consumed_energy);
162 
163  // either start a new calculation of consumed energy, or combine with data
164  // from previous flight
165  if (settings.StatsBehavior == FLIGHTSTATSSETTINGS_STATSBEHAVIOR_RESETONARM) {
167  }
168  else {
169  previous_consumed_energy = flightStatsData.ConsumedEnergy;
170  }
171 
172  // only get the initial voltage if we reset on arm or if it is uninitialized
173  if ((settings.StatsBehavior == FLIGHTSTATSSETTINGS_STATSBEHAVIOR_RESETONARM)\
174  || (flightStatsData.InitialBatteryVoltage == 0)){
175  float voltage;
176  FlightBatteryStateVoltageGet(&voltage);
177  flightStatsData.InitialBatteryVoltage = roundf(1000.f * voltage);
178  }
179  }
180  first_run = false;
181  }
182  collectStats(&flightStatsData);
183  if (!isArmed()) {
184  flightStatsData.State = FLIGHTSTATS_STATE_IDLE;
185  }
186  FlightStatsSet(&flightStatsData);
187  break;
188  }
189  }
190 }
191 
196 static bool isArmed()
197 {
198  uint8_t arm_status;
199  FlightStatusArmedGet(&arm_status);
200  return (arm_status == FLIGHTSTATUS_ARMED_ARMED);
201 }
202 
206 static void resetStats(FlightStatsData *stats)
207 {
208  // reset everything
209  memset((void*)stats, 0, sizeof(FlightStatsData));
210 }
211 
215 static void collectStats(FlightStatsData *stats)
216 {
217  float tmp;
218  PositionActualData positionActual;
219  PositionActualGet(&positionActual);
220 
221  // Total (horizontal) distance
222  stats->DistanceTravelled += sqrtf(powf(positionActual.North - lastPositionActual.North, 2.f) \
223  + powf(positionActual.East - lastPositionActual.East, 2.f));
224 
225  // Max distance to home
226  tmp = sqrtf(powf(positionActual.North, 2.f) + powf(positionActual.East, 2.f));
227  stats->MaxDistanceToHome = MAX(stats->MaxDistanceToHome, tmp);
228 
229  // Max altitude
230  stats->MaxAltitude = MAX(stats->MaxAltitude, -1.f * positionActual.Down);
231 
232  VelocityActualData velocityActual;
233  VelocityActualGet(&velocityActual);
234 
235  // Max groundspeed
236  tmp = sqrtf(powf(velocityActual.North, 2.f) + powf(velocityActual.East, 2.f));
237  stats->MaxGroundSpeed = MAX(stats->MaxGroundSpeed, tmp);
238 
239  // Max climb rate
240  stats->MaxClimbRate = MAX(stats->MaxClimbRate, -1.f * velocityActual.Down);
241 
242  // Max descent rate
243  stats->MaxDescentRate = MAX(stats->MaxDescentRate, velocityActual.Down);
244 
245  // Max airspeed
246  if (AirspeedActualHandle()) {
247  AirspeedActualTrueAirspeedGet(&tmp);
248  stats->MaxAirSpeed = MAX(stats->MaxAirSpeed, tmp);
249  }
250 
251  // Max roll/pitch/yaw rates
252  GyrosData gyros;
253  GyrosGet(&gyros);
254  stats->MaxPitchRate = MAX(stats->MaxPitchRate, fabsf(gyros.y));
255  stats->MaxRollRate = MAX(stats->MaxRollRate, fabsf(gyros.x));
256  stats->MaxYawRate = MAX(stats->MaxYawRate, fabsf(gyros.z));
257 
258  // Consumed energy
259  if (FlightBatteryStateHandle()) {
260  FlightBatteryStateConsumedEnergyGet(&tmp);
261  stats->ConsumedEnergy = previous_consumed_energy + tmp - initial_consumed_energy;
262  }
263 
264  // update things for next call
265  lastPositionActual = positionActual;
266 }
static bool isArmed()
static void resetStats(FlightStatsData *stats)
static struct pios_thread * flightStatsTaskHandle
static float initial_consumed_energy
static PositionActualData lastPositionActual
static bool module_enabled
static void collectStats(FlightStatsData *stats)
MODULE_INITCALL(FlightStatsModuleInitialize, FlightStatModuleStart)
#define MAX(a, b)
Definition: misc_math.h:40
#define STACK_SIZE_BYTES
static volatile FlightStatsSettingsData settings
#define TASK_PRIORITY
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
Definition: pios_thread.c:89
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
Definition: taskmonitor.c:67
static void flightStatsTask(void *parameters)
void PIOS_Thread_Sleep(uint32_t time_ms)
Definition: pios_thread.c:229
static float previous_consumed_energy
static EventStats stats
Definition: systemmod.c:132
tuple f
Definition: px_mkfw.py:81
int32_t FlightStatsModuleInitialize(void)
int32_t FlightStatModuleStart(void)
Includes PiOS and core architecture components.
uint16_t voltage