/
main.c
242 lines (194 loc) · 7.03 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#include "includes.h"
#include "sys/alt_timestamp.h" //for time measurement
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include "main.h"//contains all semaphores OS_EVENTs for external files
#include "RCReceiver.h" // RC required
#include "Logger.h"
#include "SensorDataManager.h"
#include "SensorDataFilter.h"
#include "PIDs/PIDPitch.h"
#include "PIDs/PIDRoll.h"
#include "PIDs/PIDYaw.h"
#include "PIDToMotorMapper.h"
/* Task for reading UART and parse a SUMD frame then opens a semaphore for other task */
void RCReceiverTask(void* pdata) {
printf("Starting RC task...\n");
INT8U err = OS_NO_ERR;
while (1) {
//printf for timer testing
OSSemPend(rcTaskSem, 0, &err);
err = updateChannelsRC(); // RC required
}
}
/*
* Task which is sending logging Data
*/
void LoggerTask(void* pdata) {
printf("Starting Logger task...\n");
INT8U err = OS_NO_ERR;
struct logData* rxData = malloc(sizeof(struct logData));
while (1) {
//reading latest byte out of LOGGER OS Message Que. 2nd argument is OSQPend() is timeout value
//OSQPend() should block Task if no new data is in Queue
rxData = OSQPend(loggerQsem, 0, &err); //returns 0
if (err != OS_NO_ERR) {
printf("Logging ERROR Code: %d\n", err);
}
//TODO send rxLoggerData to MCAPI
//MCAPI format is defined in struct Logdata.
//TODO Error handling on ERRORCODE 30 (Que Full) e.g. reset Que
printf("LoggerTask running: avgData= %d\n", rxData->raw[0]);
}
}
/*
* Main Task
*/
void MainTask(void* pdata) {
// int frameDone = 0; // RC required
printf("Starting Main task...\n");
int16_t avgSensorData[9] = { 0 }; //Order: ACC- GYR - COMP
uint32_t averagedDataDeltaT = 0;
float filteredSensorData[9] = { 0 }; //Order: ACC- GYR - COMP
int16_t rcValues[8];
INT8U os_err = OS_ERR_NONE;
uint8_t data_err = NO_ERR;
struct logData* loggData = malloc(sizeof(struct logData));
while (1) {
//Semaphore for periodic task
OSSemPend(mainTaskSem, 0, &os_err);
//Sensor Test
if (SDM_NEW_DATA_AVAILABLE == 1) {
os_err = getSensorData(avgSensorData, &averagedDataDeltaT);
data_err = filterSensorData(avgSensorData, filteredSensorData, averagedDataDeltaT); //only filter new data
}
if (RC_RECEIVER_NEW_DATA_AVAILABLE == 1 ){
getRCvalues(rcValues); //new rc commands will be copied in local array
printf("THROTTLE: %d\tROLL: %d\tYAW: %d\tPITCH: %d\n", rcValues[RC_THROTTLE_INDEX], rcValues[RC_ROLL_INDEX], rcValues[RC_YAW_INDEX], rcValues[RC_PITCH_INDEX]);
}
//assuming X axis from Filter is PITCH
float pidPITCHMidVal = PIDPitchCalculation(rcValues[RC_PITCH_INDEX], (float) filteredSensorData[EULER_PITCH_INDEX]);
//assuming X axis from Filter is ROLL
float pidROLLMidVal = PIDRollCalculation(rcValues[RC_ROLL_INDEX], (float) filteredSensorData[EULER_ROLL_INDEX]);
//assuming X axis from Filter is YAW
float pidYAWMidVal = PIDYawCalculation(rcValues[RC_YAW_INDEX], (float) filteredSensorData[EULER_YAW_INDEX]);
// printf("PITCH: %f\tROLL: %f\tYAW: %f\n", pidPITCHMidVal, pidROLLMidVal, pidYAWMidVal); //debug print
mapToMotors(rcValues[RC_THROTTLE_INDEX], pidROLLMidVal, pidPITCHMidVal, pidYAWMidVal);
//TODO Copy new Data to Struct for logging
// int i;
// for (i = 0; i < 9; ++i) { //copy logging data to txStruct
// loggData->raw[i] = avgSensorData[i];
// loggData->filter[i] = filteredSensorData[i];
// }
//
// loggData->pid[0] = pidPITCHMidVal;
// loggData->pid[1] = pidROLLMidVal;
// loggData->pid[2] = pidYAWMidVal;
//
// int j;
// for (j = 0; j < 8; ++j) {
// loggData->rawRadio[i] = rcValues[i];
// }
// OSQPost(loggerQsem, (void*) loggData);
}
}
/*
* RCReceiver periodic timer Callback
*/
alt_u32 mainTasktimerCallback(void* context) {
OSSemPost(mainTaskSem);
return alt_ticks_per_second() * MAIN_TASK_PERIOD / 1000; //must return the periode ticks
}
/*
* SensorDataManager periodic timer Callback
*/
alt_u32 RCReceiverTaskTasktimerCallback(void* context) {
OSSemPost(rcTaskSem);
return alt_ticks_per_second() * RCRECEIVER_TASK_PERIOD / 1000; //must return the periode ticks
}
/*
* mainTask periodic timer Callback
*/
alt_u32 SensorDataManagerTasktimerCallback(void* context) {
OSSemPost(sensorDataManageTaskSem);
return alt_ticks_per_second() * SENSORDATAMANAGER_TASK_PERIOD / 1000; //must return the periode ticks
}
/**
* init method to init Driver related Stuff
*/
void DriverInit() {
uartQsem = OSQCreate((void*) &uartQmessageTable, UART_Q_SIZE); //create Message Queue for UART driver
initRCreceiver();
initSensors();
}
/*
* Starting point for SimpleFlightController
*/
int main(void) {
printf("Starting Program\n");
printf("initialize components...");
DriverInit();
INT8U err = OS_NO_ERR; //error variable for init errors
/*
* create mutex and semaphores
*/
loggerQsem = OSQCreate((void*) &loggerQmessageTable, LOGGER_Q_SIZE); //create Message Queue for LOGGER
sensorDataMutex = OSMutexCreate(SENSOR_DATA_MUTEX_PRIORITY, &err); // Used to synchronize Main task and SensorDataManager
rcReceiverMutex = OSMutexCreate(RC_RECEIVER_MUTEX_PRIORITY, &err); // Used to synchronize Main task and RCTask
mainTaskSem = OSSemCreate(0); //used to make the MainTask periodic
sensorDataManageTaskSem = OSSemCreate(0); //used to make the SensorDataMgr periodic
rcTaskSem = OSSemCreate(0); //used to make the RcReciever periodic
/*
* init state -> wait 2 seconds (alt_ticks_per_second() * 2) until every task starts
*/
alt_alarm_start(&periodicMainTaskAlarm, alt_ticks_per_second() * MAIN_TASK_DELAY,
mainTasktimerCallback, NULL); // periodic timer for MainTask
alt_alarm_start(&periodicRCReceiverTaskAlarm, alt_ticks_per_second() * RC_TASK_DELAY,
RCReceiverTaskTasktimerCallback, NULL); // periodic timer for RCTask
alt_alarm_start(&periodicSensorDataManagerTasktimerAlarm,
alt_ticks_per_second() * SENSORDATA_TASK_DELAY, SensorDataManagerTasktimerCallback,
NULL); // periodic timer for SensorDataManagerTask
printf("Init done\n");
/*
* create RCReceiver Task
*/
OSTaskCreateExt(RCReceiverTask,
NULL, (void *) &RCReceiverTask_stk[TASK_STACKSIZE - 1],
RC_TASK_PRIORITY,
RC_TASK_PRIORITY, RCReceiverTask_stk,
TASK_STACKSIZE,
NULL, 0);
/*
* create SensorDataManagerTask
* Task is in an external Task
* declared in SensorDataManager.h
*/
err = OSTaskCreateExt(SensorDataManagerTask,
NULL, (void *) &SensorDataManagerTask_stk[TASK_STACKSIZE - 1],
SDM_TASK_PRIORITY,
SDM_TASK_PRIORITY, SensorDataManagerTask_stk,
TASK_STACKSIZE,
NULL, 0);
/*
* create LoggerTask
*/
err = OSTaskCreateExt(LoggerTask,
NULL, (void *) &LoggerTask_stk[TASK_STACKSIZE - 1],
LOGGER_TASK_PRIORITY,
LOGGER_TASK_PRIORITY, LoggerTask_stk,
TASK_STACKSIZE,
NULL, 0);
/*
* create MainTask
*/
err = OSTaskCreateExt(MainTask,
NULL, (void *) &MainTask_stk[TASK_STACKSIZE - 1],
MAIN_TASK_PRIORITY,
MAIN_TASK_PRIORITY, MainTask_stk,
TASK_STACKSIZE,
NULL, 0);
OSStart();
return 0;
}