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 Instrument. 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 // INSInstrument.cpp: implementation of the CINSInstrument class. 00032 // 00034 // CompassInstrument.cpp: implementation of the CINSInstrument class. 00035 // 00037 #include <MOOSLIB/MOOSLib.h> 00038 #include <iostream> 00039 #include <sstream> 00040 #include <math.h> 00041 using namespace std; 00042 #include "INSInstrument.h" 00043 00044 00046 // Construction/Destruction 00048 #define CROSSBOW_POLLED_ANGLE_MODE_REPLY_LENGTH 30 00049 00050 bool INSPortReadCallBack(char * pData, int nBufferLen,int nRead) 00051 { 00052 return nRead==CROSSBOW_POLLED_ANGLE_MODE_REPLY_LENGTH; 00053 } 00054 00055 CINSInstrument::CINSInstrument() 00056 { 00057 m_dfMagneticOffset; 00058 m_nTempCnt = 0; 00059 } 00060 00061 CINSInstrument::~CINSInstrument() 00062 { 00063 00064 } 00065 00066 00069 bool CINSInstrument::Iterate() 00070 { 00071 if(GetData()) 00072 { 00073 PublishData(); 00074 } 00075 00076 return true; 00077 } 00078 00080 // tell the world 00081 bool CINSInstrument::PublishData() 00082 { 00083 return PublishFreshMOOSVariables(); 00084 00085 } 00086 00087 00088 bool CINSInstrument::OnStartUp() 00089 { 00090 //call base class member first 00091 CMOOSInstrument::OnStartUp(); 00092 00093 //here we make the variables that we are managing 00094 double dfINSPeriod = 0.2; 00095 00096 00097 if(!m_MissionReader.GetConfigurationParam("TWIST",m_dfVehicleYToCrossBowX)) 00098 { 00099 m_dfVehicleYToCrossBowX = 0; 00100 } 00101 00102 //INS update @ 2Hz 00103 AddMOOSVariable("Heading", "SIM_HEADING", "INS_HEADING", dfINSPeriod); 00104 AddMOOSVariable("Yaw", "SIM_YAW", "INS_YAW", dfINSPeriod); 00105 AddMOOSVariable("Temperature", "", "INS_TEMPERATURE", dfINSPeriod); 00106 00107 // AddMOOSVariable("YawRate", "SIM_YAWRATE", "INS_YAWRATE", dfINSPeriod); 00108 AddMOOSVariable("Pitch", "SIM_PITCH", "INS_PITCH", dfINSPeriod); 00109 AddMOOSVariable("Roll", "SIM_ROLL", "INS_ROLL", dfINSPeriod); 00110 00111 //we shall need the diference between true north and magnetic north. 00112 GetMagneticOffset(); 00113 00114 if(IsSimulateMode()) 00115 { 00116 //not much to do...othe than register for input from 00117 //simulator ... 00118 RegisterMOOSVariables(); 00119 } 00120 else 00121 { 00122 //try to open 00123 if(!SetupPort()) 00124 { 00125 return false; 00126 } 00127 00128 m_Port.SetIsCompleteReplyCallBack(INSPortReadCallBack); 00129 00130 //try 10 times to initialise sensor 00131 if(!InitialiseSensorN(10,"INS")) 00132 { 00133 return false; 00134 } 00135 } 00136 00137 00138 return true; 00139 } 00140 00141 00142 00143 bool CINSInstrument::OnNewMail(MOOSMSG_LIST &NewMail) 00144 { 00145 return UpdateMOOSVariables(NewMail); 00146 } 00147 00148 00149 00150 00151 bool CINSInstrument::OnConnectToServer() 00152 { 00153 if(IsSimulateMode()) 00154 { 00155 //not much to do... 00156 return RegisterMOOSVariables(); 00157 00158 } 00159 else 00160 { 00161 00162 } 00163 return true; 00164 } 00165 00166 00168 // here we initialise the sensor, giving it start up values 00169 bool CINSInstrument::InitialiseSensor() 00170 { 00171 //set to polled moade in angles... 00172 m_Port.Write("P",1); 00173 MOOSPause(100); 00174 00175 //set to angle mode 00176 m_Port.Write("a",1); 00177 00178 char Spare[10]; 00179 m_Port.ReadNWithTimeOut(Spare,1); 00180 00181 if(Spare[0]!='A') 00182 { 00183 MOOSTrace("Unexpected reply when setting angle mode (expecting 'A')\n"); 00184 return false; 00185 } 00186 00187 00188 return true; 00189 00190 } 00191 00192 bool CINSInstrument::GetData() 00193 { 00194 00195 if(!IsSimulateMode()) 00196 { 00197 //here we actually access serial ports etc 00198 if(m_Port.IsStreaming()) 00199 { 00200 MOOSTrace("Crossbow must not be streaming\n"); 00201 return false; 00202 } 00203 00204 00205 m_Port.Write("G",1); 00206 00207 00208 string sWhat; 00209 00210 unsigned char Reply[30]; 00211 00212 //note local call back invoked here to specify termination 00213 int nRead = m_Port.ReadNWithTimeOut((char*)Reply,sizeof(Reply)); 00214 00215 00216 if(nRead ==CROSSBOW_POLLED_ANGLE_MODE_REPLY_LENGTH) 00217 { 00218 if(Reply[0]!=255) 00219 { 00220 MOOSTrace("Unexpected Header in CrossBow reply\n"); 00221 } 00222 00223 short nRoll = (Reply[1]<<8) + Reply[2]; 00224 short nPitch = (Reply[3]<<8) + Reply[4]; 00225 short nYaw = (Reply[5]<<8) + Reply[6]; 00226 00227 double dfCBRoll = nRoll*180.0/pow(2.0,15.0); 00228 double dfCBPitch = nPitch*90.0/pow(2.0,15.0); 00229 double dfCBYaw = nYaw*180.0/pow(2.0,15.0); 00230 00231 //acount for alignment of crossbow in vehicle frame 00232 //this is the angle measured from the vehicle ceneter line(y) 00233 //to teh x axis of teh crossbow unit. Note that if this is non zero then 00234 //we'll have to do a real 3 transfgormation of axe sto use pitch correctly 00235 //this is good enough to get us going for now but more needs to be done. 00236 double dfHeading = dfCBYaw+m_dfVehicleYToCrossBowX; 00237 00238 //no correct for magnetic offset 00239 dfHeading+=m_dfMagneticOffset; 00240 00241 //convert to Yaw.. 00242 double dfYaw = -dfHeading*PI/180.0; 00243 dfYaw = MOOS_ANGLE_WRAP(dfYaw); 00244 00245 00246 //look after pitch 00247 double dfPitch = MOOSDeg2Rad(dfCBPitch); 00248 00249 //look after roll 00250 double dfRoll = MOOSDeg2Rad(dfCBRoll); 00251 00252 00253 //find the temperature every so often 00254 m_nTempCnt++; 00255 if((m_nTempCnt % 100) == 0) 00256 { 00257 short nTemp = ( Reply[25] << 8 ) + Reply[26]; 00258 double dfTemp = 44.4 * ( ((double)nTemp * 5.0/4096.0) - 1.375); 00259 SetMOOSVar( "Temperature", dfTemp, MOOSTime() ); 00260 } 00261 00262 //set our local variables... 00263 SetMOOSVar("Heading",dfHeading,MOOSTime()); 00264 SetMOOSVar("Yaw",dfYaw,MOOSTime()); 00265 SetMOOSVar("Pitch",dfPitch,MOOSTime()); 00266 SetMOOSVar("Roll",dfRoll,MOOSTime()); 00267 00268 00269 if(m_Port.IsVerbose()) 00270 { 00271 //this allows us to print data in verbose mode 00272 //when teh port couldn't as it is verbose 00273 MOOSTrace("Roll = %7.3f Pitch = %7.3f Yaw = %7.3f deg\n", 00274 dfCBRoll, 00275 dfCBPitch, 00276 dfCBYaw); 00277 } 00278 00279 } 00280 else 00281 { 00282 MOOSTrace("read %d byte while expecting %d\n", 00283 nRead, 00284 CROSSBOW_POLLED_ANGLE_MODE_REPLY_LENGTH); 00285 } 00286 00287 00288 } 00289 else 00290 { 00291 //in simulated mode there is nothing to do..all data 00292 //arrives via comms. 00293 } 00294 00295 return true; 00296 00297 } 00298 00299