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/LDTravModel.hpp>
00038
00039 #include <boost/numeric/ublas/banded.hpp>
00040 #include <boost/numeric/ublas/matrix_proxy.hpp>
00041
00042 using namespace labust::navigation;
00043
00044 LDTravModel::LDTravModel():
00045 dvlModel(0)
00046 {
00047 this->initModel();
00048 };
00049
00050 LDTravModel::~LDTravModel(){};
00051
00052 void LDTravModel::initModel()
00053 {
00054
00055 x = vector::Zero(stateNum);
00056 xdot = 0;
00057 ydot = 0;
00058
00059 derivativeAW();
00060 R0 = R;
00061 V0 = V;
00062
00063
00064 }
00065
00066 void LDTravModel::calculateXYInovationVariance(const LDTravModel::matrix& P, double& xin,double &yin)
00067 {
00068 xin = sqrt(P(xp,xp)) + sqrt(R0(xp,xp));
00069 yin = sqrt(P(yp,yp)) + sqrt(R0(yp,yp));
00070 }
00071
00072 void LDTravModel::calculateUVInovationVariance(const LDTravModel::matrix& P, double& uin,double &vin)
00073 {
00074 uin = sqrt(P(u,u)) + sqrt(R0(v,v));
00075 vin = sqrt(P(v,v)) + sqrt(R0(v,v));
00076 }
00077
00078 void LDTravModel::step(const input_type& input)
00079 {
00080 x(u) += Ts*(-surge.Beta(x(u))/surge.alpha*x(u) + 1/surge.alpha * input(X));
00081 x(v) += Ts*(-sway.Beta(x(v))/sway.alpha*x(v) + 1/sway.alpha * input(Y));
00082 x(w) += Ts*(-heave.Beta(x(w))/heave.alpha*x(w) + 1/heave.alpha * (input(Z) + x(buoyancy)));
00083 x(r) += Ts*(-yaw.Beta(x(r))/yaw.alpha*x(r) + 1/yaw.alpha * input(N) + 0*x(b));
00084
00085 xdot = x(u)*cos(x(psi)) - x(v)*sin(x(psi)) + x(xc);
00086 ydot = x(u)*sin(x(psi)) + x(v)*cos(x(psi)) + x(yc);
00087 x(xp) += Ts * xdot;
00088 x(yp) += Ts * ydot;
00089
00090
00091 x(zp) -= Ts * x(w);
00092 x(psi) += Ts * x(r);
00093
00094 xk_1 = x;
00095
00096 derivativeAW();
00097 };
00098
00099 void LDTravModel::derivativeAW()
00100 {
00101 A = matrix::Identity(stateNum, stateNum);
00102
00103 A(u,u) = 1-Ts*(surge.beta + 2*surge.betaa*fabs(x(u)))/surge.alpha;
00104 A(v,v) = 1-Ts*(sway.beta + 2*sway.betaa*fabs(x(v)))/sway.alpha;
00105 A(w,w) = 1-Ts*(heave.beta + 2*heave.betaa*fabs(x(w)))/heave.alpha;
00106 A(w,buoyancy) = Ts/heave.alpha;
00107 A(r,r) = 1-Ts*(yaw.beta + 2*yaw.betaa*fabs(x(r)))/yaw.alpha;
00108 A(r,b) = 0*Ts;
00109
00110 A(xp,u) = Ts*cos(x(psi));
00111 A(xp,v) = -Ts*sin(x(psi));
00112 A(xp,psi) = Ts*(-x(u)*sin(x(psi) - x(v)*cos(x(psi))));
00113 A(xp,xc) = Ts;
00114
00115 A(yp,u) = Ts*sin(x(psi));
00116 A(yp,v) = Ts*cos(x(psi));
00117 A(yp,psi) = Ts*(x(u)*cos(x(psi)) - x(v)*sin(x(psi)));
00118 A(yp,yc) = Ts;
00119
00120
00121
00122 A(zp,w) = -Ts;
00123
00124 A(psi,r) = Ts;
00125 }
00126
00127 const LDTravModel::output_type& LDTravModel::update(vector& measurements, vector& newMeas)
00128 {
00129 std::vector<size_t> arrived;
00130 std::vector<double> dataVec;
00131
00132 for (size_t i=0; i<newMeas.size(); ++i)
00133 {
00134 if (newMeas(i))
00135 {
00136 arrived.push_back(i);
00137 dataVec.push_back(measurements(i));
00138 newMeas(i) = 0;
00139 }
00140 }
00141
00142 if (dvlModel != 0) derivativeH();
00143
00144 measurement.resize(arrived.size());
00145 H = matrix::Zero(arrived.size(),stateNum);
00146 y = vector::Zero(arrived.size());
00147 R = matrix::Zero(arrived.size(),arrived.size());
00148 V = matrix::Zero(arrived.size(),arrived.size());
00149
00150 for (size_t i=0; i<arrived.size();++i)
00151 {
00152 measurement(i) = dataVec[i];
00153
00154 if (dvlModel != 0)
00155 {
00156 H.row(i)=Hnl.row(arrived[i]);
00157 y(i) = ynl(arrived[i]);
00158 }
00159 else
00160 {
00161 H(i,arrived[i]) = 1;
00162 y(i) = x(arrived[i]);
00163 }
00164
00165 for (size_t j=0; j<arrived.size(); ++j)
00166 {
00167 R(i,j)=R0(arrived[i],arrived[j]);
00168 V(i,j)=V0(arrived[i],arrived[j]);
00169 }
00170 }
00171
00172
00173
00174
00175
00176 return measurement;
00177 }
00178
00179 void LDTravModel::estimate_y(output_type& y)
00180 {
00181 y=this->y;
00182 }
00183
00184 void LDTravModel::derivativeH()
00185 {
00186 Hnl=matrix::Identity(stateNum,stateNum);
00187 ynl = Hnl*x;
00188
00189 switch (dvlModel)
00190 {
00191 case 1:
00192
00193 ynl(u) = x(u)+x(xc)*cos(x(psi))+x(yc)*sin(x(psi));
00194 ynl(v) = x(v)-x(xc)*sin(x(psi))+x(yc)*cos(x(psi));
00195
00196
00197 Hnl(u,u) = 1;
00198 Hnl(u,xc) = cos(x(psi));
00199 Hnl(u,yc) = sin(x(psi));
00200 Hnl(u,psi) = -x(xc)*sin(x(psi)) + x(yc)*cos(x(psi));
00201
00202 Hnl(v,v) = 1;
00203 Hnl(v,xc) = -sin(x(psi));
00204 Hnl(v,yc) = cos(x(psi));
00205 Hnl(v,psi) = -x(xc)*cos(x(psi)) - x(yc)*sin(x(psi));
00206 break;
00207 case 2:
00208
00209 y(u) = x(u)*cos(x(psi)) - x(v)*sin(x(psi)) + x(xc);
00210 y(v) = x(u)*sin(x(psi)) + x(v)*cos(x(psi)) + x(yc);
00211
00212
00213 Hnl(u,xc) = 1;
00214 Hnl(u,u) = cos(x(psi));
00215 Hnl(u,v) = -sin(x(psi));
00216 Hnl(u,psi) = -x(u)*sin(x(psi)) - x(v)*cos(x(psi));
00217
00218 Hnl(v,yc) = 1;
00219 Hnl(v,u) = sin(x(psi));
00220 Hnl(v,v) = cos(x(psi));
00221 Hnl(v,psi) = x(u)*cos(x(psi)) - x(v)*sin(x(psi));
00222 break;
00223 }
00224 }
00225