DevGuide/DesignOverview

From PaparazziUAV
Revision as of 06:03, 13 May 2008 by Poine (talk | contribs)
Jump to navigation Jump to search

Functional Diagram

Functional diagram.png


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

Modularity.png

 -Separation of concerns
 -Maintenability
 -Interface
 -C provide no dedicated mechanism for modularity
 -Main issues with modularity are configuration and dependancies

Dependancies example.png

Hardware abstraction

 -Segregate hardware dependant modules

Hardware abstraction.png


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

  1. 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: