dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gps_airspeed.c
Go to the documentation of this file.
1 
17 /*
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful, but
24  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26  * for more details.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with this program; if not, see <http://www.gnu.org/licenses/>
30  */
31 
32 
33 #include "openpilot.h"
34 #include "physical_constants.h"
35 #include "gps_airspeed.h"
36 #include "gpsvelocity.h"
37 #include "attitudeactual.h"
38 #include "coordinate_conversions.h"
39 
40 
41 // Private constants
42 #define GPS_AIRSPEED_BIAS_KP 0.1f //Needs to be settable in a UAVO
43 #define GPS_AIRSPEED_BIAS_KI 0.1f //Needs to be settable in a UAVO
44 #define SAMPLING_DELAY_MS_GPS 100 //Needs to be settable in a UAVO
45 #define GPS_AIRSPEED_TIME_CONSTANT_MS 500.0f //Needs to be settable in a UAVO
46 
47 // Private types
48 struct GPSGlobals {
49  float RbeCol1_old[3];
50  float gpsVelOld_N;
51  float gpsVelOld_E;
52  float gpsVelOld_D;
53 };
54 
55 // Private variables
56 static struct GPSGlobals *gps;
57 
58 // Private functions
59 
60 /*
61  * Initialize function loads first data sets, and allocates memory for structure.
62  */
64 {
65  //This method saves memory in case we don't use the GPS module.
66  gps=(struct GPSGlobals *)PIOS_malloc(sizeof(struct GPSGlobals));
67  if (gps == NULL)
68  return -1;
69 
70  //GPS airspeed calculation variables
71  GPSVelocityData gpsVelData;
72  GPSVelocityGet(&gpsVelData);
73 
74  gps->gpsVelOld_N=gpsVelData.North;
75  gps->gpsVelOld_E=gpsVelData.East;
76  gps->gpsVelOld_D=gpsVelData.Down;
77 
78  AttitudeActualData attData;
79  AttitudeActualGet(&attData);
80 
81  float Rbe[3][3];
82  float q[4] ={attData.q1, attData.q2, attData.q3, attData.q4};
83 
84  //Calculate rotation matrix
85  Quaternion2R(q, Rbe);
86 
87  gps->RbeCol1_old[0]=Rbe[0][0];
88  gps->RbeCol1_old[1]=Rbe[0][1];
89  gps->RbeCol1_old[2]=Rbe[0][2];
90 
91  return 0;
92 }
93 
94 /*
95  * Calculate airspeed as a function of GPS groundspeed and vehicle attitude.
96  * From "IMU Wind Estimation (Theory)", by William Premerlani.
97  * The idea is that V_gps=V_air+V_wind. If we assume wind constant, =>
98  * V_gps_2-V_gps_1 = (V_air_2+V_wind_2) -(V_air_1+V_wind_1) = V_air_2 - V_air_1.
99  * If we assume airspeed constant, => V_gps_2-V_gps_1 = |V|*(f_2 - f1),
100  * where "f" is the fuselage vector in earth coordinates.
101  * We then solve for |V| = |V_gps_2-V_gps_1|/ |f_2 - f1|.
102  */
103 void gps_airspeedGet(float *v_air_GPS)
104 {
105  float Rbe[3][3];
106 
107  { //Scoping to save memory. We really just need Rbe.
108  AttitudeActualData attData;
109  AttitudeActualGet(&attData);
110 
111  float q[4] ={attData.q1, attData.q2, attData.q3, attData.q4};
112 
113  //Calculate rotation matrix
114  Quaternion2R(q, Rbe);
115  }
116 
117  //Calculate the cos(angle) between the two fuselage basis vectors
118  float cosDiff=(Rbe[0][0]*gps->RbeCol1_old[0]) + (Rbe[0][1]*gps->RbeCol1_old[1]) + (Rbe[0][2]*gps->RbeCol1_old[2]);
119 
120  //If there's more than a 5 degree difference between two fuselage measurements, then we have sufficient delta to continue.
121  if (fabsf(cosDiff) < cosf(5.0f*DEG2RAD)) {
122  GPSVelocityData gpsVelData;
123  GPSVelocityGet(&gpsVelData);
124 
125  //Calculate the norm^2 of the difference between the two GPS vectors
126  float normDiffGPS2 = powf(gpsVelData.North-gps->gpsVelOld_N,2.0f) + powf(gpsVelData.East-gps->gpsVelOld_E,2.0f) + powf(gpsVelData.Down-gps->gpsVelOld_D,2.0f);
127 
128  //Calculate the norm^2 of the difference between the two fuselage vectors
129  float normDiffAttitude2=powf(Rbe[0][0]-gps->RbeCol1_old[0],2.0f) + powf(Rbe[0][1]-gps->RbeCol1_old[1],2.0f) + powf(Rbe[0][2]-gps->RbeCol1_old[2],2.0f);
130 
131  //Airspeed magnitude is the ratio between the two difference norms
132  *v_air_GPS = sqrtf(normDiffGPS2/normDiffAttitude2);
133 
134  //Save old variables for next pass
135  gps->gpsVelOld_N=gpsVelData.North;
136  gps->gpsVelOld_E=gpsVelData.East;
137  gps->gpsVelOld_D=gpsVelData.Down;
138 
139  gps->RbeCol1_old[0]=Rbe[0][0];
140  gps->RbeCol1_old[1]=Rbe[0][1];
141  gps->RbeCol1_old[2]=Rbe[0][2];
142  }
143  else {
144 
145  }
146 
147 
148 }
149 
150 
151 
float gpsVelOld_E
Definition: gps_airspeed.c:51
int32_t gps_airspeedInitialize()
Definition: gps_airspeed.c:63
float gpsVelOld_D
Definition: gps_airspeed.c:52
void Quaternion2R(float q[4], float Rbe[3][3])
static struct GPSGlobals * gps
Definition: gps_airspeed.c:56
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
Airspeed module, reads temperature and pressure from BMP085.
float RbeCol1_old[3]
Definition: gps_airspeed.c:49
Header for Coordinate conversions library in coordinate_conversions.c.
tuple f
Definition: px_mkfw.py:81
Includes PiOS and core architecture components.
float gpsVelOld_N
Definition: gps_airspeed.c:50
void gps_airspeedGet(float *v_air_GPS)
Definition: gps_airspeed.c:103