MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/NavigationAndControl/MOOSTaskLib/DiveTask.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 and others
00010 //   at MIT 2001-2002 and Oxford University 2003-2005.
00011 //   email: pnewman@robots.ox.ac.uk. 
00012 //      
00013 //   This file is part of a  MOOS Basic (Common) Application. 
00014 //        
00015 //   This program is free software; you can redistribute it and/or 
00016 //   modify it under the terms of the GNU General Public License as 
00017 //   published by the Free Software Foundation; either version 2 of the 
00018 //   License, or (at your option) any later version. 
00019 //          
00020 //   This program is distributed in the hope that it will be useful, 
00021 //   but WITHOUT ANY WARRANTY; without even the implied warranty of 
00022 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
00023 //   General Public License for more details. 
00024 //            
00025 //   You should have received a copy of the GNU General Public License 
00026 //   along with this program; if not, write to the Free Software 
00027 //   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
00028 //   02111-1307, USA. 
00029 //
00031 // DiveTask.cpp: implementation of the CDiveTask class.
00032 //
00034 #ifdef _WIN32
00035     #pragma warning(disable : 4786)
00036 #endif
00037 
00038 #include "MOOSTaskDefaults.h"
00039 
00040 #include "DiveTask.h"
00041 
00042 
00043 #define CHUCK_DIVE_MAX 3.0
00044 
00046 // Construction/Destruction
00048 
00049 CDiveTask::CDiveTask()
00050 {
00051     m_bReverseDive = false;
00052     m_bChuckDive = false;
00053     m_bInitialised = false;
00054     m_ZPID.SetReversing(m_bReverseDive);
00055     m_dfTimeOut = 60;
00056 
00057     m_Elevator.SetCurrent(2,MOOSTime());
00058     m_Rudder.SetCurrent(0,MOOSTime());
00059     m_Thrust.SetCurrent(20,MOOSTime());
00060     m_DepthDOF.SetDesired(CHUCK_DIVE_MAX);
00061 }
00062 
00063 CDiveTask::~CDiveTask()
00064 {
00065 
00066 }
00067 
00068 
00069 bool CDiveTask::SetParam(string sParam, string sVal)
00070 {
00071 
00072     MOOSToUpper(sParam);
00073     MOOSToUpper(sVal);
00074 
00075 
00076     if(!CMOOSBehaviour::SetParam(sParam,sVal))
00077     {
00078         //this is for us...
00079         if(MOOSStrCmp(sParam,"RUDDER"))
00080         {
00081             m_Rudder.SetCurrent(atof(sVal.c_str()),MOOSTime());
00082         }
00083         
00084         //this is for us...
00085         else if(MOOSStrCmp(sParam,"ELEVATOR"))
00086         {
00087             m_Elevator.SetCurrent(atof(sVal.c_str()),MOOSTime());
00088         }
00089 
00090         
00091         //this is for us...
00092         else if(MOOSStrCmp(sParam,"DEPTH"))
00093         {
00094             m_DepthDOF.SetDesired(atof(sVal.c_str()));
00095         }
00096 
00097 
00098         else if(MOOSStrCmp(sParam,"THRUST"))
00099         {
00100             m_Thrust.SetCurrent(atof(sVal.c_str()),MOOSTime());
00101         }
00102 
00103         else if(MOOSStrCmp(sParam,"MODE"))
00104         {
00105             if(MOOSStrCmp(sVal,"REVERSE"))
00106             {
00107                 m_bReverseDive = true;
00108             }
00109             else if(MOOSStrCmp(sVal,"CHUCK"))
00110             {
00111                 m_bChuckDive = true;
00112                 m_bReverseDive = true;
00113             }
00114         }
00115 
00116         else
00117         {
00118             //hmmm - it wasn't for us at all: base class didn't understand either
00119             MOOSTrace("Param \"%s\" not understood!\n",sParam.c_str());
00120             return false;
00121         }
00122     }
00123 
00124     return true;
00125 
00126 }
00127 
00128 bool CDiveTask::GetNotifications(MOOSMSG_LIST & List)
00129 {
00130     if(m_bActive)
00131     {
00132         CMOOSMsg Msg(MOOS_NOTIFY,
00133          "DESIRED_PITCH",
00134          m_ZPID.GetPitchDesired());
00135 
00136         List.push_back(Msg);
00137     }
00138 
00139     return CMOOSBehaviour::GetNotifications(List);
00140 }
00141 
00142 
00143 
00144 //returns false if we haven't received data in a while..bad news!
00145 bool CDiveTask::RegularMailDelivery(double dfTimeNow)
00146 {
00147     return !(
00148         m_DepthDOF.IsStale(dfTimeNow,GetStartTime()) ||
00149         m_PitchDOF.IsStale(dfTimeNow,GetStartTime())
00150         );
00151 }
00152 
00153 
00154 
00155 bool CDiveTask::Initialise()
00156 {
00157 
00158     //set a pitch driven depth controller
00159     m_ZPID.SetAsDepthController(true);
00160     
00161     m_bInitialised = true;
00162 
00163     return true;
00164 }
00165 
00166 bool CDiveTask::Run(CPathAction &DesiredAction)
00167 {
00168 
00169     if(!m_bInitialised)
00170     {
00171         Initialise();
00172     }
00173     
00174     if(!m_DepthDOF.IsValid() || !m_PitchDOF.IsValid())
00175     {
00176         return false;
00177     }
00178     double dfCmd= 0;
00179 
00180     if(m_bChuckDive)
00181     {
00182         //an open loop dive
00183         if(m_DepthDOF.GetCurrent()>CHUCK_DIVE_MAX)
00184         {
00185             Stop("Chuck Dive Went Too Deep");
00186             return true;
00187         }
00188 
00189 
00190         if(m_DepthDOF.GetError()>0 && MOOSTime()-m_dfStartTime<m_dfTimeOut*0.7)
00191         {
00192             //we haven't reached our depth yet and still have more than
00193             //30% of dive time left..
00194             dfCmd = m_Elevator.GetCurrent();
00195         }
00196         else
00197         {
00198             //we are in levelling stage..
00199 
00200             //look for roughly horizontal (nose down) pose
00201             if(m_PitchDOF.GetCurrent()<0)
00202             {
00203                 Stop("Chuck Dive Complete");        
00204                 return true;
00205             }
00206 
00207             dfCmd = -m_Elevator.GetCurrent();
00208 
00209         }
00210     }
00211     else
00212     {
00213         //use PID controler to figure stuff out    
00214         double dfError = m_DepthDOF.GetError();
00215         
00216         if(dfError<0)
00217         {
00218             //we have reached our desired depth..
00219             //break...
00220             Stop("Dive Complete");
00221             return true;
00222         }
00223 
00224     
00225         if(!m_ZPID.Run(    dfError,
00226                             m_DepthDOF.GetErrorTime(),
00227                             dfCmd,
00228                             m_PitchDOF.GetCurrent(),
00229                             m_PitchDOF.GetErrorTime()))
00230         {
00231             return false;
00232         }
00233     }
00234     
00235     double dfSign = m_bReverseDive ? -1 : 1;
00236 
00237 
00238     //OK we need to change something
00239     DesiredAction.Set(  ACTUATOR_THRUST,
00240                         dfSign*m_Thrust.GetCurrent(),
00241                         m_nPriority,
00242                         "Dive Depth");
00243 
00244     DesiredAction.Set(  ACTUATOR_RUDDER,
00245                         m_Rudder.GetCurrent(),
00246                         m_nPriority,
00247                         "Dive Depth");
00248 
00249     DesiredAction.Set(  ACTUATOR_ELEVATOR,
00250                         dfCmd,
00251                         m_nPriority,
00252                         "Dive Depth");
00253     
00254     return true;
00255 }
00256 
00257 bool CDiveTask::OnNewMail(MOOSMSG_LIST &NewMail)
00258 {
00259     CMOOSMsg Msg;
00260     
00261     if(PeekMail(NewMail,"NAV_DEPTH",Msg))
00262     {
00263         if(!Msg.IsSkewed(GetTimeNow()))
00264         {
00265             m_DepthDOF.SetCurrent(Msg.m_dfVal,Msg.m_dfTime);
00266         }
00267     }
00268 
00269     if(PeekMail(NewMail,"NAV_PITCH",Msg))
00270     {
00271         if(!Msg.IsSkewed(GetTimeNow()))
00272         {
00273             m_PitchDOF.SetCurrent(Msg.m_dfVal,Msg.m_dfTime);
00274         }
00275     }
00276 
00277 
00278     //always call base class version
00279     CMOOSBehaviour::OnNewMail(NewMail);
00280 
00281     return true;
00282 }
00283 
00284 bool CDiveTask::GetRegistrations(STRING_LIST &List)
00285 {
00286 
00287     List.push_front("NAV_DEPTH");
00288     List.push_front("NAV_PITCH");
00289 
00290     //always call base class version
00291     CMOOSBehaviour::GetRegistrations(List);
00292 
00293     return true;
00294 }
00295 
00296 
00297 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines