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 at MIT 2001-2002 and Oxford 00010 // University 2003-2005. email: pnewman@robots.ox.ac.uk. 00011 // 00012 // This file is part of a MOOS Utility Component. 00013 // 00014 // This program is free software; you can redistribute it and/or 00015 // modify it under the terms of the GNU General Public License as 00016 // published by the Free Software Foundation; either version 2 of the 00017 // License, or (at your option) any later version. 00018 // 00019 // This program is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00022 // General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with this program; if not, write to the Free Software 00026 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00027 // 02111-1307, USA. 00028 // 00030 00031 // SimEntity.cpp: implementation of the CSimEntity class. 00032 // 00034 #ifdef _WIN32 00035 #pragma warning(disable : 4786) 00036 #endif 00037 #include "SimGlobalHelper.h" 00038 #include "SimEnvironment.h" 00039 #include "SimEntity.h" 00040 #include <iostream> 00041 #include <iomanip> 00043 // Construction/Destruction 00045 00046 CSimEntity::CSimEntity() 00047 { 00048 m_pEnvironment = NULL; 00049 m_Pos_e.ReSize(6,1); 00050 m_Vel_e.ReSize(6,1); 00051 m_dfLastLogState = -1; 00052 m_dfLogFrequency = 2.0; 00053 } 00054 00055 CSimEntity::~CSimEntity() 00056 { 00057 00058 } 00059 00060 bool CSimEntity::SetParams(CSimParams *pParams) 00061 { 00062 m_pParams = pParams; 00063 00064 ACOUSTIC_NODE_LIST::iterator p; 00065 00066 for(p=m_AcousticNodes.begin();p!=m_AcousticNodes.end();p++) 00067 { 00068 (*p)->SetParams(m_pParams); 00069 } 00070 00071 return true; 00072 } 00073 00074 00075 00076 bool CSimEntity::Iterate(double dfTimeNow,double dfDT) 00077 { 00078 return true; 00079 } 00080 00081 bool CSimEntity::GetAcousticNodes(ACOUSTIC_NODE_LIST &List) 00082 { 00083 List = m_AcousticNodes; 00084 00085 return true; 00086 00087 00088 } 00089 00090 bool CSimEntity::GetNodePosition(CAcousticNode &Node, double dfDT, Matrix &Result) 00091 { 00092 //for now assume zero offset of node... put transformation in here... 00093 //simple stuff but boring... 00094 if(!Node.m_OffsetPos.IsZero()) 00095 { 00096 printf("Transformation for non zero offsets not written yet\n"); 00097 } 00098 00099 Result = m_Pos_e+dfDT*m_Vel_e; 00100 00101 return true; 00102 } 00103 00104 void CSimEntity::SetEnvironment(CSimEnvironment *pEnv) 00105 { 00106 m_pEnvironment = pEnv; 00107 } 00108 00109 00110 bool CSimEntity::SolveAcoustics(double dfTime,double dfDT) 00111 { 00112 00113 ACOUSTIC_NODE_LIST::iterator w; 00114 ACOUSTIC_SIGNAL_LIST::iterator q; 00115 00116 // MOOSTrace("Solving Acoustics for %s\n", GetName().c_str()); 00117 00118 00119 for(w = m_AcousticNodes.begin();w!=m_AcousticNodes.end();w++) 00120 { 00121 //dereference the node 00122 CAcousticNode* pNode = *w; 00123 00124 // MOOSTrace("\t Node %s\n", pNode->GetName().c_str()); 00125 00126 pNode->SetEnvironment(m_pEnvironment); 00127 00128 //and where it is now... 00129 Matrix X0; 00130 00131 GetNodePosition(*pNode,0,X0); 00132 00133 #ifdef SIM_ENTITY_VERBOSE 00134 MOOSTraceMatrix(X0,"X0"); 00135 #endif 00136 00137 //MOOSTrace("%d acoustic signals in environment \n",m_pEnvironment->m_AcousticSignals.size()); 00138 00139 for(q = m_pEnvironment->m_AcousticSignals.begin();q!=m_pEnvironment->m_AcousticSignals.end();q++) 00140 { 00141 //dereference it... 00142 CAcousticSignal & rSignal = *q; 00143 00144 //is the node listening on this channel? 00145 if(pNode->Listening(rSignal.GetChannel())) 00146 { 00147 00148 if(IsLocalSource(rSignal.GetSrcName())) 00149 { 00150 #ifdef SIM_ENTITY_VERBOSE 00151 MOOSTrace("%s is local to %s, Tx = %f Now = %f Age = %f - continue\n", 00152 rSignal.GetSrcName().c_str(), 00153 pNode->GetFullName().c_str(), 00154 rSignal.GetStartTime(),dfTime,rSignal.Age(dfTime)); 00155 #endif 00156 continue; 00157 } 00158 00159 //so when approximately would the signal intercept the node? 00160 double dfT0 = rSignal.GetExpectedIntersectionTime(X0); 00161 00162 #ifdef SIM_ENTITY_VERBOSE 00163 00164 MOOSTrace("T = %f : Signal[%d] [Chan=%d] from %s will intersect %s in %f s\n", 00165 dfTime, 00166 rSignal.m_nID, 00167 rSignal.GetChannel(), 00168 rSignal.GetSrcName().c_str(), 00169 pNode->GetFullName().c_str(), 00170 dfT0-dfTime); 00171 #endif 00172 00173 //is that close to us? ie within this epoch? 00174 if(dfT0>dfTime && dfT0<dfTime+dfDT) 00175 { 00176 00177 //OK lets figure out where node would have been dfSmallDT 00178 //seconds ago...(we have already moved the host entity above) 00179 Matrix X1; 00180 GetNodePosition(*pNode,-dfDT,X1); 00181 00182 // MOOSTraceMatrix(X1,"X1"); 00183 00184 double dfT1 = rSignal.GetExpectedIntersectionTime(X1); 00185 00186 //now need to find the intersection between the line joining points 00187 // (m_dfTimeNow,dfT0) and (m_dfTimeNow-dfSmallDT,dfT1) and the line 00188 // with gradient one ... 00189 00190 double dfGrad = (dfT0-dfT1)/(dfTime-(dfTime-dfDT)); 00191 double dfC = dfT1+dfGrad*(-(dfTime-dfDT)); 00192 00193 //intersection time is 00194 double dfTi = dfC/(1-dfGrad); 00195 00196 /* MOOSTrace("ACoustic Hit @ %f timenow = %f\n", 00197 dfTi-m_pEnvironment->GetStartTime(), 00198 dfTime-m_pEnvironment->GetStartTime()); 00199 00200 MOOSTrace("D = %f\n",(dfTi-rSignal.GetStartTime())*1498.0); 00201 */ 00202 pNode->OnAcousticHit(rSignal,dfTi); 00203 } 00204 } 00205 else 00206 { 00207 #ifdef SIM_ENTITY_VERBOSE 00208 MOOSTrace("%s is NOT listening for Signal[%d] from %s\n", 00209 pNode->GetFullName().c_str(), 00210 rSignal.m_nID, 00211 rSignal.GetSrcName().c_str()); 00212 #endif 00213 } 00214 } 00215 00216 //this call lets the node go about its normal action such as 00217 //pinging when required 00218 pNode->Iterate(dfTime); 00219 } 00220 00221 return true; 00222 } 00223 00224 bool CSimEntity::IsLocalSource(std::string sSrc) 00225 { 00226 //this is a catch for auto-excitation 00227 std::string sSrcVeh = MOOSChomp(sSrc,"/"); 00228 if(GetName()==sSrcVeh) 00229 return true; 00230 00231 return false; 00232 00233 } 00234 00235 00236 double CSimEntity::HeadingFromYaw(double dfYaw) 00237 { 00238 double dfYawDeg = dfYaw*180.0/PI; 00239 00240 //heading is negative yaw 00241 double dfHeading = dfYawDeg>0 ? 360-dfYawDeg : -dfYawDeg; 00242 00243 //subtract magnetic offset (out of simulator you add it) 00244 dfHeading-=m_pEnvironment->m_dfMagneticOffset; 00245 00246 //and check again... 00247 dfHeading = dfHeading<0 ? 360.0+dfHeading : dfHeading; 00248 00249 return dfHeading; 00250 } 00251 00252 00253 bool CSimEntity::LogState(double dfTimeNow) 00254 { 00255 00256 //housekeeping.. 00257 if(m_dfLogFrequency<=0) 00258 return false; 00259 00260 if(dfTimeNow-m_dfLastLogState<1.0/m_dfLogFrequency) 00261 return false; 00262 00263 m_dfLastLogState = dfTimeNow; 00264 00265 //logging happens here.. 00266 00267 ostringstream os; 00268 00269 os.setf(ios::fixed,ios::floatfield); 00270 os<<setprecision(3); 00271 00272 os <<"State," 00273 00274 <<"T="<<m_pEnvironment->GetElapsedTime(dfTimeNow)<<"," 00275 00276 <<"Name="<<GetName().c_str()<<"," 00277 00278 <<"Pose=[" <<m_Pos_e(1,1)<<"," 00279 <<m_Pos_e(2,1)<<"," 00280 <<m_Pos_e(3,1)<<"," 00281 <<m_Pos_e(4,1)<<"," 00282 <<m_Pos_e(5,1)<<"," 00283 <<m_Pos_e(6,1)<<"]," 00284 00285 <<"Vel=[" <<m_Vel_e(1,1)<<"," 00286 <<m_Vel_e(2,1)<<"," 00287 <<m_Vel_e(3,1)<<"," 00288 <<m_Vel_e(4,1)<<"," 00289 <<m_Vel_e(5,1)<<"," 00290 <<m_Vel_e(6,1)<<"]" 00291 00292 <<endl<<ends; 00293 00294 return Log(os); 00295 00296 00297 } 00298