LDTravModelExtended.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2010, LABUST, UNIZG-FER
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the LABUST nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *
00034 *  Created on: Feb 25, 2013
00035 *  Author: Dula Nad
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   //std::cout<<"Init model."<<std::endl;
00059   x = vector::Zero(stateNum);
00060   xdot = 0;
00061   ydot = 0;
00062   //Setup the transition matrix
00063   derivativeAW();
00064   R0 = R;
00065   V0 = V;
00066 
00067   //std::cout<<"R:"<<R<<"\n"<<V<<std::endl;
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   //x(p) += Ts*(-roll.Beta(x(p))/roll.alpha*x(p) + 1/roll.alpha * (input(Kroll) + x(roll_restore)));
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   //if (fabs(x(v)) < 0.15) use_sc=0;
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   //\todo This is not actually true since angles depend on each other
00115   //\todo Also x,y are dependent on the whole rotation matrix.
00116   //\todo We make a simplification here for testing with small angles ~10°
00117   //x(phi) += Ts * x(p);
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         //A(p,p) = 1-Ts*(roll.beta + 2*roll.betaa*fabs(x(p)))/roll.alpha;
00135         //A(p,roll_restore) = Ts/roll.alpha;
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         //A(r,b) = Ts;
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 //      //\todo If you don't want the altitude to contribute comment this out.
00154         A(altitude,w) = -Ts;
00155 
00156 //      A(phi,p) = Ts;
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                 //Correct the nonlinear part
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                 //Correct for the nonlinear parts
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                 //Correct the nonlinear part
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                 //Correct for the nonlinear parts
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 


labust_navigation
Author(s): Gyula Nagy
autogenerated on Fri Aug 28 2015 11:23:33