2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
5 * @addtogroup FlightPlan Flight Plan Module
6 * @brief Executes flight plan scripts in Python
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
11 * @brief Executes flight plan scripts in Python
13 * @see The GNU Public License (GPL) Version 3
15 *****************************************************************************/
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include <openpilot.h>
34 #include "flightplanstatus.h"
35 #include "flightplancontrol.h"
36 #include "flightplansettings.h"
42 #define STACK_SIZE_BYTES 1500
43 #define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
44 #define MAX_QUEUE_SIZE 2
49 static xTaskHandle taskHandle
;
50 static xQueueHandle queue
;
53 static void flightPlanTask(void *parameters
);
54 static void objectUpdatedCb(UAVObjEvent
*ev
);
56 // External variables (temporary, TODO: this will be loaded from the SD card)
57 extern unsigned char usrlib_img
[];
60 * Module initialization
62 int32_t FlightPlanStart()
67 xTaskCreate(flightPlanTask
, (signed char *)"FlightPlan", STACK_SIZE_BYTES
/ 4, NULL
, TASK_PRIORITY
, &taskHandle
);
68 PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_FLIGHTPLAN
, taskHandle
);
74 * Module initialization
76 int32_t FlightPlanInitialize()
80 FlightPlanStatusInitialize();
81 FlightPlanControlInitialize();
83 // Listen for object updates
84 FlightPlanControlConnectCallback(&objectUpdatedCb
);
86 // Create object queue
87 queue
= xQueueCreate(MAX_QUEUE_SIZE
, sizeof(UAVObjEvent
));
89 // Listen for FlightPlanControl updates
90 FlightPlanControlConnectQueue(queue
);
94 MODULE_INITCALL(FlightPlanInitialize
, FlightPlanStart
);
98 static void flightPlanTask(__attribute__((unused
)) void *parameters
)
102 FlightPlanStatusData status
;
103 FlightPlanControlData control
;
105 // Setup status object
106 status
.Status
= FLIGHTPLANSTATUS_STATUS_STOPPED
;
107 status
.ErrorFileID
= 0;
108 status
.ErrorLineNum
= 0;
109 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_NONE
;
110 status
.Debug
[0] = 0.0;
111 status
.Debug
[1] = 0.0;
112 FlightPlanStatusSet(&status
);
116 // Wait for FlightPlanControl updates
117 while (xQueueReceive(queue
, &ev
, portMAX_DELAY
) != pdTRUE
) {
121 // Get object and check if a start command was sent
122 FlightPlanControlGet(&control
);
123 if (control
.Command
== FLIGHTPLANCONTROL_COMMAND_START
) {
125 retval
= pm_init(MEMSPACE_PROG
, usrlib_img
);
126 if (retval
== PM_RET_OK
) {
128 FlightPlanStatusGet(&status
);
129 status
.Status
= FLIGHTPLANSTATUS_STATUS_RUNNING
;
130 FlightPlanStatusSet(&status
);
131 // Run the test script (TODO: load from SD card)
132 retval
= pm_run((uint8_t *)"test");
133 // Check if an error or exception was thrown
134 if (retval
== PM_RET_OK
|| retval
== PM_RET_EX_EXIT
) {
135 status
.Status
= FLIGHTPLANSTATUS_STATUS_STOPPED
;
136 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_NONE
;
137 } else if (retval
== PM_RET_EX
) {
138 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
139 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_EXCEPTION
;
140 } else if (retval
== PM_RET_EX_IO
) {
141 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
142 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_IOERROR
;
143 } else if (retval
== PM_RET_EX_ZDIV
) {
144 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
145 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_DIVBYZERO
;
146 } else if (retval
== PM_RET_EX_ASSRT
) {
147 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
148 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_ASSERTERROR
;
149 } else if (retval
== PM_RET_EX_ATTR
) {
150 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
151 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_ATTRIBUTEERROR
;
152 } else if (retval
== PM_RET_EX_IMPRT
) {
153 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
154 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_IMPORTERROR
;
155 } else if (retval
== PM_RET_EX_INDX
) {
156 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
157 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_INDEXERROR
;
158 } else if (retval
== PM_RET_EX_KEY
) {
159 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
160 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_KEYERROR
;
161 } else if (retval
== PM_RET_EX_MEM
) {
162 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
163 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_MEMORYERROR
;
164 } else if (retval
== PM_RET_EX_NAME
) {
165 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
166 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_NAMEERROR
;
167 } else if (retval
== PM_RET_EX_SYNTAX
) {
168 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
169 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_SYNTAXERROR
;
170 } else if (retval
== PM_RET_EX_SYS
) {
171 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
172 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_SYSTEMERROR
;
173 } else if (retval
== PM_RET_EX_TYPE
) {
174 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
175 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_TYPEERROR
;
176 } else if (retval
== PM_RET_EX_VAL
) {
177 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
178 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_VALUEERROR
;
179 } else if (retval
== PM_RET_EX_STOP
) {
180 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
181 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_STOPITERATION
;
182 } else if (retval
== PM_RET_EX_WARN
) {
183 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
184 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_WARNING
;
186 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
187 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_UNKNOWNERROR
;
189 // Get file ID and line number of error (if one)
190 status
.ErrorFileID
= gVmGlobal
.errFileId
;
191 status
.ErrorLineNum
= gVmGlobal
.errLineNum
;
193 status
.Status
= FLIGHTPLANSTATUS_STATUS_ERROR
;
194 status
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_VMINITERROR
;
197 // Update status object
198 FlightPlanStatusSet(&status
);
204 * Function called in response to object updates.
205 * Used to force kill the VM thread.
207 static void objectUpdatedCb(UAVObjEvent
*ev
)
209 FlightPlanControlData controlData
;
210 FlightPlanStatusData statusData
;
212 // If the object updated was the FlightPlanControl execute requested action
213 if (ev
->obj
== FlightPlanControlHandle()) {
215 FlightPlanControlGet(&controlData
);
217 if (controlData
.Command
== FLIGHTPLANCONTROL_COMMAND_START
) {
218 // Start VM task if not running already
219 if (taskHandle
== NULL
) {
220 xTaskCreate(flightPlanTask
, (signed char *)"FlightPlan", STACK_SIZE_BYTES
/ 4, NULL
, TASK_PRIORITY
, &taskHandle
);
221 PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_FLIGHTPLAN
, taskHandle
);
223 } else if (controlData
.Command
== FLIGHTPLANCONTROL_COMMAND_KILL
) {
224 // Force kill VM task if it is already running
225 // (NOTE: the STOP command is preferred as it allows the script to terminate without killing the VM)
226 if (taskHandle
!= NULL
) {
228 PIOS_TASK_MONITOR_UnregisterTask(TASKINFO_RUNNING_FLIGHTPLAN
);
229 vTaskDelete(taskHandle
);
231 // Update status object
232 statusData
.Status
= FLIGHTPLANSTATUS_STATUS_STOPPED
;
233 statusData
.ErrorFileID
= 0;
234 statusData
.ErrorLineNum
= 0;
235 statusData
.ErrorType
= FLIGHTPLANSTATUS_ERRORTYPE_NONE
;
236 statusData
.Debug
[0] = 0.0;
237 statusData
.Debug
[1] = 0.0;
238 FlightPlanStatusSet(&statusData
);