Rleg  2
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
main2.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <signal.h>
5 #include <string.h>
6 #include <ncurses.h>
7 #include <time.h>
8 #include <sys/time.h>
9 #include <pthread.h>
10 #include <math.h>
11 //#include "gmatrix.h"
12 #include "calibration.h"
13 //#include "protocol.h"
14 //#include "estimation.h"
15 //#include "control.h"
17 #include "datalogger.h"
18 #include "ui.h"
19 #include "main2.h"
20 //#include "calibration/calibration.h"
21 
22 /* This runs tasks in three points:
23  * 1) In the while(quittask == 0) loop: background (semi-periodic, usleep governed) tasks (datalogger update)
24  * 2) In the int periodic_task_1(void) function, periodic (low-precision), set by the TASK1_PERIOD_US define:
25  * (main data acquisition/control task)
26  * 3) In the int periodic_task_2(void) function, periodic (low-precision), set by the TASK2_PERIOD_US define:
27  * (UI task)
28  */
29 
30 // Configuration
31 #define TASK1_PERIOD_US 20000 //20ms
32 #define TASK2_PERIOD_US 100000 //100ms
33 
34 // Internal functions
35 void f_timer_task_1(union sigval sigval);
36 void f_timer_task_2(union sigval sigval);
37 
38 // Module variables
39 unsigned char quittask=0;
40 int acquire=0;
41 int total = 0;
42 int failure = 0;
43 
44 // Task 1: Data acquisition/control task
45 timer_t timer_task_1;
46 volatile double t_task_1_global = 0.0;
47 volatile double T_task_1_exec_global = 0.0;
48 volatile double T_task_1_mean_global = 0.0;
49 volatile double T_task_1_min_global = 0.0;
50 volatile double T_task_1_max_global = 0.0;
52 volatile int flag_task_1_firstexecution = 1;
53 volatile double t0 = 0.0;
54 
55 // Task 2: UI task
56 
57 timer_t timer_task_2;
58 volatile double t_task_2_global = 0.0;
59 volatile double T_task_2_exec_global = 0.0;
60 volatile double T_task_2_mean_global = 0.0;
61 volatile double T_task_2_min_global = 0.0;
62 volatile double T_task_2_max_global = 0.0;
64 volatile int flag_task_2_firstexecution = 1;
66 
67 int buff_i=0; //i of buffer
68 short int buff[3][3][3]; //{acc,gyr,mag}{x,y,z}{i=1,2,3}
69 
70 // Shared structures
71 //
78 // Calibrated data
79 //IMUMEASURE imu_measure;
80 //MAGNETOMETERMEASURE magnetometer_measure;
81 
82 // State estimate
83 //ESTIMATION_DATA_STRUCT estimation_data;
84 
85 // Controllers
86 //CONTROL_DATA_STRUCT control_data;
87 
88 int main(void)
89 {
90  int status = 0;
91  int n = 0;
92  int return_value = SUCCESS;
93 
94 // Parameters for IMU and SPI
95 
96  imu_param.acc.full_res=1;
97  imu_param.acc.rate=100;
98  imu_param.acc.range=16;
99  imu_param.gyr.rate=100;
100  imu_param.gyr.lpf_bw=188;
101  imu_param.gyr.clk_source='Z';
102  imu_param.gyr.act="XYZ";
103  imu_param.mag.rate=75;
104  imu_param.mag.range=0;
105  imu_param.mag.samples_avg=8;
106  imu_param.mag.meas_mode=0;
107  imu_param.mag.op_mode=0;
108 
109  spi_param.mode=0;
110  spi_param.speed=375000;
111  spi_param.cs=0;
112 
113  // printf("\ngpio186 inicialmente = %d\n",gpio_read(GPIO_S0));
114  //printf("gpio10 inicialmente = %d\n",gpio_read(GPIO_SHDN));
115 
116 // Initialization
117 
118  if( devices_init(&imu_param, &spi_param, &mra_data)==FAILURE )
119  {
120  perror("Unsuccesful devices initialization");
121  return -1;
122  }
123  if( datalogger_init()!=SUCCESS )
124  {
125  perror("Unsuccesful datalogger initialization");
126  return -1;
127  }
128  if( ui_init() != SUCCESS)
129  {
130  perror("Unsuccesful user interface initialization");
131  return -1;
132  }
133  // enc_zero_set(enc_data)!=SUCCESS ? perror("Unsuccesfull encoder set zero "); return -1;
134 
135  //gpio_write(GPIO_S0,1);
136  //mra_data.Out_0=2275;
137  //actuate(spi_param.spi_dev,&mra_data);
138 
139  //return_value=FAILURE;
140 
141  // Main Loop
142  if(return_value != FAILURE)
143  {
144  //datalogger_start();
146  usleep(0.5*task_1_period_us);
148  usleep(5*task_1_period_us);
149 
150  while(quittask == 0)
151  {
152  #if ANU_COMPILE_FOR_OVERO
153  #else
154  //if(datalogger_status() == DATALOGGER_RUNNING) datalogger_update_IPC();
155  #endif
156 
157 
158  if(++n>100)
159  {
160  //printf("n = %d\n",n);
162  n = 0;
163  }
164  usleep(5*task_1_period_us);
165  }
166  datalogger_stop();
168  usleep(TASK1_PERIOD_US);
170  usleep(TASK2_PERIOD_US);
171  }
172 
173  status = datalogger_close();
174  if(status != DATALOGGER_SUCCESS)
175  {
176  return_value = FAILURE;
177  }
178 
179  status = ui_close();
180  if(status != SUCCESS)
181  {
182  return_value = FAILURE;
183  }
184 
185  devices_close(&imu_param, &spi_param, &mra_data);
186 
187  return return_value;
188 }
189 
191 {
192  //static int previous_calibration_status = CALIBRATION_NOT_RUNNING;
193  //int current_calibration_status; // Used to detect lowering edge
194  static int previous_datalogger_status = DATALOGGER_NOT_RUNNING;
195  int current_datalogger_status; // Used to detect rising edge
196  char user =0;
197  /* int buff_i=0; //i of buffer
198  int i, j, k, equal=0;
199  short int buff[3][3][3]; //{acc,gyr,mag}{x,y,z}{i=1,2,3}
200 */
201 
202  // Main communication/control thread
203 
204  //Acquire
205  total++;
206  if( read_all_data(imu_param.i2c_dev, spi_param.spi_dev, &imu_data, &eff_data, &mra_data, &enc_data) != SUCCESS)
207  failure++;
208 
209  // Calibrate and Estimate
210  calibrate_all(&imu_data);
211  //calibration_calibrate_all(&pwm_read_data, &scp1000_data, &battery_data, &gps_data, &imu_data, &pitot_data, &sonar_data, &calibration_local_coordinate_system_data, &calibration_altimeter_data, &calibration_local_fields_data, &gps_measure, &imu_measure, &magnetometer_measure);
212  //estimation_update_state_estimate(&estimation_data, &gps_measure, &imu_measure, &magnetometer_measure, &sonar_measure, &calibration_local_fields_data, task_1_period_us/(double)1e6);
213 
214  // Control
215  mra_data.v_ctl=1275+(uint8_t)(800*cosf(t_task_1_global*1000));
216  //control_main_task(t_task_1_global, &pwm_write_data, &pwm_read_data, &control_data, &estimation_data);
217 
218  // Actuate
219  actuate(spi_param.spi_dev, &mra_data);
220  //protocol_send_actuation_data(&pwm_write_data);
221 
222  // Log
223  /*user=getch();
224  switch(user){
225  case 'e':
226  exit_program();
227  break;
228  case 'a':
229  acquire=1;
230  break;
231  case 's':
232  acquire=0;
233  break;
234  default:
235  break;
236  }*/
237  current_datalogger_status = datalogger_status();
238  if( (current_datalogger_status == DATALOGGER_RUNNING))
239  {
240  if(previous_datalogger_status == DATALOGGER_NOT_RUNNING) // Rising edge
241  {
243  reset_timer();
244  }
245  datalogger_update(t_task_1_global, T_task_1_exec_global, T_task_2_exec_global, t0, &imu_data, &eff_data, &mra_data /*&imu_measure, &magnetometer_measure, &estimation_data, &control_data*/);
246  //printf("\n %d\t|",i);
247  /* printw("%d\t|",eff_data.F.x);
248  printw("\t%d\t%d\t%d\t|",imu_data.acc.x,imu_data.acc.y,imu_data.acc.z);
249  printw("\t%d\t%d\t%d\t|",imu_data.mag.x,imu_data.mag.y,imu_data.mag.z);
250  printw("\t%d\t%d\t%d\t%d",imu_data.gyr.x,imu_data.gyr.y,imu_data.gyr.z, imu_data.temp);
251  printw("\t%d\t%d",eff_data.new_data,imu_data.new_data);
252  printw("\t%d\t%d",mra_data.Out_0, mra_data.Read_0);
253  printw("\n");
254  refresh();*/
255  }
256  previous_datalogger_status = current_datalogger_status;
257 
258 /* current_calibration_status = calibration_get_status();
259  if(current_calibration_status == CALIBRATION_RUNNING)
260  {
261  calibration_imu_add_sample_bias_estimate(&imu_data);
262  calibration_altimeter_add_sample_initial_pressure(&scp1000_data, &calibration_altimeter_data);
263  }
264  else // Calibration not running
265  {
266  if(previous_calibration_status == CALIBRATION_RUNNING) // Lowering edge
267  {
268  calibration_imu_finish_bias_estimate(&imu_data);
269  calibration_altimeter_finish_initial_pressure_estimate(&calibration_altimeter_data);
270  }
271  }
272  previous_calibration_status = current_calibration_status;
273 */
274  return SUCCESS;
275 }
276 
278 {
279 
280  int i, j, k, equal=0;
281 
282  // UI thread
284  {
285  ui_update(&imu_data, &eff_data, &mra_data,&enc_data, total, failure);
286  }
287 
288  buff_i=buff_i%5;
289  buff[0][0][buff_i]=imu_data.acc.x;
290  buff[0][1][buff_i]=imu_data.acc.y;
291  buff[0][2][buff_i]=imu_data.acc.z;
292  buff[1][0][buff_i]=imu_data.gyr.x;
293  buff[1][0][buff_i]=imu_data.gyr.x;
294  buff[1][1][buff_i]=imu_data.gyr.y;
295  buff[1][2][buff_i]=imu_data.gyr.z;
296  buff[2][0][buff_i]=imu_data.mag.x;
297  buff[2][1][buff_i]=imu_data.mag.y;
298  buff[2][2][buff_i]=imu_data.mag.z;
299  buff_i++;
300 
301  for( i=0; i<3; i++)
302  {
303 
304  for( j=0; j<3; j++)
305  for( k=1; k<3; k++)
306  {
307  if( buff[i][j][k]==buff[i][j][0] )
308  equal=1;
309  else
310  equal=0;
311  }
312  if( equal==1)
313  i=3;
314  }
315  if( equal==1 )
316  {
317  close(imu_param.i2c_dev);
318  close(spi_param.spi_dev);
319  devices_init(&imu_param, &spi_param, &mra_data);
320  equal=0;
321  }
322  /*if(telemetry_mode == UI_MAVLINK_MODE)
323  {
324  mavlink_module_update(t_task_1_global, t0, &battery_data, &gps_data, &imu_data, &pitot_data, &pwm_read_data, &pwm_write_data, &scp1000_data, &sonar_data, &gps_measure, &imu_measure, &magnetometer_measure, &estimation_data, &control_data);
325  }*/
326 
327  return SUCCESS;
328 }
329 
330 void f_timer_task_1(union sigval sigval)
331 {
332  sigval.sival_int = 0; // Remove warning
334 }
335 
336 void f_timer_task_2(union sigval sigval)
337 {
338  sigval.sival_int = 0; // Remove warning
340 }
341 
343 {
344  struct itimerspec itimer;
345  struct sigevent sigev;
346  int erno = 0;
347 
349 
350  itimer.it_interval.tv_sec=0;
351  itimer.it_interval.tv_nsec=task_1_period_us * 1000;
352  itimer.it_value=itimer.it_interval;
353 
354  memset(&sigev, 0, sizeof (struct sigevent));
355 
356  sigev.sigev_value.sival_int = 0;
357  sigev.sigev_notify = SIGEV_THREAD;
358  sigev.sigev_notify_attributes = NULL;
359  sigev.sigev_notify_function = f_timer_task_1;
360 
361  if (timer_create(CLOCK_REALTIME, &sigev, &timer_task_1) < 0)
362  {
363  fprintf(stderr, "[%d]: %s\n", __LINE__, strerror(erno));
364  exit(erno);
365  }
366 
367  if(timer_settime(timer_task_1, 0, &itimer, NULL) < 0)
368  {
369  fprintf(stderr, "[%d]: %s\n", __LINE__, strerror(erno));
370  exit(erno);
371  }
372 
373 }
374 
376 {
377  struct itimerspec itimer;
378  struct sigevent sigev;
379  int erno = 0;
380 
382 
383  itimer.it_interval.tv_sec=0;
384  itimer.it_interval.tv_nsec=task_2_period_us * 1000;
385  itimer.it_value=itimer.it_interval;
386 
387  memset (&sigev, 0, sizeof (struct sigevent));
388  sigev.sigev_value.sival_int = 0;
389  sigev.sigev_notify = SIGEV_THREAD;
390  sigev.sigev_notify_attributes = NULL;
391  sigev.sigev_notify_function = f_timer_task_2;
392 
393  if(timer_create(CLOCK_REALTIME, &sigev, &timer_task_2) < 0)
394  {
395  fprintf(stderr, "[%d]: %s\n", __LINE__, strerror(erno));
396  exit(erno);
397  }
398 
399  if(timer_settime(timer_task_2, 0, &itimer, NULL) < 0)
400  {
401  fprintf(stderr, "[%d]: %s\n", __LINE__, strerror(erno));
402  exit(erno);
403  }
404 }
405 
407 {
408  int erno = 0;
409  if(timer_delete(timer_task_1) < 0)
410  {
411  fprintf(stderr, "[%d]: %s\n", __LINE__, strerror(erno));
412  exit(erno);
413  }
414 }
415 
417 {
418  int erno = 0;
419  if(timer_delete(timer_task_2) < 0)
420  {
421  fprintf(stderr, "[%d]: %s\n", __LINE__, strerror(erno));
422  exit(erno);
423  }
424 }
425 
427 {
428  int status = 0;
429  static struct timeval timereset;
430  static struct timeval time;
431  static struct timeval time_exec_start;
432  static struct timeval time_exec_end;
433  static double T_task,t_task,t_task_previous;
434  static double T_task_mean,T_task_min,T_task_max,T_task_exec;
435 
436  gettimeofday(&time_exec_start, NULL);
437 
438  // Time calculation
440  {
441  gettimeofday(&timereset, NULL);
442  t_task = 0.0;
443  T_task_mean = 0.0;
444  T_task_min = 0.0;
445  T_task_max = 0.0;
446  T_task_exec = 0.0;
447  }
448 
449  gettimeofday(&time, NULL);
450  t_task = ((time.tv_sec - timereset.tv_sec) + (time.tv_usec - timereset.tv_usec)*1e-6);
451  T_task = t_task - t_task_previous;
452  t_task_previous = t_task;
453 
455  {
456  T_task_mean = T_task;
457  T_task_min = 1e200;
458  T_task_max = 0.0;
459  t0 = t_task;
460  }
461  else
462  {
463  T_task_mean = 0.05*T_task + 0.95*T_task_mean;
464  if(T_task < T_task_min) T_task_min = T_task;
465  if(T_task > T_task_max) T_task_max = T_task;
466  }
467 
468  // Run the thread
469  status = periodic_task_1();
470 
471  gettimeofday(&time_exec_end, NULL);
472  T_task_exec = ((time_exec_end.tv_sec - time_exec_start.tv_sec) + (time_exec_end.tv_usec - time_exec_start.tv_usec)*1e-6);
473 
474  t_task_1_global = t_task;
475  T_task_1_mean_global = T_task_mean;
476  T_task_1_min_global = T_task_min;
477  T_task_1_max_global = T_task_max;
478  T_task_1_exec_global = T_task_exec;
479 
481 }
482 
484 {
485  int status = 0;
486  static struct timeval timereset;
487  static struct timeval time;
488  static struct timeval time_exec_start;
489  static struct timeval time_exec_end;
490  static double T_task,t_task,t_task_previous;
491  static double T_task_mean,T_task_min,T_task_max,T_task_exec;
492 
493  gettimeofday(&time_exec_start, NULL);
494 
495  // Time calculation
497  {
498  gettimeofday(&timereset, NULL);
499  t_task = 0.0;
500  T_task_mean = 0.0;
501  T_task_min = 0.0;
502  T_task_max = 0.0;
503  T_task_exec = 0.0;
504  }
505 
506  gettimeofday(&time, NULL);
507  t_task = ((time.tv_sec - timereset.tv_sec) + (time.tv_usec - timereset.tv_usec)*1e-6);
508  T_task = t_task - t_task_previous;
509  t_task_previous = t_task;
510 
512  {
513  T_task_mean = T_task;
514  T_task_min = 1e200;
515  T_task_max = 0.0;
516  }
517  else
518  {
519  T_task_mean = 0.05*T_task + 0.95*T_task_mean;
520  if(T_task < T_task_min) T_task_min = T_task;
521  if(T_task > T_task_max) T_task_max = T_task;
522  }
523 
524  // Run the thread
525  status = periodic_task_2();
526 
527  gettimeofday(&time_exec_end, NULL);
528  T_task_exec = ((time_exec_end.tv_sec - time_exec_start.tv_sec) + (time_exec_end.tv_usec - time_exec_start.tv_usec)*1e-6);
529 
530  t_task_2_global = t_task;
531  T_task_2_mean_global = T_task_mean;
532  T_task_2_min_global = T_task_min;
533  T_task_2_max_global = T_task_max;
534  T_task_2_exec_global = T_task_exec;
535 
537 }
538 
539 int reset_timer(void)
540 {
542  return SUCCESS;
543 }
544 
545 int get_time(double *time_control_task_s, double *Ts_control_task_s, double *mean_time_control_task_s, double *t0_control_task_s)
546 {
547  *time_control_task_s = t_task_1_global;
548  *Ts_control_task_s = task_1_period_us/1e6;
549  *mean_time_control_task_s = T_task_1_mean_global;
550  *t0_control_task_s = t0;
551  return SUCCESS;
552 }
553 
554 void exit_program(void)
555 {
556  quittask = 1;
557  return;
558 }
volatile int flag_task_2_firstexecution
Definition: main2.c:64
IMU_DATA_STRUCT imu_data
Definition: main2.c:74
Configs for SPI.
Definition: communication.h:65
struct IMU_PARAM_STRUCT::param_mag mag
void actuate(int spi_dev, MRA_DATA_STRUCT *mra_data)
Applies the control signal to the actuator.
int ui_close(void)
Close UI.
Definition: ui.c:41
int datalogger_set_Ts(double Ts)
Definition: datalogger.c:540
int reset_timer(void)
Definition: main2.c:539
#define TASK2_PERIOD_US
Definition: main2.c:32
volatile double T_task_2_max_global
Definition: main2.c:62
#define DATALOGGER_RUNNING
Definition: datalogger.h:30
volatile double T_task_1_mean_global
Definition: main2.c:48
Struct to control MRA.
void timer_function_task_1(void)
Definition: main2.c:426
int total
Definition: main2.c:41
Data of IMU structure.
Definition: communication.h:93
volatile int flag_task_1_firstexecution
Definition: main2.c:52
volatile double T_task_1_min_global
Definition: main2.c:49
short int y
Definition: communication.h:77
timer_t timer_task_2
Definition: main2.c:57
volatile double t_task_2_global
Definition: main2.c:58
void calibrate_all(IMU_DATA_STRUCT *imu_data)
Calibrate all sensors.
Definition: calibration.c:8
unsigned char quittask
Definition: main2.c:39
int datalogger_close(void)
Definition: datalogger.c:215
volatile int task_1_period_us
Definition: main2.c:51
#define FAILURE
Definition: calibration.h:7
void f_timer_task_2(union sigval sigval)
Definition: main2.c:336
SPI_PARAM_STRUCT spi_param
Definition: main2.c:73
int buff_i
Definition: main2.c:67
volatile double T_task_2_exec_global
Definition: main2.c:59
int periodic_task_2(void)
Definition: main2.c:277
#define TASK1_PERIOD_US
Definition: main2.c:31
DATA_XYZ mag
Magnetormeter Vector.
Definition: communication.h:96
int datalogger_write_file(void)
Definition: datalogger.c:240
volatile double t_task_1_global
Definition: main2.c:46
int datalogger_init(void)
Definition: datalogger.c:41
struct IMU_PARAM_STRUCT::param_gyr gyr
short int buff[3][3][3]
Definition: main2.c:68
struct IMU_PARAM_STRUCT::param_acc acc
int datalogger_update(double t_s, double t_control_exec_s, double t_ui_exec_s, double t0_s, IMU_DATA_STRUCT *pimu_data, EFF_DATA_STRUCT *peff_data, MRA_DATA_STRUCT *pmra_data)
Definition: datalogger.c:272
volatile double t0
Definition: main2.c:53
int status
Definition: communication.c:10
unsigned int telemetry_mode
Definition: main2.c:65
void timer_stop_task_2(void)
Definition: main2.c:416
void timer_function_task_2(void)
Definition: main2.c:483
MRA_DATA_STRUCT mra_data
Definition: main2.c:76
volatile int task_2_period_us
Definition: main2.c:63
int periodic_task_1(void)
Definition: main2.c:190
DATA_XYZ acc
Accel Vector.
Definition: communication.h:94
int failure
Definition: main2.c:42
#define SUCCESS
Definition: calibration.h:6
#define DATALOGGER_NOT_RUNNING
Definition: datalogger.h:29
#define DATALOGGER_SUCCESS
Definition: datalogger.h:35
void timer_start_task_2(void)
Definition: main2.c:375
int devices_init(IMU_PARAM_STRUCT *imu_param, SPI_PARAM_STRUCT *spi_param, MRA_DATA_STRUCT *mra_data)
INITIALIZATION OF SENSORS AND DEVICES.
Definition: communication.c:12
short int z
Definition: communication.h:78
void f_timer_task_1(union sigval sigval)
Definition: main2.c:330
volatile double T_task_1_exec_global
Definition: main2.c:47
#define UI_NCURSES_MODE
Definition: ui.h:5
void timer_start_task_1(void)
Definition: main2.c:342
int read_all_data(int i2c_dev, int spi_dev, IMU_DATA_STRUCT *imu_data, EFF_DATA_STRUCT *eff_data, MRA_DATA_STRUCT *mra_data, ENC_DATA_STRUCT *enc_data)
READ ALL DATA FROM SENSORS AND ADC.
Definition: communication.c:94
int get_time(double *time_control_task_s, double *Ts_control_task_s, double *mean_time_control_task_s, double *t0_control_task_s)
Review of this function:
Definition: main2.c:545
ENC_DATA_STRUCT enc_data
Definition: main2.c:77
volatile double T_task_2_mean_global
Definition: main2.c:60
timer_t timer_task_1
Definition: main2.c:45
int acquire
Definition: main2.c:40
Configs of IMU.
Definition: communication.h:31
EFF_DATA_STRUCT eff_data
Definition: main2.c:75
void timer_stop_task_1(void)
Definition: main2.c:406
int ui_init(void)
Initialize UI.
Definition: ui.c:26
int devices_close(IMU_PARAM_STRUCT *imu_param, SPI_PARAM_STRUCT *spi_param, MRA_DATA_STRUCT *mra_data)
Fuction to close all communication with the sensors and devices.
Definition: communication.c:82
DATA_XYZ gyr
Gyrometer Vector.
Definition: communication.h:95
int main(void)
Definition: main2.c:88
int ui_update(IMU_DATA_STRUCT *pimu_data, EFF_DATA_STRUCT *peff_data, MRA_DATA_STRUCT *pmra_data, ENC_DATA_STRUCT *enc_data, int total, int failure)
Update Screen with new data of sensors.
Definition: ui.c:53
IMU_PARAM_STRUCT imu_param
Definition: main2.c:72
short int x
Definition: communication.h:76
short int v_ctl
Voltage level for control output.
void exit_program(void)
Internal function to end program.
Definition: main2.c:554
volatile double T_task_2_min_global
Definition: main2.c:61
int datalogger_status(void)
Definition: datalogger.c:571
volatile double T_task_1_max_global
Definition: main2.c:50
int datalogger_stop(void)
Definition: datalogger.c:601