dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
autotune.c
Go to the documentation of this file.
1 
18 /*
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful, but
25  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27  * for more details.
28  *
29  * You should have received a copy of the GNU General Public License along
30  * with this program; if not, see <http://www.gnu.org/licenses/>
31  *
32  * Additional note on redistribution: The copyright and license notices above
33  * must be maintained in each individual source file that is a derivative work
34  * of this source file; otherwise redistribution is prohibited.
35  */
36 
37 #include "openpilot.h"
38 #include "pios.h"
39 #include "physical_constants.h"
40 #include "flightstatus.h"
41 #include "modulesettings.h"
42 #include "manualcontrolcommand.h"
43 #include "manualcontrolsettings.h"
44 #include "gyros.h"
45 #include "actuatordesired.h"
46 #include "stabilizationdesired.h"
47 #include "stabilizationsettings.h"
48 #include "systemident.h"
49 #include <pios_board_info.h>
50 #include <eventdispatcher.h>
51 #include "systemsettings.h"
52 
53 #include "misc_math.h"
54 
55 // Private constants
56 #define AUTOTUNE_STATE_PERIOD_MS 100
57 
58 #ifndef AUTOTUNE_AVERAGING_DECIMATION
59 #define AUTOTUNE_AVERAGING_DECIMATION 1
60 #endif
61 
62 // Private types
64 
65 #define ATFLASH_MAGIC 0x656e755480008041 /* A...Tune */
67  uint64_t magic;
68  uint16_t wiggle_points;
69  uint16_t aux_data_len;
70  uint16_t sample_rate;
71 
72  // Consider total number of averages here
73  uint16_t resv;
74 };
75 
77  float y[3]; /* Gyro measurements */
78  float u[3]; /* Actuator desired */
79 };
80 
81 static struct at_measurement *at_averages;
82 
83 // Private variables
84 static bool module_enabled;
85 
86 static volatile uint32_t throttle_accumulator;
87 static volatile uint32_t update_counter = 0;
88 static volatile bool tune_running = false;
89 extern uint16_t ident_wiggle_points;
90 
92 static bool save_needed = false;
93 static uint16_t decim_wiggle_points;
94 
95 // Private functions
96 static void autotune_step(const UAVObjEvent *ev,
97  void *ctx, void *obj, int len);
98 
103 int32_t AutotuneInitialize(void)
104 {
105  if (SystemIdentInitialize() == -1) {
106  module_enabled = false;
107  return -1;
108  }
109 
110  // Create a queue, connect to manual control command and flightstatus
111 #ifdef MODULE_Autotune_BUILTIN
112  module_enabled = true;
113 #else
114  uint8_t module_state[MODULESETTINGS_ADMINSTATE_NUMELEM];
115  ModuleSettingsAdminStateGet(module_state);
116  if (module_state[MODULESETTINGS_ADMINSTATE_AUTOTUNE] == MODULESETTINGS_ADMINSTATE_ENABLED)
117  module_enabled = true;
118  else
119  module_enabled = false;
120 #endif
121 
122  return 0;
123 }
124 
129 int32_t AutotuneStart(void)
130 {
131  // Start main task if it is enabled
132  if (module_enabled) {
133  // Schedule periodic task to check position
134  UAVObjEvent ev = {
135  .obj = SystemIdentHandle(),
136  .instId = 0,
137  .event = 0,
138  };
141  }
142  return 0;
143 }
144 
146 
147 static void at_new_actuators(const UAVObjEvent *ev,
148  void *ctx, void *obj, int len) {
149  (void) ev; (void) ctx;
150 
151  static bool first_cycle = false;
152 
153  ActuatorDesiredData actuators;
154  ActuatorDesiredGet(&actuators);
155 
156  GyrosData g;
157  GyrosGet(&g);
158 
159  if (actuators.SystemIdentCycle == 0xffff) {
160  if (tune_running) {
161  tune_running = false;
162  first_cycle = false;
163  }
164 
165  return; // No data
166  }
167 
168  /* Simple state machine.
169  * !running !first_cycle -> running first_cycle -> running !first_cycle
170  */
171  if (!tune_running || first_cycle) {
172  if (actuators.SystemIdentCycle == 0x0000) {
173  if (!tune_running) {
174  update_counter = 0;
176  }
177 
178  tune_running = true;
179  first_cycle = ! first_cycle;
180  }
181  }
182 
183  struct at_measurement *avg_point = &at_averages[actuators.SystemIdentCycle / AUTOTUNE_AVERAGING_DECIMATION];
184 
185  if (first_cycle) {
186  *avg_point = (struct at_measurement) { { 0 } };
187  }
188 
189  avg_point->y[0] += g.x;
190  avg_point->y[1] += g.y;
191  avg_point->y[2] += g.z;
192 
193  avg_point->u[0] += actuators.Roll;
194  avg_point->u[1] += actuators.Pitch;
195  avg_point->u[2] += actuators.Yaw;
196 
197  update_counter++;
198  throttle_accumulator += 10000 * actuators.Thrust;
199 }
200 
201 static void UpdateSystemIdent(uint32_t predicts, float hover_throttle,
202  bool new_tune) {
203  SystemIdentData system_ident;
204 
205  system_ident.NewTune = new_tune;
206  system_ident.NumAfPredicts = predicts;
207 
208  system_ident.HoverThrottle = hover_throttle;
209 
210  SystemIdentSet(&system_ident);
211 }
212 
214  uintptr_t part_id;
215 
218  &part_id)) {
219  return -1;
220  }
221 
222 
223  if (PIOS_FLASH_start_transaction(part_id)) {
224  return -2;
225  }
226 
227  if (PIOS_FLASH_erase_partition(part_id)) {
229  return -3;
230  }
231 
232  struct at_flash_header hdr = {
233  .magic = ATFLASH_MAGIC,
234  .wiggle_points = decim_wiggle_points,
235  .aux_data_len = 0,
237  };
238 
239  uint32_t offset = 0;
240 
241  if (PIOS_FLASH_write_data(part_id, 0, (uint8_t *) &hdr,
242  sizeof(hdr))) {
244  return -4;
245  }
246 
247  offset += sizeof(hdr);
248 
249  if (PIOS_FLASH_write_data(part_id, offset, (uint8_t *) at_averages,
250  sizeof(*at_averages) * decim_wiggle_points)) {
252  return -5;
253  }
254 
256  return 0;
257 }
258 
262 static void autotune_step(const UAVObjEvent *ev,
263  void *ctx, void *obj, int len)
264 {
265  (void) ev; (void) ctx; (void) obj; (void) len;
266 
267  /* Wait for stabilization module to complete startup and tell us
268  * its dT, etc.
269  */
270  if (!ident_wiggle_points) {
271  return;
272  }
273 
274  if (!decim_wiggle_points) {
277 
278  uint16_t buf_size = sizeof(*at_averages) * decim_wiggle_points;
279  at_averages = PIOS_malloc(buf_size);
280 
281  if (at_averages) {
282  ActuatorDesiredConnectCallback(at_new_actuators);
284  }
285  }
286 
287  if (!at_averages) {
288  /* Do nothing because we couldn't get our buffer */
289  /* Assert alarm XXX? */
290  return;
291  }
292 
293  uint8_t armed;
294 
295  FlightStatusArmedGet(&armed);
296 
297  if (save_needed) {
298  if (armed == FLIGHTSTATUS_ARMED_DISARMED) {
299  if (autotune_save_averaging()) {
300  // Try again next time, I guess.
301  return;
302  }
303 
304  float hover_throttle = ((float) (throttle_accumulator / update_counter)) / 10000.0f;
305 
306  UpdateSystemIdent(update_counter, hover_throttle,
307  true);
308 
309  // Save the UAVO locally.
310  UAVObjSave(SystemIdentHandle(), 0);
311  state = AT_INIT;
312 
313  save_needed = false;
314  }
315 
316  }
317 
318  switch(state) {
319  default:
320  case AT_INIT:
321  if (tune_running) {
322  // Reset save status; only save if this
323  // tune completes.
324  save_needed = false;
325  state = AT_RUN;
326  }
327 
328  break;
329 
330  case AT_RUN:
331  (void) 0;
332 
333  float hover_throttle = ((float) (throttle_accumulator / update_counter)) / 10000.0f;
334 
335  UpdateSystemIdent(update_counter, hover_throttle,
336  false);
337 
338  if (!tune_running) {
339  /* Threshold: 24 seconds of data @ 500Hz */
340  if (update_counter > 12000) {
341  save_needed = true;
342  }
343 
344  state = AT_INIT;
345  }
346 
347  break;
348  }
349 }
350 
int32_t PIOS_FLASH_find_partition_id(enum pios_flash_partition_labels label, uintptr_t *partition_id)
int32_t PIOS_FLASH_erase_partition(uintptr_t partition_id)
uint16_t ident_wiggle_points
Main PiOS header to include all the compiled in PiOS options.
#define AUTOTUNE_AVERAGING_DECIMATION
Definition: autotune.c:59
static int autotune_save_averaging()
Definition: autotune.c:213
uint16_t sample_rate
Definition: autotune.c:70
#define ATFLASH_MAGIC
Definition: autotune.c:65
void PIOS_Modules_Enable(enum pios_modules module)
Definition: pios_modules.c:34
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
float y[3]
Definition: autotune.c:77
uint16_t wiggle_points
Definition: autotune.c:68
int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId)
static volatile uint32_t throttle_accumulator
Definition: autotune.c:86
static void UpdateSystemIdent(uint32_t predicts, float hover_throttle, bool new_tune)
Definition: autotune.c:201
static bool module_enabled
Definition: autotune.c:84
uint32_t PIOS_SENSORS_GetSampleRate(enum pios_sensor_type type)
Get the sample rate of a sensor (Hz)
Definition: pios_sensors.c:181
uint16_t resv
Definition: autotune.c:73
UAVObjHandle obj
int32_t EventPeriodicCallbackCreate(UAVObjEvent *ev, UAVObjEventCallback cb, uint16_t periodMs)
Definition: systemmod.c:884
int32_t PIOS_FLASH_write_data(uintptr_t partition_id, uint32_t offset, const uint8_t *data, uint16_t len)
float u[3]
Definition: autotune.c:78
int32_t PIOS_FLASH_end_transaction(uintptr_t partition_id)
#define MODULE_INITCALL(ifn, sfn)
Definition: pios_initcall.h:67
uint16_t aux_data_len
Definition: autotune.c:69
int32_t AutotuneStart(void)
Definition: autotune.c:129
struct @16 actuators[FPPROTO_MAX_SERVOS]
Event dispatcher, distributes object events as callbacks. Alternative to using tasks and queues...
static volatile uint32_t update_counter
Definition: autotune.c:87
static bool save_needed
Definition: autotune.c:92
uint32_t offset
Definition: uavtalk_priv.h:51
tuple f
Definition: px_mkfw.py:81
static volatile bool tune_running
Definition: autotune.c:88
uint64_t magic
Definition: autotune.c:67
Includes PiOS and core architecture components.
static uint16_t decim_wiggle_points
Definition: autotune.c:93
static void at_new_actuators(const UAVObjEvent *ev, void *ctx, void *obj, int len)
Definition: autotune.c:147
static void autotune_step(const UAVObjEvent *ev, void *ctx, void *obj, int len)
Definition: autotune.c:262
autotune_state
Definition: autotune.c:63
int32_t PIOS_FLASH_start_transaction(uintptr_t partition_id)
#define AUTOTUNE_STATE_PERIOD_MS
Definition: autotune.c:56
static enum autotune_state state
Definition: autotune.c:91
int32_t AutotuneInitialize(void)
Definition: autotune.c:103
static struct at_measurement * at_averages
Definition: autotune.c:81