00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 #include <labust/navigation/EKF_3D_USBLModel.hpp>
00046 
00047 using namespace labust::navigation;
00048 
00049 #include <vector>
00050 
00051 #include <ros/ros.h>
00052 
00053 EKF_3D_USBLModel::EKF_3D_USBLModel():
00054                 dvlModel(0),
00055                 xdot(0),
00056                 ydot(0){
00057 
00058         this->initModel();
00059 };
00060 
00061 EKF_3D_USBLModel::~EKF_3D_USBLModel(){};
00062 
00063 void EKF_3D_USBLModel::initModel(){
00064 
00065   x = vector::Zero(stateNum);
00066   xdot = 0;
00067   ydot = 0;
00068   
00069   derivativeAW();
00070   R0 = R;
00071   V0 = V;
00072   
00073 }
00074 
00075 void EKF_3D_USBLModel::calculateXYInovationVariance(const EKF_3D_USBLModel::matrix& P, double& xin,double &yin){
00076 
00077         xin = sqrt(P(xp,xp)) + sqrt(R0(xp,xp));
00078         yin = sqrt(P(yp,yp)) + sqrt(R0(yp,yp));
00079 }
00080 
00081 double EKF_3D_USBLModel::calculateAltInovationVariance(const EKF_3D_USBLModel::matrix& P){
00082 
00083         return sqrt(P(altitude,altitude)) + sqrt(R0(altitude,altitude));
00084 }
00085 
00086 void EKF_3D_USBLModel::calculateUVInovationVariance(const EKF_3D_USBLModel::matrix& P, double& uin,double &vin){
00087 
00088         uin = sqrt(P(u,u)) + sqrt(R0(v,v));
00089         vin = sqrt(P(v,v)) + sqrt(R0(v,v));
00090 }
00091 
00092 void EKF_3D_USBLModel::step(const input_type& input){
00093 
00094   x(u) += Ts*(-surge.Beta(x(u))/surge.alpha*x(u) + 1/surge.alpha * input(X));
00095   x(v) += Ts*(-sway.Beta(x(v))/sway.alpha*x(v) + 1/sway.alpha * input(Y));
00096   x(w) += Ts*(-heave.Beta(x(w))/heave.alpha*x(w) + 1/heave.alpha * (input(Z) + x(buoyancy)));
00097   
00098   
00099   x(r) += Ts*(-yaw.Beta(x(r))/yaw.alpha*x(r) + 1/yaw.alpha * input(N) + x(b));
00100 
00101   xdot = x(u)*cos(x(psi)) - x(v)*sin(x(psi)) + x(xc);
00102   ydot = x(u)*sin(x(psi)) + x(v)*cos(x(psi)) + x(yc);
00103   x(xp) += Ts * xdot;
00104   x(yp) += Ts * ydot;
00105   x(zp) += Ts * x(w);
00106   x(altitude) += -Ts * x(w);
00107   
00108   
00109   
00110   
00111   
00112   x(psi) += Ts * x(r);
00113 
00114   xk_1 = x;
00115 
00116   derivativeAW();
00117 }
00118 
00119 void EKF_3D_USBLModel::derivativeAW(){
00120 
00121         A = matrix::Identity(stateNum, stateNum);
00122 
00123         A(u,u) = 1-Ts*(surge.beta + 2*surge.betaa*fabs(x(u)))/surge.alpha;
00124         A(v,v) = 1-Ts*(sway.beta + 2*sway.betaa*fabs(x(v)))/sway.alpha;
00125         A(w,w) = 1-Ts*(heave.beta + 2*heave.betaa*fabs(x(w)))/heave.alpha;
00126         A(w,buoyancy) = Ts/heave.alpha;
00127         
00128         
00129         
00130         
00131         A(r,r) = 1-Ts*(yaw.beta + 2*yaw.betaa*fabs(x(r)))/yaw.alpha;
00132         A(r,b) = Ts;
00133 
00134         A(xp,u) = Ts*cos(x(psi));
00135         A(xp,v) = -Ts*sin(x(psi));
00136         A(xp,psi) = Ts*(-x(u)*sin(x(psi)) - x(v)*cos(x(psi)));
00137         A(xp,xc) = Ts;
00138 
00139         A(yp,u) = Ts*sin(x(psi));
00140         A(yp,v) = Ts*cos(x(psi));
00141         A(yp,psi) = Ts*(x(u)*cos(x(psi)) - x(v)*sin(x(psi)));
00142         A(yp,yc) = Ts;
00143 
00144         A(zp,w) = Ts;
00145         
00146         A(altitude,w) = -Ts;
00147 
00148         
00149         
00150         A(psi,r) = Ts;
00151 }
00152 
00153 const EKF_3D_USBLModel::output_type& EKF_3D_USBLModel::update(vector& measurements, vector& newMeas){
00154 
00155         std::vector<size_t> arrived;
00156         std::vector<double> dataVec;
00157 
00158         for (size_t i=0; i<newMeas.size(); ++i)
00159         {
00160                 if (newMeas(i))
00161                 {
00162                         arrived.push_back(i);
00163                         dataVec.push_back(measurements(i));
00164                         newMeas(i) = 0;
00165                 }
00166         }
00167 
00168         if (dvlModel != 0) derivativeH();
00169 
00170         measurement.resize(arrived.size());
00171         H = matrix::Zero(arrived.size(),stateNum);
00172         y = vector::Zero(arrived.size());
00173         R = matrix::Zero(arrived.size(),arrived.size());
00174         V = matrix::Zero(arrived.size(),arrived.size());
00175 
00176         for (size_t i=0; i<arrived.size();++i)
00177         {
00178                 measurement(i) = dataVec[i];
00179 
00180                 if (dvlModel != 0)
00181                 {
00182                         H.row(i)=Hnl.row(arrived[i]);
00183                         y(i) = ynl(arrived[i]);
00184                 }
00185                 else
00186                 {
00187                         H(i,arrived[i]) = 1;
00188                         y(i) = x(arrived[i]);
00189                 }
00190 
00191                 for (size_t j=0; j<arrived.size(); ++j)
00192                 {
00193                         R(i,j)=R0(arrived[i],arrived[j]);
00194                         V(i,j)=V0(arrived[i],arrived[j]);
00195                 }
00196         }
00197 
00198         
00199 
00200 
00201 
00202 
00203         return measurement;
00204 }
00205 
00206 void EKF_3D_USBLModel::estimate_y(output_type& y){
00207         y=this->y;
00208 }
00209 
00210 void EKF_3D_USBLModel::derivativeH(){
00211 
00212         Hnl = matrix::Zero(measSize,stateNum); 
00213         Hnl.topLeftCorner(stateNum,stateNum) = matrix::Identity(stateNum,stateNum);
00214 
00215         ynl = vector::Zero(measSize);
00216         ynl.head(stateNum) = matrix::Identity(stateNum,stateNum)*x;
00217 
00218         switch (dvlModel){
00219         case 1:
00220                 
00221                 ynl(u) = x(u)+x(xc)*cos(x(psi))+x(yc)*sin(x(psi));
00222                 ynl(v) = x(v)-x(xc)*sin(x(psi))+x(yc)*cos(x(psi));
00223 
00224                 
00225                 Hnl(u,u) = 1;
00226                 Hnl(u,xc) = cos(x(psi));
00227                 Hnl(u,yc) = sin(x(psi));
00228                 Hnl(u,psi) = -x(xc)*sin(x(psi)) + x(yc)*cos(x(psi));
00229 
00230                 Hnl(v,v) = 1;
00231                 Hnl(v,xc) = -sin(x(psi));
00232                 Hnl(v,yc) = cos(x(psi));
00233                 Hnl(v,psi) = -x(xc)*cos(x(psi)) - x(yc)*sin(x(psi));
00234                 break;
00235 
00236         case 2:
00237                 
00238                 y(u) = x(u)*cos(x(psi)) - x(v)*sin(x(psi)) + x(xc);
00239                 y(v) = x(u)*sin(x(psi)) + x(v)*cos(x(psi)) + x(yc);
00240 
00241             
00242                 Hnl(u,xc) = 1;
00243                 Hnl(u,u) = cos(x(psi));
00244                 Hnl(u,v) = -sin(x(psi));
00245                 Hnl(u,psi) = -x(u)*sin(x(psi)) - x(v)*cos(x(psi));
00246 
00247                 Hnl(v,yc) = 1;
00248                 Hnl(v,u) = sin(x(psi));
00249                 Hnl(v,v) = cos(x(psi));
00250                 Hnl(v,psi) = x(u)*cos(x(psi)) - x(v)*sin(x(psi));
00251                 break;
00252         }
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289         double rng  = sqrt(pow((x(xp)-x(xb)),2)+pow((x(yp)-x(yb)),2)+pow((x(zp)-x(zb)),2));
00290         double delta_x = (x(xb)-x(xp));
00291         double delta_y = (x(yb)-x(yp));
00292 
00293         if(rng<0.00001)
00294                 rng = 0.00001;
00295 
00296         if(abs(delta_x)<0.00001)
00297                 delta_x = (delta_x<0)?-0.00001:0.00001;
00298 
00299         if(abs(delta_y)<0.00001)
00300                 delta_y = (delta_y<0)?-0.00001:0.00001;
00301 
00302         ynl(range) = rng;
00303         ynl(bearing) = atan2(delta_y,delta_x) -1*x(psi);
00304         ynl(elevation) = asin((x(zp)-x(zb))/rng);
00305 
00306         Hnl(range, xp)  = -(x(xb)-x(xp))/rng;
00307         Hnl(range, yp)  = -(x(yb)-x(yp))/rng;
00308         Hnl(range, zp)  = -(x(zb)-x(zp))/rng;
00309 
00310         Hnl(range, xb)  = (x(xb)-x(xp))/rng;
00311         Hnl(range, yb)  = (x(yb)-x(yp))/rng;
00312         Hnl(range, zb)  = (x(zb)-x(zp))/rng;
00313 
00314         Hnl(bearing, xp) = delta_y/(delta_x*delta_x+delta_y*delta_y);
00315         Hnl(bearing, yp) = -delta_x/(delta_x*delta_x+delta_y*delta_y);
00316         Hnl(bearing, xb) = -delta_y/(delta_x*delta_x+delta_y*delta_y);
00317         Hnl(bearing, yb) = delta_x/(delta_x*delta_x+delta_y*delta_y);
00318 
00319         Hnl(bearing, psi) = -1;
00320 
00321 
00322 
00323         
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 }
00334