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 // AcousticTransceiver.cpp: implementation of the CAcousticTransceiver class. 00032 // 00034 #ifdef _WIN32 00035 #pragma warning(disable : 4786) 00036 #endif 00037 00038 #include "AcousticTransceiver.h" 00039 #include <iomanip> 00040 #include "SimEntity.h" 00041 #include "SimGlobalHelper.h" 00042 00043 #define DEFAULT_TCVR_RX_WINDOW 3.0 00044 00045 // Construction/Destruction 00047 00048 CAcousticTransceiver::CAcousticTransceiver() 00049 { 00050 m_dfRxWindow = DEFAULT_TCVR_RX_WINDOW; 00051 SetRxChan(ACOUSTIC_CHAN_CRF); 00052 SetRxChan(ACOUSTIC_CHAN_1); 00053 SetRxChan(ACOUSTIC_CHAN_2); 00054 SetRxChan(ACOUSTIC_CHAN_3); 00055 SetRxChan(ACOUSTIC_CHAN_4); 00056 SetRxChan(ACOUSTIC_CHAN_5); 00057 SetRxChan(ACOUSTIC_CHAN_6); 00058 SetRxChan(ACOUSTIC_CHAN_7); 00059 SetRxChan(ACOUSTIC_CHAN_8); 00060 SetRxChan(ACOUSTIC_CHAN_9); 00061 SetRxChan(ACOUSTIC_CHAN_10); 00062 SetRxChan(ACOUSTIC_CHAN_11); 00063 SetRxChan(ACOUSTIC_CHAN_12); 00064 00065 SetTxChan(ACOUSTIC_CHAN_CIF); 00066 } 00067 00068 CAcousticTransceiver::~CAcousticTransceiver() 00069 { 00070 00071 } 00072 00073 00074 bool CAcousticTransceiver::OnAcousticHit(CAcousticSignal & Signal,double dfTime) 00075 { 00076 #ifdef VERBOSE 00077 00078 MOOSTrace("CAcousticTransceiver::OnAcousticHit on %s Signal[%d] from %s on Channel %d\n", 00079 GetFullName().c_str(), 00080 Signal.m_nID, 00081 Signal.GetSrcName().c_str(), 00082 Signal.GetChannel()); 00083 #endif 00084 if(IsReceiving(dfTime) && Listening(Signal.GetChannel())) 00085 { 00086 //this is a catch for auto-excitation 00087 std::string sTmp = Signal.GetSrcName(); 00088 std::string sSrcVeh = MOOSChomp(sTmp,"/"); 00089 if(sSrcVeh==GetParent()->GetName()) 00090 return false; 00091 00092 00093 double dfTOF = dfTime-m_dfLastPingTime; 00094 00095 //here we corrupt the reply.. 00096 dfTOF +=MOOSWhiteNoise(1)*m_pParams->m_dfTOFStd; 00097 00098 //and occasionally add multipath 00099 double pMultiPath = m_pParams->m_dfProbMultiPath; 00100 00101 if(pMultiPath>0) 00102 { 00103 double dfRV = MOOSWhiteNoise(1); 00104 double dfThreshold = MOOSNormalInv(pMultiPath); 00105 if(dfRV<dfThreshold) 00106 { 00107 dfTOF+=(50.0+(20.0*dfRV*dfRV))/1500.0; 00108 00109 MOOSTrace("Making outlier TOF = %f @ %f\n",dfTOF,dfTime); 00110 } 00111 } 00112 00113 00114 00115 if(dfTOF<m_dfRxWindow) 00116 { 00117 CPingReply Reply; 00118 00119 Reply.m_dfTOF = dfTOF; 00120 Reply.m_eChannel = Signal.GetChannel(); 00121 Reply.m_sResponder = Signal.GetSrcName(); 00122 Reply.m_dfRxTime = dfTime; 00123 00124 00125 Matrix NodePos; 00126 00127 GetParent()->GetNodePosition(*this, 00128 0, 00129 NodePos); 00130 00131 #ifdef VERBOSE 00132 MOOSTrace("HIT! T = %f\n",dfTime); 00133 MOOSTraceMatrix(NodePos," Received @ \n"); 00134 #endif 00135 00136 00137 if(m_pParams->m_bImmediateAcousticLog) 00138 { 00139 LogReply(Reply); 00140 } 00141 else 00142 { 00143 MOOSTrace("%s Gets a 2WR from %s on Channel %d TOF %f\n", 00144 GetFullName().c_str(), 00145 Reply.m_sResponder.c_str(), 00146 Reply.m_eChannel, 00147 Reply.m_dfTOF); 00148 00149 m_Replies.push_back(Reply); 00150 } 00151 } 00152 } 00153 return true; 00154 } 00155 00156 bool CAcousticTransceiver::Ping(double dfTimeNow) 00157 { 00158 00159 m_dfLastPingTime = dfTimeNow; 00160 00161 m_Replies.clear(); 00162 00163 Matrix NodePos; 00164 00165 GetParent()->GetNodePosition(*this, 00166 0, 00167 NodePos); 00168 00169 CAcousticSignal Ping( NodePos(1,1), 00170 NodePos(2,1), 00171 NodePos(3,1), 00172 dfTimeNow); 00173 00174 #ifdef VERBOSE 00175 MOOSTrace("\n*********\nPING! T = %f\n",dfTimeNow); 00176 MOOSTraceMatrix(NodePos,"Pinged from \n"); 00177 #endif 00178 00179 Ping.SetSrcName(GetFullName()); 00180 00181 Ping.SetChannel(GetTxChannel()); 00182 #ifdef VERBOSE 00183 00184 MOOSTrace("%s launches ping[%d] on Channel %d\n", 00185 GetFullName().c_str(), 00186 Ping.m_nID, 00187 GetTxChannel()); 00188 #endif 00189 00190 return m_pEnvironment->AddSignal(Ping); 00191 00192 } 00193 00194 bool CAcousticTransceiver::IsReceiving(double dfTimeNow) 00195 { 00196 00197 00198 return m_bIsReceiving; 00199 } 00200 00201 bool CAcousticTransceiver::Iterate(double dfTimeNow) 00202 { 00203 if(dfTimeNow-m_dfLastPingTime<m_dfRxWindow && m_dfLastPingTime!=-1) 00204 { 00205 m_bIsReceiving = true; 00206 } 00207 else 00208 { 00209 //window has closed - time to publish results 00210 PING_REPLY_LIST::iterator p; 00211 00212 for(p = m_Replies.begin();p!=m_Replies.end();p++) 00213 { 00214 CPingReply& rReply = *p; 00215 00216 if(!m_pParams->m_bImmediateAcousticLog) 00217 { 00218 LogReply(rReply); 00219 } 00220 00221 } 00222 00223 00224 m_bIsReceiving = false; 00225 00226 //now ping again 00227 Ping(dfTimeNow); 00228 00229 } 00230 00231 return true; 00232 } 00233 00234 bool CAcousticTransceiver::LogReply(CAcousticTransceiver::CPingReply &rReply) 00235 { 00236 00237 // MOOSTrace("Reply on chan[%d] TOF = %10.5f\n",rReply.m_eChannel,rReply.m_dfTOF); 00238 00239 00240 ostringstream os; 00241 00242 //default to 3 dp 00243 os.setf(ios::fixed,ios::floatfield); 00244 os<<setprecision(3); 00245 00246 00247 //begin output...firslt what kind of record is this? 00248 os <<"TwoWayRange"<<"," 00249 00250 //when 00251 <<"T="<<m_pEnvironment->GetElapsedTime(rReply.m_dfRxTime)<<"," 00252 //"Tx="<<rReply.m_dfRxTime-rReply.m_dfTOF<<"," 00253 00254 //who recieved (ourselves) 00255 <<"RxNode="<<GetFullName().c_str()<<"," 00256 00257 //higher precision for TOF 00258 <<setprecision(5) 00259 <<"TOF="<<rReply.m_dfTOF<<"," 00260 <<setprecision(3) 00261 00262 //what channel 00263 <<"Ch="<<rReply.m_eChannel<<"," 00264 00265 //a bit of cheat information - tcvr only really gives above information 00266 //but we also say what beacon was involved to help simulator user 00267 <<"[" <<rReply.m_sResponder.c_str() <<"]" 00268 00269 //terminate 00270 <<endl 00271 <<ends; 00272 00273 Log(os); 00274 00275 00276 //finally add to MOOS Messages (if required?) 00277 //simple single vehicle format 00278 ostringstream osSimple; 00279 00280 osSimple.setf(ios::fixed); 00281 osSimple.precision(3); 00282 osSimple<<"Tx="<<rReply.m_dfRxTime-rReply.m_dfTOF; 00283 00284 osSimple.precision(6); 00285 osSimple<<",Ch["<<rReply.m_eChannel<<"]="<<rReply.m_dfTOF; 00286 osSimple<<ends; 00287 00288 //send report 00289 m_pEnvironment->AddReport(GetParent()->m_sOutputPrefix+"LBL_TOF",osSimple.str()); 00290 00291 00292 return true; 00293 }