MOOS 0.2375
|
00001 /* 00002 * VehicleFrameWayPointTask.cpp 00003 * MOOS 00004 * 00005 * Created by pnewman on 27/03/2008. 00006 * Copyright 2008 __MyCompanyName__. All rights reserved. 00007 * 00008 */ 00009 00010 #include "VehicleFrameWayPointTask.h" 00011 00012 #define DEFAULT_VICINITY_RADIUS 0.1 00013 #define POSE_HISTORY_SIZE 10.0 00014 00015 00016 /* 00017 TaskConfiguration: 00018 00019 PoseSource - Name of message containing pose data (which should be of form "Pose = [3x1]{x,y,a},time = 12.5") 00020 Radius - precision of waypoint homing 00021 WayPointSource - Nmae of Message which contains waypoint data (which should be of form "Pose = [3x1]{x,y,a},time = 12.5" where Pose in in vehicle frame at time=XYZ) 00022 ThrustSource = Name of Message which contains thrust data 00023 Thrust - if present specifies constant (default thrust) 00024 00025 */ 00026 00027 00028 00029 CVehicleFrameWayPointTask::CVehicleFrameWayPointTask() 00030 { 00031 m_sTargetWayPoint = ""; 00032 m_sPoseSource = ""; 00033 m_sDesiredThrustSource = ""; 00034 m_dfVicinityRadius = DEFAULT_VICINITY_RADIUS; 00035 m_bThrustSet = false; 00036 m_bWayPointSet = false; 00037 00038 } 00039 CVehicleFrameWayPointTask::~CVehicleFrameWayPointTask() 00040 { 00041 00042 } 00043 00044 bool CVehicleFrameWayPointTask::GetRegistrations(STRING_LIST &List) 00045 { 00046 if(!m_sPoseSource.empty()) 00047 { 00048 List.push_back(m_sPoseSource); 00049 } 00050 if(!m_sTargetWayPoint.empty()) 00051 { 00052 List.push_back(m_sTargetWayPoint); 00053 } 00054 return true; 00055 } 00056 00057 bool CVehicleFrameWayPointTask::OnNewMail(MOOSMSG_LIST &NewMail) 00058 { 00059 CMOOSMsg Msg; 00060 00061 //are we being infomred of a new pose? 00062 if(PeekMail(NewMail,m_sPoseSource,Msg)) 00063 { 00064 std::vector<double> P; 00065 int nRows,nCols; 00066 if(MOOSValFromString(P, nRows,nCols,Msg.GetString(),"Pose")) 00067 { 00068 double dfTime; 00069 if(MOOSValFromString(dfTime, Msg.GetString(), "time")) 00070 { 00071 CSE2Pose Pose; 00072 Pose.X = P[0]; 00073 Pose.Y = P[1]; 00074 Pose.A = P[2]; 00075 00076 m_PoseHistory[dfTime] = Pose; 00077 00078 m_PoseHistory.MakeSpanTime(POSE_HISTORY_SIZE); 00079 00080 m_XDOF.SetCurrent(Pose.X,dfTime); 00081 m_YDOF.SetCurrent(Pose.Y,dfTime); 00082 m_YawDOF.SetCurrent(Pose.A,dfTime); 00083 } 00084 00085 } 00086 } 00087 00088 //are we being told about a new thrust? 00089 if(!m_sDesiredThrustSource.empty() && PeekMail(NewMail, m_sDesiredThrustSource, Msg)) 00090 { 00091 m_dfDesiredThrust = Msg.GetDouble(); 00092 m_bThrustSet = true; 00093 } 00094 00095 //have we been sent a new waypoint? 00096 if(PeekMail(NewMail,m_sTargetWayPoint,Msg)) 00097 { 00098 OnNewTargetWayPoint(Msg.GetString(),Msg.GetTime()); 00099 } 00100 00101 00102 //always call base class version 00103 return CMOOSBehaviour::OnNewMail(NewMail); 00104 00105 00106 } 00107 00108 bool CVehicleFrameWayPointTask::OnNewTargetWayPoint(const std::string & sVal,double dfMsgTime ) 00109 { 00110 //check it isn't old... 00111 if(fabs(dfMsgTime-MOOSTime())>1.0) 00112 return false; 00113 00114 00115 //this sets a waupoint specified in the coordinate frame of the vehicle 00116 //at a specified time 00117 std::vector<double> P; 00118 int nRows,nCols; 00119 if(MOOSValFromString(P, nRows,nCols,sVal,"Waypoint")) 00120 { 00121 double dfTime; 00122 if(!MOOSValFromString(dfTime, sVal, "time")) 00123 { 00124 dfTime = dfMsgTime; 00125 } 00126 00127 CSE2Pose WPBody; 00128 WPBody.X = P[0]; 00129 WPBody.Y = P[1]; 00130 WPBody.A = P[2]; 00131 00132 //get gloabl position at this time... 00133 CSE2Pose PoseVehicle = m_PoseHistory(dfTime); 00134 00135 double dfMostRecentTime = m_PoseHistory.MaxKey(); 00136 CSE2Pose PoseNow; 00137 m_PoseHistory.MaxData(PoseNow); 00138 MOOSTrace("retrieved %.3f %.3f @ %.3f",PoseVehicle.X,PoseVehicle.Y, dfTime); 00139 MOOSTrace("current %.3f %.3f @ %.3f",PoseNow.X,PoseNow.Y, dfMostRecentTime); 00140 00141 00142 00143 //figure out gloabl position of way point 00144 CSE2Pose WPGlobal = Compose(PoseVehicle, WPBody); 00145 00146 //use this gloabl waypoint to set goals; 00147 m_XDOF.SetDesired(WPGlobal.X); 00148 m_YDOF.SetDesired(WPGlobal.Y); 00149 m_YawDOF.SetDesired(WPGlobal.A); 00150 00151 m_bWayPointSet = true; 00152 00153 MOOSTrace("Formed New GlobalWayPoint: %.2f %.2f %.2f\n",WPGlobal.X,WPGlobal.Y,WPGlobal.A); 00154 00155 return true; 00156 00157 00158 } 00159 00160 return false; 00161 } 00162 00163 double CVehicleFrameWayPointTask::GetDistanceToGo() 00164 { 00165 return sqrt(pow(m_YDOF.GetError(),2)+pow(m_XDOF.GetError(),2)); 00166 } 00167 00168 bool CVehicleFrameWayPointTask::ValidData() 00169 { 00170 if(m_sPoseSource.empty()) 00171 return false; 00172 00173 if(m_sTargetWayPoint.empty()) 00174 return false; 00175 00176 if(m_PoseHistory.empty()) 00177 return false; 00178 00179 if(!m_XDOF.IsValid()) 00180 return false; 00181 00182 if(!m_YDOF.IsValid()) 00183 return false; 00184 00185 if(!m_YawDOF.IsValid()) 00186 return false; 00187 00188 if(!m_bWayPointSet) 00189 return false; 00190 00191 return true; 00192 } 00193 00194 bool CVehicleFrameWayPointTask::Run(CPathAction &DesiredAction) 00195 { 00196 00197 if(ShouldRun()) 00198 { 00199 00200 if(ValidData()) 00201 { 00202 00203 double dfDistanceToGo = GetDistanceToGo(); 00204 00205 if(dfDistanceToGo<m_dfVicinityRadius) 00206 { 00207 //nothing to do.... 00208 return true; 00209 } 00210 else 00211 { 00212 00213 //calculate vector heading angle to goal 00214 double dfDesiredYaw = -atan2(m_XDOF.GetError(),m_YDOF.GetError()); 00215 00216 m_YawDOF.SetDesired(dfDesiredYaw); 00217 00218 double dfError = m_YawDOF.GetError(); 00219 00220 dfError = MOOS_ANGLE_WRAP(dfError); 00221 00222 double dfCmd = 0; 00223 00224 //this is for logging purposes only 00225 m_YawPID.SetGoal(m_YawDOF.GetDesired()); 00226 00227 00228 if(m_YawPID.Run(dfError,m_YawDOF.GetErrorTime(),dfCmd)) 00229 { 00230 //OK we need to change something 00231 00232 DesiredAction.Set( ACTUATOR_RUDDER, 00233 -dfCmd, 00234 m_nPriority, 00235 GetName().c_str()); 00236 00237 //MOOSTrace("Rudder Cmd = %f\n",-dfCmd); 00238 00239 00240 // we culd also be asked to control thrust 00241 if(m_bThrustSet) 00242 { 00243 DesiredAction.Set( ACTUATOR_THRUST, 00244 m_dfDesiredThrust, 00245 m_nPriority, 00246 GetName().c_str()); 00247 00248 //MOOSTrace("Thrust Cmd = %f\n",m_dfDesiredThrust); 00249 00250 } 00251 } 00252 00253 00254 } 00255 } 00256 } 00257 return true; 00258 00259 } 00260 00261 bool CVehicleFrameWayPointTask::RegularMailDelivery(double dfTimeNow) 00262 { 00263 if(m_YDOF.IsStale(dfTimeNow, GetStartTime(), 100.0)) 00264 return false; 00265 00266 return true; 00267 } 00268 00269 bool CVehicleFrameWayPointTask::SetParam(string sParam, string sVal) 00270 { 00271 if(!CMOOSBehaviour::SetParam(sParam,sVal)) 00272 { 00273 //this is for us... 00274 if(MOOSStrCmp(sParam,"PoseSource")) 00275 { 00276 m_sPoseSource = sVal; 00277 } 00278 else if(MOOSStrCmp(sParam,"Radius")) 00279 { 00280 m_dfVicinityRadius=atof(sVal.c_str()); 00281 } 00282 else if(MOOSStrCmp(sParam,"WaypointSource")) 00283 { 00284 m_sTargetWayPoint = sVal; 00285 } 00286 else if(MOOSStrCmp(sParam, "ThrustSource")) 00287 { 00288 m_sDesiredThrustSource = sVal; 00289 } 00290 else if(MOOSStrCmp(sParam, "Thrust")) 00291 { 00292 m_dfDesiredThrust = atof(sVal.c_str()); 00293 m_bThrustSet = true; 00294 } 00295 else 00296 { 00297 MOOSTrace("Unknown Parameter - %s\n",sParam.c_str()); 00298 return false; 00299 } 00300 } 00301 return true; 00302 } 00303 00304 00305