|
From: <bo...@us...> - 2009-11-08 11:51:38
|
Revision: 457
http://gearbox.svn.sourceforge.net/gearbox/?rev=457&view=rev
Author: borax00
Date: 2009-11-08 11:51:23 +0000 (Sun, 08 Nov 2009)
Log Message:
-----------
MR Changes
Modified Paths:
--------------
gearbox/trunk/doc/history.dox
gearbox/trunk/src/gbxgarminacfr/driver.cpp
gearbox/trunk/src/gbxgarminacfr/driver.h
gearbox/trunk/src/gbxgarminacfr/nmea.cpp
gearbox/trunk/src/gbxgarminacfr/nmea.h
gearbox/trunk/src/gbxgarminacfr/test/test.cpp
gearbox/trunk/src/gbxsickacfr/messages.cpp
gearbox/trunk/src/gbxsickacfr/test/test.cpp
gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.cpp
gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.h
gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverhealthchecks.cpp
gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverparser.cpp
gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.cpp
gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.h
gearbox/trunk/src/gbxsmartbatteryacfr/test/darttest/checksumtest.cpp
gearbox/trunk/src/gbxsmartbatteryacfr/test/longtest.cpp
gearbox/trunk/src/gbxutilacfr/exceptions.cpp
gearbox/trunk/src/gbxutilacfr/exceptions.h
Modified: gearbox/trunk/doc/history.dox
===================================================================
--- gearbox/trunk/doc/history.dox 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/doc/history.dox 2009-11-08 11:51:23 UTC (rev 457)
@@ -46,6 +46,13 @@
@par Updated libraries
+-libGbxSmartBatteryAcfr (tobi)
+ - improved robustness by encapsulating data of the oceanserversystem class and implementing access/set and check-for-empty functions
+ - improved healthcheck functions
+ - bug fix related to initialisation
+ - improved exception and error handling
+ - added a raw data record to the oceanserversystem data record useful for debugging
+
- libflexiport
- The UDP port type now properly supports sending and receiving broadcast packets on all operating systems.
(GeoffB)
@@ -56,7 +63,7 @@
- Thread class: now derives from gbxutilacfr::Stoppable. No changes in user code are requried. (alexm)
- Function checkedSleep() is defined in terms of the new light interface class gbxutilacfr::Stoppable.
No changes in user code are required. (alexm)
- - Implemented store::peek() (Alexb)
+ - Implemented store::peek() (AlexB)
- libGbxUtilAcfr:
- Status class: removed SubsystemStalled from the list of health types for a subsystem. The stall condition
Modified: gearbox/trunk/src/gbxgarminacfr/driver.cpp
===================================================================
--- gearbox/trunk/src/gbxgarminacfr/driver.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxgarminacfr/driver.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -23,16 +23,17 @@
#include "driver.h"
using namespace std;
-using namespace gbxgarminacfr;
///////////////////////////////////////
+namespace gbxgarminacfr {
+
namespace {
// Get the useful bits from a GGA message
-GenericData* extractGgaData( gbxgpsutilacfr::NmeaMessage& msg, int timeSec, int timeUsec )
+GenericData* extractGgaData( const gbxgpsutilacfr::NmeaMessage& msg, int timeSec, int timeUsec )
{
- GgaData* data = new GgaData;
+ std::auto_ptr<GgaData> data( new GgaData );
data->timeStampSec = timeSec;
data->timeStampUsec = timeUsec;
@@ -58,7 +59,7 @@
data->longitude = 0.0;
data->altitude = 0.0;
data->geoidalSeparation = 0.0;
- return data;
+ return data.release();
case '1':
data->fixType = Autonomous;
break;
@@ -84,18 +85,20 @@
data->longitude=dir*(deg+(min/60.0));
//altitude
- data->altitude=atof(msg.getDataToken(Hgt).c_str());
+ data->isAltitudeKnown = !msg.isDataTokenEmpty(Hgt);
+ if ( data->isAltitudeKnown )
+ data->altitude=atof(msg.getDataToken(Hgt).c_str());
//geoidal Separation
data->geoidalSeparation=atof(msg.getDataToken(GeoidHgt).c_str());
- return data;
+ return data.release();
}
// VTG provides velocity and heading information
-GenericData* extractVtgData( gbxgpsutilacfr::NmeaMessage& msg, int timeSec, int timeUsec )
+GenericData* extractVtgData( const gbxgpsutilacfr::NmeaMessage& msg, int timeSec, int timeUsec )
{
- VtgData* data = new VtgData;
+ std::auto_ptr<VtgData> data( new VtgData );
data->timeStampSec = timeSec;
data->timeStampUsec = timeUsec;
@@ -104,15 +107,16 @@
enum VtgTokens{MsgType=0,HeadingTrue,T,HeadingMag,M,SpeedKnots,
N,SpeedKPH,K,ModeInd};
- //Check for an empty string. Means that we are not moving
- //When the message has empty fields tokeniser skips so we get the next field inline.
- if( msg.getDataToken(HeadingTrue)[0] == 'T' ) {
- data->headingTrue=0.0;
- data->headingMagnetic=0.0;
- data->speed=0.0;
- // NOTE: not processing the rest!
- return data;
+ //Check for an empty string. Means that we can't tell anything useful.
+ if ( msg.isDataTokenEmpty(HeadingTrue) )
+ {
+ data->isValid = false;
+ data->headingTrue = 0.0;
+ data->headingMagnetic = 0.0;
+ data->speed = 0.0;
+ return data.release();
}
+ data->isValid = true;
// true heading
double headingRad = DEG2RAD(atof(msg.getDataToken(HeadingTrue).c_str()));
@@ -128,16 +132,16 @@
data->speed=atof(msg.getDataToken(SpeedKPH).c_str());
data->speed*=(1000/3600.0);
- return data;
+ return data.release();
}
// RME message. This one is garmin specific... Give position error estimates
// See doc.dox for a discussion of the position errors as reported here.
// Essentially the EPE reported by the garmin is a 1 sigma error (RMS) or a
// 68% confidence bounds.
-GenericData* extractRmeData( gbxgpsutilacfr::NmeaMessage& msg, int timeSec, int timeUsec )
+GenericData* extractRmeData( const gbxgpsutilacfr::NmeaMessage& msg, int timeSec, int timeUsec )
{
- RmeData* data = new RmeData;
+ std::auto_ptr<RmeData> data( new RmeData );
data->timeStampSec = timeSec;
data->timeStampUsec = timeUsec;
@@ -145,11 +149,33 @@
//Names for the RME message items
enum RmeTokens{MsgType=0,HError,M1,VError,M2,EPE,M3};
+ if ( msg.isDataTokenEmpty(HError) )
+ {
+ // No valid information
+ data->isValid = false;
+ data->isVerticalPositionErrorValid = false;
+ data->horizontalPositionError = 0.0;
+ data->verticalPositionError = 0.0;
+ data->estimatedPositionError = 0.0;
+ return data.release();
+ }
+ data->isValid = true;
+
data->horizontalPositionError = atof(msg.getDataToken(HError).c_str());
- data->verticalPositionError = atof(msg.getDataToken(VError).c_str());
+ if ( msg.isDataTokenEmpty(VError) )
+ {
+ data->isVerticalPositionErrorValid = false;
+ data->verticalPositionError = -1;
+ }
+ else
+ {
+ data->isVerticalPositionErrorValid = true;
+ data->verticalPositionError = atof(msg.getDataToken(VError).c_str());
+ }
+
data->estimatedPositionError = atof(msg.getDataToken(EPE).c_str());
- return data;
+ return data.release();
}
}
@@ -172,9 +198,9 @@
Config::toString() const
{
std::stringstream ss;
- ss << "Garmin driver config: " <<
- "\tdevice="<<device <<
- "\twill read sentences: GPGGA="<<readGga<<" GPVTG="<<readVtg<<" PGRME="<<readRme;
+ ss << "Garmin driver config: " << endl
+ << "\tdevice="<<device << endl
+ << "\twill read sentences: GPGGA="<<readGga<<" GPVTG="<<readVtg<<" PGRME="<<readRme;
return ss.str();
}
@@ -209,7 +235,15 @@
Driver::~Driver()
{
- disableDevice();
+ // Don't throw from destructors...
+ try {
+ disableDevice();
+ }
+ catch ( const std::exception &e )
+ {
+ cout << "Driver::~Driver: exception while disabling: " << e.what() << endl;
+ }
+ catch ( ... ) {}
}
void
@@ -240,6 +274,7 @@
gbxgpsutilacfr::NmeaMessage disableAllMsg( "$PGRMO,,2*xx\r\n",gbxgpsutilacfr::AddChecksum );
serial_->writeString( disableAllMsg.sentence() );
+ // alexb: what is this sleep for?
sleep(1);
if ( config_.readGga ) {
@@ -247,7 +282,6 @@
serial_->writeString( enableGgaMsg.sentence() );
}
-
if ( config_.readVtg ) {
gbxgpsutilacfr::NmeaMessage enableVtgMsg( "$PGRMO,GPVTG,1*xx\r\n",gbxgpsutilacfr::AddChecksum );
serial_->writeString( enableVtgMsg.sentence() );
@@ -258,6 +292,7 @@
serial_->writeString( enableRmeMsg.sentence() );
}
+ // alexb: what is this sleep for?
sleep(1);
}
@@ -273,11 +308,7 @@
Driver::read()
{
std::auto_ptr<GenericData> genericData;
-
gbxgpsutilacfr::NmeaMessage nmeaMessage;
- // Make sure that we clear our internal data structures
- // alexm: is this necessary? should NmeaMessage do it for itself?
- memset((void*)(&nmeaMessage) , 0 , sizeof(nmeaMessage));
int nmeaExceptionCount = 0;
int nmeaFailChecksumCount = 0;
@@ -330,7 +361,7 @@
//Put it into the message object and checksum the data
try {
// This throws if it cannot find the * to deliminate the checksum field
- nmeaMessage.setSentence( serialData.c_str(), gbxgpsutilacfr::TestChecksum );
+ nmeaMessage.setSentence( serialData, gbxgpsutilacfr::TestChecksum );
}
catch ( const gbxgpsutilacfr::NmeaException& e ) {
//Don't throw on isolated checksum problems
@@ -384,7 +415,10 @@
else
throw gbxutilacfr::Exception( ERROR_INFO, "got unexpected GPGGA message" );
genericData.reset( extractGgaData( nmeaMessage, now.tv_sec, now.tv_usec ) );
- break;
+ if ( genericData.get() )
+ break;
+ else
+ continue;
}
else if ( MsgType == "$GPVTG" ) {
if ( config_.readVtg )
@@ -392,7 +426,10 @@
else
throw gbxutilacfr::Exception( ERROR_INFO, "got unexpected GPVTG message" );
genericData.reset( extractVtgData( nmeaMessage, now.tv_sec, now.tv_usec ) );
- break;
+ if ( genericData.get() )
+ break;
+ else
+ continue;
}
else if ( MsgType == "$PGRME" ) {
if ( config_.readRme )
@@ -400,7 +437,10 @@
else
throw gbxutilacfr::Exception( ERROR_INFO, "got unexpected PGRME message" );
genericData.reset( extractRmeData( nmeaMessage, now.tv_sec, now.tv_usec ) );
- break;
+ if ( genericData.get() )
+ break;
+ else
+ continue;
}
else if ( MsgType == "$PGRMO" ) {
//This message is sent by us to control msg transmission and then echoed by GPS
@@ -415,8 +455,64 @@
else
throw gbxutilacfr::Exception( ERROR_INFO, ss.str() );
}
+ }
+ return genericData;
+}
+std::string toString( const FixType &f )
+{
+ switch ( f )
+ {
+ case Invalid: return "Invalid";
+ case Autonomous: return "Autonomous";
+ case Differential: return "Differential";
+ default: return "??";
}
+}
- return genericData;
+std::string toString( const GgaData &d )
+{
+ stringstream ss;
+ ss << endl;
+ ss << " timeStampSec : " << d.timeStampSec << endl
+ << " timeStampUsec : " << d.timeStampUsec << endl
+ << " utcTimeHrs : " << d.utcTimeHrs << endl
+ << " utcTimeMin : " << d.utcTimeMin << endl
+ << " utcTimeSec : " << d.utcTimeSec << endl
+ << " latitude : " << d.latitude << endl
+ << " longitude : " << d.longitude << endl
+ << " isAltitudeKnown : " << d.isAltitudeKnown << endl
+ << " altitude : " << d.altitude << endl
+ << " fixType : " << d.fixType << endl
+ << " satellites : " << d.satellites << endl
+ << " horizontalDilutionOfPosition : " << d.horizontalDilutionOfPosition << endl
+ << " geoidalSeparation : " << d.geoidalSeparation;
+ return ss.str();
}
+std::string toString( const VtgData &d )
+{
+ stringstream ss;
+ ss << endl;
+ ss << " timeStampSec : " << d.timeStampSec << endl
+ << " timeStampUsec : " << d.timeStampUsec << endl
+ << " isValid : " << d.isValid << endl
+ << " headingTrue : " << d.headingTrue << endl
+ << " headingMagnetic : " << d.headingMagnetic << endl
+ << " speed : " << d.speed;
+ return ss.str();
+}
+std::string toString( const RmeData &d )
+{
+ stringstream ss;
+ ss << endl;
+ ss << " timeStampSec : " << d.timeStampSec << endl
+ << " timeStampUsec : " << d.timeStampUsec << endl
+ << " isValid : " << d.isValid << endl
+ << " horizontalPositionError : " << d.horizontalPositionError << endl
+ << " isVerticalPositionErrorValid : " << d.isVerticalPositionErrorValid << endl
+ << " verticalPositionError : " << d.verticalPositionError << endl
+ << " estimatedPositionError : " << d.estimatedPositionError;
+ return ss.str();
+}
+
+}
Modified: gearbox/trunk/src/gbxgarminacfr/driver.h
===================================================================
--- gearbox/trunk/src/gbxgarminacfr/driver.h 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxgarminacfr/driver.h 2009-11-08 11:51:23 UTC (rev 457)
@@ -85,6 +85,7 @@
//! Differentially corrected
Differential
};
+std::string toString( const FixType &f );
//! Fix data structure. Note that when fixType is Invalid, all other data except the time stamps
//! are meaningless.
@@ -114,7 +115,9 @@
double latitude;
//! Longitude [degrees]
double longitude;
- //! Altitude [metres above ellipsoid]
+ //! Altitude is meaningful if and only if isAltitudeKnown
+ bool isAltitudeKnown;
+ //! Altitude [metres above ellipsoid] (only meaningful if isAltitudeKnown)
double altitude;
//! Fix type. When fixType is Invalid, all other data except the time stamps
@@ -130,6 +133,9 @@
//! Height of geoid (mean sea level) above WGS84 ellipsoid [metres]
double geoidalSeparation;
};
+std::string toString( const GgaData &d );
+inline std::ostream &operator<<( std::ostream &s, const GgaData &d )
+{ return s << toString(d); }
//! Vector track and speed over ground data structure.
class VtgData : public GenericData
@@ -143,6 +149,10 @@
//! Time (according to the computer clock) when data was measured.
//! Number of microseconds
int timeStampUsec;
+
+ //! When false, means that the GPS unit can't make a valid measurement
+ //! (so all data other than the timestamp is meaningless).
+ bool isValid;
//! Heading/track/course with respect to true North [rad]
double headingTrue;
@@ -151,6 +161,9 @@
//! Horizontal velocity [metres/second]
double speed;
};
+std::string toString( const VtgData &d );
+inline std::ostream &operator<<( std::ostream &s, const VtgData &d )
+{ return s << toString(d); }
//! Gps data structure
class RmeData : public GenericData
@@ -165,6 +178,14 @@
//! Number of microseconds
int timeStampUsec;
+ //! When false, means that the GPS unit can't make a valid measurement
+ //! (so all data other than the timestamp is meaningless).
+ bool isValid;
+
+ //! When false, means that the GPS unit can't tell us anything
+ //! about our vertical error
+ bool isVerticalPositionErrorValid;
+
//! Horizontal position error: one standard deviation [metres)]
double horizontalPositionError;
//! Vertical position error: one standard deviation [metres]
@@ -173,6 +194,9 @@
//! Estimated position error.
double estimatedPositionError;
};
+std::string toString( const RmeData &d );
+inline std::ostream &operator<<( std::ostream &s, const RmeData &d )
+{ return s << toString(d); }
/*!
Garmin GPS driver.
Modified: gearbox/trunk/src/gbxgarminacfr/nmea.cpp
===================================================================
--- gearbox/trunk/src/gbxgarminacfr/nmea.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxgarminacfr/nmea.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -12,33 +12,34 @@
#include <string>
#include <iostream>
#include <assert.h>
+#include <sstream>
#include <gbxutilacfr/tokenise.h>
-//////////////////////////////
+// //////////////////////////////
-// Ensure we have strnlen
-// eg. Solaris doesn't define strnlen in string.h, so define it here.
-#if !HAVE_STRNLEN
+// // Ensure we have strnlen
+// // eg. Solaris doesn't define strnlen in string.h, so define it here.
+// #if !HAVE_STRNLEN
-#include <cstring>
+// #include <cstring>
-// inline the fucker to guard against multiple inclusion, without the
-// hassle of a special lib.
-inline size_t strnlen(const char *s, size_t maxlen)
-{
- char *p;
- if (s == NULL) {
- return maxlen;
- }
- p = (char *)memchr(s, 0, maxlen);
- if (p == NULL) {
- return maxlen;
- }
- return ((p - s) + 1);
-}
-#endif
+// // inline the fucker to guard against multiple inclusion, without the
+// // hassle of a special lib.
+// inline size_t strnlen(const char *s, size_t maxlen)
+// {
+// char *p;
+// if (s == NULL) {
+// return maxlen;
+// }
+// p = (char *)memchr(s, 0, maxlen);
+// if (p == NULL) {
+// return maxlen;
+// }
+// return ((p - s) + 1);
+// }
+// #endif
-//////////////////////////////
+// //////////////////////////////
#include "nmea.h"
@@ -57,39 +58,30 @@
void NmeaMessage::init()
{
- haveSentence_ = false;
- haveTokens_ = false;
haveCheckSum_ = false;
checkSumOK_ = false;
// Now clear the internal data store
- sentence_[0] = 0;
+ sentence_.clear();
dataTokens_.clear();
}
-
-NmeaMessage::NmeaMessage(const char *sentence, int testCheckSum)
+NmeaMessage::NmeaMessage(const std::string &sentence, NmeaMessageOptions addOrTestCheckSum)
{
init();
- setSentence(sentence,testCheckSum);
+ setSentence(sentence,addOrTestCheckSum);
}
//Load the data as requested and test the checksum if we are asked to.
void
-NmeaMessage::setSentence(const char *data, int AddOrTestCheckSum)
+NmeaMessage::setSentence(const std::string &data, NmeaMessageOptions addOrTestCheckSum)
{
init();
-
- strncpy(sentence_,data, MAX_SENTENCE_LEN);
- //terminate just in case, Note that we have a buffer which is
- //MAX_SENTENCE_LEN + 1 long!
-
- sentence_[MAX_SENTENCE_LEN] = '\0';
- haveSentence_ = true;
+ sentence_ = data;
- switch ( AddOrTestCheckSum )
+ switch ( addOrTestCheckSum )
{
case TestChecksum: {
// This is for Rx'd data that we need to test for correct reception
@@ -106,7 +98,7 @@
case DontTestOrAddChecksum:
break;
default:
- assert( true && "unrecognized message option" );
+ assert( false && "unrecognized message option" );
}
}
@@ -116,34 +108,36 @@
haveCheckSum_ = true;
checkSumOK_ = false;
- //First save the checksum chars from the existing message
- char* ptr;
- char chksum_HIB,chksum_LOB;
-
//First save the existing two checksum chars from the message
//These are straight after the '*' character
- ptr = strchr(sentence_, NMEAChecksumDelim);
- if ( !ptr ) {
-// cout<<"device: no checksum delimiter"<<endl;
+ const size_t starPos = sentence_.find( NMEAChecksumDelim );
+ if ( starPos == std::string::npos )
+ {
+ // cout<<"device: no checksum delimiter"<<endl;
return false;
}
+
+ if ( starPos+2 >= sentence_.size() )
+ {
+ // cout<<"device: no checksum after delimiter"<<endl;
+ return false;
+ }
//save the high and low bytes of the checksum
//Make sure they are in upper case!
- chksum_HIB = (char)toupper(*(++ptr));
- chksum_LOB = (char)toupper(*(ptr + 1));
-
+ const int checksumPos = starPos+1;
+ const char chksum_HIB = (char)toupper(sentence_[checksumPos]);
+ const char chksum_LOB = (char)toupper(sentence_[checksumPos+1]);
//invalidate the existing checksum
- *ptr = *(ptr+1) = 'x';
-
- //****NOTE** We leave the ptr pointing at the first chksum byte
-
+ sentence_[checksumPos] = 'x';
+ sentence_[checksumPos+1] = 'x';
+
//Re-calculate our own copy of the checksum
addCheckSum();
//Now compare our saved version with our new ones
- if( (chksum_HIB == *ptr) && (chksum_LOB == *(ptr+1)) ) {
+ if( (chksum_HIB == sentence_[checksumPos]) && (chksum_LOB == sentence_[checksumPos+1]) ) {
//all looked good!
checkSumOK_ = true;
return true;
@@ -160,9 +154,9 @@
// the checksum, and that the checksum delimiter is there
void
NmeaMessage::addCheckSum()
-{
- assert( haveSentence_ && "calling addCheckSum() without a sentence" );
-
+{
+ assert( haveSentence() && "calling addCheckSum() without a sentence" );
+
haveCheckSum_ = true;
//check that we have the '$' at the start
@@ -172,12 +166,11 @@
unsigned char chkRunning = 0;
+ // we start from 1 to skip the leading '$'
int loopCount;
- unsigned char nextChar;
- // we start from 1 to skip the leading '$'
- for( loopCount=1; loopCount<MAX_SENTENCE_LEN; ++loopCount )
+ for ( loopCount = 1; loopCount < (int)(sentence_.size()); loopCount++ )
{
- nextChar = static_cast<unsigned char>(sentence_[loopCount]);
+ unsigned char nextChar = static_cast<unsigned char>(sentence_[loopCount]);
// no delimiter uh oh
if( (nextChar=='\r') || (nextChar=='\n') || (nextChar=='\0') ) {
@@ -196,9 +189,14 @@
// Keep the running XOR total
chkRunning ^= nextChar;
}
+
+ if ( loopCount+2 >= (int)(sentence_.size()) )
+ {
+ throw NmeaException("addCheckSum(): no space for checksum of '*' not found.");
+ }
//Put the byte values as upper case HEX back into the message
- sprintf( sentence_ + loopCount + 1,"%02X", chkRunning );
+ sprintf( &(sentence_[loopCount + 1]),"%02X", chkRunning );
}
// Parse the data fields of our message...
@@ -218,3 +216,39 @@
//keep track of what we have done.
haveTokens_ = true;
}
+
+bool
+NmeaMessage::isDataTokenEmpty(int i) const
+{
+ if ( i >= (int)(dataTokens_.size()) )
+ {
+ stringstream ss;
+ ss << "NmeaMessage::" << __func__
+ << ": attempt to getDataToken("<<i<<") but only " << dataTokens_.size() << " exist in sentence: "
+ << sentence_;
+ throw NmeaException( ss.str() );
+ }
+ return dataTokens_[i].empty();
+}
+
+const std::string &
+NmeaMessage::getDataToken(int i) const
+{
+ if ( i >= (int)(dataTokens_.size()) )
+ {
+ stringstream ss;
+ ss << "NmeaMessage::" << __func__
+ << ": attempt to getDataToken("<<i<<") but only " << dataTokens_.size() << " exist in sentence: "
+ << sentence_;
+ throw NmeaException( ss.str() );
+ }
+ if ( dataTokens_[i].empty() )
+ {
+ stringstream ss;
+ ss << "NmeaMessage::" << __func__
+ << ": attempt to getDataToken("<<i<<") but this token is empty in sentence: "
+ << sentence_;
+ throw NmeaException( ss.str() );
+ }
+ return dataTokens_[i];
+}
Modified: gearbox/trunk/src/gbxgarminacfr/nmea.h
===================================================================
--- gearbox/trunk/src/gbxgarminacfr/nmea.h 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxgarminacfr/nmea.h 2009-11-08 11:51:23 UTC (rev 457)
@@ -78,14 +78,14 @@
{
public:
NmeaMessage();
- NmeaMessage(const char *sentence, int testCheckSum=DontTestOrAddChecksum );
+ NmeaMessage(const std::string &sentence, NmeaMessageOptions addOrTestCheckSum=DontTestOrAddChecksum );
// Set up the internal data for a sentence.
// May throw NmeaException if TestChecksum is specified.
- void setSentence(const char *data, int testCheckSum=DontTestOrAddChecksum );
+ void setSentence(const std::string &data, NmeaMessageOptions addOrTestCheckSum=DontTestOrAddChecksum );
- // Do we only have the raw string?
- bool haveSentence() const { return haveSentence_; };
+ // Do we have the raw string?
+ bool haveSentence() const { return !sentence_.empty(); };
// Do we have parsed fields?
bool haveTokens() const { return haveTokens_; };
@@ -101,11 +101,14 @@
bool testChecksumOk();
// Return the raw sentence string
- const char* sentence() { return sentence_; };
+ const std::string &sentence() const { return sentence_; };
- // Return a single data token as a string
- std::string& getDataToken(int i) { return dataTokens_[i]; };
+ // Return a single data token as a string.
+ // Throws an exception if that token is empty (see 'isDataTokenEmpty()')
+ const std::string &getDataToken(int i) const;
+ bool isDataTokenEmpty(int i) const;
+
// Return the number of fields
int numDataTokens() const { return dataTokens_.size(); };
@@ -116,15 +119,14 @@
void init();
// May throw NmeaException.
void addCheckSum();
- // Do we only have the raw string ?
- bool haveSentence_;
// Have we parsed data into tokens ?
bool haveTokens_;
// Have we a checksum and is it valid?
bool haveCheckSum_;
bool checkSumOK_;
// The raw sentence, allow for terminator
- char sentence_[MAX_SENTENCE_LEN+1];
+// char sentence_[MAX_SENTENCE_LEN+1];
+ std::string sentence_;
// The tokenised data
std::vector<std::string> dataTokens_;
};
Modified: gearbox/trunk/src/gbxgarminacfr/test/test.cpp
===================================================================
--- gearbox/trunk/src/gbxgarminacfr/test/test.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxgarminacfr/test/test.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -32,22 +32,31 @@
// defaults
string port = "/dev/ttyS0";
bool quiet = false;
+ int numReads = 30;
+ int debugLevel = 5;
// Get some options from the command line
- while ((opt = getopt(argc, argv, "p:q")) != -1)
+ while ((opt = getopt(argc, argv, "p:n:d:q")) != -1)
{
switch ( opt )
{
case 'p':
port = optarg;
break;
+ case 'n':
+ numReads=atoi(optarg);
+ break;
+ case 'd':
+ debugLevel=atoi(optarg);
+ break;
case 'q':
quiet = true;
break;
default:
cout << "Usage: " << argv[0] << " [-p port]" << endl << endl
- << "-p port\tPort the device is connected to. E.g. /dev/ttyS0"
- << "-q \tMakes normal operation quiet, only errors are traced." << endl;
+ << "-p port \tPort the device is connected to. E.g. /dev/ttyS0" << endl
+ << "-n numReads\tNumber of times to read from the device" << endl
+ << "-q \tMakes normal operation quiet, only errors are traced." << endl;
return 1;
}
}
@@ -66,17 +75,16 @@
cout << "Using configuration: " << config.toString() << endl;
// Instantiate objects to handle messages from the driver
- bool debug = 5;
if ( quiet )
- debug = 0;
- gbxutilacfr::TrivialTracer tracer( debug );
+ debugLevel = 0;
+ gbxutilacfr::TrivialTracer tracer( debugLevel );
gbxutilacfr::TrivialStatus status( tracer );
// Instantiate the driver itself
- gbxgarminacfr::Driver* device;
+ std::auto_ptr<gbxgarminacfr::Driver> device;
try
{
- device = new gbxgarminacfr::Driver( config, tracer, status );
+ device.reset( new gbxgarminacfr::Driver( config, tracer, status ) );
}
catch ( const std::exception& e )
{
@@ -88,7 +96,6 @@
std::auto_ptr<gbxgarminacfr::GenericData> data;
// Read a few times
- const int numReads = 30 + 10000000;
for ( int i=0; i < numReads; i++ )
{
try
@@ -142,7 +149,5 @@
cout <<"Test: Failed to read data: "<<e.what()<<endl;
}
}
-
- delete device;
return 0;
}
Modified: gearbox/trunk/src/gbxsickacfr/messages.cpp
===================================================================
--- gearbox/trunk/src/gbxsickacfr/messages.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsickacfr/messages.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -893,6 +893,7 @@
if ( checksumFailed )
{
IceUtil::Time t = IceUtil::Time::now();
+ cout << "========== Checksum failed, timestamp: " << t.toDateTime() << endl;
// cout << "WARN(messages.cpp): " << t.toDateTime() << ": Checksum failed at buf pos " <<bytesParsed << endl;
// cout<<"TRACE(messages.cpp): checksum was over: " << toHexString( &(buffer[bytesParsed]), telegramLength ) << endl;
bytesParsed++;
Modified: gearbox/trunk/src/gbxsickacfr/test/test.cpp
===================================================================
--- gearbox/trunk/src/gbxsickacfr/test/test.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsickacfr/test/test.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -12,7 +12,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include <iostream>
#include <sstream>
@@ -28,30 +27,35 @@
//
int main( int argc, char **argv )
{
- int opt;
int baud = 38400;
string port = "/dev/ttyS0";
int debug = 0;
bool showScan = false;
// Get some options from the command line
- while ((opt = getopt(argc, argv, "p:b:vs")) != -1)
+ for ( int i=1; i < argc; i++ )
{
- switch ( opt )
+ if ( !strcmp(argv[i],"-p") && i < argc-1 )
{
- case 'p':
- port = optarg;
- break;
- case 'b':
- baud = atoi( optarg );
- break;
- case 'v':
- debug = 5;
- break;
- case 's':
+ port = argv[i+1];
+ i++;
+ }
+ else if ( !strcmp(argv[i],"-b") && i < argc-1 )
+ {
+ baud = atoi(argv[i+1]);
+ i++;
+ }
+ else if ( !strcmp(argv[i],"-v") )
+ {
+ debug = true;
+ }
+ else if ( !strcmp(argv[i],"-s") )
+ {
showScan = true;
- break;
- default:
+ }
+ else
+ {
+ cout << "Unknown option: " << argv[i] << endl;
cout << "Usage: " << argv[0] << " [-p port] [-b baud] [-v(erbose)] [-s(how scan)]" << endl << endl
<< "-p port\tPort the laser scanner is connected to. E.g. /dev/ttyS0" << endl
<< "-b baud\tBaud rate to connect at (9600, 19200, 38400, or 500000)." << endl;
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.cpp
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -36,7 +36,7 @@
// read new data, this may throw
reader_->read(data);
- // if successful, reset counter and string
+ // successful read: reset counter and string
exceptionCounter_ = 0;
exceptionString_ = "";
@@ -54,8 +54,8 @@
exceptionCounter_++;
stringstream ssEx;
ssEx << e.what() << endl;
- for (unsigned int i=0; i<data.rawRecord.size(); i++)
- ssEx << data.rawRecord[i] << endl;
+ for (unsigned int i=0; i<data.rawRecord().size(); i++)
+ ssEx << data.rawRecord()[i] << endl;
ssEx << endl;
exceptionString_ = exceptionString_ + ssEx.str();
@@ -79,7 +79,8 @@
}
// return updated internal storage
- // if there was an exception on read, we just return the previous record
+ // if there was an exception on read which does not get re-thrown above,
+ // the internal storage will contain the previous record
return data_;
}
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.h
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.h 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/oceanserver.h 2009-11-08 11:51:23 UTC (rev 457)
@@ -38,6 +38,7 @@
//! Reads data from OceanServer, incrementally updates internal storage
//! Returns a reference to the internal storage
//! May throw gbxutilacfr::Exception
+ //! May return an empty record ( check with isEmpty() )
const gbxsmartbatteryacfr::OceanServerSystem& getData();
private:
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverhealthchecks.cpp
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverhealthchecks.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverhealthchecks.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -18,12 +18,24 @@
{
namespace
{
-
+
+ bool isRecordEmpty( const OceanServerSystem &batteryData,
+ vector<string> &warnShort,
+ vector<string> &warnVerbose)
+ {
+ if ( !batteryData.isEmpty() )
+ return false;
+
+ warnVerbose.push_back("The OceanServerSystem data record was empty");
+ warnShort.push_back("EMPTY RECORD");
+ return true;
+ }
+
bool haveBattery( const OceanServerSystem &batteryData,
vector<string> &warnShort,
vector<string> &warnVerbose )
{
- const vector<bool> &bats = batteryData.availableBatteries;
+ const vector<bool> &bats = batteryData.availableBatteries();
bool haveBattery = false;
for (unsigned int i=0; i<bats.size(); i++)
{
@@ -58,10 +70,12 @@
std::vector<std::string> &warnVerbose,
int expectedNumBatteries )
{
+ if ( isRecordEmpty(batteryData, warnShort, warnVerbose) ) return true;
+
bool haveWarning = false;
int numBatteries = 0;
- const vector<bool> &bats = batteryData.availableBatteries;
+ const vector<bool> &bats = batteryData.availableBatteries();
for (unsigned int i=0; i<bats.size(); i++)
{
@@ -72,10 +86,10 @@
if ( numBatteries!=expectedNumBatteries )
{
stringstream ssWarnShort;
- ssWarnShort << "ONLY " << numBatteries << " BATTERIES! ";
+ ssWarnShort << "HAVE " << numBatteries << ", EXP " << expectedNumBatteries << " BAT! ";
warnShort.push_back(ssWarnShort.str());
stringstream ssWarnVerbose;
- ssWarnVerbose << "Only found " << numBatteries << " battery modules (expected to see " << expectedNumBatteries << ")" << endl;
+ ssWarnVerbose << "Found " << numBatteries << " battery modules (expected to see " << expectedNumBatteries << ")" << endl;
warnVerbose.push_back( ssWarnVerbose.str() );
haveWarning = true;
}
@@ -89,6 +103,8 @@
int numCyclesThreshhold,
bool printRawRecord )
{
+ if ( isRecordEmpty(batteryData, warnShort, warnVerbose) ) return true;
+
bool haveWarning = false;
map<int,SmartBattery>::const_iterator it;
@@ -114,7 +130,7 @@
if (haveWarning && printRawRecord)
{
stringstream ssWarnVerbose;
- ssWarnVerbose << "Latest raw record: " << endl << toString(batteryData.rawRecord) << endl;
+ ssWarnVerbose << "Latest raw record: " << endl << toString(batteryData.rawRecord()) << endl;
warnVerbose.push_back(ssWarnVerbose.str());
}
@@ -128,7 +144,9 @@
double chargeTempThreshhold,
double dischargeTempThreshhold,
bool printRawRecord )
-{
+{
+ if ( isRecordEmpty(batteryData, warnShort, warnVerbose) ) return true;
+
bool haveWarning = false;
map<int,SmartBattery>::const_iterator it;
@@ -139,8 +157,8 @@
const SmartBattery &bat = batteryData.battery( batteryNumber );
if ( !bat.has(Temperature) ) continue;
- assert( (int)batteryData.chargingStates.size() >= batteryNumber-1 );
- bool isCharging = batteryData.chargingStates[batteryNumber-1];
+ assert( (int)batteryData.chargingStates().size() >= batteryNumber-1 );
+ bool isCharging = batteryData.chargingStates()[batteryNumber-1];
double tempThreshhold = 0.0;
if (isCharging) {
@@ -165,7 +183,7 @@
if (haveWarning && printRawRecord)
{
stringstream ssWarnVerbose;
- ssWarnVerbose << "Latest raw record: " << endl << toString(batteryData.rawRecord) << endl;
+ ssWarnVerbose << "Latest raw record: " << endl << toString(batteryData.rawRecord()) << endl;
warnVerbose.push_back(ssWarnVerbose.str());
}
@@ -178,6 +196,12 @@
int chargeWarnThreshhold,
int chargeDeviationThreshold )
{
+
+ if ( isRecordEmpty(batteryData, warnShort, warnVerbose) ) return true;
+
+ // if the system is charging, don't bother issuing warnings
+ if ( isSystemOnCharge(batteryData) ) return false;
+
bool haveWarning = false;
map<int,SmartBattery>::const_iterator it;
@@ -189,7 +213,7 @@
if ( !bat.has(RelativeStateOfCharge) ) continue;
int charge = bat.relativeStateOfCharge();
- const int avgCharge = batteryData.percentCharge;
+ const int avgCharge = batteryData.percentCharge();
// check whether battery charge is lower than the average
if ( charge < (avgCharge - chargeDeviationThreshold) )
@@ -202,8 +226,7 @@
ssWarnVerbose << "Inconsistent charge! Battery no " << batteryNumber << "'s charge is " << charge << "% (average: " << avgCharge << "%)" << endl;
warnVerbose.push_back(ssWarnVerbose.str());
}
-
- // check whether battery charge is below a threshhold
+
if (charge < chargeWarnThreshhold)
{
haveWarning = true;
@@ -219,14 +242,17 @@
return haveWarning;
}
-bool checkModuleHealth( const OceanServerSystem &batteryData,
+bool checkModuleHealth( const OceanServerSystem &batteryData,
vector<string> &warnShort,
vector<string> &warnVerbose )
{
+
+ if ( isRecordEmpty(batteryData, warnShort, warnVerbose) ) return true;
+
bool haveWarning = false;
// check the flags
- const vector<bool> &badPower = batteryData.powerNoGoodStates;
+ const vector<bool> &badPower = batteryData.powerNoGoodStates();
for (unsigned int i=0; i<badPower.size(); i++)
{
if (badPower[i]==true)
@@ -241,7 +267,7 @@
}
}
- const vector<bool> &chargeInhibit = batteryData.chargeInhibitedStates;
+ const vector<bool> &chargeInhibit = batteryData.chargeInhibitedStates();
for (unsigned int i=0; i<chargeInhibit.size(); i++)
{
if (chargeInhibit[i]==true)
@@ -265,20 +291,29 @@
std::vector<std::string> &warnVerbose,
bool printRawRecord )
{
- if ( !haveBattery( batteryData, warnShort, warnVerbose ) ) return true;
+ if ( isRecordEmpty(batteryData, warnShort, warnVerbose) ) return true;
- bool warnNumBatteries = checkNumberOfBatteries( batteryData, warnShort, warnVerbose, batteryConfig.expectedNumBatteries );
- bool warnModule = checkModuleHealth( batteryData, warnShort, warnVerbose );
- bool warnCycle = checkNumCycles( batteryData, warnShort, warnVerbose, batteryConfig.numCyclesThreshhold, false );
- bool warnTemp = checkTemperatures( batteryData, warnShort, warnVerbose, batteryConfig.chargeTempThreshhold, batteryConfig.dischargeTempThreshhold, false );
- bool warnCharge = checkCharges( batteryData, warnShort, warnVerbose, batteryConfig.chargeWarnThreshhold, batteryConfig.chargeDeviationThreshold );
+ bool haveWarnings = false;
+
+ if ( haveBattery( batteryData, warnShort, warnVerbose ) )
+ {
+ bool warnNumBatteries = checkNumberOfBatteries( batteryData, warnShort, warnVerbose, batteryConfig.expectedNumBatteries );
+ bool warnModule = checkModuleHealth( batteryData, warnShort, warnVerbose );
+ bool warnCycle = checkNumCycles( batteryData, warnShort, warnVerbose, batteryConfig.numCyclesThreshhold, false );
+ bool warnTemp = checkTemperatures( batteryData, warnShort, warnVerbose, batteryConfig.chargeTempThreshhold, batteryConfig.dischargeTempThreshhold, false );
+ bool warnCharge = checkCharges( batteryData, warnShort, warnVerbose, batteryConfig.chargeWarnThreshhold, batteryConfig.chargeDeviationThreshold );
+
+ haveWarnings = warnNumBatteries || warnModule || warnCycle || warnTemp || warnCharge;
+ }
+ else
+ {
+ haveWarnings = true;
+ }
- bool haveWarnings = warnNumBatteries || warnModule || warnCycle || warnTemp || warnCharge;
-
if (printRawRecord && haveWarnings )
{
stringstream ssWarnVerbose;
- ssWarnVerbose << "Latest raw record: " << endl << toString(batteryData.rawRecord) << endl;
+ ssWarnVerbose << "Latest raw record: " << endl << toString(batteryData.rawRecord()) << endl;
warnVerbose.push_back(ssWarnVerbose.str());
}
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverparser.cpp
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverparser.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/oceanserverparser.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -34,16 +34,16 @@
for (it=keyValuePairs.begin(); it!=keyValuePairs.end(); it++)
{
if (it->first=="01") {
- batterySystem.minToEmpty = readMinutes(it->second);
+ batterySystem.setMinToEmpty( readMinutes(it->second) );
}
else if (it->first=="02") {
// reserved, do nothing
}
else if (it->first=="03") {
- batterySystem.messageToSystem = it->second;
+ batterySystem.setMessageToSystem( it->second );
}
else if (it->first=="04") {
- batterySystem.percentCharge = readPercentByte(it->second);
+ batterySystem.setPercentCharge( readPercentByte(it->second) );
}
else
{
@@ -66,30 +66,30 @@
if (it->first=="01") {
readFlags(it->second, states);
- batterySystem.availableBatteries = states;
+ batterySystem.availableBatteries() = states;
}
else if (it->first=="02") {
readFlags(it->second, states);
- batterySystem.chargingStates = states;
+ batterySystem.chargingStates() = states;
}
else if (it->first=="03") {
readFlags(it->second, states);
- batterySystem.supplyingPowerStates = states;
+ batterySystem.supplyingPowerStates() = states;
}
else if (it->first=="04") {
// reserved, do nothing
}
else if (it->first=="05") {
readFlags(it->second, states);
- batterySystem.chargePowerPresentStates = states;
+ batterySystem.chargePowerPresentStates() = states;
}
else if (it->first=="06") {
readFlags(it->second, states);
- batterySystem.powerNoGoodStates = states;
+ batterySystem.powerNoGoodStates() = states;
}
else if (it->first=="07") {
readFlags(it->second, states);
- batterySystem.chargeInhibitedStates = states;
+ batterySystem.chargeInhibitedStates() = states;
}
else
{
@@ -254,7 +254,7 @@
{
// put the raw record into the batterySystem representation
// useful for "higher-level" debugging: the caller can choose how to make use of this information
- batterySystem.rawRecord = stringList;
+ batterySystem.rawRecord() = stringList;
//
// Debugging output
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.cpp
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -49,17 +49,18 @@
//
// Non-member functions
//
+
string toString( const OceanServerSystem &system )
{
stringstream ss;
- ss << "Charge: \t" << system.percentCharge << endl;
- ss << "Minutes to empty:\t" << system.minToEmpty << endl;
- ss << "Available batt.: \t" << toString( system.availableBatteries ) << endl;
- ss << "Charging: \t" << toString( system.chargingStates ) << endl;
- ss << "Supplying power: \t" << toString( system.supplyingPowerStates ) << endl;
- ss << "Charge power: \t" << toString( system.chargePowerPresentStates ) << endl;
- ss << "Power no good: \t" << toString( system.powerNoGoodStates ) << endl;
- ss << "Charge inhibited:\t" << toString( system.chargeInhibitedStates ) << endl;
+ ss << "Charge: \t" << system.percentCharge() << endl;
+ ss << "Minutes to empty:\t" << system.minToEmpty() << endl;
+ ss << "Available batt.: \t" << toString( system.availableBatteries() ) << endl;
+ ss << "Charging: \t" << toString( system.chargingStates() ) << endl;
+ ss << "Supplying power: \t" << toString( system.supplyingPowerStates() ) << endl;
+ ss << "Charge power: \t" << toString( system.chargePowerPresentStates() ) << endl;
+ ss << "Power no good: \t" << toString( system.powerNoGoodStates() ) << endl;
+ ss << "Charge inhibited:\t" << toString( system.chargeInhibitedStates() ) << endl;
map<int,SmartBattery>::const_iterator it;
for (it=system.batteries().begin(); it!=system.batteries().end(); it++)
@@ -74,14 +75,14 @@
string toLogString( const OceanServerSystem &system )
{
stringstream ss;
- ss << system.percentCharge << " ";
- ss << system.minToEmpty << " ";
- ss << toLogString( system.availableBatteries ) << " ";
- ss << toLogString( system.chargingStates ) << " ";
- ss << toLogString( system.supplyingPowerStates ) << " ";
- ss << toLogString( system.chargePowerPresentStates ) << " ";
- ss << toLogString( system.powerNoGoodStates ) << " ";
- ss << toLogString( system.chargeInhibitedStates ) << endl;
+ ss << system.percentCharge() << " ";
+ ss << system.minToEmpty() << " ";
+ ss << toLogString( system.availableBatteries() ) << " ";
+ ss << toLogString( system.chargingStates() ) << " ";
+ ss << toLogString( system.supplyingPowerStates() ) << " ";
+ ss << toLogString( system.chargePowerPresentStates() ) << " ";
+ ss << toLogString( system.powerNoGoodStates() ) << " ";
+ ss << toLogString( system.chargeInhibitedStates() ) << endl;
ss << system.batteries().size();
@@ -97,19 +98,19 @@
void updateWithNewData( const OceanServerSystem &from,
OceanServerSystem &to )
{
- to.rawRecord = from.rawRecord;
+ to.rawRecord() = from.rawRecord();
typedef map<int,SmartBattery>::const_iterator BatIt;
- to.availableBatteries = from.availableBatteries;
- to.percentCharge = from.percentCharge;
- to.minToEmpty = from.minToEmpty;
- to.messageToSystem = from.messageToSystem;
- to.chargingStates = from.chargingStates;
- to.supplyingPowerStates = from.supplyingPowerStates;
- to.chargePowerPresentStates = from.chargePowerPresentStates;
- to.powerNoGoodStates = from.powerNoGoodStates;
- to.chargeInhibitedStates = from.chargeInhibitedStates;
+ to.setPercentCharge( from.percentCharge() );
+ to.setMinToEmpty( from.minToEmpty() );
+ to.setMessageToSystem( from.messageToSystem() );
+ to.availableBatteries() = from.availableBatteries();
+ to.chargingStates() = from.chargingStates();
+ to.supplyingPowerStates() = from.supplyingPowerStates();
+ to.chargePowerPresentStates() = from.chargePowerPresentStates();
+ to.powerNoGoodStates() = from.powerNoGoodStates();
+ to.chargeInhibitedStates() = from.chargeInhibitedStates();
for (BatIt it=from.batteries().begin(); it!=from.batteries().end(); it++)
{
@@ -177,23 +178,35 @@
}
+bool isSystemOnCharge( const gbxsmartbatteryacfr::OceanServerSystem &batterySystem )
+{
+ for (unsigned int i=0; i<batterySystem.chargingStates().size(); ++i)
+ {
+ if (batterySystem.chargingStates()[i]==true)
+ return true;
+ }
+ return false;
+}
+
+
//
// Member functions
//
OceanServerSystem::OceanServerSystem()
- : percentCharge(0),
- minToEmpty(0),
- messageToSystem("")
+ : isEmpty_(true),
+ percentCharge_(0),
+ minToEmpty_(0),
+ messageToSystem_("")
{
// fixed number of slots for oceanserver system
const int NUM_BATTERY_SLOTS = 8;
- availableBatteries.resize(NUM_BATTERY_SLOTS);
- chargingStates.resize(NUM_BATTERY_SLOTS);
- supplyingPowerStates.resize(NUM_BATTERY_SLOTS);
- chargePowerPresentStates.resize(NUM_BATTERY_SLOTS);
- powerNoGoodStates.resize(NUM_BATTERY_SLOTS);
- chargeInhibitedStates.resize(NUM_BATTERY_SLOTS);
+ availableBatteries_.resize(NUM_BATTERY_SLOTS);
+ chargingStates_.resize(NUM_BATTERY_SLOTS);
+ supplyingPowerStates_.resize(NUM_BATTERY_SLOTS);
+ chargePowerPresentStates_.resize(NUM_BATTERY_SLOTS);
+ powerNoGoodStates_.resize(NUM_BATTERY_SLOTS);
+ chargeInhibitedStates_.resize(NUM_BATTERY_SLOTS);
}
// read access to all batteries
@@ -207,6 +220,8 @@
SmartBattery&
OceanServerSystem::battery( unsigned int batteryNumber )
{
+ isEmpty_=false;
+
map<int,SmartBattery>::iterator it = batteries_.find(batteryNumber);
if ( it==batteries_.end() )
{
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.h
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.h 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/oceanserversystem.h 2009-11-08 11:51:23 UTC (rev 457)
@@ -26,9 +26,12 @@
class OceanServerSystem
{
public:
-
+
+ //! Initialises all data in OceanServerSystem class
OceanServerSystem();
- ~OceanServerSystem() {};
+
+ //! Returns true if no valid data has been set
+ bool isEmpty() const { return isEmpty_; };
//! Read access to all batteries
const std::map<int,SmartBattery>& batteries() const;
@@ -42,24 +45,69 @@
//! Erase a battery
void eraseBattery( unsigned int batteryNumber );
- //! Average battery values
- int percentCharge;
- int minToEmpty;
- std::string messageToSystem;
+ //! Set charge in %
+ void setPercentCharge(int percentCharge) { isEmpty_=false; percentCharge_ = percentCharge; };
+ //! Access charget in %
+ int percentCharge() const { return percentCharge_; };
+ //! Set minutes to empty
+ void setMinToEmpty(int minToEmpty) { isEmpty_=false; minToEmpty_ = minToEmpty; };
+ //! Access minutes-to-empty
+ int minToEmpty() const { return minToEmpty_; };
+ //! Set message-to-system string
+ void setMessageToSystem(const std::string &messageToSystem) { isEmpty_=false; messageToSystem_ = messageToSystem; };
+ //! Access message-to-system string
+ std::string messageToSystem() const { return messageToSystem_; };
- //! Battery module states. Each vector is always of size 8 because OceanServer's Battery
- //! Management Modules have a maximum of 8 slots (either 2, 4, or 8 dependent on the model)
- std::vector<bool> availableBatteries;
- std::vector<bool> chargingStates;
- std::vector<bool> supplyingPowerStates;
- std::vector<bool> chargePowerPresentStates;
- std::vector<bool> powerNoGoodStates;
- std::vector<bool> chargeInhibitedStates;
+ //! Access availableBatteries flags
+ const std::vector<bool> &availableBatteries() const { return availableBatteries_; };
+ //! Set availableBatteries flags
+ std::vector<bool> &availableBatteries() { isEmpty_=false; return availableBatteries_; };
+ //! Access chargingStates flags
+ const std::vector<bool> &chargingStates() const { return chargingStates_; };
+ //! Set chargingStates flags
+ std::vector<bool> &chargingStates() { isEmpty_=false; return chargingStates_; };
+ //! Access supplyingPowerStates flags
+ const std::vector<bool> &supplyingPowerStates() const { return supplyingPowerStates_; };
+ //! Set supplyingPowerStates flags
+ std::vector<bool> &supplyingPowerStates() { isEmpty_=false; return supplyingPowerStates_; };
+ //! Access chargePowerPresentStates flags
+ const std::vector<bool> &chargePowerPresentStates() const { return chargePowerPresentStates_; };
+ //! Set chargePowerPresentStates flags
+ std::vector<bool> &chargePowerPresentStates() { isEmpty_=false; return chargePowerPresentStates_; };
+ //! Access powerNoGoodStates flags
+ const std::vector<bool> &powerNoGoodStates() const { return powerNoGoodStates_; };
+ //! Set powerNoGoodStates flags
+ std::vector<bool> &powerNoGoodStates() { isEmpty_=false; return powerNoGoodStates_; };
+ //! Access chargeInhibitedStates flags
+ const std::vector<bool> &chargeInhibitedStates() const { return chargeInhibitedStates_; }
+ //! Set chargeInhibitedStates flags
+ std::vector<bool> &chargeInhibitedStates() { isEmpty_=false; return chargeInhibitedStates_; }
- //! the latest raw record, useful for debugging
- std::vector<std::string> rawRecord;
+ //! Access the latest raw record, useful for debugging
+ const std::vector<std::string> &rawRecord() const { return rawRecord_; };
+ //! Set the latest raw record
+ std::vector<std::string> &rawRecord() { isEmpty_=false; return rawRecord_; };
private:
+
+ bool isEmpty_;
+
+ // Average battery values
+ int percentCharge_;
+ int minToEmpty_;
+ std::string messageToSystem_;
+
+ // Battery module states. Each vector is always of size 8 because OceanServer's Battery
+ // Management Modules have a maximum of 8 slots (either 2, 4, or 8 dependent on the model)
+ std::vector<bool> availableBatteries_;
+ std::vector<bool> chargingStates_;
+ std::vector<bool> supplyingPowerStates_;
+ std::vector<bool> chargePowerPresentStates_;
+ std::vector<bool> powerNoGoodStates_;
+ std::vector<bool> chargeInhibitedStates_;
+
+ // the latest raw record, useful for debugging
+ std::vector<std::string> rawRecord_;
// key: slot number, data: a single smart battery module
std::map<int,SmartBattery> batteries_;
@@ -78,6 +126,9 @@
//! The reaping capability makes sure that battery modules which are no longer connected don't persist.
void updateWithNewData( const OceanServerSystem &from,
OceanServerSystem &to );
+
+//! Returns true if at least one of the battery modules is on charge otherwise false
+bool isSystemOnCharge( const OceanServerSystem &batterySystem );
} // namespace
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/test/darttest/checksumtest.cpp
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/test/darttest/checksumtest.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/test/darttest/checksumtest.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -76,7 +76,7 @@
string checksumStr = ss.str();
for (unsigned int i=0; i<checksumStr.size(); i++)
- checksumStr[i] = toupper( checksumStr[i] );
+ checksumStr[i] = (char)(toupper( checksumStr[i] ));
cout << "Expected checksum result is:\t" << resultHex << endl;
cout << "Computed checksum result is:\t" << checksumStr << endl << endl;
Modified: gearbox/trunk/src/gbxsmartbatteryacfr/test/longtest.cpp
===================================================================
--- gearbox/trunk/src/gbxsmartbatteryacfr/test/longtest.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxsmartbatteryacfr/test/longtest.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -58,10 +58,15 @@
while (true)
{
- cout << "TRACE(test): Reading record " << numRecords << endl;
+ cout << "Reading record " << numRecords << endl;
numRecords++;
gbxsmartbatteryacfr::OceanServerSystem data = oceanserver.getData();
+ if ( data.isEmpty() )
+ {
+ cout << "Data was empty. No worries, keep trying to read." << endl;
+ continue;
+ }
vector<string> shortWarning;
vector<string> verboseWarning;
const bool printRawRecord = true;
Modified: gearbox/trunk/src/gbxutilacfr/exceptions.cpp
===================================================================
--- gearbox/trunk/src/gbxutilacfr/exceptions.cpp 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxutilacfr/exceptions.cpp 2009-11-08 11:51:23 UTC (rev 457)
@@ -25,7 +25,7 @@
}
const char *
-Exception::basename( const char *s )
+Exception::basename( const char *s ) const
{
#ifndef WIN32
return strrchr( s, '/' )+1;
@@ -35,7 +35,7 @@
};
std::string
-Exception::toMessageString( const char *file, const char *line, const std::string &message )
+Exception::toMessageString( const char *file, const char *line, const std::string &message ) const
{
std::string msg = "\n *** ERROR(";
// not to confuse our local basename() with gbxutilacfr::basename()
Modified: gearbox/trunk/src/gbxutilacfr/exceptions.h
===================================================================
--- gearbox/trunk/src/gbxutilacfr/exceptions.h 2009-11-07 04:25:00 UTC (rev 456)
+++ gearbox/trunk/src/gbxutilacfr/exceptions.h 2009-11-08 11:51:23 UTC (rev 457)
@@ -72,12 +72,12 @@
virtual const char* what() const throw() { return message_.c_str(); }
protected:
- std::string toMessageString( const char *file, const char *line, const std::string &message );
+ std::string toMessageString( const char *file, const char *line, const std::string &message ) const;
std::string message_;
private:
- const char *basename( const char *s );
+ const char *basename( const char *s ) const;
};
//! This exception is raised when something is wrong with the hardware.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|