1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-10 18:24:11 +01:00

Flight/FlightPlan: Enable Python VM and test flightplan execution. From now on a Python executable needs to be in the system path as it is used in the Makefile.

A test script is statically linked (will eventually be uploaded by the GCS and stored in the VM), it can be found under: Modules/FlightPlan/flightplans/test.py

To start the script send the FlightPlanControl object with the Start command, to stop send the Stop or Kill commands.

Next release will be the OpenPilot python libraries and access to UAVObjects from the script.



git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2480 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
vassilis 2011-01-19 03:34:01 +00:00 committed by vassilis
parent 780f441ae9
commit d7fd8a3bcd
8 changed files with 212 additions and 45 deletions

View File

@ -32,10 +32,12 @@
#include "openpilot.h" #include "openpilot.h"
#include "pm.h" #include "pm.h"
#include "flightplanstatus.h" #include "flightplanstatus.h"
#include "flightplancontrol.h"
#include "flightplansettings.h"
// Private constants // Private constants
#define STACK_SIZE_BYTES 1500 #define STACK_SIZE_BYTES 1500
#define TASK_PRIORITY (tskIDLE_PRIORITY+4) #define TASK_PRIORITY (tskIDLE_PRIORITY+1)
// Private types // Private types
@ -44,6 +46,7 @@ static xTaskHandle taskHandle;
// Private functions // Private functions
static void flightPlanTask(void *parameters); static void flightPlanTask(void *parameters);
static void objectUpdatedCb(UAVObjEvent * ev);
// External variables (temporary, TODO: this will be loaded from the SD card) // External variables (temporary, TODO: this will be loaded from the SD card)
extern unsigned char usrlib_img[]; extern unsigned char usrlib_img[];
@ -53,9 +56,9 @@ extern unsigned char usrlib_img[];
*/ */
int32_t FlightPlanInitialize() int32_t FlightPlanInitialize()
{ {
// Start main task taskHandle = NULL;
xTaskCreate(flightPlanTask, (signed char *)"FlightPlan", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle); // Listen for object updates
TaskMonitorAdd(TASKINFO_RUNNING_FLIGHTPLAN, taskHandle); FlightPlanControlConnectCallback(&objectUpdatedCb);
return 0; return 0;
} }
@ -70,30 +73,125 @@ static void flightPlanTask(void *parameters)
FlightPlanStatusData status; FlightPlanStatusData status;
// Setup status object // Setup status object
status.Status = FLIGHTPLANSTATUS_STATUS_NONE; status.Status = FLIGHTPLANSTATUS_STATUS_RUNNING;
status.ErrorFileID = 0; status.ErrorFileID = 0;
status.ErrorLineNum = 0; status.ErrorLineNum = 0;
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_NONE; status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_NONE;
status.Debug = 0.0; status.Debug1 = 0.0;
status.Debug2 = 0.0;
FlightPlanStatusSet(&status);
// Init PyMite // Init PyMite
status.Status = FLIGHTPLANSTATUS_STATUS_IDLE;
retval = pm_init(MEMSPACE_PROG, usrlib_img); retval = pm_init(MEMSPACE_PROG, usrlib_img);
if (retval != PM_RET_OK) if (retval == PM_RET_OK)
{ {
status.Status = FLIGHTPLANSTATUS_STATUS_VMINITERROR; // 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)
{
status.Status = FLIGHTPLANSTATUS_STATUS_FINISHED;
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_EXIT)
{
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_EXIT;
}
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;
}
}
else
{
status.Status = FLIGHTPLANSTATUS_STATUS_ERROR;
status.ErrorType = FLIGHTPLANSTATUS_ERRORTYPE_VMINITERROR;
} }
// Run the sample program // Update status object
status.Status = FLIGHTPLANSTATUS_STATUS_RUNNING;
FlightPlanStatusSet(&status); FlightPlanStatusSet(&status);
retval = pm_run((uint8_t *)"test");
if (retval != PM_RET_OK)
{
status.Status = FLIGHTPLANSTATUS_STATUS_SCRIPTSTARTERROR;
status.Debug = retval;
FlightPlanStatusSet(&status);
}
// Do not return // Do not return
lastSysTime = xTaskGetTickCount(); lastSysTime = xTaskGetTickCount();
@ -101,8 +199,52 @@ static void flightPlanTask(void *parameters)
{ {
vTaskDelayUntil(&lastSysTime, 1000 / portTICK_RATE_MS); vTaskDelayUntil(&lastSysTime, 1000 / portTICK_RATE_MS);
} }
}
/**
* Function called in response to object updates
*/
static void objectUpdatedCb(UAVObjEvent * ev)
{
FlightPlanControlData controlData;
FlightPlanStatusData statusData;
// 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);
}
}
else if ( controlData.Command == FLIGHTPLANCONTROL_COMMAND_KILL || controlData.Command == FLIGHTPLANCONTROL_COMMAND_STOP )
{
// Force kill VM task if it is already running
// (NOTE: when implemented, the STOP command will allow the script to terminate without killing the VM)
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;
statusData.Debug1 = 0.0;
statusData.Debug2 = 0.0;
FlightPlanStatusSet(&statusData);
}
}
}
} }
/** /**

View File

@ -1,6 +1,9 @@
import uavobjects import uavobjects
import sys import sys
uavobjects.FlightPlanStatusUpdate(12) n=0
while n<200000:
uavobjects.FlightPlanStatusUpdate(n)
n=n+1

View File

@ -8,11 +8,13 @@ def FlightPlanStatusUpdate(val):
pPmObj_t pobj; pPmObj_t pobj;
FlightPlanStatusData status; FlightPlanStatusData status;
FlightPlanStatusGet(&status);
pobj = NATIVE_GET_LOCAL(0); pobj = NATIVE_GET_LOCAL(0);
if ( OBJ_GET_TYPE(pobj) == OBJ_TYPE_INT ) if ( OBJ_GET_TYPE(pobj) == OBJ_TYPE_INT )
status.Debug = ((pPmInt_t) pobj)->val; status.Debug1 = ((pPmInt_t) pobj)->val;
else if ( OBJ_GET_TYPE(pobj) == OBJ_TYPE_FLT ) else if ( OBJ_GET_TYPE(pobj) == OBJ_TYPE_FLT )
status.Debug = ((pPmFloat_t) pobj)->val; status.Debug1 = ((pPmFloat_t) pobj)->val;
FlightPlanStatusSet(&status); FlightPlanStatusSet(&status);

View File

@ -57,7 +57,7 @@ FLASH_TOOL = OPENOCD
USE_THUMB_MODE = YES USE_THUMB_MODE = YES
# List of modules to include # List of modules to include
MODULES = Actuator Telemetry GPS ManualControl Altitude AHRSComms Stabilization Guidance FirmwareIAP MODULES = Actuator Telemetry GPS ManualControl Altitude AHRSComms Stabilization Guidance FirmwareIAP FlightPlan
#MODULES = Telemetry Example #MODULES = Telemetry Example
#MODULES = Telemetry MK/MKSerial #MODULES = Telemetry MK/MKSerial
@ -298,12 +298,12 @@ SRC += $(AHRSBOOTLOADER)/ahrs_spi_program_master.c
SRC += $(AHRSBOOTLOADER)/ahrs_spi_program.c SRC += $(AHRSBOOTLOADER)/ahrs_spi_program.c
## PyMite files ## PyMite files
#SRC += $(wildcard ${PYMITEVM}/*.c) SRC += $(OUTDIR)/pmlib_img.c
#SRC += $(wildcard ${PYMITEPLAT}/*.c) SRC += $(OUTDIR)/pmlib_nat.c
#SRC += $(OUTDIR)/pmlib_img.c SRC += $(OUTDIR)/pmlibusr_img.c
#SRC += $(OUTDIR)/pmlib_nat.c SRC += $(OUTDIR)/pmlibusr_nat.c
#SRC += $(OUTDIR)/pmlibusr_img.c SRC += $(wildcard ${PYMITEVM}/*.c)
#SRC += $(OUTDIR)/pmlibusr_nat.c SRC += $(wildcard ${PYMITEPLAT}/*.c)
## Mass Storage Device ## Mass Storage Device
#SRC += $(MSDDIR)/msd.c #SRC += $(MSDDIR)/msd.c
@ -614,7 +614,7 @@ else
endif endif
# Generate intermediate code # Generate intermediate code
gencode: ${OUTDIR}/InitMods.c #$(OUTDIR)/pmlib_img.c $(OUTDIR)/pmlib_nat.c $(OUTDIR)/pmlibusr_img.c $(OUTDIR)/pmlibusr_nat.c $(OUTDIR)/pmfeatures.h gencode: ${OUTDIR}/InitMods.c ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h
# Generate code for module initialization # Generate code for module initialization
${OUTDIR}/InitMods.c: Makefile ${OUTDIR}/InitMods.c: Makefile
@ -626,11 +626,11 @@ ${OUTDIR}/InitMods.c: Makefile
@echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c @echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c
# Generate code for PyMite # Generate code for PyMite
#$(OUTDIR)/pmlib_img.c $(OUTDIR)/pmlib_nat.c $(OUTDIR)/pmlibusr_img.c $(OUTDIR)/pmlibusr_nat.c $(OUTDIR)/pmfeatures.h: $(wildcard $(PYMITELIB)/*.py) $(wildcard $(PYMITEPLAT)/*.py) $(wildcard $(FLIGHTPLANLIB)/*.py) $(wildcard $(FLIGHTPLANS)/*.py) ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py)
# @echo ${MSG_PYMITEINIT} @echo ${MSG_PYMITEINIT}
# @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py) @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py)
# @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h
# @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py
# Eye candy. # Eye candy.
begin: begin:

View File

@ -32,6 +32,7 @@
int32_t TaskMonitorInitialize(void); int32_t TaskMonitorInitialize(void);
int32_t TaskMonitorAdd(TaskInfoRunningElem task, xTaskHandle handle); int32_t TaskMonitorAdd(TaskInfoRunningElem task, xTaskHandle handle);
int32_t TaskMonitorRemove(TaskInfoRunningElem task);
void TaskMonitorUpdateAll(void); void TaskMonitorUpdateAll(void);
#endif // TASKMONITOR_H #endif // TASKMONITOR_H

View File

@ -66,6 +66,24 @@ int32_t TaskMonitorAdd(TaskInfoRunningElem task, xTaskHandle handle)
} }
} }
/**
* Remove a task handle from the library
*/
int32_t TaskMonitorRemove(TaskInfoRunningElem task)
{
if (task < TASKINFO_RUNNING_NUMELEM)
{
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
handles[task] = 0;
xSemaphoreGiveRecursive(lock);
return 0;
}
else
{
return -1;
}
}
/** /**
* Update the status of all tasks * Update the status of all tasks
*/ */

