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 // GoToWayPoint.cpp: implementation of the CGoToWayPoint class. 00032 // 00034 #ifdef _WIN32 00035 #pragma warning(disable : 4786) 00036 #endif 00037 00038 #include "MOOSTaskDefaults.h" 00039 #include "GoToWayPoint.h" 00040 #include "math.h" 00041 #include <iostream> 00042 using namespace std; 00044 // Construction/Destruction 00046 00047 00048 00049 00050 CGoToWayPoint::CGoToWayPoint() 00051 { 00052 m_nPriority = 3; 00053 00054 m_bInitialised = false; 00055 00056 m_dfVicinityRadius = 0; 00057 00058 m_bPositionSet = true; 00059 00060 m_bThrustSet = false; 00061 00062 m_dfThrust = 0; 00063 } 00064 00065 CGoToWayPoint::~CGoToWayPoint() 00066 { 00067 00068 } 00069 00070 bool CGoToWayPoint::OnNewMail(MOOSMSG_LIST &NewMail) 00071 { 00072 CMOOSMsg Msg; 00073 if(PeekMail(NewMail,"NAV_X",Msg)) 00074 { 00075 00076 if(!Msg.IsSkewed(GetTimeNow())) 00077 { 00078 m_XDOF.SetCurrent(Msg.m_dfVal,Msg.m_dfTime); 00079 } 00080 } 00081 if(PeekMail(NewMail,"NAV_Y",Msg)) 00082 { 00083 if(!Msg.IsSkewed(GetTimeNow())) 00084 { 00085 m_YDOF.SetCurrent(Msg.m_dfVal,Msg.m_dfTime); 00086 } 00087 } 00088 00089 if(PeekMail(NewMail,"NAV_YAW",Msg)) 00090 { 00091 if(!Msg.IsSkewed(GetTimeNow())) 00092 { 00093 00094 double dfVal = Msg.m_dfVal; 00095 00096 if(dfVal>PI) 00097 { 00098 dfVal-=2*PI; 00099 } 00100 m_YawDOF.SetCurrent(dfVal,Msg.m_dfTime); 00101 } 00102 00103 } 00104 00105 //always call base class version 00106 CMOOSBehaviour::OnNewMail(NewMail); 00107 00108 return true; 00109 } 00110 00111 bool CGoToWayPoint::GetRegistrations(STRING_LIST &List) 00112 { 00113 List.push_front("NAV_X"); 00114 List.push_front("NAV_Y"); 00115 List.push_front("NAV_YAW"); 00116 00117 //always call base class version 00118 return CMOOSBehaviour::GetRegistrations(List); 00119 00120 } 00121 00122 00123 00124 00125 //returns false if we haven't received data in a while..bad news! 00126 bool CGoToWayPoint::RegularMailDelivery(double dfTimeNow) 00127 { 00128 if(m_YawDOF.IsStale(dfTimeNow,GetStartTime())) 00129 return false; 00130 00131 if(m_XDOF.IsStale(dfTimeNow,GetStartTime())) 00132 return false; 00133 00134 if(m_YDOF.IsStale(dfTimeNow,GetStartTime())) 00135 return false; 00136 00137 return true; 00138 } 00139 00140 00141 00142 bool CGoToWayPoint::Run(CPathAction &DesiredAction) 00143 { 00144 if(!m_bPositionSet) 00145 { 00146 MOOSTrace("Waypoint position not set\n");; 00147 return false; 00148 } 00149 00150 if(!m_bInitialised) 00151 { 00152 Initialise(); 00153 } 00154 00155 if(ShouldRun()) 00156 { 00157 00158 if(ValidData()) 00159 { 00160 00161 double dfDistanceToGo = GetDistanceToGo(); 00162 00163 00164 if(dfDistanceToGo<m_dfVicinityRadius) 00165 { 00166 OnComplete(); 00167 } 00168 else 00169 { 00170 00171 //calculate vector heading angle to goal 00172 double dfDesiredYaw = -atan2(m_XDOF.GetError(),m_YDOF.GetError()); 00173 00174 m_YawDOF.SetDesired(dfDesiredYaw); 00175 00176 double dfError = m_YawDOF.GetError(); 00177 00178 dfError = MOOS_ANGLE_WRAP(dfError); 00179 00180 double dfCmd = 0; 00181 00182 //this is for logging purposes only 00183 m_YawPID.SetGoal(m_YawDOF.GetDesired()); 00184 00185 00186 if(m_YawPID.Run(dfError,m_YawDOF.GetErrorTime(),dfCmd)) 00187 { 00188 //OK we need to change something 00189 00190 //convert to degrees! 00191 DesiredAction.Set( ACTUATOR_RUDDER, 00192 -dfCmd, 00193 m_nPriority, 00194 GetName().c_str()); 00195 00196 00197 //convert to degrees! 00198 if(m_bThrustSet) 00199 { 00200 DesiredAction.Set( ACTUATOR_THRUST, 00201 m_dfThrust, 00202 m_nPriority, 00203 GetName().c_str()); 00204 } 00205 00206 00207 } 00208 } 00209 } 00210 } 00211 return true; 00212 } 00213 00214 bool CGoToWayPoint::Initialise() 00215 { 00216 00217 m_YawDOF.SetDesired(0); 00218 m_YawDOF.SetTolerance(0.00); 00219 00220 m_bInitialised = true; 00221 00222 return m_bInitialised; 00223 } 00224 00225 bool CGoToWayPoint::ValidData() 00226 { 00227 return m_XDOF.IsValid() && 00228 m_YDOF.IsValid() && 00229 m_YawDOF.IsValid(); 00230 } 00231 00232 00233 00234 bool CGoToWayPoint::SetParam(string sParam, string sVal) 00235 { 00236 MOOSToUpper(sParam); 00237 MOOSToUpper(sVal); 00238 00239 00240 if(!CMOOSBehaviour::SetParam(sParam,sVal)) 00241 { 00242 //this is for us... 00243 if(sParam=="RADIUS") 00244 { 00245 m_dfVicinityRadius=atof(sVal.c_str()); 00246 } 00247 else if(sParam=="THRUST") 00248 { 00249 m_dfThrust=atof(sVal.c_str()); 00250 m_bThrustSet = true; 00251 } 00252 else if(sParam=="LOCATION") 00253 { 00254 //useful for later... 00255 m_sLocation = sVal; 00256 00257 string sTmpX = MOOSChomp(sVal,","); 00258 string sTmpY = MOOSChomp(sVal,","); 00259 string sTmpZ = MOOSChomp(sVal,","); 00260 00261 if(sTmpX.empty()||sTmpY.empty()) 00262 { 00263 MOOSTrace("error in parsing waypoint location from %s\n",m_sLocation.c_str()); 00264 return false; 00265 } 00266 00267 double dfX = atof(sTmpX.c_str()); 00268 m_XDOF.SetDesired(dfX); 00269 00270 double dfY = atof(sTmpY.c_str()); 00271 m_YDOF.SetDesired(dfY); 00272 00273 } 00274 else 00275 { 00276 //hmmm - it wasn't for us at all: base class didn't understand either 00277 MOOSTrace("Param \"%s\" not understood!\n",sParam.c_str()); 00278 return false; 00279 } 00280 } 00281 00282 return true; 00283 } 00284 00285 double CGoToWayPoint::GetDistanceToGo() 00286 { 00287 return sqrt(pow(m_YDOF.GetError(),2)+pow(m_XDOF.GetError(),2)); 00288 }