MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Instruments/Ocean/iBattery/BluefinBatteryDriverV1.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 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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines