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 #include <labust/navigation/LDTravModelExtended.hpp>
00038 
00039 using namespace labust::navigation;
00040 
00041 #include <vector>
00042 #include <ros/ros.h>
00043 
00044 LDTravModel::LDTravModel():
00045                 dvlModel(0),
00046                 xdot(0),
00047                 ydot(0),
00048                 trustf(0),
00049                 kvr(0)
00050 {
00051         this->initModel();
00052 };
00053 
00054 LDTravModel::~LDTravModel(){};
00055 
00056 void LDTravModel::initModel()
00057 {
00058   
00059   x = vector::Zero(stateNum);
00060   xdot = 0;
00061   ydot = 0;
00062   
00063   derivativeAW();
00064   R0 = R;
00065   V0 = V;
00066 
00067   
00068 }
00069 
00070 void LDTravModel::calculateXYInovationVariance(const LDTravModel::matrix& P, double& xin,double &yin)
00071 {
00072         xin = sqrt(P(xp,xp)) + sqrt(R0(xp,xp));
00073         yin = sqrt(P(yp,yp)) + sqrt(R0(yp,yp));
00074 }
00075 
00076 double LDTravModel::calculateAltInovationVariance(const LDTravModel::matrix& P)
00077 {
00078         return sqrt(P(altitude,altitude)) + sqrt(R0(altitude,altitude));
00079 }
00080 
00081 void LDTravModel::calculateUVInovationVariance(const LDTravModel::matrix& P, double& uin,double &vin)
00082 {
00083         uin = sqrt(P(u,u)) + sqrt(R0(v,v));
00084         vin = sqrt(P(v,v)) + sqrt(R0(v,v));
00085 }
00086 
00087 void LDTravModel::step(const input_type& input)
00088 {
00089   x(u) += Ts*(-surge.Beta(x(u))/surge.alpha*x(u) + 1/surge.alpha * input(X));
00090   double vd = -sway.Beta(x(v))/sway.alpha*x(v) + 1/sway.alpha * input(Y);
00091   x(v) += Ts*(-sway.Beta(x(v))/sway.alpha*x(v) + 1/sway.alpha * input(Y));
00092   x(w) += Ts*(-heave.Beta(x(w))/heave.alpha*x(w) + 1/heave.alpha * (input(Z) + x(buoyancy)));
00093   
00094   x(q) += Ts*(-pitch.Beta(x(p))/pitch.alpha*x(q) + 1/pitch.alpha * (input(M) + x(pitch_restore)));
00095   
00096   double use_sc(1);
00097   double acc_port = 0.3;
00098   double acc_starboard = 0.3;
00099   double vec_port = 0.07;
00100   double vec_starboard = 0.07;
00101 
00102   double acc = (x(v)>0)?acc_starboard:acc_port;
00103   double vec = (x(v)>0)?vec_starboard:vec_port;
00104   
00105   
00106 x(r) += Ts*(-yaw.Beta(x(r))/yaw.alpha*x(r) + 1/yaw.alpha * input(N) + 0*x(b) - use_sc*vec*x(v) - acc*use_sc*vd);
00107 
00108   xdot = x(u)*cos(x(psi)) - x(v)*sin(x(psi)) + x(xc);
00109   ydot = x(u)*sin(x(psi)) + x(v)*cos(x(psi)) + x(yc);
00110   x(xp) += Ts * xdot;
00111   x(yp) += Ts * ydot;
00112   x(zp) += Ts * x(w);
00113   x(altitude) += -Ts * x(w);
00114   
00115   
00116   
00117   
00118   x(theta) += Ts * x(q);
00119   x(psi) += Ts * x(r);
00120 
00121   xk_1 = x;
00122 
00123   derivativeAW();
00124 };
00125 
00126 void LDTravModel::derivativeAW()
00127 {
00128         A = matrix::Identity(stateNum, stateNum);
00129 
00130         A(u,u) = 1-Ts*(surge.beta + 2*surge.betaa*fabs(x(u)))/surge.alpha;
00131         A(v,v) = 1-Ts*(sway.beta + 2*sway.betaa*fabs(x(v)))/sway.alpha;
00132         A(w,w) = 1-Ts*(heave.beta + 2*heave.betaa*fabs(x(w)))/heave.alpha;
00133         A(w,buoyancy) = Ts/heave.alpha;
00134         
00135         
00136         A(q,q) = 1-Ts*(pitch.beta + 2*pitch.betaa*fabs(x(q)))/pitch.alpha;
00137         A(q,pitch_restore) = Ts/pitch.alpha;
00138         A(r,r) = 1-Ts*(yaw.beta + 2*yaw.betaa*fabs(x(r)))/yaw.alpha;
00139         A(r,v) = Ts*kvr;
00140         
00141 
00142         A(xp,u) = Ts*cos(x(psi));
00143         A(xp,v) = -Ts*sin(x(psi));
00144         A(xp,psi) = Ts*(-x(u)*sin(x(psi)) - x(v)*cos(x(psi)));
00145         A(xp,xc) = Ts;
00146 
00147         A(yp,u) = Ts*sin(x(psi));
00148         A(yp,v) = Ts*cos(x(psi));
00149         A(yp,psi) = Ts*(x(u)*cos(x(psi)) - x(v)*sin(x(psi)));
00150         A(yp,yc) = Ts;
00151 
00152         A(zp,w) = Ts;
00153 
00154         A(altitude,w) = -Ts;
00155 
00156 
00157         A(theta,q) = Ts;
00158         A(psi,r) = Ts;
00159 }
00160 
00161 const LDTravModel::output_type& LDTravModel::update(vector& measurements, vector& newMeas)
00162 {
00163         std::vector<size_t> arrived;
00164         std::vector<double> dataVec;
00165 
00166         static double r0u=R0(u,u);
00167         static double r0xc=R0(xc,xc);
00168 
00169         for (size_t i=0; i<newMeas.size(); ++i)
00170         {
00171                 if (newMeas(i))
00172                 {
00173                         ROS_INFO("New meas: %d", i);
00174                         if (i == u)
00175                         {
00176                                 ROS_INFO("Trust factor:%f",cosh(trustf*x(r)));
00177                                 R0(u,u) = cosh(trustf*x(r))*r0u;
00178                                 R0(v,v) = cosh(trustf*x(r))*r0u;
00179                                 R0(xc,xc) = cosh(trustf*x(r))*r0xc;
00180                                 R0(yc,yc) = cosh(trustf*x(r))*r0xc;
00181                         }
00182                         arrived.push_back(i);
00183                         dataVec.push_back(measurements(i));
00184                         newMeas(i) = 0;
00185                 }
00186         }
00187 
00188         if (dvlModel != 0) derivativeH();
00189 
00190         measurement.resize(arrived.size());
00191         H = matrix::Zero(arrived.size(),stateNum);
00192         y = vector::Zero(arrived.size());
00193         R = matrix::Zero(arrived.size(),arrived.size());
00194         V = matrix::Zero(arrived.size(),arrived.size());
00195 
00196         for (size_t i=0; i<arrived.size();++i)
00197         {
00198                 measurement(i) = dataVec[i];
00199 
00200                 if (dvlModel != 0)
00201                 {
00202                         H.row(i)=Hnl.row(arrived[i]);
00203                         y(i) = ynl(arrived[i]);
00204                 }
00205                 else
00206                 {
00207                         H(i,arrived[i]) = 1;
00208                         y(i) = x(arrived[i]);
00209                 }
00210 
00211                 for (size_t j=0; j<arrived.size(); ++j)
00212                 {
00213                         R(i,j)=R0(arrived[i],arrived[j]);
00214                         V(i,j)=V0(arrived[i],arrived[j]);
00215                 }
00216         }
00217 
00218         return measurement;
00219 }
00220 
00221 void LDTravModel::estimate_y(output_type& y)
00222 {
00223   y=this->y;
00224 }
00225 
00226 void LDTravModel::derivativeH()
00227 {
00228         Hnl=matrix::Identity(stateNum,stateNum);
00229         ynl = Hnl*x;
00230 
00231         switch (dvlModel)
00232         {
00233         case 1:
00234                 
00235                 ynl(u) = x(u)+x(xc)*cos(x(psi))+x(yc)*sin(x(psi));
00236                 ynl(v) = x(v)-x(xc)*sin(x(psi))+x(yc)*cos(x(psi));
00237 
00238                 
00239                 Hnl(u,u) = 1;
00240                 Hnl(u,xc) = cos(x(psi));
00241                 Hnl(u,yc) = sin(x(psi));
00242                 Hnl(u,psi) = -x(xc)*sin(x(psi)) + x(yc)*cos(x(psi));
00243 
00244                 Hnl(v,v) = 1;
00245                 Hnl(v,xc) = -sin(x(psi));
00246                 Hnl(v,yc) = cos(x(psi));
00247                 Hnl(v,psi) = -x(xc)*cos(x(psi)) - x(yc)*sin(x(psi));
00248                 break;
00249         case 2:
00250                 
00251                 y(u) = x(u)*cos(x(psi)) - x(v)*sin(x(psi)) + x(xc);
00252                 y(v) = x(u)*sin(x(psi)) + x(v)*cos(x(psi)) + x(yc);
00253 
00254                 
00255                 Hnl(u,xc) = 1;
00256                 Hnl(u,u) = cos(x(psi));
00257                 Hnl(u,v) = -sin(x(psi));
00258                 Hnl(u,psi) = -x(u)*sin(x(psi)) - x(v)*cos(x(psi));
00259 
00260                 Hnl(v,yc) = 1;
00261                 Hnl(v,u) = sin(x(psi));
00262                 Hnl(v,v) = cos(x(psi));
00263                 Hnl(v,psi) = x(u)*cos(x(psi)) - x(v)*sin(x(psi));
00264                 break;
00265         }
00266 }
00267