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