DevGuide/StateInterface

From PaparazziUAV
Jump to navigation Jump to search

The idea is to create a general state interface that holds the most important vehicle states like attitude, position, speed, acceleration.

state.h


/* abstract state interface */
struct State {
  /* Earth Centered Earth Fixed in centimeters */
  struct EcefCoor_i ecef_pos;

  /* lon, lat in radians*1e7  */
  /* alt in centimeters above MSL  */
  struct LlaCoor_i lla_pos;

  /* definition of the local (flat earth) coordinate system */
  struct LtpDef_i ned_origin;
  bool_t ned_initialised;

  /* North East Down local tangent plane */
  struct NedCoor_i ned_pos;
  struct NedCoor_i ned_speed;
  struct NedCoor_i ned_accel;

  /* vehicle attitude */
  struct Int32Quat   ned_to_body_quat;
  struct Int32Eulers ned_to_body_euler;
  struct Int32RMat   ned_to_body_rmat;
  struct Int32Rates  body_rate;

  /* horizontal windspeed x = north, y = east */
  struct Int32Vect2 h_windspeed;

  struct int32_t airspeed_norm;

  /***** float representations ****/

  /* Position within UTM zone in meters, z in meters above MSL */
  struct FloatVect3 utm_pos;
  uint8_t utm_zone;
  /* altitude above ground level in meters */
  float alt_agl;

  /* accelerations in North East Down local tangent plane */
  struct FloatVect3 ned_accel;

  /* speed in North East Down local tangent plane */
  struct FloatVect3 ned_speed;
  /* horizontal ground speed in norm and dir (m/s, rad (CW/North)) */
  float h_speed_norm;
  float h_speed_dir;

  struct FloatVect2 h_windspeed; /* m/s ; x = north, y = east */
  float airspeed_norm; /* m/s */

  struct FloatQuat   ned_to_body_quat;
  struct FloatEulers ned_to_body_euler;
  struct FloatRMat   ned_to_body_rmat;
  struct FloatRates  body_rate;
}


We should also make clear that the angle psi means the heading (where the aircraft's noise is pointing) and not the direction it is actually moving (groundspeed direction). For fixedwings I think we currently assume it is the same (without a magnetometer).

How to set/get the state ?

State accessor functions we need:

Integer set versions (inline void):
  • StateSetPositionEcef_i(EcefCoor_i ecef_pos)
  • StateSetPositionNed_i(NedCoor_i ned_pos)
  • StateSetPositionLla_i(LlaCoor_i lla_pos)
  • StateSetSpeedNed_i(NedCoor_i ned_speed)
  • StateSetAccelNed_i(NedCoor_i ned_accel)
  • StateSetNedToBodyQuat_i(Int32Quat ned_to_body_quat)
  • StateSetNedToBodyRMat_i(Int32RMat ned_to_body_rmat)
  • StateSetNedToBodyEulers_i(Int32Eulers ned_to_body_eulers)
  • StateSetBodyRates_i(Int32Rates body_rate)
  • StateSetHorizontalWindspeed(Int32Vect2 h_windspeed)
  • StateSetAirspeedNorm(int32_t airspeed_norm)

On time computation

With this solution, the state can be updated and read with any format with a little overhead (do some tests on a status).

The conversion is done only if needed and is not done again until the state is updated.

The following structure has to be done for the different "groups" of states: position, speed, attitude,...

#define XXX 1<<0
#define YYY 1<<1
#define ZZZ 1<<2
uint XYZ_status;

// set the new value and reset the status to tell that other format are not up to date anymore
#define STATE_SET_XXX(_v) {
 state.XXX = _v;
 pos_status = XXX;
}
--> do the same for YYY and ZZZ, and even for XXX_YYY, XXX_ZZZ, ... if needed

// get the value and transformation if needed
#define STATE_GET_XXX(_r) {
 if (status bit XXX is not set) {
  transform_XXX();
  set bit XXX in status;
 }
 _r = XXX;
}
--> do the same for the other states

// conversion function
// the order the "if _ else if _" is chosen to begin with the less cpu consuming conversions
void transform_XXX() {
 if (status bit YYY is set) {
  compute XXX_of_YYY;
 } else
 if (status bit ZZZ is set) {
  compute XXX_of_ZZZ;
 } else
 { // default, no data available
  XXX = ZERO ?
  set UNINIT flag somewhere ?
 }
}
--> do the same for the other states

--> maybe a part of this could be generated ?
--> we can use functions instead of macros