View File

@ -1,9 +1,9 @@
<xml> <xml>
<object name="FlightPlanControl" singleinstance="true" settings="false"> <object name="FlightPlanControl" singleinstance="true" settings="false">
<description>Control the flight plan script</description> <description>Control the flight plan script</description>
<field name="Test" units="%" type="float" elements="1"/> <field name="Command" units="" type="enum" options="Start,Stop,Kill" defaultvalue="Start" elements="1"/>
<access gcs="readwrite" flight="readwrite"/> <access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/> <telemetrygcs acked="true" updatemode="manual" period="0"/>
<telemetryflight acked="true" updatemode="manual" period="0"/> <telemetryflight acked="true" updatemode="manual" period="0"/>
<logging updatemode="never" period="0"/> <logging updatemode="never" period="0"/>
</object> </object>

View File

@ -1,11 +1,12 @@
<xml> <xml>
<object name="FlightPlanStatus" singleinstance="true" settings="false"> <object name="FlightPlanStatus" singleinstance="true" settings="false">
<description>Status of the flight plan script</description> <description>Status of the flight plan script</description>
<field name="Status" units="" type="enum" elements="1" options="None,Running,Idle,VMInitError,ScriptStartError,RunTimeError" defaultvalue="None"/> <field name="Status" units="" type="enum" elements="1" options="Stopped,Running,Finished,Error" defaultvalue="Stopped"/>
<field name="ErrorType" units="" type="enum" elements="1" options="None" defaultvalue="None"/> <field name="ErrorType" units="" type="enum" elements="1" options="None,VMInitError,Exception,Exit,IOError,DivByZero,AssertError,AttributeError,ImportError,IndexError,KeyError,MemoryError,NameError,SyntaxError,SystemError,TypeError,ValueError,StopIteration,Warning,UnknownError" defaultvalue="None"/>
<field name="ErrorFileID" units="" type="uint32" elements="1"/> <field name="ErrorFileID" units="" type="uint32" elements="1"/>
<field name="ErrorLineNum" units="" type="uint32" elements="1"/> <field name="ErrorLineNum" units="" type="uint32" elements="1"/>
<field name="Debug" units="" type="float" elements="1"/> <field name="Debug1" units="" type="float" elements="1" defaultvalue="0.0"/>
<field name="Debug2" units="" type="float" elements="1" defaultvalue="0.0"/>
<access gcs="readwrite" flight="readwrite"/> <access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="false" updatemode="manual" period="0"/> <telemetrygcs acked="false" updatemode="manual" period="0"/>
<telemetryflight acked="false" updatemode="periodic" period="2000"/> <telemetryflight acked="false" updatemode="periodic" period="2000"/>