MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/NavigationAndControl/MOOSTaskLib/XYPatternTask.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 // XYPatternTask.cpp: implementation of the CXYPatternTask class.
00032 //
00034 #ifdef _WIN32
00035     #pragma warning(disable : 4786)
00036 #endif
00037 
00038 #include "MOOSTaskDefaults.h"
00039 #include "XYPatternTask.h"
00040 #include "math.h"
00041 #include <sstream>
00042 #include <iostream>
00043 using namespace std;
00044 
00045 
00047 // Construction/Destruction
00049 
00050 CXYPatternTask::CXYPatternTask()
00051 {
00052     m_nPriority = 2;
00053 
00054 
00055     m_bInitialised = false;
00056 
00057     m_dfVicinityRadius = 0;
00058 
00059     m_bPositionSet = true;
00060 
00061     m_bThrustSet = false;
00062 
00063     m_dfThrust = 0;
00064 
00065     m_nTotalPositions = 0;
00066 
00067     m_nTotalRepetitions = 0;
00068 
00069     m_nCurrentPosition = 0;
00070 
00071     m_nRepCounter = 0;
00072 
00073 }
00074 
00075 CXYPatternTask::~CXYPatternTask()
00076 {
00077     m_XYPoints.clear();
00078 }
00079 
00080 bool CXYPatternTask::OnNewMail(MOOSMSG_LIST &NewMail)
00081 {
00082 
00083     CMOOSMsg Msg;
00084 
00085         if(PeekMail(NewMail,"NAV_POSE",Msg))
00086         {
00087         if(!Msg.IsSkewed(GetTimeNow()))
00088         {
00089                         std::vector<double> Pose;
00090                         int nRows,nCols;
00091                         if(MOOSValFromString(Pose,nRows,nCols,Msg.GetString(),"Pose",true))
00092                         {
00093                                 if(Pose.size() == 3)
00094                                 {
00095                                         m_XDOF.SetCurrent(Pose[0],Msg.GetTime());
00096                                         m_YDOF.SetCurrent(Pose[1],Msg.GetTime());
00097                                         m_YawDOF.SetCurrent(Pose[2],Msg.GetTime());
00098 
00099                     // MOOSTrace("we are at %f %f %f\n",Pose[0],Pose[1],Pose[2]);
00100                                 }
00101                         }
00102 
00103         }
00104     }
00105 
00106     if(PeekMail(NewMail,"NAV_X",Msg))
00107     {
00108         if(!Msg.IsSkewed(GetTimeNow()))
00109         {
00110             m_XDOF.SetCurrent(Msg.m_dfVal,Msg.m_dfTime);
00111         }
00112     }
00113     if(PeekMail(NewMail,"NAV_Y",Msg))
00114     {
00115         if(!Msg.IsSkewed(GetTimeNow()))
00116         {   
00117             m_YDOF.SetCurrent(Msg.m_dfVal,Msg.m_dfTime);
00118         }
00119     }
00120 
00121     if(PeekMail(NewMail,"NAV_YAW",Msg))
00122     {
00123         if(!Msg.IsSkewed(GetTimeNow()))
00124         {
00125 
00126             double dfVal = Msg.m_dfVal;
00127 
00128             if(dfVal>PI)
00129             {
00130                 dfVal-=2*PI;
00131             }
00132             m_YawDOF.SetCurrent(dfVal,Msg.m_dfTime);
00133 
00134         //    MOOSTrace("%s gets yaw = %f @ %f\n",m_sName.c_str(),dfVal,Msg.m_dfTime);
00135         }
00136 
00137     }
00138 
00139     //always call base class version
00140     CMOOSBehaviour::OnNewMail(NewMail);
00141 
00142     return true;
00143 }
00144 
00145 bool CXYPatternTask::GetRegistrations(STRING_LIST &List)
00146 {
00147     List.push_front("NAV_X");
00148     List.push_front("NAV_Y");
00149     List.push_front("NAV_YAW");
00150     List.push_front("NAV_POSE");
00151 
00152     //always call base class version
00153     CMOOSBehaviour::GetRegistrations(List);
00154 
00155     return true;
00156 }
00157 
00158 
00159 
00160 //returns false if we haven't received data in a while..bad news!
00161 bool CXYPatternTask::RegularMailDelivery(double dfTimeNow)
00162 {
00163     if(m_YawDOF.IsStale(dfTimeNow,GetStartTime()))
00164         return false;
00165     
00166     if(m_XDOF.IsStale(dfTimeNow,GetStartTime()))
00167         return false;
00168 
00169     if(m_YDOF.IsStale(dfTimeNow,GetStartTime()))
00170         return false;
00171 
00172     return true;
00173 }
00174 
00175 
00176 
00177 bool CXYPatternTask::Run(CPathAction &DesiredAction)
00178 {
00179     if(!m_bPositionSet)
00180     {
00181         MOOSTrace("position not set\n");;
00182         return false;
00183     }
00184 
00185     if(!m_bInitialised)
00186     {
00187         Initialise();
00188     }
00189 
00190     if(ShouldRun())
00191     {
00192      
00193         if(ValidData() && m_nTotalPositions!=0)
00194         {
00195                    
00196             double dfDistanceToGo = sqrt(pow(m_YDOF.GetError(),2)+pow(m_XDOF.GetError(),2));
00197 
00198 
00199             if(dfDistanceToGo<m_dfVicinityRadius)
00200             {            
00201                 
00202                 if(m_nRepCounter < m_nTotalRepetitions)
00203                 {
00204                     SetNextPoint();
00205                 }
00206                 else
00207                 {
00208                     OnComplete();    
00209                 }
00210             }
00211             else
00212             {
00213                 //calculate vector heading angle to goal
00214                         
00215 
00216                 double dfDesiredYaw = -atan2(m_XDOF.GetError(),m_YDOF.GetError());
00217 
00218                 m_YawDOF.SetDesired(dfDesiredYaw);
00219 
00220                 double dfError = m_YawDOF.GetError();
00221 
00222 //                              MOOSTrace("x_err = %f y_err = %f current_yaw = %f desired_yaw = %f\n",
00223                 //                              m_XDOF.GetError(),m_YDOF.GetError(),m_YawDOF.GetCurrent(),dfDesiredYaw);
00224 
00225 
00226                 dfError = MOOS_ANGLE_WRAP(dfError);
00227         
00228                 double dfCmd = 0;
00229 
00230                 //this is for loggin purposes only
00231                 m_YawPID.SetGoal(m_YawDOF.GetDesired());
00232                 if(m_YawPID.Run(dfError,m_YawDOF.GetErrorTime(),dfCmd))
00233                 {
00234                     //OK we need to change something
00235                     SetControl(DesiredAction,-dfCmd,m_dfThrust);                        
00236                 }
00237             }
00238         }
00239     }
00240     return true;
00241 }
00242 
00243 
00244 bool CXYPatternTask::SetControl(CPathAction &DesiredAction,double dfRudder,double dfThrust)
00245 {
00246     DesiredAction.Set(  ACTUATOR_RUDDER,
00247                         dfRudder,
00248                         m_nPriority,
00249                         GetName().c_str());
00250 
00251     //set the thrust
00252     if(m_bThrustSet)
00253     {
00254         DesiredAction.Set(  ACTUATOR_THRUST,
00255                             dfThrust,
00256                             m_nPriority,
00257                             GetName().c_str());
00258     }
00259 
00260     return true;
00261 }
00262 
00263 
00264 
00265 bool CXYPatternTask::Initialise()
00266 {
00267     
00268     m_YawDOF.SetDesired(0);
00269     m_YawDOF.SetTolerance(0.00);
00270 
00271     //begin the loop-d-loop of points 
00272     SetNextPoint();
00273 
00274     m_bInitialised = true;
00275 
00276     return m_bInitialised;
00277 }
00278 
00279 bool CXYPatternTask::ValidData()
00280 {   
00281     return  m_XDOF.IsValid() &&
00282             m_YDOF.IsValid() &&
00283             m_YawDOF.IsValid();
00284 }
00285 
00286 
00287 
00288 bool CXYPatternTask::SetParam(string sParam, string sVal)
00289 {
00290     MOOSToUpper(sParam);
00291     MOOSToUpper(sVal);
00292 
00293 
00294     if(!CMOOSBehaviour::SetParam(sParam,sVal))
00295     {
00296         //this is for us...
00297         if(sParam=="RADIUS")
00298         {
00299             m_dfVicinityRadius=atof(sVal.c_str());
00300         }
00301         else if(sParam=="THRUST")
00302         {
00303             m_dfThrust=atof(sVal.c_str());
00304             m_bThrustSet = true;
00305         }
00306         else if(sParam=="LOCATION")
00307         {
00308             //useful for later...
00309             m_sLocation = sVal;
00310             string sCopyOfLocation = sVal;
00311 
00312             string sTmpX = MOOSChomp(sVal,",");
00313             string sTmpY = MOOSChomp(sVal,",");
00314             string sTmpZ = MOOSChomp(sVal,",");
00315             
00316             if(sTmpX.empty()||sTmpY.empty()||sTmpZ.empty())
00317             {
00318                 MOOSTrace("error in reading  location from file\n");
00319                 return false;
00320             }
00321 
00322             //instead of setting this as the X,Y point to go to,
00323             //store the points in a list that will be parsed later
00324             m_Positions.push_back(sCopyOfLocation);
00325             m_nTotalPositions++;
00326 
00327         }
00328         else if((sParam == "REPEAT"))
00329         {
00330             int nTotal = atoi(sVal.c_str());
00331             //only accept positive values
00332             if((nTotal > 0) && (nTotal < XYPATTERN_MAX_TOTAL_REPETITION))
00333             {
00334                 m_nTotalRepetitions = nTotal;
00335             }
00336             else if((nTotal > 0) && (nTotal > XYPATTERN_MAX_TOTAL_REPETITION))
00337             {
00338                 m_nTotalRepetitions = XYPATTERN_MAX_TOTAL_REPETITION;
00339             }
00340             else
00341             {
00342                 //default
00343                 m_nTotalRepetitions = XYPATTERN_DEFAULT_TOTAL_REPETITION;
00344             }
00345 
00346         }
00347         else
00348         {
00349             //hmmm - it wasn't for us at all: base class didn't understand either
00350             MOOSTrace("Param \"%s\" not understood by %s!\n",sParam.c_str(),m_sName.c_str());
00351             return false;
00352         }
00353     }
00354 
00355     return true;
00356 }
00357 
00358 
00359 void CXYPatternTask::SetNextPoint()
00360 {
00361     //first time through, we need to make some calculations
00362     if(!m_bInitialised)
00363     {
00364         //always start by heading to the first position around the center
00365         m_nCurrentPosition = 0;
00366         
00367         //guarantee enough space
00368         m_XYPoints.clear();
00369         m_XYPoints.resize(m_nTotalPositions + 1);
00370 
00371         for(int i = 0; i < m_nTotalPositions; i++)
00372         {
00373             string sVal = m_Positions.front();
00374             m_Positions.pop_front();
00375             double dfX  = atof(MOOSChomp(sVal,",").c_str());
00376             double dfY  = atof(MOOSChomp(sVal,",").c_str());
00377 
00378             CXYPoint Position;
00379             
00380             Position.SetX(dfX);
00381             Position.SetY(dfY);
00382 
00383             m_XYPoints[i] = Position;
00384             
00385         }
00386     }
00387     else
00388     {
00389         //otherwise just augment our current point we are heading to
00390         //and have the new Desired location input for the controller
00391         m_nCurrentPosition++;
00392         //make sure we go in a circle
00393         m_nCurrentPosition %= m_nTotalPositions;
00394         //augment our repetitions
00395         if(m_nCurrentPosition==0)
00396         {
00397             m_nRepCounter++;
00398         }
00399     }
00400 
00401     //announce where we are going to
00402     ostringstream os;
00403 
00404     os<<"XYPATTERN - transiting to: pos["<<m_nCurrentPosition<<"]"<<
00405         " -> "<<m_XYPoints[m_nCurrentPosition].GetX()<<","<<
00406         m_XYPoints[m_nCurrentPosition].GetY()<<" - [REP : "<<
00407         m_nRepCounter<<"]"<<endl<<ends;
00408 
00409     DebugNotify(os.str());
00410 
00411     //now set the point we are heading to
00412     m_XDOF.SetDesired(m_XYPoints[m_nCurrentPosition].GetX());
00413     m_YDOF.SetDesired(m_XYPoints[m_nCurrentPosition].GetY());
00414 
00415     return;
00416 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines