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 // PilotTask.cpp: implementation of the CPilotTask class. 00032 // 00034 00035 #include "PilotTask.h" 00036 #define SET_POINT_TIMEOUT 20.0 00037 00039 // Construction/Destruction 00041 #define DEFAULT_SPEED_TO_THRUST_FACTOR 30.0 00042 CPilotTask::CPilotTask() 00043 { 00044 m_bInitialised = false; 00045 m_dfSpeedToThrustFactor = DEFAULT_SPEED_TO_THRUST_FACTOR; 00046 } 00047 00048 CPilotTask::~CPilotTask() 00049 { 00050 00051 } 00052 00053 //returns false if we haven't received data in a while..bad news! 00054 bool CPilotTask::RegularMailDelivery(double dfTimeNow) 00055 { 00056 if(m_YawDOF.IsStale(dfTimeNow,GetStartTime())) 00057 { 00058 DebugNotify(MOOSFormat("%s Not Rx'ing NAV_YAW\n",GetName().c_str())); 00059 return false; 00060 } 00061 if(m_DepthDOF.IsStale(dfTimeNow,GetStartTime())) 00062 { 00063 DebugNotify(MOOSFormat("%s Not Rx'ing NAV_DEPTH\n",GetName().c_str())); 00064 return false; 00065 } 00066 if(m_YawSetPoint.IsStale(dfTimeNow,GetStartTime(),SET_POINT_TIMEOUT)) 00067 { 00068 DebugNotify(MOOSFormat("%s Not Rx'ing PILOT_DESIRED_YAW for more than %f s\n",GetName().c_str(),SET_POINT_TIMEOUT)); 00069 return false; 00070 } 00071 if(m_SpeedSetPoint.IsStale(dfTimeNow,GetStartTime(),SET_POINT_TIMEOUT)) 00072 { 00073 DebugNotify(MOOSFormat("%s Not Rx'ing PILOT_DESIRED_SPEED for more than %f s\n",GetName().c_str(),SET_POINT_TIMEOUT)); 00074 return false; 00075 } 00076 if(m_DepthSetPoint.IsStale(dfTimeNow,GetStartTime(),SET_POINT_TIMEOUT)) 00077 { 00078 DebugNotify(MOOSFormat("%s Not Rx'ing PILOT_DESIRED_DEPTH for more than %f s\n",GetName().c_str(),SET_POINT_TIMEOUT)); 00079 return false; 00080 } 00081 00082 00083 00084 return true; 00085 00086 } 00087 00088 bool CPilotTask::GetNotifications(MOOSMSG_LIST & List) 00089 { 00090 if(m_bActive) 00091 { 00092 } 00093 00094 return CMOOSBehaviour::GetNotifications(List); 00095 } 00096 00097 00098 bool CPilotTask::Run(CPathAction &DesiredAction) 00099 { 00100 00101 if(!m_bInitialised) 00102 { 00103 Initialise(); 00104 } 00105 00106 if(m_YawDOF.IsValid()) 00107 { 00108 00109 double dfError = MOOS_ANGLE_WRAP(m_YawDOF.GetError()); 00110 00111 double dfCmd= 0; 00112 00113 00114 // 1 RUDDER CONTROL 00115 //this is for loggin purposes only 00116 m_YawPID.SetGoal(m_YawDOF.GetDesired()); 00117 00118 if(m_YawPID.Run(dfError,m_YawDOF.GetErrorTime(),dfCmd)) 00119 { 00120 00121 //OK we need to change something 00122 DesiredAction.Set( ACTUATOR_RUDDER, 00123 -(dfCmd), 00124 m_nPriority, 00125 m_sName.c_str()); 00126 00127 //MOOSTrace("just wrote rudder = %f\n",dfCmd); 00128 00129 } 00130 00131 //2 THRUST CONTROL 00132 if(m_SpeedSetPoint.IsValid()) 00133 { 00134 //OK we need to change something 00135 DesiredAction.Set( ACTUATOR_THRUST, 00136 m_SpeedSetPoint.GetCurrent(), 00137 m_nPriority, 00138 m_sName.c_str()); 00139 00140 //MOOSTrace("just wrote thrust = %f\n",m_ThrustSetPoint.GetCurrent()); 00141 00142 } 00143 00144 //3 ELEVATOR CONTROL 00145 if(m_DepthDOF.IsValid() && m_PitchDOF.IsValid()) 00146 { 00147 double dfError = m_DepthDOF.GetError(); 00148 00149 double dfCmd= 0; 00150 00151 //this is for logging purposes only 00152 m_ZPID.SetGoal(m_DepthDOF.GetDesired()); 00153 00154 00155 if(m_ZPID.Run(dfError, 00156 m_DepthDOF.GetErrorTime(), 00157 dfCmd,m_PitchDOF.GetCurrent(), 00158 m_PitchDOF.GetErrorTime())) 00159 { 00160 //OK we need to change something 00161 DesiredAction.Set( ACTUATOR_ELEVATOR, 00162 dfCmd, 00163 m_nPriority, 00164 m_sName.c_str()); 00165 00166 //MOOSTrace("just wrote elevator = %f\n",dfCmd); 00167 00168 } 00169 } 00170 00171 } 00172 return true; 00173 } 00174 00175 bool CPilotTask::OnNewMail(MOOSMSG_LIST &NewMail) 00176 { 00177 CMOOSMsg Msg; 00178 00179 //get yaw 00180 if(PeekMail(NewMail,"NAV_YAW",Msg)) 00181 { 00182 if(!Msg.IsSkewed(GetTimeNow())) 00183 { 00184 m_YawDOF.SetCurrent(Msg.GetDouble(),Msg.m_dfTime); 00185 } 00186 } 00187 00188 //depth 00189 if(PeekMail(NewMail,"NAV_DEPTH",Msg)) 00190 { 00191 if(!Msg.IsSkewed(GetTimeNow())) 00192 { 00193 m_DepthDOF.SetCurrent(Msg.GetDouble(),Msg.m_dfTime); 00194 } 00195 } 00196 00197 //pitch 00198 if(PeekMail(NewMail,"NAV_PITCH",Msg)) 00199 { 00200 if(!Msg.IsSkewed(GetTimeNow())) 00201 { 00202 m_PitchDOF.SetCurrent(Msg.GetDouble(),Msg.m_dfTime); 00203 } 00204 } 00205 00206 if(PeekMail(NewMail,"PILOT_DESIRED_YAW",Msg)) 00207 { 00208 if(!Msg.IsSkewed(GetTimeNow())) 00209 { 00210 if(MOOSStrCmp(Msg.GetSource(),m_sYawSetPointSourceProcess)) 00211 { 00212 m_YawDOF.SetDesired(Msg.GetDouble()); 00213 m_YawSetPoint.SetCurrent(Msg.GetDouble(),Msg.GetTime()); 00214 } 00215 else 00216 { 00217 static double dfT =MOOSTime(); 00218 if(MOOSTime()-dfT>2.0) 00219 { 00220 DebugNotify(MOOSFormat("Process %s : no Pilot task permission",Msg.GetSource().c_str())); 00221 dfT = MOOSTime(); 00222 } 00223 } 00224 } 00225 } 00226 00227 if(PeekMail(NewMail,"PILOT_DESIRED_DEPTH",Msg)) 00228 { 00229 if(!Msg.IsSkewed(GetTimeNow())) 00230 { 00231 if(MOOSStrCmp(Msg.GetSource(),m_sDepthSetPointSourceProcess)) 00232 { 00233 m_DepthDOF.SetDesired(Msg.GetDouble()); 00234 m_DepthSetPoint.SetCurrent(Msg.GetDouble(),Msg.GetTime()); 00235 } 00236 else 00237 { 00238 static double dfT =MOOSTime(); 00239 if(MOOSTime()-dfT>2.0) 00240 { 00241 DebugNotify(MOOSFormat("Process %s : no Pilot task permission",Msg.GetSource().c_str())); 00242 dfT = MOOSTime(); 00243 } 00244 } 00245 } 00246 } 00247 00248 if(PeekMail(NewMail,"PILOT_DESIRED_SPEED",Msg)) 00249 { 00250 if(!Msg.IsSkewed(GetTimeNow())) 00251 { 00252 if(MOOSStrCmp(Msg.GetSource(),m_sSpeedSetPointSourceProcess)) 00253 { 00254 double dfT = MOOSClamp<double>(m_dfSpeedToThrustFactor*Msg.GetDouble(),0,100); 00255 m_SpeedSetPoint.SetCurrent(dfT,Msg.GetTime()); 00256 // MOOSTrace("Just Set thrust SP to %f\n",Msg.GetDouble()); 00257 } 00258 else 00259 { 00260 static double dfT =MOOSTime(); 00261 if(MOOSTime()-dfT>2.0) 00262 { 00263 00264 DebugNotify(MOOSFormat("Process %s : no Pilot task permission",Msg.GetSource().c_str())); 00265 dfT = MOOSTime(); 00266 } 00267 } 00268 } 00269 } 00270 00271 //always call base class version 00272 CMOOSBehaviour::OnNewMail(NewMail); 00273 00274 return true; 00275 } 00276 00277 bool CPilotTask::GetRegistrations(STRING_LIST &List) 00278 { 00279 00280 List.push_front("NAV_YAW"); 00281 List.push_front("NAV_PITCH"); 00282 List.push_front("NAV_DEPTH"); 00283 List.push_front("PILOT_DESIRED_YAW"); 00284 List.push_front("PILOT_DESIRED_DEPTH"); 00285 List.push_front("PILOT_DESIRED_SPEED"); 00286 00287 //always call base class version 00288 CMOOSBehaviour::GetRegistrations(List); 00289 00290 return true; 00291 } 00292 00293 00294 bool CPilotTask::SetParam(string sParam, string sVal) 00295 { 00296 MOOSToUpper(sParam); 00297 MOOSToUpper(sVal); 00298 00299 00300 if(!CMOOSBehaviour::SetParam(sParam,sVal)) 00301 { 00302 //this is for us... 00303 if(MOOSStrCmp(sParam,"YawControllingProcess")) 00304 { 00305 m_sYawSetPointSourceProcess = sVal; 00306 } 00307 //this is for us... 00308 else if(MOOSStrCmp(sParam,"SpeedControllingProcess")) 00309 { 00310 m_sSpeedSetPointSourceProcess = sVal; 00311 } 00312 //this is for us... 00313 else if(MOOSStrCmp(sParam,"DepthControllingProcess")) 00314 { 00315 m_sDepthSetPointSourceProcess = sVal; 00316 } 00317 else if(MOOSStrCmp(sParam,"SpeedToThrustFactor")) 00318 { 00319 m_dfSpeedToThrustFactor = atof(sVal.c_str()); 00320 } 00321 else 00322 { 00323 //hmmm - it wasn't for us at all: base class didn't understand either 00324 MOOSTrace("Param \"%s\" not understood!\n",sParam.c_str()); 00325 return false; 00326 } 00327 } 00328 00329 return true; 00330 00331 } 00332 00333 bool CPilotTask::Initialise() 00334 { 00335 if(m_sYawSetPointSourceProcess=="") 00336 { 00337 return MOOSFail("%s : \"YawControllingProcess\" not set\n",GetName().c_str()); 00338 } 00339 00340 if(m_sDepthSetPointSourceProcess=="") 00341 { 00342 return MOOSFail("%s : \"DepthControllingProcess\" not set\n",GetName().c_str()); 00343 } 00344 if(m_sSpeedSetPointSourceProcess=="") 00345 { 00346 return MOOSFail("%s : \"SpeedControllingProcess\" not set\n",GetName().c_str()); 00347 } 00348 00349 00350 00351 //set a pitch driven depth controller 00352 m_ZPID.SetAsDepthController(true); 00353 00354 00355 m_bInitialised = true; 00356 return true; 00357 }