Difference between revisions of "DevGuide/DesignOverview"
Jump to navigation
Jump to search
Line 28: | Line 28: | ||
-Main issues with modularity are configuration and dependancies | -Main issues with modularity are configuration and dependancies | ||
[[Image:dependancies_example. | [[Image:dependancies_example.pdf]] | ||
=== Hardware abstraction === | === Hardware abstraction === | ||
Line 38: | Line 38: | ||
=== Runtime Efficiency === | === Runtime Efficiency === | ||
It's very unlikely that we will change the serial port on which we connected our modem inflight. | |||
bad : | bad : | ||
Line 48: | Line 49: | ||
#define UartWrite(x) UART ## _write(x) | #define UartWrite(x) UART ## _write(x) | ||
UartWrite(...); | UartWrite(...); | ||
== Design Solutions == | |||
* Heavy pre-processor usage | |||
* C code generation | |||
* Heavy Makefile usage | |||
* Conventions to define our own module layer | |||
=== pre-processor === | |||
==== header selection ==== | |||
conf/airframes/funjet1.xml | |||
<makefile> | |||
ap.CFLAGS += -DACTUATORS=\"servos_4017_hw.h\" | |||
</makefile> | |||
generated var/FJ1/Makefile.ac | |||
ap.CFLAGS += -DACTUATORS=\"servos_4017_hw.h\" | |||
sw/airborne/actuators.h | |||
#include ACTUATORS | |||
expanded by pre-processor to | |||
#include "servos_4017_hw.h" | |||
==== macros ==== | |||
conf/airframes/funjet1.xml | |||
ap.CFLAGS += -DXBEE_UART=Uart1 | |||
sw/airborne/xbee.h | |||
#define __XBeeLink(dev, _x) dev##_x | |||
#define _XBeeLink(dev, _x) __XBeeLink(dev, _x) | |||
#define XBeeLink(_x) _XBeeLink(XBEE_UART, _x) | |||
#define XBeeBuffer() XBeeLink(ChAvailable()) | |||
expanded by pre-processor to | |||
Uart1ChAvailable() | |||
=== C code generation === | |||
For problems too complex to solve by the pre processor, we use custom compilers to generate code from a description in xml | |||
==== example 1 : command laws, aka mixers ==== | |||
conf/airframes/funjet1.xml | |||
<command_laws> | |||
<let var="aileron" value="@ROLL * AILEVON_AILERON_RATE"/> | |||
<let var="elevator" value="@PITCH * AILEVON_ELEVATOR_RATE"/> | |||
<set servo="AILEVON_LEFT" value="$elevator + $aileron"/> | |||
<set servo="AILEVON_RIGHT" value="$elevator - $aileron"/> | |||
</command_laws> | |||
generated var/FJ1/airframe.h | |||
#define SetActuatorsFromCommands(values) { \ | |||
uint16_t servo_value;\ | |||
float command_value;\ | |||
int16_t _var_aileron = values[COMMAND_ROLL] * AILEVON_AILERON_RATE;\ | |||
int16_t _var_elevator = values[COMMAND_PITCH] * AILEVON_ELEVATOR_RATE;\ | |||
[....] | |||
command_value = _var_elevator + _var_aileron;\ | |||
command_value *= command_value>0 ? SERVO_AILEVON_LEFT_TRAVEL_UP : SERVO_AILEVON_LEFT_TRAVEL_DOWN;\ | |||
servo_value = SERVO_AILEVON_LEFT_NEUTRAL + (int16_t)(command_value);\ | |||
actuators[SERVO_AILEVON_LEFT] = ChopServo(servo_value, SERVO_AILEVON_LEFT_MIN, SERVO_AILEVON_LEFT_MAX);\ | |||
Actuator(SERVO_AILEVON_LEFT) = SERVOS_TICS_OF_USEC(actuators[SERVO_AILEVON_LEFT]);\ | |||
==== example 2 : flight plan ==== | |||
conf/flight plans/example.xml | |||
<blocks> | |||
<block name="see 1"> | |||
<circle target="1" wp="HOME" cam_mode="target" alt="GROUND_ALT+50" radius="75"/> | |||
</block> | |||
<block name="nadir"> | |||
<circle wp="HOME" cam_mode="nadir" alt="GROUND_ALT+50" radius="75"/> | |||
</block> | |||
</blocks> | |||
generated var/flight plan.h | |||
switch (nav_block) { | |||
case 0: | |||
switch(nav_stage) { | |||
case 0: | |||
NavVerticalAutoThrottleMode(0.0); | |||
NavVerticalAltitudeMode(GROUND_ALT+50, 0.); | |||
NavCircleWaypoint(1, 75); | |||
cam_waypoint_target(2); | |||
return; | |||
case 1: | |||
NextBlock() | |||
} | |||
case 1: | |||
switch(nav_stage) { | |||
case 0: |
Revision as of 05:49, 13 May 2008
Functional Diagram
Design Goals
-Static approach -Modularity -Hardware absraction -Runtime efficiency
Static Approach
-only "things that needs to be changed during flight are changeable -maximise compilation time resolutions
advantages Error checking Efficiency Safety/Robustness
Modularity
-Separation of concerns -Maintenability -Interface -C provide no dedicated mechanism for modularity -Main issues with modularity are configuration and dependancies
Hardware abstraction
-Segregate hardware dependant modules
Runtime Efficiency
It's very unlikely that we will change the serial port on which we connected our modem inflight.
bad : switch(UART) { case UART0 : UARTO_write(...); break; case UART1 : UART1_write(...); break; }
good : #define UartWrite(x) UART ## _write(x) UartWrite(...);
Design Solutions
* Heavy pre-processor usage * C code generation * Heavy Makefile usage * Conventions to define our own module layer
pre-processor
header selection
conf/airframes/funjet1.xml <makefile> ap.CFLAGS += -DACTUATORS=\"servos_4017_hw.h\" </makefile> generated var/FJ1/Makefile.ac ap.CFLAGS += -DACTUATORS=\"servos_4017_hw.h\" sw/airborne/actuators.h
- include ACTUATORS
expanded by pre-processor to
- include "servos_4017_hw.h"
macros
conf/airframes/funjet1.xml ap.CFLAGS += -DXBEE_UART=Uart1 sw/airborne/xbee.h
- define __XBeeLink(dev, _x) dev##_x
- define _XBeeLink(dev, _x) __XBeeLink(dev, _x)
- define XBeeLink(_x) _XBeeLink(XBEE_UART, _x)
- define XBeeBuffer() XBeeLink(ChAvailable())
expanded by pre-processor to Uart1ChAvailable()
C code generation
For problems too complex to solve by the pre processor, we use custom compilers to generate code from a description in xml
example 1 : command laws, aka mixers
conf/airframes/funjet1.xml <command_laws>
<let var="aileron" value="@ROLL * AILEVON_AILERON_RATE"/> <let var="elevator" value="@PITCH * AILEVON_ELEVATOR_RATE"/> <set servo="AILEVON_LEFT" value="$elevator + $aileron"/> <set servo="AILEVON_RIGHT" value="$elevator - $aileron"/>
</command_laws> generated var/FJ1/airframe.h
- define SetActuatorsFromCommands(values) { \
uint16_t servo_value;\ float command_value;\ int16_t _var_aileron = values[COMMAND_ROLL] * AILEVON_AILERON_RATE;\ int16_t _var_elevator = values[COMMAND_PITCH] * AILEVON_ELEVATOR_RATE;\
[....]
command_value = _var_elevator + _var_aileron;\ command_value *= command_value>0 ? SERVO_AILEVON_LEFT_TRAVEL_UP : SERVO_AILEVON_LEFT_TRAVEL_DOWN;\ servo_value = SERVO_AILEVON_LEFT_NEUTRAL + (int16_t)(command_value);\ actuators[SERVO_AILEVON_LEFT] = ChopServo(servo_value, SERVO_AILEVON_LEFT_MIN, SERVO_AILEVON_LEFT_MAX);\ Actuator(SERVO_AILEVON_LEFT) = SERVOS_TICS_OF_USEC(actuators[SERVO_AILEVON_LEFT]);\
example 2 : flight plan
conf/flight plans/example.xml
<blocks> <block name="see 1"> <circle target="1" wp="HOME" cam_mode="target" alt="GROUND_ALT+50" radius="75"/> </block> <block name="nadir"> <circle wp="HOME" cam_mode="nadir" alt="GROUND_ALT+50" radius="75"/> </block> </blocks>
generated var/flight plan.h
switch (nav_block) { case 0: switch(nav_stage) { case 0: NavVerticalAutoThrottleMode(0.0); NavVerticalAltitudeMode(GROUND_ALT+50, 0.); NavCircleWaypoint(1, 75); cam_waypoint_target(2); return; case 1: NextBlock() } case 1: switch(nav_stage) { case 0: