MOOS 0.2375
|
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