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 // BluefinBatteryDriverV1.cpp: implementation of the CBluefinBatteryDriverV1 class. 00032 // 00034 #ifdef _WIN32 00035 #pragma warning(disable : 4786) 00036 #endif 00037 00038 #include <MOOSGenLib/MOOSGenLib.h> 00039 #include <strstream> 00040 #include "BluefinBatteryDriverV1.h" 00041 00042 00043 #define NORMAL_CELL_LOW 3.75 00044 #define NORMAL_CELL_HIGH 4.2 00045 #define NORMAL_PACK_LOW 8*NORMAL_CELL_LOW 00046 #define NORMAL_PACK_HIGH 8*NORMAL_CELL_HIGH 00047 00048 00050 // Construction/Destruction 00052 00053 CBluefinBatteryDriverV1::CBluefinBatteryDriverV1() 00054 { 00055 m_Batteries[0].m_nPackAddress = 0x02; 00056 m_Batteries[1].m_nPackAddress = 0x05; 00057 00058 m_Batteries[0].m_dfVoltage = -1; 00059 m_Batteries[0].m_dfVoltage = -1; 00060 00061 00062 } 00063 00064 CBluefinBatteryDriverV1::~CBluefinBatteryDriverV1() 00065 { 00066 Switch(false); 00067 00068 } 00069 00070 bool CBluefinBatteryDriverV1::Initialise() 00071 { 00072 return Switch(true); 00073 } 00074 00075 00076 bool CBluefinBatteryDriverV1::GetData() 00077 { 00078 //read from harware sensor here... 00079 if(!GetCellData(0)) 00080 { 00081 MOOSTrace("Can't reach pack 0\n"); 00082 } 00083 00084 00085 if(!GetCellData(1)) 00086 { 00087 MOOSTrace("Can't reach pack 1\n"); 00088 } 00089 00090 if(!GetPackVoltage(0)) 00091 { 00092 MOOSTrace("Can't reach pack 0\n"); 00093 } 00094 00095 if(!GetPackVoltage(1)) 00096 { 00097 MOOSTrace("Can't reach pack 1\n"); 00098 } 00099 00100 m_Status.m_dfVoltage = GetMeanVoltage(); 00101 00102 return true; 00103 } 00104 00105 00106 00107 bool CBluefinBatteryDriverV1::GetCellData(int nPack) 00108 { 00109 int nAddr = m_Batteries[nPack].m_nPackAddress; 00110 00111 BYTE TxContent[10]; 00112 BYTE RxContent[10]; 00113 00114 TxContent[0] = nAddr&0xFF; 00115 TxContent[1] = 0x03; 00116 00117 for(int i = 0; i<CELLS_PER_PACK;i++) 00118 { 00119 TxContent[2] = i&0xFF; 00120 if(SendAndRecieve(TxContent,3,RxContent,4)) 00121 { 00122 int nLevel =( RxContent[1]<<8) + RxContent[2]; 00123 double dfVoltage = nLevel*5.0/4095.0; 00124 // MOOSTrace("Voltage Pack[%d],Cell[%d] = %f \n",nPack,i+1,dfVoltage); 00125 00126 m_Batteries[nPack].m_Cells[i].m_dfVoltage=dfVoltage; 00127 } 00128 } 00129 00130 return true; 00131 } 00132 00133 bool CBluefinBatteryDriverV1::SendAndRecieve(BYTE *pTx, int nTx, BYTE *pRx, int nRx) 00134 { 00135 int nMsgLen = nTx+5; 00136 BYTE Msg[20]; 00137 00138 int nCheckSum = 0; 00139 for(int i = 0;i<nTx;i++) 00140 { 00141 nCheckSum^=pTx[i]; 00142 } 00143 00144 Msg[0] = 0xAA; 00145 Msg[1] = 0x00; 00146 memcpy(&Msg[2],pTx,nTx); 00147 Msg[2+nTx] = nCheckSum&0xFF; 00148 Msg[3+nTx] = 0xAA; 00149 Msg[4+nTx] = 0x01; 00150 00151 m_pPort->Write((char*)Msg,nMsgLen); 00152 00153 00154 //note we seem to be getting an extra 0x00 at teh end of 00155 //some messages!!! 00156 int nReplyLen = nRx+6; 00157 BYTE Reply[100]; 00158 00159 int nRead = m_pPort->ReadNWithTimeOut((char*)Reply,nReplyLen,0.1); 00160 00161 bool bSuccess = (nRead >0 && nRead>= nRx+2)?true:false; 00162 if(bSuccess) 00163 { 00164 memcpy(pRx,&Reply[2],nRx); 00165 } 00166 00167 00168 return bSuccess; 00169 } 00170 00171 bool CBluefinBatteryDriverV1::SwitchPack(int nPack, bool bOn) 00172 { 00173 int nAddr = m_Batteries[nPack].m_nPackAddress; 00174 00175 00176 /* 00177 Battery on: 00178 addr type (forced operational) 00179 | | | 00180 bat4: 0xAA 0x00 0x04 0x02 0x06 0xAA CRC 0x01 00181 bat5: 0xAA 0x00 0x05 0x02 0x06 0xAA CRC 0x01 00182 00183 Battery off: 00184 addr type (off) 00185 | | | 00186 bat4: 0xAA 0x00 0x04 0x02 0x00 0xAA 0x01 00187 bat5: 0xAA 0x00 0x05 0x02 0x00 0xAA 0x01 00188 */ 00189 00190 BYTE TxContent[3]; 00191 BYTE RxContent[2]; 00192 00193 TxContent[0] = nAddr&0xFF; 00194 TxContent[1] = 0x02; 00195 TxContent[2] = bOn? 0x06 : 0x00; 00196 00197 if(SendAndRecieve(TxContent,3,RxContent,2)) 00198 { 00199 if(RxContent[0]==0x0 && RxContent[1]==0x01) 00200 return true; 00201 } 00202 return false; 00203 } 00204 00205 bool CBluefinBatteryDriverV1::GetPackStatus(int nPack) 00206 { 00207 int nAddr = m_Batteries[nPack].m_nPackAddress; 00208 BYTE TxContent[2]; 00209 BYTE RxContent[3]; 00210 00211 TxContent[0] = nAddr&0xFF; 00212 TxContent[1] = 0x01; 00213 00214 if(SendAndRecieve(TxContent,2,RxContent,3)) 00215 { 00216 BYTE Status = RxContent[1]; 00217 if(Status&&0x6) 00218 { 00219 m_Batteries[nPack].m_eState = ON; 00220 MOOSTrace("Battery[%d] is ON\n",nPack); 00221 } 00222 else 00223 { 00224 m_Batteries[nPack].m_eState = OFF; 00225 MOOSTrace("Battery[%d] is OFF\n",nPack); 00226 } 00227 } 00228 00229 return true; 00230 00231 } 00232 00233 bool CBluefinBatteryDriverV1::GetPackVoltage(int nPack) 00234 { 00235 int nAddr = m_Batteries[nPack].m_nPackAddress; 00236 BYTE TxContent[3]; 00237 BYTE RxContent[3]; 00238 00239 TxContent[0] = nAddr&0xFF; 00240 TxContent[1] = 0x06; 00241 TxContent[2] = 0x03; 00242 00243 if(SendAndRecieve(TxContent,3,RxContent,3)) 00244 { 00245 int nLevel =( RxContent[1]<<8) + RxContent[2]; 00246 double dfVoltage = nLevel*60.0/4095.0; 00247 m_Batteries[nPack].m_dfVoltage = dfVoltage; 00248 //MOOSTrace("TOTAL Voltage Pack[%d] %f \n",nPack,dfVoltage); 00249 return true; 00250 } 00251 00252 return false; 00253 00254 } 00255 00256 bool CBluefinBatteryDriverV1::IsError() 00257 { 00258 //here we embedd the rules.... 00259 m_sError = ""; 00260 00261 for(int nPack = 0;nPack<2;nPack++) 00262 { 00263 int nCell=0; 00264 for(nCell = 0; nCell<CELLS_PER_PACK;nCell++) 00265 { 00266 double dfVoltage = m_Batteries[nPack].m_Cells[nCell].m_dfVoltage; 00267 00268 if(dfVoltage<NORMAL_CELL_LOW) 00269 { 00270 char sError[100]; 00271 sprintf(sError,"Cell %d on pack %d is undervoltage %f", 00272 nCell, 00273 nPack, 00274 dfVoltage); 00275 m_sError = sError; 00276 00277 SwitchPack(nPack,false); 00278 00279 return true; 00280 } 00281 00282 if(dfVoltage>NORMAL_CELL_HIGH) 00283 { 00284 char sError[100]; 00285 sprintf(sError,"Cell %d on pack %d is overvoltage %f (stop charging if applicable)", 00286 nCell, 00287 nPack, 00288 dfVoltage); 00289 m_sError = sError; 00290 00291 SwitchPack(nPack,false); 00292 00293 return true; 00294 } 00295 } 00296 00297 //now check total voltages!!! 00298 if(m_Batteries[nPack].m_dfVoltage<NORMAL_PACK_LOW) 00299 { 00300 char sError[100]; 00301 sprintf(sError,"Pack %d is undervoltage %f ", 00302 nCell, 00303 nPack, 00304 m_Batteries[nPack].m_dfVoltage); 00305 m_sError = sError; 00306 00307 SwitchPack(nPack,false); 00308 00309 return true; 00310 } 00311 00312 if(m_Batteries[nPack].m_dfVoltage>NORMAL_PACK_HIGH) 00313 { 00314 char sError[100]; 00315 sprintf(sError,"Pack %d is overvoltage %f (stop charging if applicable)", 00316 nCell, 00317 nPack, 00318 m_Batteries[nPack].m_dfVoltage); 00319 m_sError = sError; 00320 00321 SwitchPack(nPack,false); 00322 00323 return true; 00324 } 00325 } 00326 00327 00328 00329 return false; 00330 00331 } 00332 00333 double CBluefinBatteryDriverV1::GetMeanVoltage() 00334 { 00335 return (m_Batteries[0].m_dfVoltage+m_Batteries[0].m_dfVoltage)/2; 00336 } 00337 00338 bool CBluefinBatteryDriverV1::Switch(bool bSwitch) 00339 { 00340 if(!SwitchPack(0,bSwitch)) 00341 { 00342 MOOSTrace("Can't reach pack 0\n"); 00343 } 00344 00345 if(!SwitchPack(1,bSwitch)) 00346 { 00347 MOOSTrace("Can't reach pack 0\n"); 00348 } 00349 00350 GetPackStatus(0); 00351 GetPackStatus(1); 00352 00353 return true; 00354 } 00355 00356 string CBluefinBatteryDriverV1::GetCellsString() 00357 { 00358 ostrstream os; 00359 00360 for(int nPack = 0;nPack<2;nPack++) 00361 { 00362 os<<"PACK="<<nPack<<":"; 00363 os<<"V="<<m_Batteries[nPack].m_dfVoltage<<","; 00364 os<<"Cells=["; 00365 00366 for(int nCell = 0; nCell<CELLS_PER_PACK;nCell++) 00367 { 00368 os<<m_Batteries[nPack].m_Cells[nCell].m_dfVoltage<<","; 00369 } 00370 00371 os<<"];"; 00372 } 00373 00374 os<<ends; 00375 00376 string sResult = os.str(); 00377 00378 os.rdbuf()->freeze(0); 00379 00380 return sResult; 00381 }