00001 #pragma once
00002
00021 #ifndef __DRONEKALMANFILTER_H
00022 #define __DRONEKALMANFILTER_H
00023
00024 #include <TooN/TooN.h>
00025 #include <deque>
00026 #include <iostream>
00027 #include <fstream>
00028 #include <ardrone_autonomy/Navdata.h>
00029 #include <geometry_msgs/Twist.h>
00030 #include <geometry_msgs/TwistStamped.h>
00031 #include <pthread.h>
00032 #include "../HelperFunctions.h"
00033 #include "tum_ardrone/filter_state.h"
00034
00035 class EstimationNode;
00036
00037
00038 class ScaleStruct
00039 {
00040 public:
00041 TooN::Vector<3> ptam;
00042 TooN::Vector<3> imu;
00043 double ptamNorm;
00044 double imuNorm;
00045 double alphaSingleEstimate;
00046 double pp, ii, pi;
00047
00048 inline double computeEstimator(double spp, double sii, double spi, double stdDevPTAM = 0.2, double stdDevIMU = 0.1)
00049 {
00050 double sII = stdDevPTAM * stdDevPTAM * sii;
00051 double sPP = stdDevIMU * stdDevIMU * spp;
00052 double sPI = stdDevIMU * stdDevPTAM * spi;
00053
00054 double tmp = (sII-sPP)*(sII-sPP) + 4*sPI*sPI;
00055 if(tmp <= 0) tmp = 1e-5;
00056 return 0.5*((sII-sPP)+sqrt(tmp)) / (stdDevPTAM * stdDevPTAM * spi);
00057
00058 }
00059
00060 inline ScaleStruct(TooN::Vector<3> ptamDist, TooN::Vector<3> imuDist)
00061 {
00062 ptam = ptamDist;
00063 imu = imuDist;
00064 pp = ptam[0]*ptam[0] + ptam[1]*ptam[1] + ptam[2]*ptam[2];
00065 ii = imu[0]*imu[0] + imu[1]*imu[1] + imu[2]*imu[2];
00066 pi = imu[0]*ptam[0] + imu[1]*ptam[1] + imu[2]*ptam[2];
00067
00068 ptamNorm = sqrt(pp);
00069 imuNorm = sqrt(ii);
00070
00071 alphaSingleEstimate = computeEstimator(pp,ii,pi);
00072 }
00073
00074 inline bool operator < (const ScaleStruct& comp) const
00075 {
00076 return alphaSingleEstimate < comp.alphaSingleEstimate;
00077 }
00078 };
00079
00080
00081
00082 class PVFilter
00083 {
00084 public:
00085 TooN::Vector<2> state;
00086 TooN::Matrix<2,2> var;
00087
00088
00089
00090 inline PVFilter(TooN::Vector<2> state, TooN::Matrix<2,2> var)
00091 : state(state), var(var)
00092 {
00093 }
00094
00095 inline PVFilter(double pose, double speed)
00096 : state(TooN::makeVector(pose,speed)), var(TooN::Zeros)
00097 {
00098 }
00099
00100 inline PVFilter(double pose)
00101 : state(TooN::makeVector(pose,0)), var(TooN::Zeros)
00102 {
00103 var(1,1) = 1e10;
00104 }
00105
00106 inline PVFilter()
00107 : state(TooN::makeVector(0,0)), var(TooN::Zeros)
00108 {
00109 var(1,1) = var(0,0) = 1e10;
00110 }
00111
00112
00113 inline void observePose(double obs, double obsVar)
00114 {
00115
00116
00117
00118
00119
00120
00121 TooN::Vector<2> K = var[0] / (obsVar + var(0,0));
00122 state = state + K * (obs - state[0]);
00123 TooN::Matrix<2> tmp = TooN::Identity;
00124 tmp(0,0) -= K[0];
00125 tmp(1,0) -= K[1];
00126 var = tmp * var;
00127
00128 }
00129
00130
00131 inline void observeSpeed(double obs, double obsVar)
00132 {
00133
00134
00135
00136
00137
00138
00139 TooN::Vector<2> K = var[1] / (obsVar + var(1,1));
00140 state = state + K * (obs - state[1]);
00141 TooN::Matrix<2> tmp = TooN::Identity;
00142 tmp(0,1) -= K[0];
00143 tmp(1,1) -= K[1];
00144 var = tmp * var;
00145 }
00146
00147
00148
00149
00150 inline void predict(double ms, double accelerationVar, TooN::Vector<2> controlGains = TooN::makeVector(0,0), double coVarFac = 1, double speedVarFac = 1)
00151 {
00152
00153
00154
00155
00156
00157
00158
00159 ms /= 1000;
00160
00161 TooN::Matrix<2,2> G = TooN::Identity;
00162 G(0,1) = ms;
00163
00164 state = G * state + controlGains;
00165 var = G * var * G.T();
00166 var(0,0) += accelerationVar * 0.25 * ms*ms*ms*ms;
00167 var(1,0) += coVarFac * accelerationVar * 0.5 * ms*ms*ms * 4;
00168 var(0,1) += coVarFac * accelerationVar * 0.5 * ms*ms*ms * 4;
00169 var(1,1) += speedVarFac * accelerationVar * 1 * ms*ms * 4 * 4;
00170 }
00171
00172
00173
00174
00175 inline void predict(double ms, TooN::Vector<3> vars, TooN::Vector<2> controlGains = TooN::makeVector(0,0))
00176 {
00177
00178
00179
00180
00181
00182
00183
00184 ms /= 1000;
00185
00186 TooN::Matrix<2,2> G = TooN::Identity;
00187 G(0,1) = ms;
00188
00189 state = G * state + controlGains;
00190 var = G * var * G.T();
00191 var(0,0) += vars[0];
00192 var(1,0) += vars[2];
00193 var(0,1) += vars[2];
00194 var(1,1) += vars[1];
00195 }
00196 };
00197
00198
00199
00200 class PFilter
00201 {
00202 public:
00203 double state;
00204 double var;
00205
00206 inline PFilter() : state(0), var(1e10) {};
00207 inline PFilter(double initState) : state(initState), var(0) {};
00208
00209 inline void predict(double ms, double speedVar, double controlGains = 0)
00210 {
00211
00212
00213
00214
00215 state += controlGains;
00216 var += speedVar * ms * ms / 1000000;
00217 }
00218
00219 inline void observe(double obs, double obsVar)
00220 {
00221
00222
00223
00224
00225
00226 double w = var / (var + obsVar);
00227 state = (1-w) * state + w * obs;
00228 var = var * obsVar / (var + obsVar);
00229 }
00230 };
00231
00232
00233 class DroneKalmanFilter
00234 {
00235 private:
00236
00237 PVFilter x;
00238 PVFilter y;
00239 PVFilter z;
00240 PFilter roll;
00241 PFilter pitch;
00242 PVFilter yaw;
00243
00244
00245
00246 double x_offset, y_offset, z_offset;
00247 double xy_scale, z_scale;
00248 double scale_from_z;
00249 double scale_from_xy;
00250 double roll_offset, pitch_offset, yaw_offset;
00251 bool offsets_xyz_initialized;
00252 bool scale_xyz_initialized;
00253
00254
00255 double xyz_sum_IMUxIMU;
00256 double xyz_sum_PTAMxPTAM;
00257 double xyz_sum_PTAMxIMU;
00258 double rp_offset_framesContributed;
00259 std::vector<ScaleStruct>* scalePairs;
00260
00261
00262 double last_yaw_IMU;
00263 double last_z_IMU;
00264 long last_yaw_droneTime;
00265 long last_z_droneTime;
00266 long last_z_packageID;
00267
00268
00269 TooN::Vector<3> last_PTAM_pose;
00270
00271
00272 TooN::Vector<3> last_fused_pose;
00273 bool lastPosesValid;
00274
00275
00276
00277 int numGoodIMUObservations;
00278 int numGoodPTAMObservations;
00279
00280
00281 long lastIMU_XYZ_dronetime;
00282 long lastIMU_RPY_dronetime;
00283 long lastIMU_dronetime;
00284 int lastIMU_XYZ_ID;
00285 int lastIMU_RPY_ID;
00286 double lastPredictedRoll;
00287 double lastPredictedPitch;
00288 double initialScaleSet;
00289
00290
00291 void predictInternal(geometry_msgs::Twist activeControlInfo, int timeSpanMicros, bool useControlGains = true);
00292 void observeIMU_XYZ(const ardrone_autonomy::Navdata* nav);
00293 void observeIMU_RPY(const ardrone_autonomy::Navdata* nav);
00294 void observePTAM(TooN::Vector<6> pose);
00295
00296
00297
00298 void sync_xyz(double x_global, double y_global, double z_global);
00299 void sync_rpy(double roll_global, double pitch_global, double yaw_global);
00300
00301
00302 int predictedUpToTotal;
00303 long predictedUpToDroneTime;
00304
00305
00306 double lastdYaw, lastdZ;
00307 double baselineZ_IMU;
00308 double baselineZ_Filter;
00309 double last_z_heightDiff;
00310 double baselineY_IMU;
00311 double baselineY_Filter;
00312 bool baselinesYValid;
00313 int timestampYawBaselineFrom;
00314 double lastVXGain;
00315 double lastVYGain;
00316
00317
00318
00319 EstimationNode* node;
00320 public:
00321 DroneKalmanFilter(EstimationNode* node);
00322 ~DroneKalmanFilter(void);
00323 void release();
00324
00325 static int delayRPY;
00326 static int delayXYZ;
00327 static int delayVideo;
00328 static int delayControl;
00329
00330 static const int base_delayXYZ;
00331 static const int base_delayVideo;
00332 static const int base_delayControl;
00333
00334 std::deque<ardrone_autonomy::Navdata>* navdataQueue;
00335 std::deque<geometry_msgs::TwistStamped>* velQueue;
00336 static pthread_mutex_t filter_CS;
00337
00338
00339 int predictdUpToTimestamp;
00340 int scalePairsIn, scalePairsOut;
00341
00342
00343
00344
00345 void reset();
00346
00347
00348
00349 void clearPTAM();
00350
00351
00352
00353 void predictUpTo(int timestamp, bool consume = true, bool useControlGains = true);
00354
00355 void setPing(unsigned int navPing, unsigned int vidPing);
00356
00357
00358 TooN::Vector<6> getCurrentPose();
00359 tum_ardrone::filter_state getCurrentPoseSpeed();
00360 TooN::Vector<10> getCurrentPoseSpeedAsVec();
00361 TooN::Vector<10> getCurrentPoseSpeedVariances();
00362 TooN::Vector<6> getCurrentPoseVariances();
00363 TooN::Vector<6> getCurrentOffsets();
00364 TooN::Vector<3> getCurrentScales();
00365 TooN::Vector<3> getCurrentScalesForLog();
00366 float getScaleAccuracy();
00367 void setCurrentScales(TooN::Vector<3> scales);
00368
00369
00370 void updateScaleXYZ(TooN::Vector<3> ptamDiff, TooN::Vector<3> imuDiff, TooN::Vector<3> OrgPtamPose);
00371
00372
00373
00374
00375
00376
00377
00378
00379 TooN::Vector<3> transformPTAMObservation(double x,double y,double z);
00380 TooN::Vector<3> transformPTAMObservation(double x,double y,double z, double yaw);
00381 TooN::Vector<6> transformPTAMObservation(TooN::Vector<6> obs);
00382 TooN::Vector<6> backTransformPTAMObservation(TooN::Vector<6> obs);
00383
00384 inline int getNumGoodPTAMObservations() {return numGoodPTAMObservations;}
00385
00386
00387
00388 TooN::Vector<3> scalingFixpoint;
00389 bool useScalingFixpoint;
00390
00391
00392 void flushScalePairs();
00393
00394
00395 bool allSyncLocked;
00396 bool useControl;
00397 bool useNavdata;
00398 bool usePTAM;
00399
00400
00401 float c1;
00402 float c2;
00403 float c3;
00404 float c4;
00405 float c5;
00406 float c6;
00407 float c7;
00408 float c8;
00409
00410
00411
00412 bool handleCommand(std::string s);
00413
00414
00415 void addPTAMObservation(TooN::Vector<6> trans, int time);
00416 void addFakePTAMObservation(int time);
00417 tum_ardrone::filter_state getPoseAt(ros::Time t, bool useControlGains = true);
00418 TooN::Vector<10> getPoseAtAsVec(int timestamp, bool useControlGains = true);
00419
00420 };
00421 #endif