2011-01-09 23:36:15 +01:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
* @addtogroup OpenPilotModules OpenPilot Modules
|
|
|
|
* @{
|
|
|
|
* @addtogroup FlightPlan Flight Plan Module
|
|
|
|
* @brief Executes flight plan scripts in Python
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file flightplan.c
|
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
|
|
* @brief Executes flight plan scripts in Python
|
|
|
|
*
|
|
|
|
* @see The GNU Public License (GPL) Version 3
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "openpilot.h"
|
|
|
|
#include "pm.h"
|
2011-06-17 07:13:19 +02:00
|
|
|
#include "flightplan.h"
|
2011-01-09 23:36:15 +01:00
|
|
|
#include "flightplanstatus.h"
|
2011-01-19 04:34:01 +01:00
|
|
|
#include "flightplancontrol.h"
|
|
|
|
#include "flightplansettings.h"
|
2011-01-09 23:36:15 +01:00
|
|
|
|
|
|
|
// Private constants
|
|
|
|
#define STACK_SIZE_BYTES 1500
|
2011-01-19 04:34:01 +01:00
|
|
|
#define TASK_PRIORITY (tskIDLE_PRIORITY+1)
|
2011-01-22 22:32:23 +01:00
|
|
|
#define MAX_QUEUE_SIZE 2
|
2011-01-09 23:36:15 +01:00
|
|
|
|
|
|
|
// Private types
|
|
|
|
|
|
|
|
// Private variables
|
|
|
|
static xTaskHandle taskHandle;
|
2011-01-22 22:32:23 +01:00
|
|
|
static xQueueHandle queue;
|
2011-01-09 23:36:15 +01:00
|
|
|
|
|
|
|
// Private functions
|
|
|
|
static void flightPlanTask(void *parameters);
|
2011-01-19 04:34:01 +01:00
|
|
|
static void objectUpdatedCb(UAVObjEvent * ev);
|
2011-01-09 23:36:15 +01:00
|
|
|
|
|
|
|
// External variables (temporary, TODO: this will be loaded from the SD card)
|
|
|
|
extern unsigned char usrlib_img[];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Module initialization
|
|
|
|
*/
|
2011-06-20 07:35:40 +02:00
|
|
|
int32_t FlightPlanStart()
|
|
|
|
{
|
|
|
|
taskHandle = NULL;
|
|
|
|
|
|
|
|
// Start VM thread
|
|
|
|
xTaskCreate(flightPlanTask, (signed char *)"FlightPlan", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
|
|
|
|
TaskMonitorAdd(TASKINFO_RUNNING_FLIGHTPLAN, taskHandle);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Module initialization
|
|
|
|
*/
|
2011-01-09 23:36:15 +01:00
|
|
|
int32_t FlightPlanInitialize()
|
|
|
|
{
|
2011-01-19 04:34:01 +01:00
|
|
|
taskHandle = NULL;
|
2011-08-19 16:52:05 +02:00
|
|
|
|
|
|
|
FlightPlanStatusInitialize();
|
|
|
|
FlightPlanControlInitialize();
|
|
|
|
FlightPlanSettingsInitialize();
|
|
|
|
|
2011-01-19 04:34:01 +01:00
|
|
|
// Listen for object updates
|
|
|
|
FlightPlanControlConnectCallback(&objectUpdatedCb);
|
2011-01-09 23:36:15 +01:00
|
|
|
|
2011-01-22 22:32:23 +01:00
|
|
|
// Create object queue
|
|
|
|
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
|
|
|
|
|
|
|
// Listen for FlightPlanControl updates
|
|
|
|
FlightPlanControlConnectQueue(queue);
|
|
|
|
|
2011-01-09 23:36:15 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2011-07-13 05:44:32 +02:00
|
|
|
MODULE_INITCALL(FlightPlanInitialize, FlightPlanStart)
|
2011-01-09 23:36:15 +01:00
|
|
|
/**
|
|
|
|
* Module task
|
|
|
|
*/
|
|
|
|
static void flightPlanTask(void *parameters)
|
|
|
|
{
|
2011-01-22 22:32:23 +01:00
|
|
|
UAVObjEvent ev;
|
2011-01-09 23:36:15 +01:00
|
|
|
PmReturn_t retval;
|
|
|
|
FlightPlanStatusData status;
|
2011-01-22 22:32:23 +01:00
|
|
|
FlightPlanControlData control;
|
2011-01-09 23:36:15 +01:00
|
|
|
|
|
|
|
// Setup status object
|
2011-01-22 22:32:23 +01:00
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_STOPPED;
|
2011-01-09 23:36:15 +01:00
|
|
|
status.ErrorFileID = 0;
|
|
|
|
status.ErrorLineNum = 0;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_NONE;
|
2011-03-03 03:22:50 +01:00
|
|
|
status.Debug[0] = 0.0;
|
|
|
|
status.Debug[1] = 0.0;
|
2011-01-19 04:34:01 +01:00
|
|
|
FlightPlanStatusSet(&status);
|
2011-01-09 23:36:15 +01:00
|
|
|
|
2011-01-22 22:32:23 +01:00
|
|
|
// Main thread loop
|
2011-01-09 23:36:15 +01:00
|
|
|
while (1)
|
|
|
|
{
|
2011-01-22 22:32:23 +01:00
|
|
|
// Wait for FlightPlanControl updates
|
|
|
|
while (xQueueReceive(queue, &ev, portMAX_DELAY) != pdTRUE) ;
|
|
|
|
|
|
|
|
// Get object and check if a start command was sent
|
|
|
|
FlightPlanControlGet(&control);
|
|
|
|
if ( control.Command == FLIGHTPLANCONTROL_COMMAND_START )
|
|
|
|
{
|
|
|
|
// Init PyMite
|
|
|
|
retval = pm_init(MEMSPACE_PROG, usrlib_img);
|
|
|
|
if (retval == PM_RET_OK)
|
|
|
|
{
|
|
|
|
// Update status
|
|
|
|
FlightPlanStatusGet(&status);
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_RUNNING;
|
|
|
|
FlightPlanStatusSet(&status);
|
|
|
|
// Run the test script (TODO: load from SD card)
|
|
|
|
retval = pm_run((uint8_t *)"test");
|
|
|
|
// Check if an error or exception was thrown
|
|
|
|
if (retval == PM_RET_OK || retval == PM_RET_EX_EXIT)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_STOPPED;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_NONE;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_EXCEPTION;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_IO)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_IOERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_ZDIV)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_DIVBYZERO;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_ASSRT)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_ASSERTERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_ATTR)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_ATTRIBUTEERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_IMPRT)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_IMPORTERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_INDX)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_INDEXERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_KEY)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_KEYERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_MEM)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_MEMORYERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_NAME)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_NAMEERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_SYNTAX)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_SYNTAXERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_SYS)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_SYSTEMERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_TYPE)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_TYPEERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_VAL)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_VALUEERROR;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_STOP)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_STOPITERATION;
|
|
|
|
}
|
|
|
|
else if (retval == PM_RET_EX_WARN)
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_WARNING;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_UNKNOWNERROR;
|
|
|
|
}
|
|
|
|
// Get file ID and line number of error (if one)
|
|
|
|
status.ErrorFileID = gVmGlobal.errFileId;
|
|
|
|
status.ErrorLineNum = gVmGlobal.errLineNum;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
|
|
|
|
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_VMINITERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update status object
|
|
|
|
FlightPlanStatusSet(&status);
|
|
|
|
}
|
2011-01-09 23:36:15 +01:00
|
|
|
}
|
2011-01-19 04:34:01 +01:00
|
|
|
}
|
2011-01-09 23:36:15 +01:00
|
|
|
|
2011-01-19 04:34:01 +01:00
|
|
|
/**
|
2011-01-22 22:32:23 +01:00
|
|
|
* Function called in response to object updates.
|
|
|
|
* Used to force kill the VM thread.
|
2011-01-19 04:34:01 +01:00
|
|
|
*/
|
|
|
|
static void objectUpdatedCb(UAVObjEvent * ev)
|
|
|
|
{
|
|
|
|
FlightPlanControlData controlData;
|
|
|
|
FlightPlanStatusData statusData;
|
2011-01-09 23:36:15 +01:00
|
|
|
|
2011-01-19 04:34:01 +01:00
|
|
|
// If the object updated was the FlightPlanControl execute requested action
|
|
|
|
if ( ev->obj == FlightPlanControlHandle() )
|
|
|
|
{
|
|
|
|
// Get data
|
|
|
|
FlightPlanControlGet(&controlData);
|
|
|
|
// Execute command
|
|
|
|
if ( controlData.Command == FLIGHTPLANCONTROL_COMMAND_START )
|
|
|
|
{
|
|
|
|
// Start VM task if not running already
|
|
|
|
if ( taskHandle == NULL )
|
|
|
|
{
|
|
|
|
xTaskCreate(flightPlanTask, (signed char *)"FlightPlan", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
|
|
|
|
TaskMonitorAdd(TASKINFO_RUNNING_FLIGHTPLAN, taskHandle);
|
|
|
|
}
|
|
|
|
}
|
2011-01-22 22:32:23 +01:00
|
|
|
else if ( controlData.Command == FLIGHTPLANCONTROL_COMMAND_KILL )
|
2011-01-19 04:34:01 +01:00
|
|
|
{
|
|
|
|
// Force kill VM task if it is already running
|
2011-01-22 22:32:23 +01:00
|
|
|
// (NOTE: the STOP command is preferred as it allows the script to terminate without killing the VM)
|
2011-01-19 04:34:01 +01:00
|
|
|
if ( taskHandle != NULL )
|
|
|
|
{
|
|
|
|
// Kill VM
|
|
|
|
TaskMonitorRemove(TASKINFO_RUNNING_FLIGHTPLAN);
|
|
|
|
vTaskDelete(taskHandle);
|
|
|
|
taskHandle = NULL;
|
|
|
|
// Update status object
|
|
|
|
statusData.Status = FLIGHTPLANSTATUS_STATUS_STOPPED;
|
|
|
|
statusData.ErrorFileID = 0;
|
|
|
|
statusData.ErrorLineNum = 0;
|
|
|
|
statusData.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_NONE;
|
2011-03-03 03:22:50 +01:00
|
|
|
statusData.Debug[0] = 0.0;
|
|
|
|
statusData.Debug[1] = 0.0;
|
2011-01-19 04:34:01 +01:00
|
|
|
FlightPlanStatusSet(&statusData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-01-09 23:36:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
* @}
|
|
|
|
*/
|