MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Tools/Simulation/Ocean/uMVS/SixDOFAUV.cpp
Go to the documentation of this file.
00001 
00002 //
00003 //   MOOS - Mission Oriented Operating Suite 
00004 //  
00005 //   A suit of Applications and Libraries for Mobile Robotics Research 
00006 //   Copyright (C) 2001-2005 Massachusetts Institute of Technology and 
00007 //   Oxford University. 
00008 //    
00009 //   This software was written by Paul Newman at MIT 2001-2002 and Oxford 
00010 //   University 2003-2005. email: pnewman@robots.ox.ac.uk. 
00011 //      
00012 //   This file is part of a  MOOS Utility Component. 
00013 //        
00014 //   This program is free software; you can redistribute it and/or 
00015 //   modify it under the terms of the GNU General Public License as 
00016 //   published by the Free Software Foundation; either version 2 of the 
00017 //   License, or (at your option) any later version. 
00018 //          
00019 //   This program is distributed in the hope that it will be useful, 
00020 //   but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
00022 //   General Public License for more details. 
00023 //            
00024 //   You should have received a copy of the GNU General Public License 
00025 //   along with this program; if not, write to the Free Software 
00026 //   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
00027 //   02111-1307, USA. 
00028 //
00030 
00031 
00032 // SixDOFAUV.cpp: implementation of the CSixDOFAUV class.
00033 //
00035 #ifdef _WIN32
00036     #pragma warning(disable : 4786)
00037 #endif
00038 
00039 
00040 
00041 #include <math.h>
00042 #include "SixDOFAUV.h"
00043 #include "AcousticTransceiver.h"
00044 using namespace std;
00045 
00046 #ifndef PI
00047     #define PI 3.141592653589793
00048 #endif
00049 
00050 Matrix CrossProduct(Matrix& v1, Matrix& v2)
00051 {
00052     double a1 = v1(1,1);
00053     double a2 = v1(2,1);
00054     double a3 = v1(3,1);
00055     
00056     double b1 = v2(1,1);
00057     double b2 = v2(2,1);
00058     double b3 = v2(3,1);
00059 
00060     Matrix Cross(3,1);
00061     Cross<<(a2* b3 - a3*b2)<<
00062            (a3*b1 - a1*b3)<<
00063            (a1*b2 - a2*b1);
00064 
00065     return Cross;
00066 }
00067 
00068 
00069 
00070 
00072 // Construction/Destruction
00074 
00075 CSixDOFAUV::CSixDOFAUV()
00076 {
00077 
00078 }
00079 
00080 CSixDOFAUV::~CSixDOFAUV()
00081 {
00082 
00083 }
00084 
00085 
00086 bool CSixDOFAUV::Initialise()
00087 {
00088     //if you were to say - Oi! Whats with all these
00089     //out-of-the-blue numbers? I would have to concur....
00090     //later versions added these to a mission file..
00091 
00092     double Mass        = 30.0;
00093     m_dfWeight        = Mass*9.81;
00094     m_dfBuoyancy    = m_dfWeight+0.001;
00095     m_dfHeading         = 0;
00096 
00097     //y points to front of vessel
00098 //    double Ixx  = 10.00;
00099     double Ixx  = 5.00;
00100     double Iyy  = 2.08;
00101     double Izz  = 8.0;
00102     
00103     m_M.ReSize(6,6);
00104     m_M = 0;
00105     m_M(1,1) = Mass;
00106     m_M(2,2) = Mass;
00107     m_M(3,3) = Mass;
00108     m_M(4,4) = Ixx;
00109     m_M(5,5) = Iyy;
00110     m_M(6,6) = Izz;
00111     m_Mi = m_M.i();
00112 
00113 
00114 
00115     m_Pos_e.ReSize(6,1);
00116     m_Pos_e = 0;
00117     
00118     m_Vel_e.ReSize(6,1);
00119     m_Vel_e = 0;
00120 
00121     m_Vel_v.ReSize(6,1);
00122     m_Vel_v = 0;
00123 
00124     //entirely made up numbers.....but they are
00125     //not ridiculous
00126     m_KDrag.ReSize(6,1);
00127     m_KDrag<<100<<60<<100<<200<<10<<70.0;
00128 
00129     m_Drag.ReSize(6,1);
00130 
00131     m_JacVel.ReSize(6,6);
00132     m_JacVel = 0;
00133 
00134 
00135     m_Uf.ReSize(6,1);
00136     m_Uf = 0;
00137 
00138     m_dfThrust = 0;
00139     m_dfRudder = 0;
00140     m_dfElevator =0;
00141 
00142     
00143     m_Hf.ReSize(6,1);
00144     m_COG.ReSize(3,1);
00145     m_COG = 0;
00146 
00147     m_COB.ReSize(3,1);
00148     m_COB<<0.0<<0.0<<0.05;
00149 
00150     m_dfDepth = 0;
00151     m_dfAltitude = 0;
00152 
00153 /*
00154     // Set up acoustic facility
00155     CAcousticNode* pTheAcousticsBit = new CAcousticTransceiver;
00156 
00157     //pass a pointer to the global params block..
00158     pTheAcousticsBit->SetParams(m_pParams);
00159 
00160     //give it a parent
00161     pTheAcousticsBit->SetParent(this);
00162 
00163     //name the acoustic node
00164     pTheAcousticsBit->SetName("Tcvr1");
00165 
00166 
00167     m_AcousticNodes.push_back(pTheAcousticsBit);
00168 */
00169 
00170     return true;
00171 }
00172 
00173 bool CSixDOFAUV::FillVelJacobian()
00174 {
00175     double dfPhi = m_Pos_e(4,1);    double cPhi = cos(dfPhi);         double sPhi=sin(dfPhi);
00176     double dfTheta = m_Pos_e(5,1);  double cTheta = cos(dfTheta);   double sTheta = sin(dfTheta);
00177     double dfPsi = m_Pos_e(6,1);    double cPsi=cos(dfPsi);         double sPsi = sin(dfPsi);
00178 
00179 
00180       m_JacVel                  << cPsi*cTheta  << -sPsi*cPhi+cPsi*sTheta*sPhi  <<    sPsi*sPhi+cPsi*sTheta*cPhi  <<0<<0<<0
00181                                    << sPsi*cTheta  <<  cPsi*cPhi+sPsi*sTheta*sPhi  <<    -cPsi*sPhi+sPsi*sTheta*cPhi <<0<<0<<0
00182                                    <<  -sTheta     <<            cTheta*sPhi         <<                cTheta*cPhi       <<0<<0<<0
00183                   
00184                                 <<0<<0<<0<<     1.0         <<   sPhi*tan(dfTheta)          <<  cPhi*tan(dfTheta)   
00185                                    <<0<<0<<0<<     0           <<      cPhi                    <<       -sPhi          
00186                                    <<0<<0<<0<<     0           <<      sPhi/cTheta             <<      cPhi/cTheta;
00187 
00188 
00189 
00190 
00191 
00192     return true;
00193 
00194 }
00195 
00196 bool CSixDOFAUV::Iterate(double dfTimeNow,double dfDT)
00197 {
00198         
00199     DoModel(dfDT);
00200 
00201 
00202     return true;
00203 }
00204 
00205 
00206 bool CSixDOFAUV::DoModel(double dfDT)
00207 {
00208 
00209     //prepare velocity jacobian
00210     FillVelJacobian();
00211 
00212     Matrix J1=m_JacVel.SubMatrix(1,3,1,3);
00213 
00215     //      calculate body forces....
00217     
00218     Matrix B(3,1); Matrix W(3,1);
00219 
00220     //if we surface we have a discontinuity!
00221     //alternatively you could integrate over submerged volume
00222     //but this is simpler
00223    
00224     int nSignDepth = m_dfDepth>=0.0?1:-1;
00225    
00226 
00227     B<<0.0<<0.0<<m_dfBuoyancy*nSignDepth;
00228     W<<0.0<<0.0<<-m_dfWeight*nSignDepth;
00229 
00230     Matrix Fg = J1.i()*W;
00231     Matrix Fb = J1.i()*B;
00232 
00233     m_Hf = (Fg+Fb) & (CrossProduct(m_COG,Fg)+CrossProduct(m_COB,Fb));
00234 
00235 
00237     //  Calculate thrust vector
00239 
00240     // uncomment this block for stand alone testing
00241     
00242     //        m_dfThrust = 5.0;
00243     //        m_dfElevator = 5.0*PI/180.0;
00244     //        m_dfRudder = 5.0*PI/180.0;
00245     
00246 
00248     //note without proper added mass terms vehicle turns very
00249     //sharply hence scaling terms in the following force vector
00250     //can be extended later.
00252 
00253     /*
00254         Matrix Thrust(3,1);
00255 
00256         Thrust<<m_dfThrust*cos(m_dfElevator)*cos(m_dfRudder)<<
00257                 m_dfThrust*cos(m_dfElevator)*sin(m_dfRudder)<<
00258                 -m_dfThrust*sin(m_dfElevator);
00259 
00260         Matrix Tail(3,1); Tail<<-dfLen<<0.0<<0;
00261 
00262         m_Uf  = Thrust & (CrossProduct(Tail,Thrust));
00263     */
00264 
00265 
00266 
00267     //note Tq_y = 0 we assume no propellor reaction torque
00268     //simple thing to add though Tprop = k* vel ?
00269 
00270     //half length of vehicle (assumed)
00271     double dfLen = 1.0;
00272 
00273     //m_dfRudder = 0;
00274     //m_dfElevator = MOOSDeg2Rad(4);
00275     //m_dfThrust = 40;
00276 
00277     m_Uf   <<  -m_dfThrust*cos(m_dfElevator)*sin(m_dfRudder)<<
00278                 3*m_dfThrust*cos(m_dfElevator)*cos(m_dfRudder)<<
00279                 0.1*m_dfThrust*sin(m_dfElevator)<<
00280                 -/*0.1**/dfLen*m_dfThrust*sin(m_dfElevator)<<
00281                 0.0<< 
00282                 -0.8*m_dfThrust*dfLen*cos(m_dfElevator)*sin(m_dfRudder);
00283         
00284 
00285     //MOOSTrace("Elevator = %f Thrust = %f Rudder = %f\n",m_dfElevator,m_dfThrust,m_dfRudder);
00287     //  calculate drag vector
00289     m_Drag  <<  -(m_KDrag(1,1)*m_Vel_v(1,1)*fabs(m_Vel_v(1,1)))<<
00290                 -(m_KDrag(2,1)*m_Vel_v(2,1)*fabs(m_Vel_v(2,1)))<<
00291                 -(m_KDrag(3,1)*m_Vel_v(3,1)*fabs(m_Vel_v(3,1)))<<
00292                 -(m_KDrag(4,1)*m_Vel_v(4,1)*fabs(m_Vel_v(4,1)))<<
00293                 -(m_KDrag(5,1)*m_Vel_v(5,1)*fabs(m_Vel_v(5,1)))<<
00294                 -(m_KDrag(6,1)*m_Vel_v(6,1)*fabs(m_Vel_v(6,1)));
00295 
00296 
00298     //  utterly trivial integration
00299     //  extend to 4th order RK when required
00301 
00302     // Newton III :
00303     m_Acc_v = m_Mi * (m_Uf+m_Drag+m_Hf);
00304 
00305     // integrate (1)
00306     m_Vel_v += m_Acc_v*dfDT;
00307 
00308     //transform to body coordinates with jacobian
00309     m_Vel_e = m_JacVel*m_Vel_v;
00310 
00311     //integrate (2)
00312     m_Pos_e += m_Vel_e*dfDT;
00313 
00314 
00316     // post integration house keeping
00318 
00319     //Look after angles...
00320     m_Pos_e(6,1) = MOOS_ANGLE_WRAP(m_Pos_e(6,1));
00321 
00322     //figure out our heading -ve around z axis from x axis...
00323     m_dfHeading = HeadingFromYaw(m_Pos_e(6,1));
00324 
00325     //figure out speed..
00326     m_dfSpeed = sqrt(pow(m_Vel_v(1,1),2)+pow(m_Vel_v(2,1),2)+pow(m_Vel_v(3,1),2));
00327 
00329     // Environmental properties...
00330     //  some things are a function of environment and so we need
00331     //  to access it to resolve some properties....
00332     if(m_pEnvironment!=NULL)
00333     {
00334         m_dfDepth = m_pEnvironment->GetDepth(GetZ());
00335         m_dfAltitude = m_pEnvironment->GetAltitude(GetX(),GetY(),GetZ());
00336     }
00337 
00338     return true;
00339 }
00340 
00341 
00342 
00343 
00344 double CSixDOFAUV::GetDepth()
00345 {
00346   
00347     return m_dfDepth;
00348 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines