You can subscribe to this list here.
| 2008 |
Jan
|
Feb
(58) |
Mar
(15) |
Apr
(23) |
May
(8) |
Jun
(92) |
Jul
(66) |
Aug
(6) |
Sep
(9) |
Oct
(44) |
Nov
(8) |
Dec
(1) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2009 |
Jan
(10) |
Feb
(8) |
Mar
(2) |
Apr
(8) |
May
(19) |
Jun
(11) |
Jul
(8) |
Aug
(6) |
Sep
(5) |
Oct
(4) |
Nov
(26) |
Dec
(4) |
| 2010 |
Jan
(5) |
Feb
(3) |
Mar
(4) |
Apr
(3) |
May
(4) |
Jun
|
Jul
(1) |
Aug
(16) |
Sep
(7) |
Oct
(3) |
Nov
(7) |
Dec
|
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <gb...@us...> - 2008-06-24 12:20:43
|
Revision: 207
http://gearbox.svn.sourceforge.net/gearbox/?rev=207&view=rev
Author: gbiggs
Date: 2008-06-24 05:19:11 -0700 (Tue, 24 Jun 2008)
Log Message:
-----------
Changes from Michael Moser's review
Modified Paths:
--------------
gearbox/trunk/submitted/flexiport/logfile.cpp
gearbox/trunk/submitted/flexiport/logreaderport.cpp
gearbox/trunk/submitted/flexiport/logreaderport.h
gearbox/trunk/submitted/flexiport/logwriterport.cpp
Modified: gearbox/trunk/submitted/flexiport/logfile.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/logfile.cpp 2008-06-24 11:51:49 UTC (rev 206)
+++ gearbox/trunk/submitted/flexiport/logfile.cpp 2008-06-24 12:19:11 UTC (rev 207)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* flexiport flexible hardware data communications library.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of flexiport.
*
* flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
@@ -28,6 +28,7 @@
#include "flexiport.h"
#include "logfile.h"
+#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
@@ -76,7 +77,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
LogFile::LogFile (unsigned int debug)
- : _read (false), _readFile (NULL), _writeFile (NULL), _readFileSize (0), _writeFileSize (0),
+ : _read (false), _readFile (NULL), _writeFile (NULL), _readFileSize (0), _writeFileSize (0),
_debug (debug), _readUsage (0), _writeUsage (0), _readSize (0), _writeSize (0),
_readBuffer (NULL), _writeBuffer (NULL), _ignoreTimes (false)
// _bufferSize (0),
@@ -112,14 +113,14 @@
if ((_readFile = fopen ((fileName + "r").c_str (), "r")) == NULL)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fopen(_readFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fopen(_readFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
if ((_writeFile = fopen ((fileName + "w").c_str (), "r")) == NULL)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fopen(_writeFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fopen(_writeFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -132,14 +133,14 @@
if ((_readFile = fopen ((fileName + "r").c_str (), "w")) == NULL)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fopen(_readFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fopen(_readFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
if ((_writeFile = fopen ((fileName + "w").c_str (), "w")) == NULL)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fopen(_writeFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fopen(_writeFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -160,7 +161,7 @@
{
_readFile = NULL;
stringstream ss;
- ss << "LogFile::" << __func__ << "() fclose(_readFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fclose(_readFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -171,7 +172,7 @@
{
_writeFile = NULL;
stringstream ss;
- ss << "LogFile::" << __func__ << "() fclose(_writeFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fclose(_writeFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -201,7 +202,7 @@
if ((pos = ftell (_readFile)) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -211,7 +212,7 @@
if ((pos = ftell (_writeFile)) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -234,14 +235,14 @@
if (fseek (_readFile, 0, SEEK_SET) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek(_readFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fseek(_readFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
if (fseek (_writeFile, 0, SEEK_SET) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek(_writeFile) error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fseek(_writeFile) error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -254,7 +255,7 @@
if (gettimeofday (&_openTime, NULL) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -338,24 +339,24 @@
{
if (_debug >= 2)
cerr << "LogFile::" << __func__ << "() Data available in file now." << endl;
-
+
// Get all the data that is immediatly available and return it
totalRead += GetChunksToTimeLimit (_readFile, data, count, now);
return totalRead;
}
-
+
// There was no data instantly, so now the timeout gets involved
if (timeout._sec == -1)
{
// Infinite timeout
if (_debug >= 2)
cerr << "LogFile::" << __func__ << "() Getting next chunk, no timeout." << endl;
-
+
// Get the next available chunk from the file
struct timeval timestamp;
size_t size;
totalRead += GetSingleChunk (_readFile, data, count, timestamp, size);
-
+
// Calculate the time difference between now and this chunk's timestamp
struct timeval diff;
GetCurrentFileTime (now);
@@ -380,7 +381,7 @@
// Limited timeout
if (_debug >= 2)
cerr << "LogFile::" << __func__ << "() Getting next chunk with timeout." << endl;
-
+
// Check if there is actually data available within this time limit
struct timeval timeoutVal, limit;
timeout.AsTimeval (timeoutVal);
@@ -392,7 +393,7 @@
struct timeval timestamp;
size_t size;
totalRead += GetSingleChunk (_readFile, data, count, timestamp, size);
-
+
// Calculate the time difference between now and this chunk's timestamp
struct timeval diff;
GetCurrentFileTime (now);
@@ -442,7 +443,7 @@
// Get the current file time
struct timeval now;
GetCurrentFileTime (now);
-
+
// Now count data from the file
if (DataAvailableWithinLimit (_readFile, now))
{
@@ -465,12 +466,12 @@
// Infinite timeout
if (_debug >= 2)
cerr << "LogFile::" << __func__ << "() Getting next chunk, no timeout." << endl;
-
+
// Get the next available chunk from the file
struct timeval timeStamp;
size_t size;
GetNextChunkInfo (_readFile, timeStamp, size);
-
+
// Calculate the time difference between now and this chunk's timestamp
struct timeval diff;
GetCurrentFileTime (now);
@@ -495,7 +496,7 @@
// Limited timeout
if (_debug >= 2)
cerr << "LogFile::" << __func__ << "() Getting next chunk with timeout." << endl;
-
+
// Check if there is actually data available within this time limit
struct timeval timeoutVal, limit;
timeout.AsTimeval (timeoutVal);
@@ -507,7 +508,7 @@
struct timeval timeStamp;
size_t size;
GetNextChunkInfo (_readFile, timeStamp, size);
-
+
// Calculate the time difference between now and this chunk's timestamp
struct timeval diff;
GetCurrentFileTime (now);
@@ -554,7 +555,7 @@
if ((readFileOffset = ftell (_readFile)) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -719,7 +720,7 @@
if (fseek (_readFile, readFileOffset, SEEK_SET) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -752,7 +753,7 @@
if (fseek (_readFile, CHUNK_HEADER_SIZE + size, SEEK_CUR) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek(_readFile) error: (" << ErrNo () <<
+ ss << "LogFile::" << __func__ << "() fseek(_readFile) error: (" << ErrNo () <<
") " << StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -787,7 +788,7 @@
if (fseek (_writeFile, CHUNK_HEADER_SIZE + size, SEEK_CUR) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek(_writeFile) error: (" << ErrNo () <<
+ ss << "LogFile::" << __func__ << "() fseek(_writeFile) error: (" << ErrNo () <<
") " << StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -809,7 +810,8 @@
" bytes." << endl;
}
WriteTimeStamp (_readFile);
- WriteToFile (_readFile, &count, sizeof (count));
+ uint32_t temp = htonl (static_cast<uint32_t> (count));
+ WriteToFile (_readFile, &temp, sizeof (temp));
WriteToFile (_readFile, data, count);
}
@@ -821,7 +823,8 @@
" bytes." << endl;
}
WriteTimeStamp (_writeFile);
- WriteToFile (_writeFile, &count, sizeof (count));
+ uint32_t temp = htonl (static_cast<uint32_t> (count));
+ WriteToFile (_writeFile, &temp, sizeof (temp));
WriteToFile (_writeFile, data, count);
}
@@ -956,7 +959,7 @@
if (gettimeofday (&now, NULL) < 0)
{
stringstream ss;
- ss << "LogReaderPort::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
+ ss << "LogReaderPort::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -989,7 +992,7 @@
if (fseek (file, -1 * CHUNK_HEADER_SIZE, SEEK_CUR) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1048,7 +1051,7 @@
if ((currentPos = ftell (file)) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1071,7 +1074,7 @@
if (fseek (file, currentPos, SEEK_SET) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1093,8 +1096,13 @@
}
// Read the chunk info
- ReadFromFile (file, &timeStamp, sizeof (timeStamp));
- ReadFromFile (file, &size, sizeof (size));
+ uint32_t secs, usecs, tempSize;
+ ReadFromFile (file, &secs, sizeof (secs));
+ ReadFromFile (file, &usecs, sizeof (usecs));
+ timeStamp.tv_sec = ntohl (secs);
+ timeStamp.tv_usec = ntohl (usecs);
+ ReadFromFile (file, &tempSize, sizeof (tempSize));
+ size = ntohl (tempSize);
if (_debug >= 3)
cerr << "LogFile::" << __func__ << "() Chunk is " << size << " bytes." << endl;
@@ -1158,7 +1166,7 @@
if ((currentPos = ftell (file)) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1167,7 +1175,7 @@
if (fseek (file, 0, SEEK_END) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1175,7 +1183,7 @@
if ((fileSize = ftell (file)) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1184,7 +1192,7 @@
if (fseek (file, currentPos, SEEK_SET) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1218,7 +1226,7 @@
else if (ferror (file))
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fread() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fread() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1251,7 +1259,7 @@
sizeof (uint8_t), count - totalWritten, file)) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() fwrite() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() fwrite() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
@@ -1268,16 +1276,20 @@
if (gettimeofday (&now, NULL) < 0)
{
stringstream ss;
- ss << "LogFile::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
+ ss << "LogFile::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
StrError (ErrNo ());
throw PortException (ss.str ());
}
timersub (&now, &_openTime, &diff);
+ uint32_t secs, usecs;
+ secs = htonl (static_cast<uint32_t> (diff.tv_sec));
+ usecs = htonl (static_cast<uint32_t> (diff.tv_usec));
// Write the time stamp to the file
- WriteToFile (file, &diff, sizeof (diff));
+ WriteToFile (file, &secs, sizeof (secs));
+ WriteToFile (file, &usecs, sizeof (usecs));
if (_debug >= 3)
{
- cerr << "LogFile::" << __func__ << "() Wrote time stamp: " << diff.tv_sec << "s " <<
+ cerr << "LogFile::" << __func__ << "() Wrote time stamp: " << diff.tv_sec << "s " <<
diff.tv_usec << "us (time of write is " << now.tv_sec << "s " << now.tv_usec << "us)."
<< endl;
}
Modified: gearbox/trunk/submitted/flexiport/logreaderport.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/logreaderport.cpp 2008-06-24 11:51:49 UTC (rev 206)
+++ gearbox/trunk/submitted/flexiport/logreaderport.cpp 2008-06-24 12:19:11 UTC (rev 207)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* flexiport flexible hardware data communications library.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of flexiport.
*
* flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
@@ -47,7 +47,6 @@
LogReaderPort::LogReaderPort (map<string, string> options)
: Port (), _logFileName ("port.log"), _strictness (0),
_jitter (100), _ignoreTimes (false), _open (false)
-// _bufferSize (0),
{
_type = "logreader";
ProcessOptions (options);
@@ -58,7 +57,6 @@
throw PortException (string ("LogReaderPort::") + __func__ +
string ("() Failed to allocate LogFile object."));
}
-// _logFile->SetBufferSize (_bufferSize);
_logFile->Open (_logFileName, true, _ignoreTimes);
if (_alwaysOpen)
@@ -129,7 +127,7 @@
if (_debug >= 2)
{
- cerr << "LogReaderPort::" << __func__ << "() Going to read until have " << count <<
+ cerr << "LogReaderPort::" << __func__ << "() Going to read until have " << count <<
" bytes" << endl;
}
@@ -158,7 +156,7 @@
SetTimeout (oldTimeout);
stringstream ss;
- ss << "LogReaderPort::" << __func__ << "() EOF while trying to read " <<
+ ss << "LogReaderPort::" << __func__ << "() EOF while trying to read " <<
count << " bytes";
throw PortException (ss.str ());
}
@@ -271,8 +269,7 @@
status << "LogReader-specific status:" << endl;
status << "Reading from " << _logFileName << endl;
status << ((_open && _logFile->IsOpen ()) ? "Port is open" : "Port is closed") << endl;
-// status << "Buffer size: " << _bufferSize << endl;
-// status << (_ignoreTimes ? "Ignoring file time stamps." : "Using file time stamps.") << endl;
+ status << (_ignoreTimes ? "Ignoring file time stamps." : "Using file time stamps.") << endl;
status << "Strictness is " << _strictness << ", with a jitter of " << _jitter << "ms" << endl;
return Port::GetStatus () + status.str ();
@@ -315,13 +312,6 @@
_logFileName = value;
return true;
}
-// else if (option == "buffersize")
-// {
-// istringstream is (value);
-// if (!(is >> _bufferSize) || is.get (c))
-// throw PortException ("Bad buffer size: " + value);
-// return true;
-// }
else if (option == "ignoretimes")
{
_ignoreTimes = true;
Modified: gearbox/trunk/submitted/flexiport/logreaderport.h
===================================================================
--- gearbox/trunk/submitted/flexiport/logreaderport.h 2008-06-24 11:51:49 UTC (rev 206)
+++ gearbox/trunk/submitted/flexiport/logreaderport.h 2008-06-24 12:19:11 UTC (rev 207)
@@ -105,7 +105,6 @@
private:
LogFile *_logFile;
std::string _logFileName;
-// unsigned int _bufferSize;
unsigned int _strictness;
int _jitter;
bool _ignoreTimes;
Modified: gearbox/trunk/submitted/flexiport/logwriterport.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/logwriterport.cpp 2008-06-24 11:51:49 UTC (rev 206)
+++ gearbox/trunk/submitted/flexiport/logwriterport.cpp 2008-06-24 12:19:11 UTC (rev 207)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* flexiport flexible hardware data communications library.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of flexiport.
*
* flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
@@ -67,7 +67,7 @@
}
// The rest of the options go on to the underlying Port object
- // Create the underlying port object
+ // Create the underlying port object
_port = CreatePort (options);
// Initialise the log file
@@ -83,6 +83,7 @@
{
// _logFile should never be NULL because it's allocated in the constructor and never deleted.
_logFile->Close ();
+ delete _logFile;
if (_port)
_port->Close ();
@@ -198,7 +199,7 @@
if (_debug >= 2)
{
- cerr << "LogWriterPort::" << __func__ << "() Skipping until '" << terminator <<
+ cerr << "LogWriterPort::" << __func__ << "() Skipping until '" << terminator <<
"' is seen " << count << " times." << endl;
}
// Read bytes one at a time until either a timeout occurs or we hit the terminator byte
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gb...@us...> - 2008-06-24 11:52:54
|
Revision: 206
http://gearbox.svn.sourceforge.net/gearbox/?rev=206&view=rev
Author: gbiggs
Date: 2008-06-24 04:51:49 -0700 (Tue, 24 Jun 2008)
Log Message:
-----------
Fixed II result scanning for USB-only devices such as the UHG-08LX
Modified Paths:
--------------
gearbox/trunk/submitted/urg_nz/test/example.cmake.in
gearbox/trunk/submitted/urg_nz/urg_nz.cpp
Modified: gearbox/trunk/submitted/urg_nz/test/example.cmake.in
===================================================================
--- gearbox/trunk/submitted/urg_nz/test/example.cmake.in 2008-06-24 11:32:45 UTC (rev 205)
+++ gearbox/trunk/submitted/urg_nz/test/example.cmake.in 2008-06-24 11:51:49 UTC (rev 206)
@@ -1,6 +1,6 @@
PROJECT( urg_nz_example )
-INCLUDE_DIRECTORIES( @CMAKE_INSTALL_PREFIX@ )
+INCLUDE_DIRECTORIES( @CMAKE_INSTALL_PREFIX@/include/gearbox )
ADD_EXECUTABLE( urg_nz_example example.cpp )
TARGET_LINK_LIBRARIES( urg_nz_example urg_nz )
Modified: gearbox/trunk/submitted/urg_nz/urg_nz.cpp
===================================================================
--- gearbox/trunk/submitted/urg_nz/urg_nz.cpp 2008-06-24 11:32:45 UTC (rev 205)
+++ gearbox/trunk/submitted/urg_nz/urg_nz.cpp 2008-06-24 11:51:49 UTC (rev 206)
@@ -1079,7 +1079,12 @@
info->measureState = &buffer[5];
// Baud rate
ReadLineWithCheck (buffer, -1, true);
- if (sscanf (buffer, "SBPS:%d[bps]", &info->baud) != 1)
+ if (strncmp (&buffer[5], "USB only", 8) == 0)
+ {
+ // No baud rate for USB-only devices such as the UHG-08LX
+ info->baud = 0;
+ }
+ else if (sscanf (buffer, "SBPS:%d[bps]", &info->baud) != 1)
throw URGError (URG_ERR_PROTOCOL, "Baud rate line parse failed.");
// Time stamp
ReadLineWithCheck (buffer, -1, true);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gb...@us...> - 2008-06-24 11:33:55
|
Revision: 205
http://gearbox.svn.sourceforge.net/gearbox/?rev=205&view=rev
Author: gbiggs
Date: 2008-06-24 04:32:45 -0700 (Tue, 24 Jun 2008)
Log Message:
-----------
Fixes for Michael Moser's comments
Modified Paths:
--------------
gearbox/trunk/submitted/urg_nz/test/example.cpp
gearbox/trunk/submitted/urg_nz/urg_nz.cpp
gearbox/trunk/submitted/urg_nz/urg_nz.h
Modified: gearbox/trunk/submitted/urg_nz/test/example.cpp
===================================================================
--- gearbox/trunk/submitted/urg_nz/test/example.cpp 2008-06-23 18:47:22 UTC (rev 204)
+++ gearbox/trunk/submitted/urg_nz/test/example.cpp 2008-06-24 11:32:45 UTC (rev 205)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* urg_nz Hokuyo URG laser scanner driver.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of urg_nz.
*
* urg_nz is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* urg_nz is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
@@ -43,7 +43,7 @@
portOptions = "type=serial,device=COM3,timeout=1";
#else
// Get some options from the command line
- while ((opt = getopt(argc, argv, "b:c:e:f:l:m:no:s:v?h")) != -1)
+ while ((opt = getopt(argc, argv, "b:c:e:f:l:m:no:s:vh")) != -1)
{
switch (opt)
{
@@ -141,7 +141,7 @@
if (getNew)
laser.GetNewRanges (&data, firstStep, lastStep, clusterCount);
else
- laser.GetRanges (&data, firstStep, lastStep, clusterCount);
+ laser.GetRanges (&data, firstStep, lastStep, clusterCount);
}
else
{
Modified: gearbox/trunk/submitted/urg_nz/urg_nz.cpp
===================================================================
--- gearbox/trunk/submitted/urg_nz/urg_nz.cpp 2008-06-23 18:47:22 UTC (rev 204)
+++ gearbox/trunk/submitted/urg_nz/urg_nz.cpp 2008-06-24 11:32:45 UTC (rev 205)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* urg_nz Hokuyo URG laser scanner driver.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of urg_nz.
*
* urg_nz is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* urg_nz is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
@@ -54,7 +54,7 @@
#ifndef RTOD
inline double RTOD (double rad)
{
- return rad * 180.0 / M_PI;
+ return rad * 180.0 / M_PI;
}
#endif
// Convert degrees to radians
@@ -74,12 +74,12 @@
// SCIP protocol version 1 notes
////////////////////////////////////////////////////////////////////////////////////////////////////
-/* | = byte boundary, ... indicates variable byte block (max 64 bytes), (x) = x byte block
+/* | = byte boundary, ... indicates variable byte block (max 64 bytes), (x) = x byte block
- No checksum
- Host to sensor: Command | Parameters... | LF
- Sensor to host: Command | Parameters... | LF | Status | LF | Data... | LF | LF
- Where a block of data would take more than 64 bytes, a line feed is inserted every 64 bytes.
- - Status 0 is OK, anything else is an error.
+ - Status 0 is OK, anything else is an error.
L Power
L|Control code|LF
@@ -210,6 +210,7 @@
return "Laser is already on";
}
}
+// No info in the manual for this.
// else if (cmd[0] == 'Q' && cmd[1] == 'T')
// {
// switch (errorCode)
@@ -314,6 +315,7 @@
return "Motor is already running at that speed";
}
}
+// No info in the manual for this.
// else if (cmd[0] == 'R' && cmd[1] == 'S')
// {
// switch (errorCode)
@@ -326,6 +328,7 @@
// return ss.str ();
// }
// }
+// No info in the manual for this.
// else if (cmd[0] == 'V' && cmd[1] == 'V')
// {
// switch (errorCode)
@@ -334,6 +337,7 @@
// return "";
// }
// }
+// No info in the manual for this.
// else if (cmd[0] == 'P' && cmd[1] == 'P')
// {
// switch (errorCode)
@@ -342,6 +346,7 @@
// return "";
// }
// }
+// No info in the manual for this.
// else if (cmd[0] == 'I' && cmd[1] == 'I')
// {
// switch (errorCode)
@@ -364,7 +369,7 @@
unsigned int Decode2ByteValue (char *data)
{
unsigned int byte1, byte2;
-
+
byte1 = data[0] - 0x30;
byte2 = data[1] - 0x30;
@@ -374,7 +379,7 @@
unsigned int Decode3ByteValue (char *data)
{
unsigned int byte1, byte2, byte3;
-
+
byte1 = data[0] - 0x30;
byte2 = data[1] - 0x30;
byte3 = data[2] - 0x30;
@@ -385,7 +390,7 @@
unsigned int Decode4ByteValue (char *data)
{
unsigned int byte1, byte2, byte3, byte4;
-
+
byte1 = data[0] - 0x30;
byte2 = data[1] - 0x30;
byte3 = data[2] - 0x30;
@@ -457,36 +462,6 @@
{
}
-URGSensorInfo::URGSensorInfo (const URGSensorInfo &rhs)
-{
- vendor = rhs.vendor;
- product = rhs.product;
- firmware = rhs.firmware;
- protocol = rhs.protocol;
- serial = rhs.serial;
-
- model = rhs.model;
- minRange = rhs.minRange;
- maxRange = rhs.maxRange;
- steps = rhs.steps;
- firstStep = rhs.firstStep;
- lastStep = rhs.lastStep;
- frontStep = rhs.frontStep;
- standardSpeed = rhs.standardSpeed;
-
- power = rhs.power;
- speed = rhs.speed;
- measureState = rhs.measureState;
- baud = rhs.baud;
- time = rhs.time;
- sensorDiagnostic = rhs.sensorDiagnostic;
-
- minAngle = rhs.minAngle;
- maxAngle = rhs.maxAngle;
- resolution = rhs.resolution;
- scanableSteps = rhs.scanableSteps;
-}
-
// Set various known values based on what the manual says
void URGSensorInfo::SetDefaults (void)
{
@@ -505,44 +480,9 @@
// We also have an incredibly high-resolution sensor.
minAngle = (static_cast<int> (firstStep) - static_cast<int> (frontStep)) * resolution;
maxAngle = (static_cast<int> (lastStep) - static_cast<int> (frontStep)) * resolution;
- scanableSteps = lastStep - firstStep;
+ scanableSteps = lastStep - firstStep + 1;
}
-URGSensorInfo& URGSensorInfo::operator= (const URGSensorInfo &rhs)
-{
- if (this == &rhs)
- return *this;
-
- vendor = rhs.vendor;
- product = rhs.product;
- firmware = rhs.firmware;
- protocol = rhs.protocol;
- serial = rhs.serial;
-
- model = rhs.model;
- minRange = rhs.minRange;
- maxRange = rhs.maxRange;
- steps = rhs.steps;
- firstStep = rhs.firstStep;
- lastStep = rhs.lastStep;
- frontStep = rhs.frontStep;
- standardSpeed = rhs.standardSpeed;
-
- power = rhs.power;
- speed = rhs.speed;
- measureState = rhs.measureState;
- baud = rhs.baud;
- time = rhs.time;
- sensorDiagnostic = rhs.sensorDiagnostic;
-
- minAngle = rhs.minAngle;
- maxAngle = rhs.maxAngle;
- resolution = rhs.resolution;
- scanableSteps = rhs.scanableSteps;
-
- return *this;
-}
-
string URGSensorInfo::AsString (void)
{
stringstream ss;
@@ -800,58 +740,6 @@
_port = flexiport::CreatePort (portOptions);
_port->Open ();
-// if (_port->GetPortType () == "serial")
-// {
-// if (_verbose)
-// {
-// cerr << "URGLaser::" << __func__ << "() Connected using serial connection." << endl;
-// cerr << _port->GetStatus ();
-// }
-// // Need to work our way down the baud rates until we get the one that the scanner is
-// // actually using. Start with the one the port is set to (hopefully the user set
-// // the port's baud option to the same as the scanner).
-// if (_verbose)
-// {
-// cerr << "URGLaser::" << __func__ << "() Trying to connect at " <<
-// reinterpret_cast<SerialPort*> (_port)->GetBaudRate () << "bps." << endl;
-// }
-// if (SetBaud (reinterpret_cast<SerialPort*> (_port)->GetBaudRate ()))
-// {
-// if (_verbose)
-// {
-// cerr << "URGLaser::" << __func__ << "() Successfully connected at " <<
-// reinterpret_cast<SerialPort*> (_port)->GetBaudRate () << "bps." << endl;
-// }
-// }
-// else
-// {
-// unsigned int bauds[] = {19200, 57600, 115200, 250000, 500000, 750000};
-// int ii;
-// for (ii = 0; ii < 6; ii++)
-// {
-// if (SetBaud (bauds[ii]))
-// {
-// if (_verbose)
-// {
-// cerr << "URGLaser::" << __func__ << "() Successfully connected at " <<
-// bauds[ii] << "bps." << endl;
-// }
-// break;
-// }
-// }
-// if (ii == 6)
-// {
-// // Did not connect at any speed
-// throw URGError (URG_ERR_CONNECT_FAILED, "Failed to connect at any baud.");
-// }
-// }
-// }
-// else if (_verbose)
-// {
-// cerr << "URGLaser::" << __func__ << "() Connected using " << _port->GetPortType () <<
-// " connection." << endl;
-// cerr << _port->GetStatus ();
-// }
if (_verbose)
{
cerr << "URGLaser::" << __func__ << "() Connected using " << _port->GetPortType () <<
@@ -1013,7 +901,7 @@
buffer[1] = 100 - (speed / 6) + 0x30;
}
}
- SendCommand ("CR", buffer, 2, "03");
+ SendCommand ("CR", buffer, 2, "03");
SkipLines (1);
}
else
@@ -1082,7 +970,7 @@
}
// Now put it through sscanf and hope...
int aperture;
- int numFound = sscanf (valueStart, "%d-%d[mm],%d[deg],%d-%d[step],%d[rpm]",
+ int numFound = sscanf (valueStart, "%d-%d[mm],%d[deg],%d-%d[step],%d[rpm]",
&info->minRange, &info->maxRange, &aperture,
&info->firstStep, &info->lastStep, &info->speed);
if (numFound != 6)
@@ -1098,10 +986,10 @@
}
// Need to calculate stuff differently since it gave us an aperture value
- info->resolution = static_cast<double> (aperture) /
+ info->resolution = static_cast<double> (aperture) /
static_cast<double> (info->lastStep - info->firstStep);
// Assume that the range is evenly spread
- info->scanableSteps = info->lastStep - info->firstStep;
+ info->scanableSteps = info->lastStep - info->firstStep + 1;
info->frontStep = info->scanableSteps / 2;
info->minAngle = (info->firstStep - info->frontStep) * info->resolution;
info->maxAngle = (info->lastStep - info->frontStep) * info->resolution;
@@ -1127,7 +1015,7 @@
char buffer[SCIP2_LINE_LENGTH];
memset (buffer, 0, sizeof (char) * SCIP2_LINE_LENGTH);
-
+
// We need to send three commands to get all the info we want: VV, PP and II
SendCommand ("VV", NULL, 0, NULL);
// Get the vendor info line
@@ -1155,17 +1043,17 @@
info->model = &buffer[5];
// On to the fun ones that require parsing
ReadLineWithCheck (buffer, -1, true);
- info->minRange = atoi (&buffer[5]);
+ info->minRange = atoi (&buffer[5]);
ReadLineWithCheck (buffer, -1, true);
- info->maxRange = atoi (&buffer[5]);
+ info->maxRange = atoi (&buffer[5]);
ReadLineWithCheck (buffer, -1, true);
- info->steps = atoi (&buffer[5]);
+ info->steps = atoi (&buffer[5]);
ReadLineWithCheck (buffer, -1, true);
- info->firstStep = atoi (&buffer[5]);
+ info->firstStep = atoi (&buffer[5]);
ReadLineWithCheck (buffer, -1, true);
- info->lastStep = atoi (&buffer[5]);
+ info->lastStep = atoi (&buffer[5]);
ReadLineWithCheck (buffer, -1, true);
- info->frontStep = atoi (&buffer[5]);
+ info->frontStep = atoi (&buffer[5]);
ReadLineWithCheck (buffer, -1, true);
info->standardSpeed = atoi (&buffer[5]);
// Skip the end-of-message
@@ -1303,19 +1191,6 @@
int startStep, endStep;
startStep = AngleToStep (startAngle);
endStep = AngleToStep (endAngle);
-// double startStepF, endStepF;
-// startStepF = _frontStep +
-// (static_cast<double> (startAngle) / static_cast<double> (_resolution));
-// // Round towards _frontStep so that the step values are always inside the angles given
-// if (startStepF < _frontStep)
-// startStep = static_cast<int> (ceil (startStepF));
-// else
-// startStep = static_cast<int> (floor (startStepF));
-// endStepF = _frontStep + (static_cast<double> (endAngle) / static_cast<double> (_resolution));
-// if (endStepF < _frontStep)
-// endStep = static_cast<int> (ceil (endStepF));
-// else
-// endStep = static_cast<int> (floor (endStepF));
// Check the steps are within the allowable range
if (startStep < _firstStep || startStep > _lastStep)
@@ -1330,7 +1205,7 @@
}
// Get the data
- return GetRanges (data, startStep, endStep, clusterCount);
+ return GetRanges (data, startStep, endStep, clusterCount);
}
unsigned int URGLaser::GetNewRanges (URGData *data, int startStep, int endStep,
@@ -1357,8 +1232,8 @@
unsigned int numSteps = (endStep - startStep + 1) / clusterCount;
if (_verbose)
{
- cerr << "URGLaser::" << __func__ << "() Reading " << numSteps <<
- " new ranges between " << startStep << " and " << endStep <<
+ cerr << "URGLaser::" << __func__ << "() Reading " << numSteps <<
+ " new ranges between " << startStep << " and " << endStep <<
" with a cluster count of " << clusterCount << endl;
}
@@ -1399,19 +1274,6 @@
int startStep, endStep;
startStep = AngleToStep (startAngle);
endStep = AngleToStep (endAngle);
-// double startStepF, endStepF;
-// startStepF = _frontStep +
-// (static_cast<double> (startAngle) / static_cast<double> (_resolution));
-// // Round towards _frontStep so that the step values are always inside the angles given
-// if (startStepF < _frontStep)
-// startStep = static_cast<int> (ceil (startStepF));
-// else
-// startStep = static_cast<int> (floor (startStepF));
-// endStepF = _frontStep + (static_cast<double> (endAngle) / static_cast<double> (_resolution));
-// if (endStepF < _frontStep)
-// endStep = static_cast<int> (ceil (endStepF));
-// else
-// endStep = static_cast<int> (floor (endStepF));
// Check the steps are within the allowable range
if (startStep < _firstStep || startStep > _lastStep)
@@ -1426,7 +1288,7 @@
}
// Get the data
- return GetNewRanges (data, startStep, endStep, clusterCount);
+ return GetNewRanges (data, startStep, endStep, clusterCount);
}
double URGLaser::StepToAngle (unsigned int step)
@@ -1493,7 +1355,7 @@
{
stringstream ss;
ss << "URGLaser::" << __func__ << "() Got an incorrect line length: " << lineLength <<
- " != " << expectedLength;
+ " != " << expectedLength;
throw URGError (URG_ERR_PROTOCOL, ss.str ());
}
// Replace the line feed with a NULL
@@ -1533,7 +1395,7 @@
// Ignore the checksum itself, and possibly a semicolon (ReadLine has already chopped off the
// line feed for us).
int bytesToConsider = lineLength - 1 - (hasSemicolon ? 1 : 0);
- int checksumIndex = bytesToConsider + (hasSemicolon ? 1 : 0);
+ int checksumIndex = bytesToConsider + (hasSemicolon ? 1 : 0);
if (_verbose)
{
cerr << "URGLaser::" << __func__ << "() Considering " << bytesToConsider <<
@@ -1543,7 +1405,7 @@
{
stringstream ss;
ss << "Not enough bytes to calculate checksum with: " << bytesToConsider <<
- " bytes (line length is " << lineLength << " bytes).";
+ " bytes (line length is " << lineLength << " bytes).";
throw URGError (URG_ERR_PROTOCOL, ss.str ());
}
@@ -1566,8 +1428,8 @@
if (checkSum != static_cast<int> (buffer[checksumIndex]))
{
stringstream ss;
- ss << "Invalid checksum - given: " << static_cast<int> (buffer[checksumIndex]) <<
- ", calculated: " << checkSum;
+ ss << "Invalid checksum - given: " << static_cast<int> (buffer[checksumIndex]) <<
+ ", calculated: " << checkSum;
throw URGError (URG_ERR_PROTOCOL, ss.str ());
}
@@ -1615,7 +1477,7 @@
if (_port->Write ("\n", 1) < 1)
throw URGError (URG_ERR_WRITE, "Failed to write termination character.");
- // Read back the response (should get at least 4 bytes , possibly up to 16 including \n's
+ // Read back the response (should get at least 4 bytes , possibly up to 16 including \n's
// depending on the parameters): cmd[0] params \n status \n
int statusIndex = 2 + paramLength;
ReadLine (response, 2 + paramLength);
@@ -1636,7 +1498,7 @@
// Next up, check the status byte
if (_verbose)
{
- cerr << "URGLaser::" << __func__ << "() Command response status: " <<
+ cerr << "URGLaser::" << __func__ << "() Command response status: " <<
response[statusIndex] << endl;
}
if (response[statusIndex] != '0')
Modified: gearbox/trunk/submitted/urg_nz/urg_nz.h
===================================================================
--- gearbox/trunk/submitted/urg_nz/urg_nz.h 2008-06-23 18:47:22 UTC (rev 204)
+++ gearbox/trunk/submitted/urg_nz/urg_nz.h 2008-06-24 11:32:45 UTC (rev 205)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* urg_nz Hokuyo URG laser scanner driver.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of urg_nz.
*
* urg_nz is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* urg_nz is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
@@ -222,7 +222,7 @@
void CalculateValues (void);
};
-/** @brief Structure to store data returned from the laser scanner. */
+/** @brief Structure to store data returned from the laser scanner. */
class URG_NZ_EXPORT URGData
{
public:
@@ -244,12 +244,13 @@
/// @brief Get the number of samples in the data.
unsigned int Length (void) const { return _length; }
/** @brief Error code for the data (if any).
-
+
@return -1 indicates no error. */
short GetErrorCode (void) const { return _error; }
/// @brief Return a string representing the error code for the data.
std::string ErrorCodeToString (void);
- /// @brief Get the time stamp of the data (only available using SCIP version 2).
+ /** @brief Get the time stamp of the data in milliseconds (only available using SCIP
+ version 2). */
unsigned int TimeStamp (void) const { return _time; }
/// @brief Assignment operator.
@@ -312,7 +313,7 @@
Not available with the SCIP v1 protocol. */
void Reset (void);
- /** @brief Set the speed at which the scanner's sensor spins.
+ /** @brief Set the speed at which the scanner's sensor spins in revolutions per minute.
Valid speeds are: 540, 546, 552, 558, 564, 570, 576, 582, 588, 594, 600. Set the speed to 0
to have it reset to the default value.
@@ -325,7 +326,7 @@
Much of the information is not available with the SCIP v1 protocol. */
void GetSensorInfo (URGSensorInfo *info);
- /** @brief Get the current value of the scanner's clock.
+ /** @brief Get the current value of the scanner's clock in milliseconds.
Not available with the SCIP v1 protocol. */
unsigned int GetTime (void);
@@ -339,7 +340,7 @@
will be re-allocated. This means you can repeatedly send the same @ref URGData object
without having to worry about allocating its data, whether it will change or not, while also
avoiding excessive allocations.
-
+
Not available with the SCIP v1 protocol.
@param data Pointer to a @ref URGData object to store the range readings in.
@@ -371,7 +372,7 @@
Unlike @ref GetRanges, which returns the most recent scan the scanner took, this function
will request a new scan. This means it will wait while the scanner performs the scan.
Otherwise behaves identicallty to @ref GetRanges.
-
+
Not available with the SCIP v1 protocol.
@param data Pointer to a @ref URGData object to store the range readings in.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gb...@us...> - 2008-06-23 18:47:56
|
Revision: 204
http://gearbox.svn.sourceforge.net/gearbox/?rev=204&view=rev
Author: gbiggs
Date: 2008-06-23 11:47:22 -0700 (Mon, 23 Jun 2008)
Log Message:
-----------
Minor changes for Alex Brooks' comments
Modified Paths:
--------------
gearbox/trunk/submitted/flexiport/flexiport.h
gearbox/trunk/submitted/flexiport/logreaderport.h
gearbox/trunk/submitted/flexiport/test/example.readme
gearbox/trunk/submitted/flexiport/test/serial_example.cpp
gearbox/trunk/submitted/urg_nz/test/example.readme
Modified: gearbox/trunk/submitted/flexiport/flexiport.h
===================================================================
--- gearbox/trunk/submitted/flexiport/flexiport.h 2008-06-23 02:26:41 UTC (rev 203)
+++ gearbox/trunk/submitted/flexiport/flexiport.h 2008-06-23 18:47:22 UTC (rev 204)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* flexiport flexible hardware data communications library.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of flexiport.
*
* flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
@@ -87,8 +87,7 @@
/** @brief Overloaded factory function. Accepts options as a string.
-This overload accepts the options as a string, similar in format to command-line options. For
-example:
+This overload accepts the options as a string. For example:
"type=serial device=/dev/ttyS0 baudrate=4800 readwrite"
Options may be separated by any of: spaces, tabs, new lines or commas. Do not put whitespace around
an equals sign.
Modified: gearbox/trunk/submitted/flexiport/logreaderport.h
===================================================================
--- gearbox/trunk/submitted/flexiport/logreaderport.h 2008-06-23 02:26:41 UTC (rev 203)
+++ gearbox/trunk/submitted/flexiport/logreaderport.h 2008-06-23 18:47:22 UTC (rev 204)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* flexiport flexible hardware data communications library.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of flexiport.
*
* flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
@@ -43,7 +43,7 @@
class LogFile;
/** @brief Simulated port using a log file.
-
+
Uses a log file created by the @ref LogWriterPort port type to simulate the data transfer over a
@ref Port object.
@@ -51,7 +51,7 @@
@par Options
- file <string>
- - File name to save the log to. Two files will be created using this name and a suffix.
+ - File name to read the log from. Two files will be created using this name and a suffix.
- Default: port.log
- ignoretimes
- Ignore time stamps in the log files. This means that all readable data is available instantly.
Modified: gearbox/trunk/submitted/flexiport/test/example.readme
===================================================================
--- gearbox/trunk/submitted/flexiport/test/example.readme 2008-06-23 02:26:41 UTC (rev 203)
+++ gearbox/trunk/submitted/flexiport/test/example.readme 2008-06-23 18:47:22 UTC (rev 204)
@@ -45,3 +45,11 @@
a timeout. e.g.:
tcp_example -o timeout=1,debug=3
+
+Note for Windows users
+----------------------
+
+Because Windows lacks a readily-available implementation of getopt, command line
+options are not available for the examples on this platform. Hard-coded options
+will be used instead; change them in the source file and recompile if you need
+to change the port options.
Modified: gearbox/trunk/submitted/flexiport/test/serial_example.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/test/serial_example.cpp 2008-06-23 02:26:41 UTC (rev 203)
+++ gearbox/trunk/submitted/flexiport/test/serial_example.cpp 2008-06-23 18:47:22 UTC (rev 204)
@@ -4,17 +4,17 @@
* Copyright (c) 2008 Geoffrey Biggs
*
* flexiport flexible hardware data communications library.
- *
- * This distribution is licensed to you under the terms described in the LICENSE file included in
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
* this distribution.
*
* This work is a product of the National Institute of Advanced Industrial Science and Technology,
* Japan. Registration number: ___
- *
+ *
* This file is part of flexiport.
*
* flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
- * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
@@ -58,11 +58,10 @@
string portOptions = "type=serial,device=/dev/ttyS0,timeout=1";
#if defined (WIN32)
- device = "COM1";
- portOptions = "timeout=1";
+ portOptions = "type=serial,device=COM1,timeout=1";
#else
// Get some options from the command line
- while ((opt = getopt (argc, argv, "d:o:")) != -1)
+ while ((opt = getopt (argc, argv, "o:")) != -1)
{
switch (opt)
{
@@ -92,7 +91,7 @@
port->Open ();
port->Flush ();
cout << port->GetStatus ();
-
+
cout << "Writing data to port, should read same data back." << endl;
string stringMessage = "Message #1";
cout << "Writing 'Message #1' using WriteString()" << endl;
@@ -217,7 +216,7 @@
cout << "Writing 'Finally, message #6\\n'" << endl;
char charMessage4[] = "Finally, message #6\n";
- if (port->Write (charMessage4, strlen (charMessage4)) != static_cast<int> (strlen (charMessage4)))
+ if (port->Write (charMessage4, strlen (charMessage4)) != static_cast<int> (strlen (charMessage4)))
{
cout << "Test failed: did not write enough bytes." << endl;
return 1;
Modified: gearbox/trunk/submitted/urg_nz/test/example.readme
===================================================================
--- gearbox/trunk/submitted/urg_nz/test/example.readme 2008-06-23 02:26:41 UTC (rev 203)
+++ gearbox/trunk/submitted/urg_nz/test/example.readme 2008-06-23 18:47:22 UTC (rev 204)
@@ -38,3 +38,11 @@
See the LogReaderPort object documentation for more options that can be used
with log file pairs. See the LogWriterPort object documentation for details
on how to make your own log file pair for testing your programs.
+
+Note for Windows users
+----------------------
+
+Because Windows lacks a readily-available implementation of getopt, command line
+options are not available for the example on this platform. Hard-coded options
+will be used instead; change them in the source file and recompile if you need
+to change the port options.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <bo...@us...> - 2008-06-23 02:26:32
|
Revision: 203
http://gearbox.svn.sourceforge.net/gearbox/?rev=203&view=rev
Author: borax00
Date: 2008-06-22 19:26:41 -0700 (Sun, 22 Jun 2008)
Log Message:
-----------
fixed typo in comment.
Modified Paths:
--------------
gearbox/trunk/submitted/flexiport/logreaderport.h
Modified: gearbox/trunk/submitted/flexiport/logreaderport.h
===================================================================
--- gearbox/trunk/submitted/flexiport/logreaderport.h 2008-06-22 12:35:41 UTC (rev 202)
+++ gearbox/trunk/submitted/flexiport/logreaderport.h 2008-06-23 02:26:41 UTC (rev 203)
@@ -54,7 +54,7 @@
- File name to save the log to. Two files will be created using this name and a suffix.
- Default: port.log
- ignoretimes
- - Ignore time stamps in the log files. This means that all readable data is avalable instantly.
+ - Ignore time stamps in the log files. This means that all readable data is available instantly.
It also overrides strictness level 2, if set, essentially turning it into strictness level 1.
- Default: false
- strictness <integer>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <bo...@us...> - 2008-06-22 12:35:35
|
Revision: 202
http://gearbox.svn.sourceforge.net/gearbox/?rev=202&view=rev
Author: borax00
Date: 2008-06-22 05:35:41 -0700 (Sun, 22 Jun 2008)
Log Message:
-----------
Modified Paths:
--------------
gearbox/trunk/src/gbxsickacfr/doc.dox
Modified: gearbox/trunk/src/gbxsickacfr/doc.dox
===================================================================
--- gearbox/trunk/src/gbxsickacfr/doc.dox 2008-06-22 04:19:00 UTC (rev 201)
+++ gearbox/trunk/src/gbxsickacfr/doc.dox 2008-06-22 12:35:41 UTC (rev 202)
@@ -66,7 +66,7 @@
An improvement would be to timestamp the start of each message,
remembering that timestamp for subsequent reads from the serial port
until the end of the message finally arrives.
-- Has only been tested with the LMS-291.
+- Has been tested with: LMS-291, LMS-211.
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rus...@us...> - 2008-06-22 05:11:56
|
Revision: 201
http://gearbox.svn.sourceforge.net/gearbox/?rev=201&view=rev
Author: russo2503v
Date: 2008-06-21 21:19:00 -0700 (Sat, 21 Jun 2008)
Log Message:
-----------
applied john yamakoski os-x patch
Modified Paths:
--------------
gearbox/trunk/cmake/SetupOs.cmake
gearbox/trunk/doc/contributors.dox
gearbox/trunk/src/gbxsickacfr/gbxserialdeviceacfr/CMakeLists.txt
Modified: gearbox/trunk/cmake/SetupOs.cmake
===================================================================
--- gearbox/trunk/cmake/SetupOs.cmake 2008-06-20 05:25:30 UTC (rev 200)
+++ gearbox/trunk/cmake/SetupOs.cmake 2008-06-22 04:19:00 UTC (rev 201)
@@ -39,3 +39,7 @@
SET( GBX_EXE_EXTENSION ".exe" )
MESSAGE( STATUS "Running on Windows" )
ENDIF( GBX_OS_WIN )
+
+IF( GBX_OS_MAC )
+ MESSAGE( STATUS "Running on OS-X" )
+ENDIF( GBX_OS_MAC )
Modified: gearbox/trunk/doc/contributors.dox
===================================================================
--- gearbox/trunk/doc/contributors.dox 2008-06-20 05:25:30 UTC (rev 200)
+++ gearbox/trunk/doc/contributors.dox 2008-06-22 04:19:00 UTC (rev 201)
@@ -22,6 +22,7 @@
- <a href="http://www.cas.edu.au/content.php/232.html?personid=9">Alex Brooks</a>
- <a href="http://www.cas.edu.au/content.php/232.html?personid=45">Tobias Kaupp</a>
- <a href="http://www.cas.edu.au/content.php/232.html?personid=69">Michael Moser</a>
+- John Yamokoski
@par Past contributors
Modified: gearbox/trunk/src/gbxsickacfr/gbxserialdeviceacfr/CMakeLists.txt
===================================================================
--- gearbox/trunk/src/gbxsickacfr/gbxserialdeviceacfr/CMakeLists.txt 2008-06-20 05:25:30 UTC (rev 200)
+++ gearbox/trunk/src/gbxsickacfr/gbxserialdeviceacfr/CMakeLists.txt 2008-06-22 04:19:00 UTC (rev 201)
@@ -6,14 +6,7 @@
# GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )
# this was already tested in the dir above
-# GBX_REQUIRE_VAR( build LIB ${lib_name} GBX_OS_LINUX "only Linux OS is supported" )
-
-# this was already tested in the dir above
-# INCLUDE( ${GBX_CMAKE_DIR}/FindIceUtil.cmake )
-# GBX_REQUIRE_VAR( build LIB ${lib_name} ICEUTIL_FOUND "libIceUtil not found" )
-
-# this was already tested in the dir above
-SET( proj_libs GbxSerialAcfr )
+SET( int_libs GbxSerialAcfr GbxIceUtilAcfr )
# GBX_REQUIRE_TARGETS( build LIB ${lib_name} ${proj_libs} )
IF( build )
@@ -23,18 +16,11 @@
FILE( GLOB hdrs *.h )
FILE( GLOB srcs *.cpp )
- SET( dep_libs ${proj_libs} )
+ SET( dep_libs ${int_libs} )
- # for config.h
- INCLUDE_DIRECTORIES( ${PROJECT_BINARY_DIR} )
-
GBX_ADD_LIBRARY( ${lib_name} SHARED ${srcs} )
TARGET_LINK_LIBRARIES( ${lib_name} ${dep_libs} )
GBX_ADD_HEADERS( gbxsickacfr/gbxserialdeviceacfr ${hdrs} )
-# IF( GBX_BUILD_TESTS )
-# ADD_SUBDIRECTORY( test )
-# ENDIF( GBX_BUILD_TESTS )
-
ENDIF( build )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gb...@us...> - 2008-06-20 05:25:22
|
Revision: 200
http://gearbox.svn.sourceforge.net/gearbox/?rev=200&view=rev
Author: gbiggs
Date: 2008-06-19 22:25:30 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
Fixed some comment typos (they were annoying me)
Modified Paths:
--------------
gearbox/trunk/submitted/flexiport/port.cpp
gearbox/trunk/submitted/flexiport/serialport.cpp
gearbox/trunk/submitted/flexiport/tcpport.cpp
Modified: gearbox/trunk/submitted/flexiport/port.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/port.cpp 2008-06-20 02:30:52 UTC (rev 199)
+++ gearbox/trunk/submitted/flexiport/port.cpp 2008-06-20 05:25:30 UTC (rev 200)
@@ -44,7 +44,7 @@
{
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Constructors/destrutor
+// Constructor/destructor
////////////////////////////////////////////////////////////////////////////////////////////////////
Port::Port (void)
Modified: gearbox/trunk/submitted/flexiport/serialport.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/serialport.cpp 2008-06-20 02:30:52 UTC (rev 199)
+++ gearbox/trunk/submitted/flexiport/serialport.cpp 2008-06-20 05:25:30 UTC (rev 200)
@@ -231,7 +231,7 @@
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Constructor/desctructor
+// Constructor/destructor
////////////////////////////////////////////////////////////////////////////////////////////////////
SerialPort::SerialPort (map<string, string> options)
Modified: gearbox/trunk/submitted/flexiport/tcpport.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/tcpport.cpp 2008-06-20 02:30:52 UTC (rev 199)
+++ gearbox/trunk/submitted/flexiport/tcpport.cpp 2008-06-20 05:25:30 UTC (rev 200)
@@ -81,7 +81,7 @@
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Constructor/desctructor
+// Constructor/destructor
////////////////////////////////////////////////////////////////////////////////////////////////////
TCPPort::TCPPort (map<string, string> options)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gb...@us...> - 2008-06-20 02:30:49
|
Revision: 199
http://gearbox.svn.sourceforge.net/gearbox/?rev=199&view=rev
Author: gbiggs
Date: 2008-06-19 19:30:52 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
Submitting the flexiport library and the replacement for the urg_nz library.
Modified Paths:
--------------
gearbox/trunk/submitted/CMakeLists.txt
Added Paths:
-----------
gearbox/trunk/submitted/flexiport/
gearbox/trunk/submitted/flexiport/CMakeLists.txt
gearbox/trunk/submitted/flexiport/doc.dox
gearbox/trunk/submitted/flexiport/flexiport.cpp
gearbox/trunk/submitted/flexiport/flexiport.h
gearbox/trunk/submitted/flexiport/flexiport_config.h.in
gearbox/trunk/submitted/flexiport/logfile.cpp
gearbox/trunk/submitted/flexiport/logfile.h
gearbox/trunk/submitted/flexiport/logreaderport.cpp
gearbox/trunk/submitted/flexiport/logreaderport.h
gearbox/trunk/submitted/flexiport/logwriterport.cpp
gearbox/trunk/submitted/flexiport/logwriterport.h
gearbox/trunk/submitted/flexiport/port.cpp
gearbox/trunk/submitted/flexiport/port.h
gearbox/trunk/submitted/flexiport/serialport.cpp
gearbox/trunk/submitted/flexiport/serialport.h
gearbox/trunk/submitted/flexiport/tcpport.cpp
gearbox/trunk/submitted/flexiport/tcpport.h
gearbox/trunk/submitted/flexiport/test/
gearbox/trunk/submitted/flexiport/test/CMakeLists.txt
gearbox/trunk/submitted/flexiport/test/example.cmake.in
gearbox/trunk/submitted/flexiport/test/example.logr
gearbox/trunk/submitted/flexiport/test/example.logw
gearbox/trunk/submitted/flexiport/test/example.readme
gearbox/trunk/submitted/flexiport/test/serial_example.cpp
gearbox/trunk/submitted/flexiport/test/tcp_example.cpp
gearbox/trunk/submitted/flexiport/timeout.cpp
gearbox/trunk/submitted/flexiport/timeout.h
gearbox/trunk/submitted/flexiport/utils/
gearbox/trunk/submitted/flexiport/utils/CMakeLists.txt
gearbox/trunk/submitted/flexiport/utils/porttoport.cpp
gearbox/trunk/submitted/flexiport/utils/utils.cmake.in
gearbox/trunk/submitted/flexiport/utils/utils.readme
gearbox/trunk/submitted/urg_nz/
gearbox/trunk/submitted/urg_nz/CMakeLists.txt
gearbox/trunk/submitted/urg_nz/doc.dox
gearbox/trunk/submitted/urg_nz/test/
gearbox/trunk/submitted/urg_nz/test/CMakeLists.txt
gearbox/trunk/submitted/urg_nz/test/example.cmake.in
gearbox/trunk/submitted/urg_nz/test/example.cpp
gearbox/trunk/submitted/urg_nz/test/example.logr
gearbox/trunk/submitted/urg_nz/test/example.logw
gearbox/trunk/submitted/urg_nz/test/example.readme
gearbox/trunk/submitted/urg_nz/urg_nz.cpp
gearbox/trunk/submitted/urg_nz/urg_nz.h
Modified: gearbox/trunk/submitted/CMakeLists.txt
===================================================================
--- gearbox/trunk/submitted/CMakeLists.txt 2008-06-19 15:36:49 UTC (rev 198)
+++ gearbox/trunk/submitted/CMakeLists.txt 2008-06-20 02:30:52 UTC (rev 199)
@@ -10,7 +10,8 @@
# When adding new directories, please maintain order of inter-dependencies.
# Otherwise, maintain alphabetical order.
# E.g. ADD_SUBDIRECTORY( mydir )
-
+ ADD_SUBDIRECTORY( flexiport )
ADD_SUBDIRECTORY( gbxnovatelacfr )
+ ADD_SUBDIRECTORY( urg_nz )
ENDIF( GBX_BUILD_SUBMITTED )
Added: gearbox/trunk/submitted/flexiport/CMakeLists.txt
===================================================================
--- gearbox/trunk/submitted/flexiport/CMakeLists.txt (rev 0)
+++ gearbox/trunk/submitted/flexiport/CMakeLists.txt 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,54 @@
+SET (libName flexiport)
+GBX_ADD_LICENSE (LGPL)
+
+SET (build TRUE)
+GBX_REQUIRE_OPTION (build LIB ${libName} ON)
+
+IF (build)
+ INCLUDE (${GBX_CMAKE_DIR}/UseBasicRules.cmake)
+
+ OPTION (FLEXIPORT_INCLUDE_SERIAL "Include the serial port in FlexiPort" ON)
+ OPTION (FLEXIPORT_INCLUDE_TCP "Include the TCP network port in FlexiPort" ON)
+ OPTION (FLEXIPORT_INCLUDE_LOGGING "Include the log reader/writer ports in FlexiPort" ON)
+ MARK_AS_ADVANCED (FLEXIPORT_INCLUDE_SERIAL FLEXIPORT_INCLUDE_TCP)
+
+ SET (flexiport_config_h_in ${CMAKE_CURRENT_SOURCE_DIR}/flexiport_config.h.in)
+ SET (flexiport_config_h ${CMAKE_CURRENT_BINARY_DIR}/flexiport_config.h)
+ CONFIGURE_FILE (${flexiport_config_h_in} ${flexiport_config_h})
+ INCLUDE_DIRECTORIES (${CMAKE_CURRENT_BINARY_DIR})
+
+ SET (hdrs flexiport.h port.h timeout.h ${flexiport_config_h})
+ SET (srcs flexiport.cpp port.cpp timeout.cpp ${flexiport_config_h})
+ IF (FLEXIPORT_INCLUDE_SERIAL)
+ SET (hdrs ${hdrs} serialport.h)
+ SET (srcs ${srcs} serialport.cpp)
+ ENDIF (FLEXIPORT_INCLUDE_SERIAL)
+ IF (FLEXIPORT_INCLUDE_TCP)
+ SET (hdrs ${hdrs} tcpport.h)
+ SET (srcs ${srcs} tcpport.cpp)
+ ENDIF (FLEXIPORT_INCLUDE_TCP)
+ IF (FLEXIPORT_INCLUDE_LOGGING)
+ IF (NOT GBX_OS_WIN)
+ SET (hdrs ${hdrs} logwriterport.h logreaderport.h)
+ SET (srcs ${srcs} logwriterport.cpp logreaderport.cpp logfile.cpp)
+ ELSE (NOT GBX_OS_WIN)
+ MESSAGE (STATUS "Flexiport log file system is not currently supported on Windows.")
+ ENDIF (NOT GBX_OS_WIN)
+ ENDIF (FLEXIPORT_INCLUDE_LOGGING)
+
+ IF (WIN32)
+ ADD_DEFINITIONS (-DFLEXIPORT_EXPORTS)
+ ENDIF (WIN32)
+ ADD_DEFINITIONS (-DFLEXIPORT_EXPORTS)
+ GBX_ADD_LIBRARY (${libName} SHARED ${srcs})
+ GBX_ADD_PKGCONFIG (${libName} "FlexiPort generic comms library" "" "" "" "")
+ GBX_ADD_HEADERS (${libName} ${hdrs})
+ IF (WIN32)
+ TARGET_LINK_LIBRARIES (${libName} Ws2_32)
+ ENDIF (WIN32)
+
+ ADD_SUBDIRECTORY (utils)
+ IF (GBX_BUILD_TESTS)
+ ADD_SUBDIRECTORY (test)
+ ENDIF (GBX_BUILD_TESTS)
+ENDIF (build)
Added: gearbox/trunk/submitted/flexiport/doc.dox
===================================================================
--- gearbox/trunk/submitted/flexiport/doc.dox (rev 0)
+++ gearbox/trunk/submitted/flexiport/doc.dox 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,91 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2008 Geoffrey Biggs
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
+
+/*!
+@ingroup gbx_libs
+@ingroup gbx_cpp
+@ingroup gbx_linux
+@ingroup gbx_windows
+@ingroup gbx_osx
+@defgroup gbx_library_flexiport FlexiPort
+@brief FlexiPort data communications library.
+
+Provides a consistent interface for communicating over a range of data port types. Currently serial
+and TCP ports are supported. Support for USB ports is planned for when I get a suitable USB device
+to test with. Logging is possible, which allows communications sessions to be played back at a later
+date without the original hardware present.
+
+The @ref SerialPort and @ref TCPPort port types are cross-platform, usable on Linux, Mac OSX and
+Microsoft Windows.
+
+@par Header file
+
+Necessary:
+@verbatim
+#include <flexiport/flexiport.h>
+#include <flexiport/port.h>
+@endverbatim
+
+Optional if port type-specific features are required:
+For SerialPort:
+@verbatim
+#include <flexiport/serialport.h>
+@endverbatim
+For TCPPort:
+@verbatim
+#include <flexiport/tcpport.h>
+@endverbatim
+For logging ports:
+@verbatim
+#include <flexiport/logwriterport.h>
+#include <flexiport/logreaderport.h>
+@endverbatim
+
+@par Example
+ See test/tcp_example.cpp and test/serial_example.cpp.
+
+@par Style
+- Naming conventions:
+ - Class methods start with a capital letter.
+ - variableNamesLikeThis.
+ - Private member variables start with an underscore _like _this.
+ - Avoid using \#defines. \#define'd values in all capitals when necessary.
+- Formatting:
+ - 1 tab indentation at start of lines, spaces only for inside lines (e.g. before commands).
+ - Function declarations on one line.
+ - Space between function name and arguments.
+- C++ API.
+ - Functionality provided through classes.
+
+@par Copyright
+ Geoffrey Biggs
+
+@par Responsible Developer
+ Geoffrey Biggs
+
+@par License
+ LGPL
+
+@par Dependencies
+
+- None
+
+*/
+
+
+/*!
+@brief FlexiPort data communications library.
+@namespace flexiport
+
+This namespace is part of the FlexiPort library.
+
+@see @ref gbx_library_flexiport
+
+*/
Added: gearbox/trunk/submitted/flexiport/flexiport.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/flexiport.cpp (rev 0)
+++ gearbox/trunk/submitted/flexiport/flexiport.cpp 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,159 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2008 Geoffrey Biggs
+ *
+ * flexiport flexible hardware data communications library.
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
+ * this distribution.
+ *
+ * This work is a product of the National Institute of Advanced Industrial Science and Technology,
+ * Japan. Registration number: ___
+ *
+ * This file is part of flexiport.
+ *
+ * flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with flexiport.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "flexiport.h"
+#include "port.h"
+#include "serialport.h"
+#include "tcpport.h"
+#include "logwriterport.h"
+#include "logreaderport.h"
+#include "flexiport_config.h"
+
+#include <errno.h>
+#include <iostream>
+#include <sstream>
+using namespace std;
+
+namespace flexiport
+{
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Central factory function
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Port* CreatePort (string options)
+{
+ const char* separators = ", \t\n";
+ map<string, string> optionsMap;
+
+ string::size_type pos = 0;
+ // Find the start of the first option (skip delimeters at the beginning)
+ string::size_type lastPos = options.find_first_not_of (separators, 0);
+ // Check first that we did actually get something in the string
+ if (lastPos == string::npos)
+ {
+ // No options. Go boom.
+ throw PortException ("No options specified. Must specify a port type.");
+ }
+
+ do
+ {
+ pos = options.find_first_of (separators, lastPos);
+
+ // Got an option, one way or the other
+ string option = options.substr (lastPos, pos - lastPos);
+
+ string::size_type splitPos = option.find ('=');
+ if (splitPos != string::npos)
+ {
+ // Need to split this token
+ optionsMap[option.substr (0, splitPos)] =
+ option.substr (splitPos + 1, option.length () - splitPos - 1);
+ }
+ else
+ {
+ // Boolean option
+ optionsMap[option] = "1";
+ }
+
+ // Bring lastPos forward to the start of the next option (not just current pos)
+ lastPos = options.find_first_not_of (separators, pos);
+ }
+ while (lastPos != string::npos && pos != string::npos);
+
+ // Now that the options are in a map, call the standard CreatePort function
+ return CreatePort (optionsMap);
+}
+
+Port* CreatePort (map<string, string> options)
+{
+ // Look for a type option
+ string type;
+ if (options.count ("type") == 0)
+ throw PortException ("No port type specified.");
+ else if (options.count ("type") != 1)
+ throw PortException ("Multiple port types specified.");
+ else
+ type = options["type"];
+ options.erase ("type");
+
+#ifdef FLEXIPORT_INCLUDE_SERIAL
+ if (type == "serial")
+ {
+ SerialPort *newPort = new SerialPort (options);
+ if (newPort == NULL)
+ throw PortException ("Failed to allocate new port");
+ return newPort;
+ }
+#endif // FLEXIPORT_INCLUDE_SERIAL
+#ifdef FLEXIPORT_INCLUDE_TCP
+ if (type == "tcp")
+ {
+ TCPPort *newPort = new TCPPort (options);
+ if (newPort == NULL)
+ throw PortException ("Failed to allocate new port");
+ return newPort;
+ }
+#endif // FLEXIPORT_INCLUDE_TCP
+
+#ifdef FLEXIPORT_INCLUDE_LOGGING
+ if (type == "logreader")
+ {
+ LogReaderPort *newPort = new LogReaderPort (options);
+ if (newPort == NULL)
+ throw PortException ("Failed to allocate new port");
+ return newPort;
+ }
+ #ifdef FLEXIPORT_INCLUDE_SERIAL
+ if (type == "seriallog")
+ {
+ options["type"] = "serial";
+ LogWriterPort *newPort = new LogWriterPort (options);
+ if (newPort == NULL)
+ throw PortException ("Failed to allocate new port");
+ return newPort;
+ }
+ #endif // FLEXIPORT_INCLUDE_SERIAL
+ #ifdef FLEXIPORT_INCLUDE_TCP
+ if (type == "tcplog")
+ {
+ options["type"] = "tcp";
+ LogWriterPort *newPort = new LogWriterPort (options);
+ if (newPort == NULL)
+ throw PortException ("Failed to allocate new port");
+ return newPort;
+ }
+ #endif // FLEXIPORT_INCLUDE_TCP
+#endif // FLEXIPORT_INCLUDE_LOGGING
+
+ // If got to here, it's an unsupported port type
+ stringstream ss;
+ ss << "Unsupported port type: " << type;
+ throw PortException (ss.str ());
+}
+
+} // namespace flexiport
Added: gearbox/trunk/submitted/flexiport/flexiport.h
===================================================================
--- gearbox/trunk/submitted/flexiport/flexiport.h (rev 0)
+++ gearbox/trunk/submitted/flexiport/flexiport.h 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,103 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2008 Geoffrey Biggs
+ *
+ * flexiport flexible hardware data communications library.
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
+ * this distribution.
+ *
+ * This work is a product of the National Institute of Advanced Industrial Science and Technology,
+ * Japan. Registration number: ___
+ *
+ * This file is part of flexiport.
+ *
+ * flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with flexiport.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __FLEXIPORT_H
+#define __FLEXIPORT_H
+
+#include <map>
+#include <string>
+
+#if defined (WIN32)
+ #if defined (FLEXIPORT_EXPORTS)
+ #define FLEXIPORT_EXPORT __declspec (dllexport)
+ #else
+ #define FLEXIPORT_EXPORT __declspec (dllimport)
+ #endif
+#else
+ #define FLEXIPORT_EXPORT
+#endif
+
+/** @ingroup gbx_library_flexiport
+@{
+*/
+
+namespace flexiport
+{
+
+/// @brief Exception thrown by the Port class and its derivatives.
+class FLEXIPORT_EXPORT PortException : public std::exception
+{
+ public:
+ PortException (const char *errorStr)
+ : _errorStr (errorStr) {};
+ PortException (const std::string &errorStr)
+ : _errorStr (errorStr) {};
+ ~PortException (void) throw () {};
+
+ virtual const char* what (void) const throw ()
+ {
+ return _errorStr.c_str ();
+ }
+
+ private:
+ std::string _errorStr;
+};
+
+// Forward declaration of the Port class
+class Port;
+
+/** @brief Factory function to create a @ref Port object of the necessary port type.
+
+This factory function is the only way to create a @ref Port object matching the type of port you
+need. Options are passed in as key/value pairs in the @ref options argument. A minimum of one option
+is necessary, the "type" option. This specifies the type of port to be created. An object of the
+correct class (@ref SerialPort, @ref TCPPort or @ref LogReaderPort, for example) will be created
+based on the value of this option. All other options, including both universal options and
+type-specific options, will be passed on to the created object.
+
+See @ref Options for a list of options accepted by all port types. See each port type's description
+for a list of options accepted by that port type.
+
+@return A pointer to a @ref Port object.*/
+FLEXIPORT_EXPORT Port* CreatePort (std::map<std::string, std::string> options);
+
+/** @brief Overloaded factory function. Accepts options as a string.
+
+This overload accepts the options as a string, similar in format to command-line options. For
+example:
+"type=serial device=/dev/ttyS0 baudrate=4800 readwrite"
+Options may be separated by any of: spaces, tabs, new lines or commas. Do not put whitespace around
+an equals sign.
+
+@return A pointer to a @ref Port object.*/
+FLEXIPORT_EXPORT Port* CreatePort (std::string options);
+
+} // namespace flexiport
+
+/** @} */
+
+#endif // __FLEXIPORT_H
Added: gearbox/trunk/submitted/flexiport/flexiport_config.h.in
===================================================================
--- gearbox/trunk/submitted/flexiport/flexiport_config.h.in (rev 0)
+++ gearbox/trunk/submitted/flexiport/flexiport_config.h.in 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,5 @@
+#cmakedefine FLEXIPORT_EXPORTS 1
+
+#cmakedefine FLEXIPORT_INCLUDE_SERIAL 1
+#cmakedefine FLEXIPORT_INCLUDE_TCP 1
+#cmakedefine FLEXIPORT_INCLUDE_LOGGING 1
\ No newline at end of file
Added: gearbox/trunk/submitted/flexiport/logfile.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/logfile.cpp (rev 0)
+++ gearbox/trunk/submitted/flexiport/logfile.cpp 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,1286 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2008 Geoffrey Biggs
+ *
+ * flexiport flexible hardware data communications library.
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
+ * this distribution.
+ *
+ * This work is a product of the National Institute of Advanced Industrial Science and Technology,
+ * Japan. Registration number: ___
+ *
+ * This file is part of flexiport.
+ *
+ * flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with flexiport.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "flexiport.h"
+#include "logfile.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sstream>
+#include <iostream>
+using namespace std;
+
+#if defined (WIN32)
+ #define __func__ __FUNCTION__
+#endif
+
+namespace flexiport
+{
+
+inline int ErrNo (void)
+{
+#if defined (WIN32)
+ return WSAGetLastError ();
+#else
+ return errno;
+#endif
+}
+
+inline string StrError (int errNo)
+{
+#if defined (WIN32)
+ LPVOID bufferPointer = NULL;
+ FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ errNo, 0, reinterpret_cast<LPTSTR> (&bufferPointer), 0, NULL);
+ string result (reinterpret_cast<LPTSTR> (bufferPointer));
+ LocalFree (bufferPointer);
+ return result;
+#else
+ return string (strerror (errNo));
+#endif
+}
+
+const size_t CHUNK_HEADER_SIZE = sizeof (size_t) + sizeof (struct timeval);
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Constructor/destructor
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+LogFile::LogFile (unsigned int debug)
+ : _read (false), _readFile (NULL), _writeFile (NULL), _readFileSize (0), _writeFileSize (0),
+ _debug (debug), _readUsage (0), _writeUsage (0), _readSize (0), _writeSize (0),
+ _readBuffer (NULL), _writeBuffer (NULL), _ignoreTimes (false)
+// _bufferSize (0),
+{
+ timerclear (&_openTime);
+}
+
+LogFile::~LogFile (void)
+{
+ Close ();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// File management
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void LogFile::Open (string fileName, bool read, bool ignoreTimes)
+{
+ Close ();
+
+ _fileName = fileName;
+ _read = read;
+ _ignoreTimes = ignoreTimes;
+
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Opening " << _fileName << " for " <<
+ (_read ? "reading." : "writing.") << endl;
+ }
+
+ if (_read)
+ {
+ if ((_readFile = fopen ((fileName + "r").c_str (), "r")) == NULL)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fopen(_readFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ if ((_writeFile = fopen ((fileName + "w").c_str (), "r")) == NULL)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fopen(_writeFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ // Get the file sizes for open checks
+ _readFileSize = GetFileSize (_readFile);
+ _writeFileSize = GetFileSize (_writeFile);
+ }
+ else
+ {
+ if ((_readFile = fopen ((fileName + "r").c_str (), "w")) == NULL)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fopen(_readFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ if ((_writeFile = fopen ((fileName + "w").c_str (), "w")) == NULL)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fopen(_writeFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ }
+
+ if (_debug >= 1)
+ {
+ cerr << "LogFile::" << __func__ << "() Opened " << _fileName << "r/w for " <<
+ (_read ? "reading." : "writing.") << endl;
+ }
+}
+
+void LogFile::Close (void)
+{
+ if (_readFile != NULL)
+ {
+ if (fclose (_readFile) == EOF)
+ {
+ _readFile = NULL;
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fclose(_readFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ }
+ if (_writeFile != NULL)
+ {
+ if (fclose (_writeFile) == EOF)
+ {
+ _writeFile = NULL;
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fclose(_writeFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ }
+
+ if (_readBuffer != NULL)
+ {
+ free (_readBuffer);
+ _readBuffer = NULL;
+ }
+ if (_writeBuffer != NULL)
+ {
+ free (_writeBuffer);
+ _writeBuffer = NULL;
+ }
+
+ if (_debug >= 1)
+ cerr << "LogFile::" << __func__ << "() Closed file." << endl;
+}
+
+bool LogFile::IsOpen (void) const
+{
+ if (_readFile == NULL || _writeFile == NULL)
+ return false;
+
+ long pos;
+ if ((pos = ftell (_readFile)) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ if (pos == _readFileSize)
+ return false;
+
+ if ((pos = ftell (_writeFile)) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ if (pos == _writeFileSize)
+ return false;
+
+ return true;
+}
+
+//void LogFile::SetBufferSize (unsigned int bufferSize)
+//{
+// _bufferSize = bufferSize;
+// AllocateReadBuffer (_bufferSize);
+// AllocateWriteBuffer (_bufferSize);
+//}
+
+void LogFile::ResetFile (void)
+{
+ // Rewind file positions
+ if (fseek (_readFile, 0, SEEK_SET) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek(_readFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ if (fseek (_writeFile, 0, SEEK_SET) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek(_writeFile) error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ // Free buffers
+ DeallocateReadBuffer ();
+ DeallocateWriteBuffer ();
+
+ // Reset file open time
+ if (gettimeofday (&_openTime, NULL) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ if (_debug >= 1)
+ cerr << "LogFile::" << __func__ << "() Reset file." << endl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Chunk reading (this stuff is messy)
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ssize_t LogFile::Read (void *data, size_t count, Timeout &timeout)
+{
+ size_t totalRead = 0;
+
+ // Get the current file time
+ struct timeval now;
+ GetCurrentFileTime (now);
+
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Reading up to " << count << " bytes." << endl;
+
+ // First copy any data in the overflow buffer
+ if (_readUsage > 0)
+ {
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Getting " << _readUsage <<
+ " bytes from overflow buffer." << endl;
+ }
+
+ size_t toCopy = (count < _readUsage) ? count : _readUsage;
+ memcpy (data, _readBuffer, toCopy);
+ totalRead += toCopy;
+ // Check if we've used up the stuff in the buffer
+ if (count < _readUsage)
+ {
+ // Shift the remaining data in the overflow buffer to the beginning
+ memmove (_readBuffer, &(reinterpret_cast<uint8_t*> (_readBuffer)[count]),
+ _readUsage - count);
+ _readUsage -= count;
+ // Have all the data we need, return
+ return count;
+ }
+ else if (count == _readUsage)
+ {
+ DeallocateReadBuffer ();
+ // Have all the data we need, return
+ return count;
+ }
+ else // count > _readUsage
+ {
+ DeallocateReadBuffer ();
+ // We haven't met count yet
+ count -= _readUsage;
+ data = reinterpret_cast<uint8_t*> (data) + _readUsage;
+ }
+ }
+
+ // Now get data from the file
+ if (_ignoreTimes)
+ {
+ // Read chunks until we have enough data
+ while (count > 0 && IsOpen ())
+ {
+ struct timeval timestamp;
+ size_t size, read;
+ read = GetSingleChunk (_readFile, &(reinterpret_cast<uint8_t*> (data)[count]), count,
+ timestamp, size);
+ count -= read;
+ data = reinterpret_cast<uint8_t*> (data) + read;
+ totalRead += read;
+ }
+ return totalRead;
+ }
+ else
+ {
+ // Have to pay attention to time stamps (annoying and messy)
+ if (DataAvailableWithinLimit (_readFile, now))
+ {
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Data available in file now." << endl;
+
+ // Get all the data that is immediatly available and return it
+ totalRead += GetChunksToTimeLimit (_readFile, data, count, now);
+ return totalRead;
+ }
+
+ // There was no data instantly, so now the timeout gets involved
+ if (timeout._sec == -1)
+ {
+ // Infinite timeout
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Getting next chunk, no timeout." << endl;
+
+ // Get the next available chunk from the file
+ struct timeval timestamp;
+ size_t size;
+ totalRead += GetSingleChunk (_readFile, data, count, timestamp, size);
+
+ // Calculate the time difference between now and this chunk's timestamp
+ struct timeval diff;
+ GetCurrentFileTime (now);
+ timersub (×tamp, &now, &diff);
+ if (diff.tv_sec >= 0 && diff.tv_usec >= 0)
+ {
+ // Sleep for this period of time
+ struct timespec diff2;
+ diff2.tv_sec = diff.tv_sec;
+ diff2.tv_nsec = diff.tv_usec * 1000;
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Sleeping for " << diff2.tv_sec << "s " <<
+ diff2.tv_nsec << "ns." << endl;
+ }
+ nanosleep (&diff2, NULL);
+ }
+ return totalRead;
+ }
+ else if (timeout._sec > 0 || timeout._usec > 0)
+ {
+ // Limited timeout
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Getting next chunk with timeout." << endl;
+
+ // Check if there is actually data available within this time limit
+ struct timeval timeoutVal, limit;
+ timeout.AsTimeval (timeoutVal);
+ GetCurrentFileTime (now);
+ timeradd (&now, &timeoutVal, &limit);
+ if (DataAvailableWithinLimit (_readFile, limit))
+ {
+ // There is so get it
+ struct timeval timestamp;
+ size_t size;
+ totalRead += GetSingleChunk (_readFile, data, count, timestamp, size);
+
+ // Calculate the time difference between now and this chunk's timestamp
+ struct timeval diff;
+ GetCurrentFileTime (now);
+ timersub (×tamp, &now, &diff);
+ if (diff.tv_sec >= 0 && diff.tv_usec >= 0)
+ {
+ // Sleep for this period of time
+ struct timespec diff2;
+ diff2.tv_sec = diff.tv_sec;
+ diff2.tv_nsec = diff.tv_usec * 1000;
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Sleeping for " << diff2.tv_sec << "s " <<
+ diff2.tv_nsec << "ns." << endl;
+ }
+ nanosleep (&diff2, NULL);
+ }
+ return totalRead;
+ }
+ else
+ {
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() No chunks within timeout." << endl;
+ // No data available, return timeout
+ return -1;
+ }
+ }
+ else
+ {
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() No data available at all." << endl;
+ // No data available, return timeout
+ return -1;
+ }
+ }
+}
+
+ssize_t LogFile::BytesAvailable (const Timeout &timeout)
+{
+ if (_ignoreTimes)
+ {
+ // Don't care about times, so just get the file size.
+ return GetFileSize (_readFile);
+ }
+ else
+ {
+ // Get the current file time
+ struct timeval now;
+ GetCurrentFileTime (now);
+
+ // Now count data from the file
+ if (DataAvailableWithinLimit (_readFile, now))
+ {
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Enough data available in file now." << endl;
+ // Data available immediately, return its size plus the size of the overflow buffer
+ return _readUsage + GetChunkSizesToTimeLimit (_readFile, now);
+ }
+ else if (_readUsage > 0)
+ {
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Only data in overflow buffer." << endl;
+ // No data from file, but there is data in the overflow buffer, so that will do
+ return _readUsage;
+ }
+
+ // There was no data instantly, so now the timeout gets involved
+ if (timeout._sec == -1)
+ {
+ // Infinite timeout
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Getting next chunk, no timeout." << endl;
+
+ // Get the next available chunk from the file
+ struct timeval timeStamp;
+ size_t size;
+ GetNextChunkInfo (_readFile, timeStamp, size);
+
+ // Calculate the time difference between now and this chunk's timestamp
+ struct timeval diff;
+ GetCurrentFileTime (now);
+ timersub (&timeStamp, &now, &diff);
+ if (diff.tv_sec >= 0 && diff.tv_usec >= 0)
+ {
+ // Sleep for this period of time
+ struct timespec diff2;
+ diff2.tv_sec = diff.tv_sec;
+ diff2.tv_nsec = diff.tv_usec * 1000;
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Sleeping for " << diff2.tv_sec << "s " <<
+ diff2.tv_nsec << "ns." << endl;
+ }
+ nanosleep (&diff2, NULL);
+ }
+ return size;
+ }
+ else if (timeout._sec > 0 || timeout._usec > 0)
+ {
+ // Limited timeout
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() Getting next chunk with timeout." << endl;
+
+ // Check if there is actually data available within this time limit
+ struct timeval timeoutVal, limit;
+ timeout.AsTimeval (timeoutVal);
+ GetCurrentFileTime (now);
+ timeradd (&now, &timeoutVal, &limit);
+ if (DataAvailableWithinLimit (_readFile, limit))
+ {
+ // There is so get it
+ struct timeval timeStamp;
+ size_t size;
+ GetNextChunkInfo (_readFile, timeStamp, size);
+
+ // Calculate the time difference between now and this chunk's timestamp
+ struct timeval diff;
+ GetCurrentFileTime (now);
+ timersub (&timeStamp, &now, &diff);
+ if (diff.tv_sec >= 0 && diff.tv_usec >= 0)
+ {
+ // Sleep for this period of time
+ struct timespec diff2;
+ diff2.tv_sec = diff.tv_sec;
+ diff2.tv_nsec = diff.tv_usec * 1000;
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Sleeping for " << diff2.tv_sec << "s " <<
+ diff2.tv_nsec << "ns." << endl;
+ }
+ nanosleep (&diff2, NULL);
+ }
+ return size;
+ }
+ else
+ {
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() No chunks within timeout." << endl;
+ // No data available, return timeout
+ return -1;
+ }
+ }
+ else
+ {
+ if (_debug >= 2)
+ cerr << "LogFile::" << __func__ << "() No data available at all." << endl;
+ // No data available, return timeout
+ return -1;
+ }
+ }
+}
+
+bool LogFile::CheckWrite (const void * const data, const size_t count, size_t * const numWritten,
+ const Timeout * const timeout)
+{
+ size_t totalRead = 0;
+ long readFileOffset;
+ // Get the current read file offset (see comment at function end)
+ if ((readFileOffset = ftell (_readFile)) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Checking " << count <<
+ " bytes for accuracy. Timeouts will " << ((timeout == NULL) ? "" : "not ") <<
+ "be used." << endl;
+ }
+
+ // Allocate space to store the data to compare with
+ uint8_t *fileData;
+ if ((fileData = new uint8_t[count]) == NULL)
+ {
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("Failed to allocate temporary space for write comparison."));
+ }
+
+ // Pull any data out of the overflow first
+ bool needMore = true;
+ if (_writeUsage > 0)
+ {
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Getting " << _writeUsage <<
+ " bytes from overflow buffer." << endl;
+ }
+
+ size_t toCopy = (count < _writeUsage) ? count : _writeUsage;
+ memcpy (fileData, _writeBuffer, toCopy);
+ totalRead += toCopy;
+ // Check if we've used up the stuff in the buffer
+ if (count < _writeUsage)
+ {
+ // Shift the remaining data in the buffer to the beginning
+ memmove (_writeBuffer, &(reinterpret_cast<uint8_t*> (_writeBuffer)[count]),
+ _writeUsage - count);
+ _writeUsage -= count;
+ // Have all the data we need
+ needMore = false;
+ }
+ else if (count == _writeUsage)
+ {
+ DeallocateWriteBuffer ();
+ // Have all the data we need
+ needMore = false;
+ }
+ else // count > _writeUsage
+ {
+ DeallocateWriteBuffer ();
+ // We haven't met count yet so get the rest from the file
+ }
+ }
+
+ if (needMore)
+ {
+ if (timeout == NULL || _ignoreTimes)
+ {
+ // Don't care about times, so just get data and compare
+ while (totalRead < count && IsOpen ())
+ {
+ struct timeval timestamp;
+ size_t size, read;
+ read = GetSingleChunk (_writeFile, &fileData[totalRead], count - totalRead,
+ timestamp, size);
+ totalRead += read;
+ }
+ }
+ else
+ {
+ // Things are more complex in this case
+ if (timeout->_sec == -1)
+ {
+ // Infinite timeout - ignore jitter
+
+ // Get the next available chunk from the file
+ struct timeval timestamp;
+ size_t size, read;
+ read = GetSingleChunk (_writeFile, &fileData[totalRead], count - totalRead,
+ timestamp, size);
+ totalRead += read;
+
+ // Calculate the time difference between now and this chunk's timestamp
+ struct timeval diff, now;
+ GetCurrentFileTime (now);
+ timersub (×tamp, &now, &diff);
+ if (diff.tv_sec >= 0 && diff.tv_usec >= 0)
+ {
+ // Sleep for this period of time
+ struct timespec diff2;
+ diff2.tv_sec = diff.tv_sec;
+ diff2.tv_nsec = diff.tv_usec * 1000;
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Sleeping for " << diff2.tv_sec << "s " <<
+ diff2.tv_nsec << "ns." << endl;
+ }
+ nanosleep (&diff2, NULL);
+ }
+ }
+ else if (timeout->_sec > 0 || timeout->_usec > 0)
+ {
+ // Limited timeout
+
+ // Check if there is actually data available within this time limit
+ struct timeval now, timeoutVal, limit;
+ timeout->AsTimeval (timeoutVal);
+ GetCurrentFileTime (now);
+ timeradd (&now, &timeoutVal, &limit);
+ if (DataAvailableWithinLimit (_writeFile, limit))
+ {
+ // There is so get it
+ struct timeval timestamp;
+ size_t size, read;
+ read = GetSingleChunk (_writeFile, &fileData[totalRead], count - totalRead,
+ timestamp, size);
+ totalRead += read;
+
+ // Calculate the time difference between now and this chunk's timestamp
+ struct timeval diff;
+ GetCurrentFileTime (now);
+ timersub (×tamp, &now, &diff);
+ if (diff.tv_sec >= 0 && diff.tv_usec >= 0)
+ {
+ // Sleep for this period of time
+ struct timespec diff2;
+ diff2.tv_sec = diff.tv_sec;
+ diff2.tv_nsec = diff.tv_usec * 1000;
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Sleeping for " << diff2.tv_sec <<
+ "s " << diff2.tv_nsec << "ns." << endl;
+ }
+ nanosleep (&diff2, NULL);
+ }
+ }
+ // else no data available
+ }
+ // else no data available
+ }
+ }
+
+ // At this point, the fileData buffer is full with the right quantity of data (or less if less
+ // was available). Compare it to the given data and return the result;
+ bool result;
+ if (totalRead < count)
+ result = false;
+ else if (memcmp (data, fileData, count) != 0)
+ result = false;
+ else
+ result = true;
+
+ // One final thing to do: it's possible that the write file has reached its end and so been
+ // closed. This means that any attempts to read the response to the write will now fail. To
+ // prevent this, reopen the files and re-position the read file's offset to where it was. Any
+ // writes after this would have choked anyway since the file is at an end so having the write
+ // file at the beginning is unlikely to cause any problems.
+ if (!IsOpen ())
+ {
+ Open (_fileName, _read, _ignoreTimes);
+ if (fseek (_readFile, readFileOffset, SEEK_SET) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ }
+
+ delete[] fileData;
+ *numWritten = totalRead;
+ return result;
+}
+
+void LogFile::Flush (void)
+{
+ // Dump the read overflow buffer
+ DeallocateWriteBuffer();
+
+ // If there is data available in the read file, skip passed it
+ struct timeval now, timeStamp;
+ size_t size;
+ GetCurrentFileTime (now);
+ if (DataAvailableWithinLimit (_readFile, now))
+ {
+ GetNextChunkInfo (_readFile, timeStamp, size);
+ do
+ {
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Skipping " << CHUNK_HEADER_SIZE + size <<
+ "bytes in _readFile." << endl;
+ }
+ if (fseek (_readFile, CHUNK_HEADER_SIZE + size, SEEK_CUR) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek(_readFile) error: (" << ErrNo () <<
+ ") " << StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ GetNextChunkInfo (_readFile, timeStamp, size);
+ }
+ while (!(timercmp (&timeStamp, &now, >)) && IsOpen ());
+ }
+
+ // Call Drain to do the same on the write file
+ Drain ();
+}
+
+void LogFile::Drain (void)
+{
+ // Dump the write overflow buffer
+ DeallocateWriteBuffer();
+
+ // If there is data available in the write file, skip passed it
+ struct timeval now, timeStamp;
+ size_t size;
+ GetCurrentFileTime (now);
+ if (DataAvailableWithinLimit (_readFile, now))
+ {
+ GetNextChunkInfo (_writeFile, timeStamp, size);
+ do
+ {
+ if (_debug >= 2)
+ {
+ cerr << "LogFile::" << __func__ << "() Skipping " << CHUNK_HEADER_SIZE + size <<
+ "bytes in _writeFile." << endl;
+ }
+ if (fseek (_writeFile, CHUNK_HEADER_SIZE + size, SEEK_CUR) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek(_writeFile) error: (" << ErrNo () <<
+ ") " << StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ GetNextChunkInfo (_writeFile, timeStamp, size);
+ }
+ while (!(timercmp (&timeStamp, &now, >)) && IsOpen ());
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// File writing (this stuff is easy)
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void LogFile::WriteRead (const void * const data, size_t count)
+{
+ if (_debug >= 1)
+ {
+ cerr << "LogFile::" << __func__ << "() Writing read chunk of size " << count <<
+ " bytes." << endl;
+ }
+ WriteTimeStamp (_readFile);
+ WriteToFile (_readFile, &count, sizeof (count));
+ WriteToFile (_readFile, data, count);
+}
+
+void LogFile::WriteWrite (const void * const data, size_t count)
+{
+ if (_debug >= 1)
+ {
+ cerr << "LogFile::" << __func__ << "() Writing write chunk of size " << count <<
+ " bytes." << endl;
+ }
+ WriteTimeStamp (_writeFile);
+ WriteToFile (_writeFile, &count, sizeof (count));
+ WriteToFile (_writeFile, data, count);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Internal functions
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void LogFile::AllocateReadBuffer (unsigned int size)
+{
+ // Allocate based on size
+ if (_readBuffer == NULL && size > 0)
+ {
+ // Allocate a new buffer
+ if ((_readBuffer = reinterpret_cast<uint8_t*> (malloc (sizeof (uint8_t) * size))) ==
+ NULL)
+ {
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("() Failed to allocate memory for read buffer."));
+ }
+ _readUsage = 0;
+ }
+ else if (_readBuffer != NULL && size > 0)
+ {
+ // Reallocate
+ uint8_t *newBuffer;
+ if ((newBuffer = reinterpret_cast<uint8_t*> (realloc (_readBuffer, sizeof (uint8_t) *
+ size))) == NULL)
+ {
+ free (_readBuffer);
+ _readBuffer = NULL;
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("() Failed to allocate memory for read buffer."));
+ }
+ _readBuffer = newBuffer;
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Read overflow buffer was reallocated." << endl;
+ }
+ else if (_readBuffer != NULL && size == 0)
+ {
+ // Free
+ free (_readBuffer);
+ _readBuffer = NULL;
+ _readUsage = 0;
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Read overflow buffer was freed." << endl;
+ }
+ _readSize = size;
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Allocated read overflow buffer of size " <<
+ _readSize << "bytes." << endl;
+ }
+}
+
+void LogFile::AllocateWriteBuffer (unsigned int size)
+{
+ // Allocate based on size
+ if (_writeBuffer == NULL && size > 0)
+ {
+ // Allocate a new buffer
+ if ((_writeBuffer = reinterpret_cast<uint8_t*> (malloc (sizeof (uint8_t) * size))) ==
+ NULL)
+ {
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("() Failed to allocate memory for read buffer."));
+ }
+ _writeUsage = 0;
+ }
+ else if (_readBuffer != NULL && size > 0)
+ {
+ // Reallocate
+ uint8_t *newBuffer;
+ if ((newBuffer = reinterpret_cast<uint8_t*> (realloc (_writeBuffer, sizeof (uint8_t) *
+ size))) == NULL)
+ {
+ free (_writeBuffer);
+ _writeBuffer = NULL;
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("() Failed to allocate memory for read buffer."));
+ }
+ _writeBuffer = newBuffer;
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Write overflow buffer was reallocated." << endl;
+ }
+ else if (_writeBuffer != NULL && size == 0)
+ {
+ // Free
+ free (_writeBuffer);
+ _writeBuffer = NULL;
+ _writeUsage = 0;
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Write overflow buffer was freed." << endl;
+ }
+ _writeSize = size;
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Allocated write overflow buffer of size " <<
+ _writeSize << "bytes." << endl;
+ }
+}
+
+void LogFile::DeallocateReadBuffer (void)
+{
+ if (_readBuffer != NULL)
+ {
+ free (_readBuffer);
+ _readBuffer = NULL;
+ _readSize = 0;
+ _readUsage = 0;
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Deallocated read overflow buffer." << endl;
+ }
+}
+
+void LogFile::DeallocateWriteBuffer (void)
+{
+ if (_writeBuffer != NULL)
+ {
+ free (_writeBuffer);
+ _writeBuffer = NULL;
+ _writeSize = 0;
+ _writeUsage = 0;
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Deallocated write overflow buffer." << endl;
+ }
+}
+
+void LogFile::GetCurrentFileTime (struct timeval &dest)
+{
+ struct timeval now;
+
+ if (gettimeofday (&now, NULL) < 0)
+ {
+ stringstream ss;
+ ss << "LogReaderPort::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ timersub (&now, &_openTime, &dest);
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Current file time is " << dest.tv_sec << "s " <<
+ dest.tv_usec << "us." << endl;
+ }
+}
+
+bool LogFile::DataAvailableWithinLimit (FILE * const file, const struct timeval &limit)
+{
+ struct timeval chunkTime;
+ size_t chunkSize;
+
+ GetNextChunkInfo (file, chunkTime, chunkSize);
+ if (!(timercmp (&chunkTime, &limit, >)))
+ return true;
+ return false;
+}
+
+void LogFile::GetNextChunkInfo (FILE * const file, struct timeval &timeStamp, size_t &size)
+{
+ // Read the chunk info
+ ReadFromFile (file, &timeStamp, sizeof (timeStamp));
+ ReadFromFile (file, &size, sizeof (size));
+ // Rewind the file back to the beginning of the chunk header
+ if (fseek (file, -1 * CHUNK_HEADER_SIZE, SEEK_CUR) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Next chunk has size " << size <<
+ " bytes and time stamp " << timeStamp.tv_sec << "s " << timeStamp.tv_usec <<
+ "us." << endl;
+ }
+}
+
+size_t LogFile::GetChunksToTimeLimit (FILE * const file, void *data, size_t count,
+ const struct timeval &limit)
+{
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Getting chunks up to " << limit.tv_sec << "s " <<
+ limit.tv_usec << "us." << endl;
+ }
+
+ // Keep reading chunks from the file until the limit is passed or count bytes have been read.
+ struct timeval chunkTime;
+ size_t chunkSize, totalRead = 0;
+ GetNextChunkInfo (file, chunkTime, chunkSize);
+ while (!(timercmp (&chunkTime, &limit, >)) && count > 0 && IsOpen ())
+ {
+ size_t numSaved = GetSingleChunk (file, data, count, chunkTime, chunkSize);
+ data = reinterpret_cast<uint8_t*> (data) + numSaved;
+ count -= numSaved;
+ totalRead += numSaved;
+ // Safety check
+ if (!IsOpen ())
+ break;
+ // Next chunk
+ GetNextChunkInfo (file, chunkTime, chunkSize);
+ }
+
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Read a total of " << totalRead << " bytes." << endl;
+ return totalRead;
+}
+
+size_t LogFile::GetChunkSizesToTimeLimit (FILE * const file, const struct timeval &limit)
+{
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Getting chunk sizes up to " << limit.tv_sec <<
+ "s " << limit.tv_usec << "us." << endl;
+ }
+
+ struct timeval chunkTime;
+ size_t chunkSize, totalSize = 0;
+
+ // Store the current file position
+ long currentPos;
+ if ((currentPos = ftell (file)) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ GetNextChunkInfo (file, chunkTime, chunkSize);
+ while (!(timercmp (&chunkTime, &limit, >)) && IsOpen ())
+ {
+ totalSize += chunkSize;
+ // Safety check
+ if (!IsOpen ())
+ break;
+ // Next chunk
+ GetNextChunkInfo (file, chunkTime, chunkSize);
+ }
+ // Reopen if necessary
+ if (!IsOpen ())
+ Open (_fileName, _read, _ignoreTimes);
+
+ // Go back to the start position
+ if (fseek (file, currentPos, SEEK_SET) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Found a total of " << totalSize << " bytes." << endl;
+ return totalSize;
+}
+
+// This function returns the number of bytes put into data. This may be less than the number of
+// bytes actually read from the chunk, as some might go into an overflow buffer.
+size_t LogFile::GetSingleChunk (FILE * const file, void *data, size_t count,
+ struct timeval &timeStamp, size_t &size)
+{
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Reading a single chunk from " <<
+ ((file == _readFile) ? "read file." : "write file.") << endl;
+ }
+
+ // Read the chunk info
+ ReadFromFile (file, &timeStamp, sizeof (timeStamp));
+ ReadFromFile (file, &size, sizeof (size));
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Chunk is " << size << " bytes." << endl;
+
+ // Check if this chunk will fit in data
+ if (size > count)
+ {
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Chunk is too big for destination." << endl;
+
+ // Need to allocate an overflow buffer
+ uint8_t *overFlow;
+ if (file == _readFile)
+ {
+ AllocateReadBuffer (size - count);
+ overFlow = _readBuffer;
+ _readUsage = size - count;
+ }
+ else
+ {
+ AllocateWriteBuffer (size - count);
+ overFlow = _writeBuffer;
+ _writeUsage = size - count;
+ }
+
+ // Read as much as can fit into data
+ ReadFromFile (file, data, sizeof (*reinterpret_cast<uint8_t*> (data)) * count);
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Read " <<
+ sizeof (*reinterpret_cast<uint8_t*> (data)) * count << " bytes into destination." <<
+ endl;
+ }
+ // Read the rest into the overflow buffer
+ ReadFromFile (file, overFlow, sizeof (uint8_t) * (size - count));
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Read " << sizeof (uint8_t) * (size - count) <<
+ " bytes into overflow buffer." << endl;
+ }
+
+ return count;
+ }
+ else
+ {
+ // It'll fit so read straight into data
+ ReadFromFile (file, data, sizeof (*reinterpret_cast<uint8_t*> (data)) * size);
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Read " <<
+ sizeof (*reinterpret_cast<uint8_t*> (data)) * size << " bytes into destination." <<
+ endl;
+ }
+ return size;
+ }
+}
+
+size_t LogFile::GetFileSize (FILE * const file)
+{
+ // Store the current position
+ long currentPos;
+ if ((currentPos = ftell (file)) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ // Seek to the end of the file and find its position
+ if (fseek (file, 0, SEEK_END) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ long fileSize;
+ if ((fileSize = ftell (file)) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() ftell() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ // Go back to the original position
+ if (fseek (file, currentPos, SEEK_SET) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fseek() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+
+ return fileSize;
+}
+
+void LogFile::ReadFromFile (FILE * const file, void * const dest, size_t count)
+{
+ if (!_read)
+ {
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("() Cannot read from write log file."));
+ }
+
+ // Test if this file is actually open
+ if (file == NULL || ftell (file) < 0)
+ throw PortException (string ("LogFile::") + __func__ + string ("() Log file is not open."));
+ if (dest == NULL)
+ throw PortException (string ("LogFile::") + __func__ + string ("() No destination."));
+
+ size_t numRead;
+ if ((numRead = fread (dest, 1, count, file)) < count)
+ {
+ cerr << "Only read " << numRead << " of " << count << " bytes" << endl;
+ if (feof (file))
+ {
+ // Close the files
+ Close ();
+ }
+ else if (ferror (file))
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fread() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ else
+ {
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("() Didn't get enough data from fread()."));
+ }
+ }
+}
+
+void LogFile::WriteToFile (FILE * const file, const void * const data, size_t count)
+{
+ size_t totalWritten = 0;
+
+ if (_read)
+ {
+ throw PortException (string ("LogFile::") + __func__ +
+ string ("() Cannot write to read log file."));
+ }
+ if (file == NULL)
+ throw PortException (string ("LogFile::") + __func__ + string ("() Log file is not open."));
+ if (data == NULL)
+ throw PortException (string ("LogFile::") + __func__ + string ("() No data to write."));
+
+ while (totalWritten < count)
+ {
+ ssize_t numWritten;
+ if ((numWritten = fwrite (&(reinterpret_cast<const uint8_t*> (data)[totalWritten]),
+ sizeof (uint8_t), count - totalWritten, file)) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() fwrite() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ totalWritten += numWritten;
+ }
+ if (_debug >= 3)
+ cerr << "LogFile::" << __func__ << "() Wrote " << totalWritten << " bytes." << endl;
+}
+
+void LogFile::WriteTimeStamp (FILE * const file)
+{
+ // Calculate the time difference between now and the time the file was opened
+ struct timeval now, diff;
+ if (gettimeofday (&now, NULL) < 0)
+ {
+ stringstream ss;
+ ss << "LogFile::" << __func__ << "() gettimeofday() error: (" << ErrNo () << ") " <<
+ StrError (ErrNo ());
+ throw PortException (ss.str ());
+ }
+ timersub (&now, &_openTime, &diff);
+ // Write the time stamp to the file
+ WriteToFile (file, &diff, sizeof (diff));
+ if (_debug >= 3)
+ {
+ cerr << "LogFile::" << __func__ << "() Wrote time stamp: " << diff.tv_sec << "s " <<
+ diff.tv_usec << "us (time of write is " << now.tv_sec << "s " << now.tv_usec << "us)."
+ << endl;
+ }
+}
+
+} // namespace flexiport
Added: gearbox/trunk/submitted/flexiport/logfile.h
===================================================================
--- gearbox/trunk/submitted/flexiport/logfile.h (rev 0)
+++ gearbox/trunk/submitted/flexiport/logfile.h 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,101 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2008 Geoffrey Biggs
+ *
+ * flexiport flexible hardware data communications library.
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
+ * this distribution.
+ *
+ * This work is a product of the National Institute of Advanced Industrial Science and Technology,
+ * Japan. Registration number: ___
+ *
+ * This file is part of flexiport.
+ *
+ * flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with flexiport.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LOGFILE_H
+#define __LOGFILE_H
+
+#include <sys/time.h>
+#include <string>
+#include <vector>
+
+#include "timeout.h"
+
+namespace flexiport
+{
+
+// Class for managing a log file pair
+class LogFile
+{
+ public:
+ LogFile (unsigned int debug);
+ ~LogFile (void);
+
+ void Open (std::string fileName, bool read, bool ignoreTimes = false);
+ void Close (void);
+ bool IsOpen (void) const;
+// void SetBufferSize (unsigned int bufferSize);
+ void ResetFile (void);
+
+ // File reading
+ ssize_t Read (void *data, size_t count, Timeout &timeout);
+ ssize_t BytesAvailable (const Timeout &timeout);
+ bool CheckWrite (const void * const data, const size_t count, size_t * const numWritten,
+ const Timeout * const timeout = NULL);
+ void Flush (void);
+ void Drain (void);
+
+ // File writing
+ void WriteRead (const void * const data, size_t count);
+ void WriteWrite (const void * const data, size_t count);
+
+ private:
+ std::string _fileName;
+ bool _read;
+ FILE *_readFile, *_writeFile;
+ long _readFileSize, _writeFileSize;
+ // When writing, this is the time the file was opened. When reading, it's the reset time.
+ struct timeval _openTime;
+ unsigned int _debug;
+// unsigned int _bufferSize;
+ size_t _readUsage, _writeUsage;
+ size_t _readSize, _writeSize;
+ uint8_t *_readBuffer, *_writeBuffer;
+ bool _ignoreTimes;
+
+ void AllocateReadBuffer (unsigned int size = 0);
+ void AllocateWriteBuffer (unsigned int size = 0);
+ void DeallocateReadBuffer (void);
+ void DeallocateWriteBuffer (void);
+
+ void GetCurrentFileTime (struct timeval &dest);
+ bool DataAvailableWithinLimit (FILE * const file, const struct timeval &limit);
+ void GetNextChunkInfo (FILE * const file, struct timeval &timeStamp, size_t &size);
+ size_t GetChunksToTimeLimit (FILE * const file, void *data, size_t count,
+ const struct timeval &limit);
+ size_t GetChunkSizesToTimeLimit (FILE * const file, const struct timeval &limit);
+ size_t GetSingleChunk (FILE * const file, void *data, size_t count,
+ struct timeval &timeStamp, size_t &size);
+ size_t GetFileSize (FILE * const file);
+
+ void ReadFromFile (FILE * const file, void * const dest, size_t count);
+ void WriteToFile (FILE * const file, const void * const data, size_t count);
+ void WriteTimeStamp (FILE * const file);
+};
+
+} // namespace flexiport
+
+#endif // __LOGFILE_H
Added: gearbox/trunk/submitted/flexiport/logreaderport.cpp
===================================================================
--- gearbox/trunk/submitted/flexiport/logreaderport.cpp (rev 0)
+++ gearbox/trunk/submitted/flexiport/logreaderport.cpp 2008-06-20 02:30:52 UTC (rev 199)
@@ -0,0 +1,360 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2008 Geoffrey Biggs
+ *
+ * flexiport flexible hardware data communications library.
+ *
+ * This distribution is licensed to you under the terms described in the LICENSE file included in
+ * this distribution.
+ *
+ * This work is a product of the National Institute of Advanced Industrial Science and Technology,
+ * Japan. Registration number: ___
+ *
+ * This file is part of flexiport.
+ *
+ * flexiport is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * Lesser General Public License as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * flexiport is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+ * even t...
[truncated message content] |
|
From: <rum...@us...> - 2008-06-19 15:36:44
|
Revision: 198
http://gearbox.svn.sourceforge.net/gearbox/?rev=198&view=rev
Author: rumataxyz
Date: 2008-06-19 08:36:49 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
converted assorted thrown things to gbxutilacfr::Exception
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 15:07:00 UTC (rev 197)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 15:36:49 UTC (rev 198)
@@ -36,6 +36,7 @@
namespace gnua = gbxnovatelutilacfr;
namespace gna = gbxnovatelacfr;
+namespace gua = gbxutilacfr;
namespace {
// binary messages defined by novatel
@@ -54,7 +55,7 @@
// these guys are used to directly decode messages;
// obviously fails on endian mismatch, any sort of size mismatch and is rather nasty in general;
// feel free to implement something better
- // TODO: at least at runtime checking
+ // TODO: at least add runtime checking
gnua::BestGpsPosLogB bestGpsPos;
gnua::BestGpsVelLogB bestGpsVel;
gnua::InsPvaLogSB insPva;
@@ -100,7 +101,7 @@
void
Driver::configure( ) {
if(false == config_.isValid()){
- throw (std::string("Invalid Configuration!"));
+ throw (gua::Exception(ERROR_INFO, "Invalid Configuration!"));
}
// configure serial port
@@ -109,7 +110,7 @@
serial_.reset(new Serial( serialDevice, baud_, Serial::Timeout(1,0) ));
serial_->setDebugLevel(0);
if(0 != connectToHardware() ){
- throw (std::string("failed to connect to receiver!"));
+ throw (gua::Exception(ERROR_INFO, "failed to connect to receiver!"));
}
// just in case something is running... stops the novatel logging any messages
@@ -399,7 +400,7 @@
if(config_.ignoreUnknownMessages_){
tracer_->warning(ss.str());
}else{
- throw( ss.str() );
+ gua::Exception(ERROR_INFO, ss.str() );
}
}
break;
@@ -409,7 +410,7 @@
std::stringstream ss;
ss << "Warning("<<__FILE__<<":"<< __LINE__
<< "Timed out while waiting for data";
- throw (ss.str());
+ gua::Exception(ERROR_INFO, ss.str());
}
}while(NULL == data.get()); // repeat till we get valid data
@@ -835,7 +836,7 @@
if(in_crc != crc) {
fprintf( stderr,"CRC Error: 0x%lx, 0x%lx\n",in_crc,crc );
- throw std::string( "CRC Error" );
+ gua::Exception(ERROR_INFO, "CRC Error" );
return -1;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 15:07:01
|
Revision: 197
http://gearbox.svn.sourceforge.net/gearbox/?rev=197&view=rev
Author: rumataxyz
Date: 2008-06-19 08:07:00 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
added implementations of toString() to the various data-types
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
gearbox/trunk/submitted/gbxnovatelacfr/driver.h
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 14:20:38 UTC (rev 196)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 15:07:00 UTC (rev 197)
@@ -54,6 +54,7 @@
// these guys are used to directly decode messages;
// obviously fails on endian mismatch, any sort of size mismatch and is rather nasty in general;
// feel free to implement something better
+ // TODO: at least at runtime checking
gnua::BestGpsPosLogB bestGpsPos;
gnua::BestGpsVelLogB bestGpsVel;
gnua::InsPvaLogSB insPva;
@@ -66,6 +67,8 @@
std::auto_ptr<gna::GenericData> createExternalMsg(gnua::BestGpsVelLogB &bestGpsVel, struct timeval &timeStamp);
std::auto_ptr<gna::GenericData> createExternalMsg(gnua::RawImuLogSB &rawImu, struct timeval &timeStamp, gnua::ImuDecoder *imuDecoder);
+ //helper functions for the toString() gear
+ std::string statusToString(gna::StatusMessagetype statusMessageType, std::string statusMessage);
std::string doubleVectorToString(vector<double > &vec, std::string seperator = std::string(" "));
}
@@ -663,6 +666,89 @@
return ss.str();
}
+std::string
+InsPvaData::toString(){
+ std::stringstream ss;
+ ss << "timeStampSec " << timeStampSec << " ";
+ ss << "timeStampUSec " << timeStampUSec << " ";
+ ss << "gpsWeekNr " << gpsWeekNr << " ";
+ ss << "secIntoWeek " << secIntoWeek << " ";
+ ss << "latitude " << latitude << " ";
+ ss << "longitude " << longitude << " ";
+ ss << "height " << height << " ";
+ ss << "northVelocity " << northVelocity << " ";
+ ss << "eastVelocity " << eastVelocity << " ";
+ ss << "upVelocity " << upVelocity << " ";
+ ss << "roll " << roll << " ";
+ ss << "pitch " << pitch << " ";
+ ss << "azimuth " << azimuth << " ";
+ ss << statusToString(statusMessageType, statusMessage);
+ return ss.str();
+};
+
+std::string
+BestGpsPosData::toString(){
+ std::stringstream ss;
+ ss << "timeStampSec " << timeStampSec << " ";
+ ss << "timeStampUSec " << timeStampUSec << " ";
+ ss << "gpsWeekNr " << gpsWeekNr << " ";
+ ss << "msIntoWeek " << msIntoWeek << " ";
+ ss << "solutionStatus " << solutionStatus << " ";
+ ss << "positionType " << positionType << " ";
+ ss << "latitude " << latitude << " ";
+ ss << "longitude " << longitude << " ";
+ ss << "heightAMSL " << heightAMSL << " ";
+ ss << "undulation " << undulation << " ";
+ ss << "datumId " << datumId << " ";
+ ss << "sigmaLatitude " << sigmaLatitude << " ";
+ ss << "sigmaLongitude " << sigmaLongitude << " ";
+ ss << "sigmaHeight " << sigmaHeight << " ";
+ ss << "baseStationId[4] " << baseStationId[4] << " ";
+ ss << "diffAge " << diffAge << " ";
+ ss << "solutionAge " << solutionAge << " ";
+ ss << "numObservations " << numObservations << " ";
+ ss << "numL1Ranges " << numL1Ranges << " ";
+ ss << "numL1RangesRTK " << numL1RangesRTK << " ";
+ ss << "numL2RangesRTK " << numL2RangesRTK << " ";
+ ss << statusToString(statusMessageType, statusMessage);
+ return ss.str();
+};
+
+std::string
+ BestGpsVelData::toString(){
+ std::stringstream ss;
+ ss << "timeStampSec " << timeStampSec << " ";
+ ss << "timeStampUSec " << timeStampUSec << " ";
+ ss << "gpsWeekNr " << gpsWeekNr << " ";
+ ss << "msIntoWeek " << msIntoWeek << " ";
+ ss << "solutionStatus " << solutionStatus << " ";
+ ss << "positionType " << positionType << " ";
+ ss << "latency " << latency << " ";
+ ss << "diffAge " << diffAge << " ";
+ ss << "horizontalSpeed " << horizontalSpeed << " ";
+ ss << "trackOverGround " << trackOverGround << " ";
+ ss << "verticalSpeed " << verticalSpeed << " ";
+ ss << statusToString(statusMessageType, statusMessage);
+ return ss.str();
+};
+
+std::string
+RawImuData::toString(){
+ std::stringstream ss;
+ ss << "timeStampSec " << timeStampSec << " ";
+ ss << "timeStampUSec " << timeStampUSec << " ";
+ ss << "gpsWeekNr " << gpsWeekNr << " ";
+ ss << "secIntoWeek " << secIntoWeek << " ";
+ ss << "zDeltaV " << zDeltaV << " ";
+ ss << "yDeltaV " << yDeltaV << " ";
+ ss << "xDeltaV " << xDeltaV << " ";
+ ss << "zDeltaAng " << zDeltaAng << " ";
+ ss << "yDeltaAng " << yDeltaAng << " ";
+ ss << "xDeltaAng " << xDeltaAng << " ";
+ ss << statusToString(statusMessageType, statusMessage);
+ return ss.str();
+};
+
} //namespace
namespace{
@@ -984,4 +1070,29 @@
}
return ss.str();
}
+
+ std::string statusToString(gna::StatusMessagetype statusMessageType, std::string statusMessage){
+ std::stringstream ss;
+ switch(statusMessageType){
+ case gna::NoMsg:
+ ss << "NoMsg" << " ";
+ break;
+ case gna::Initialising:
+ ss << "Initialising" << " ";
+ break;
+ case gna::Ok:
+ ss << "Ok" << " ";
+ break;
+ case gna::Warning:
+ ss << "Warning" << " ";
+ break;
+ case gna::Fault:
+ ss << "Fault" << " ";
+ break;
+ default:
+ ss << "UnknownStatus" << " ";
+ }
+ ss << statusMessage;
+ return ss.str();
+ }
}//namespace
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 14:20:38 UTC (rev 196)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 15:07:00 UTC (rev 197)
@@ -274,7 +274,7 @@
public:
virtual ~GenericData(){};
virtual DataType type() const=0;
- virtual std::string toString() const=0;
+ virtual std::string toString()=0;
private:
};
@@ -284,9 +284,7 @@
DataType type() const {
return InsPva;
}
- std::string toString() const{
- return "implement me!";
- }
+ std::string toString();
int gpsWeekNr; //
double secIntoWeek; //
double latitude; //!< [deg] north positive WGS84
@@ -326,9 +324,7 @@
DataType type() const {
return BestGpsPos;
}
- std::string toString() const{
- return "implement me!";
- }
+ std::string toString();
int gpsWeekNr; //
unsigned int msIntoWeek; //!< milliseconds from beginning of week
GpsSolutionStatusType solutionStatus; //
@@ -362,9 +358,7 @@
DataType type() const {
return BestGpsVel;
}
- std::string toString() const{
- return "implement me!";
- }
+ std::string toString();
int gpsWeekNr; //
unsigned int msIntoWeek; //!< milliseconds from beginning of week
GpsSolutionStatusType solutionStatus; //
@@ -388,9 +382,7 @@
DataType type() const {
return RawImu;
}
- std::string toString() const{
- return "implement me!";
- }
+ std::string toString();
int gpsWeekNr;
double secIntoWeek;
//!@name Change in speed
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 14:20:34
|
Revision: 196
http://gearbox.svn.sourceforge.net/gearbox/?rev=196&view=rev
Author: rumataxyz
Date: 2008-06-19 07:20:38 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
more docu shuffeling
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.h
gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 14:19:59 UTC (rev 195)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 14:20:38 UTC (rev 196)
@@ -80,6 +80,7 @@
};
//! @brief All the information needed to configure the driver.
+//
//! The device itself has even more options, consult your manual.
//! If all these possibilities don't seem to be sufficient, consult your friendly developer for extension (better yet, send a patch)
//! The easiest way to get a valid (and useful) Config, is to initialise it with a SimpleConfig (for INS operation) or GpsOnlyConfig (for GPS operation)
@@ -195,7 +196,9 @@
Fault //!< Problem, probably fatal
};
-//! Novatel's different solution status types; explanations from the manual
+//! Novatel's different solution status types.
+//
+//! Explanations from the manual.
enum GpsSolutionStatusType{
SolComputed, //!< Solution computed
InsufficientObs, //!< Insufficient observations
@@ -219,7 +222,9 @@
UnknownGpsSolutionStatusType
};
-//! Novatel's different fix types; sadly mixed for position/velocity with some INS gear thrown in; explanations from the manual
+//! Novatel's different fix types.
+//
+//! Sadly mixed for position/velocity with some INS gear thrown in; explanations from the manual.
enum GpsPosVelType{
None, //!< No solution
FixedPos, //!< Position has been fixed by the FIX POSITION command or by position averaging
@@ -389,7 +394,8 @@
int gpsWeekNr;
double secIntoWeek;
//!@name Change in speed
- //!The default IMU axis definitions are: Y - forward Z - up X - right hand side
+ //!Divide by dt to get accelerations.
+ //!The default IMU axis definitions are: Y - forward, Z - up, X - right hand side
//
//@{
double zDeltaV; //!< [m/s] up positive
@@ -399,7 +405,8 @@
//@}
//!@name Change in orientation
- //!The default IMU axis definitions are: Y - forward Z - up X - right hand side
+ //!Divide by dt to get turn-rates.
+ //!The default IMU axis definitions are: Y - forward, Z - up, X - right hand side
//
//@{
double zDeltaAng; //!< [rad] right handed around z
Modified: gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-19 14:19:59 UTC (rev 195)
+++ gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-19 14:20:38 UTC (rev 196)
@@ -14,11 +14,13 @@
@ingroup gbx_linux
@ingroup gbx_hardware
@defgroup gbx_library_gbxnovatelacfr GbxNovatelAcfr
-@brief ACFR driver for a Novatel(Span) system.
+@brief ACFR driver for a Novatel(SPAN) system.
+
This is a proprietary Novatel navigation system. It minimally consists out of a Novatel OEMV GPS receiver (OEM4 receivers should be compatible).
-If combined with an IMU, a SPAN system can provide a INS navigation solution at high rate (up to 100Hz).
+If combined with an IMU, a SPAN system can provide an INS navigation solution at high rate (up to 100Hz).
The driver initialises the hardware and reports navigation data continously.
+
for a full list of functions see @ref gbxnovatelacfr
@@ -31,18 +33,15 @@
@par Style
See http://orca-robotics.sourceforge.net/orca/orca_doc_style.html
-@par Units and Coordinate System
- See http://orca-robotics.sourceforge.net/orca/orca_doc_units.html
-
@par Copyright
Mathew Ridley, Ben Upcroft, Michael Moser
@par Responsible Developer
Michael Moser
-
+
@par License
LGPL
-
+
@par Dependencies.
- @ref gbx_library_gbxserialacfr
@@ -50,25 +49,27 @@
See test/test.cpp for a full blown usage-example and test/example.readme on how to compile the test program.
-To run the test program (assuming the device is connected to /dev/ttyS1) :
+To run the test program (defaults: /dev/ttyS0, 115200 bps, ...) call it without parameters.
@verbatim
-$ gbxnovatelacfrtest -p /dev/ttyS1
+$ gbxnovatelacfrtest
@endverbatim
-To get a short usage description:
+If you want to change things, get a short usage description:
@verbatim
$ gbxnovatelacfrtest -h
@endverbatim
The test program reports back all messages received from the driver and prints out the data fields for each message (in verbose mode).
-This minimal example (no error checking for clarity, but fully functional) shows the driver's intended usage:
+@par Minimal Example
+
+This example (no error checking for clarity, but fully functional) shows the driver's intended usage:
- create configuration
- create driver
- read from driver and wait for external termination
@verbatim
-#include <gearbox/gbxnovatelacfr/driver.h>
+#include <gbxnovatelacfr/driver.h>
#include <cstdlib>
#include <iostream>
#include <memory>
@@ -79,8 +80,8 @@
int main(void){
// create a valid configuration
- std::vector<double> offSet(3,0.0);
- gna::SimpleConfig sCfg(std::string("/dev/ttyS0"), 115200, std::string("IMU_HG1700_AG11"), offSet);
+ std::vector<double> imuToGpsOffset(3,0.0); // made up; this MUST be correct for real work (see gbxnovatelacfr::Config::imuToGpsOffset_)
+ gna::SimpleConfig sCfg(std::string("/dev/ttyS0"), 115200, std::string("IMU_HG1700_AG11"), imuToGpsOffset);
gna::Config cfg(sCfg);
// create the driver
@@ -137,7 +138,7 @@
- http://www.novatel.com/Documents/Manuals/om-20000104.pdf (SPAN-system manual)
The following sources have also been helpful:
-- http://www.novatel.com/Documents/Manuals/GPS+Reference.pdf (a good overview about GPS: correct, complete, terse)
+- http://www.novatel.com/Documents/Manuals/GPS+Reference.pdf (a good overview about GPS: correct, complete, concise)
- http://www.novatel.com/support/faqs.htm
- http://www.novatel.com/support/applicationnotes.htm (more details on specific subjects than the manuals)
Modified: gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-19 14:19:59 UTC (rev 195)
+++ gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-19 14:20:38 UTC (rev 196)
@@ -106,8 +106,8 @@
auto_ptr<gna::SimpleConfig > simpleCfg;
auto_ptr<gna::GpsOnlyConfig > gpsOnlyCfg;
if(0 == mode.compare("ins")){
- vector<double > offset(3,0.0); //made up offset
- simpleCfg.reset( new gna::SimpleConfig(port, baud, imuType, offset) );
+ vector<double > imuToGpsOffset(3,0.0); // made up; this MUST be correct for real work (see gbxnovatelacfr::Config::imuToGpsOffset_)
+ simpleCfg.reset( new gna::SimpleConfig(port, baud, imuType, imuToGpsOffset) );
cfg.reset( new gna::Config(*simpleCfg.get()) );
assert(0 != cfg.get());
// set up a couple of extra parameters
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 14:20:03
|
Revision: 195
http://gearbox.svn.sourceforge.net/gearbox/?rev=195&view=rev
Author: rumataxyz
Date: 2008-06-19 07:19:59 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
added check for overall data-rate, minor corrections
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 14:18:45 UTC (rev 194)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 14:19:59 UTC (rev 195)
@@ -499,6 +499,7 @@
std::cout << "serial settings invalid\n";
valid = false;
}
+
//imu gear
if(enableImu_
&& ( 0 == imuType_.compare("")
@@ -521,12 +522,14 @@
std::cout << "vehicleBodyRotation invalid\n";
valid = false;
}
+
//ins gear
if(enableImu_ && enableInsOffset_
&& 3 != insOffset_.size()){
std::cout << "insOffset invalid\n";
valid = false;
}
+
//data
if(false == (enableInsPva_ || enableGpsPos_ || enableGpsVel_ || enableRawImu_)){
std::cout << "data settings invalid, you need to enable at least one message\n";
@@ -560,6 +563,28 @@
}
}
+ //datarate
+ double dataRate = 0.0;
+ if(enableRawImu_){
+ dataRate += 1.0/0.01 * 8 * sizeof (gnua::RawImuLogSB); // TODO: there is one IMU running at 200Hz, no idea how to check for it
+ }
+ if(enableInsPva_){
+ dataRate += 1.0/dtInsPva_ * 8 * sizeof (gnua::InsPvaLogSB);
+ }
+ if(enableGpsPos_){
+ dataRate += 1.0/dtGpsPos_ * 8 * sizeof (gnua::BestGpsPosLogB);
+ }
+ if(enableGpsVel_){
+ dataRate += 1.0/dtGpsVel_ * 8 * sizeof (gnua::BestGpsVelLogB);
+ }
+ if(dataRate > (double)baudRate_){
+ std::cout << "The combined data-rate of the messages/message rates you configured excceeds the configured baud rate " << dataRate << " / " << baudRate_ << "\n";
+ valid = false;
+ }else if(dataRate > 0.95 * baudRate_){
+ std::cout << "The combined data-rate of the messages/message rates you configured is more than 95\% of the configured baud rate! " << dataRate << " / " << baudRate_ << "\n";
+ std::cout << "Consider using a higher baud rate (maximum 230400) or less messages or lower message-rates.";
+ }
+
return valid;
}
@@ -604,7 +629,7 @@
&& (9600 == baudRate_
|| 19200 == baudRate_
|| 38400 == baudRate_
- || 57600 != baudRate_
+ || 57600 == baudRate_
|| 115200 == baudRate_
|| 230400 == baudRate_) ;
}
@@ -625,7 +650,7 @@
&& (9600 == baudRate_
|| 19200 == baudRate_
|| 38400 == baudRate_
- || 57600 != baudRate_
+ || 57600 == baudRate_
|| 115200 == baudRate_
|| 230400 == baudRate_) ;
}
@@ -760,11 +785,11 @@
switch( insPva.data.insStatus ) {
case 0:
data->statusMessage = "Ins is inactive";
- data->statusMessageType = gna::Fault;
+ data->statusMessageType = gna::Fault; // TODO: check if this happens during startup
break;
case 1:
data->statusMessage = "Ins is aligning";
- data->statusMessageType = gna::Warning;
+ data->statusMessageType = gna::Initialising;
break;
case 2:
data->statusMessage = "Ins solution is bad";
@@ -789,7 +814,7 @@
break;
case 7:
data->statusMessage = "Ins alignment is complete but vehicle must perform maneuvers so that the attitude can converge";
- data->statusMessageType = gna::Ok;
+ data->statusMessageType = gna::Ok; // TODO: this is not quite Ok, check if it is usable (no sudden jumps, etc.)
break;
default:
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 14:18:42
|
Revision: 194
http://gearbox.svn.sourceforge.net/gearbox/?rev=194&view=rev
Author: rumataxyz
Date: 2008-06-19 07:18:45 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
added pack pragma
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h 2008-06-19 12:40:55 UTC (rev 193)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h 2008-06-19 14:18:45 UTC (rev 194)
@@ -17,7 +17,7 @@
InsPvaSBLogType = 508
};
-//#pragma pack(push,1)
+#pragma pack(push,1)
// binary packet header; long version, mostly used for GPS gear
// according to:
// OEM4 Family Firmware Version 2.300 Command and Log Reference Rev 16; Table 4; Page 17
@@ -50,7 +50,7 @@
uint8_t msgLength; //3 1 _without_ header or CRC
uint16_t msgId; //4 2 which log we have
uint16_t GpsWeekNr; //6 2
- uint32_t msIntoWeek; //8 4 milliseconds from beginning of week
+ uint32_t msIntoWeek; //8 4 milliseconds from beginning of week
}Oem4ShortBinaryHeader;
@@ -161,6 +161,6 @@
Oem4ShortBinaryHeader header;
RawImuData data;
}RawImuLogSB;
-//#pragma pack(pop,1)
+#pragma pack(pop)
} //namespace
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 12:40:57
|
Revision: 193
http://gearbox.svn.sourceforge.net/gearbox/?rev=193&view=rev
Author: rumataxyz
Date: 2008-06-19 05:40:55 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
more docu, trying to get doxygen produce what I want
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.h
gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 11:20:53 UTC (rev 192)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 12:40:55 UTC (rev 193)
@@ -35,16 +35,17 @@
//! Minimum information to configure the receiver in INS mode
class SimpleConfig{
public:
- //! @parameter imuToGpsOffset: vector (xyz [m]) from IMU center to Antenna Phase Center
- //! in IMU coordinates, vital for INS performance, make sure you get this right!
- //! @parameter imuType: as expected by the "SETIMUTYPE" command (SPAN Technology for OEMV User Manual Rev 3, Table 15, page 64)
+ //! @param imuType see Config::imuType_ for details
+ //! @param imuToGpsOffset see Config::imuToGpsOffset_ for details
SimpleConfig(std::string serialDevice, int baudRate, std::string imuType, std::vector<double > &imuToGpsOffset):
serialDevice_(serialDevice),
baudRate_(baudRate),
imuType_(imuType),
imuToGpsOffset_(imuToGpsOffset) {};
- //! Returns true if the configuration is sane. Checks include:
+ //!@brief Returns true if the configuration is sane.
+ //
+ //! Checks include:
//! - a non-empty device name
//! - baud rate is supported by device (9600, 19200, 38400, 115200, 230400)
//! - imuType refers to a known type
@@ -66,7 +67,9 @@
serialDevice_(serialDevice),
baudRate_(baudRate) {};
- //! Returns true if the configuration is sane. Checks include:
+ //!@brief Returns true if the configuration is sane.
+ //
+ //! Checks include:
//! - a non-empty device name
//! - baud rate is supported by device (9600, 19200, 38400, 115200, 230400)
bool isValid() const;
@@ -82,17 +85,27 @@
//! The easiest way to get a valid (and useful) Config, is to initialise it with a SimpleConfig (for INS operation) or GpsOnlyConfig (for GPS operation)
class Config{
public:
- Config(const SimpleConfig &simpleCfg); //!< yields a valid config, with reasonable defaults (RawImu 100Hz, InsPva 50Hz, BestGpsPos/Vel 5Hz)
- Config(const GpsOnlyConfig &gpsOnlyCfg); //!< yields a valid config, for gps only operation (BestGpsPos/Vel 20Hz)
- Config(); //!< disables everything, so you can (and must) set just the options you need
+ //! @brief Shortcut to set up a Configuration for INS operation
+ //
+ //! yields a valid config, with reasonable defaults (RawImu 100Hz, InsPva 50Hz, BestGpsPos/Vel 5Hz)
+ Config(const SimpleConfig &simpleCfg);
+ //! @brief Shortcut to set up a Configuration for GPS operation
+ //
+ //! yields a valid config, for gps only operation (BestGpsPos/Vel 20Hz)
+ Config(const GpsOnlyConfig &gpsOnlyCfg);
+ //! disables everything, so you can (and must) set just the options you need.
+ Config();
- //! Returns true if the configuration is sane. Checks include:
+ //! @brief Returns true if the configuration is sane.
+ //
+ //! Checks include:
//! - a non-empty device name
//! - baud rate is supported by device (9600, 19200, 38400, 57600, 115200, 230400)
//! - imuType refers to a known type
//! - offset has size 3
//! - message rates are consistent and don't exceed serial-data-rate
- bool isValid(); //!< not const, since it has limited self-fixing capabilities
+ //! - not const, since it has limited self-fixing capabilities (for incorrect message-rates)
+ bool isValid();
//! Dumps the config in human readable form
std::string toString();
@@ -107,7 +120,7 @@
//
//!@{
bool enableImu_;
- std::string imuType_;
+ std::string imuType_; //!< as expected by the "SETIMUTYPE" command (SPAN Technology for OEMV User Manual Rev 3, Table 15, page 64)
//!@}
//!@name Data settings
@@ -138,11 +151,11 @@
//!@name INS settings
//
//!@{
- std::vector<double > imuToGpsOffset_;
+ std::vector<double > imuToGpsOffset_; //!< vector (xyz [m]) from IMU center to Antenna Phase Center, in IMU coordinates, vital for INS performance, make sure you get this right!
std::vector<double > imuToGpsOffsetUncertainty_; //!< optional (size 3 or 0)
bool enableInsOffset_;
- std::vector<double > insOffset_; //!< report INS position/velocity offset (xyz [m] in IMU coordinates) from the IMU center; useful e.g. to get data w.r. to robot's center of rotation
- bool enableInsPhaseUpdate_; //!< tightly coupled (phase based vs position based) filter; Chance of better performance in adverse conditions
+ std::vector<double > insOffset_; //!< report INS position/velocity offset (xyz [m] in IMU coordinates) from the IMU center; useful e.g. to get data w.r. to robot's center of rotation
+ bool enableInsPhaseUpdate_; //!< tightly coupled (phase based vs position based) filter; Chance of better performance in adverse conditions
//!@}
@@ -252,8 +265,7 @@
};
//! Generic (base) type returned by a read
-class GenericData
-{
+class GenericData {
public:
virtual ~GenericData(){};
virtual DataType type() const=0;
Modified: gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-19 11:20:53 UTC (rev 192)
+++ gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-19 12:40:55 UTC (rev 193)
@@ -14,8 +14,10 @@
@ingroup gbx_linux
@ingroup gbx_hardware
@defgroup gbx_library_gbxnovatelacfr GbxNovatelAcfr
-@brief ACFR driver for a Novatel(Span) system
-a proprietray integrated novatel navigation system comsisting out of a gps receiver and a imu
+@brief ACFR driver for a Novatel(Span) system.
+This is a proprietary Novatel navigation system. It minimally consists out of a Novatel OEMV GPS receiver (OEM4 receivers should be compatible).
+If combined with an IMU, a SPAN system can provide a INS navigation solution at high rate (up to 100Hz).
+The driver initialises the hardware and reports navigation data continously.
for a full list of functions see @ref gbxnovatelacfr
@@ -60,14 +62,14 @@
The test program reports back all messages received from the driver and prints out the data fields for each message (in verbose mode).
-This minimal example (no error checking for clarity, but compileabel/functional) shows the driver livecycle:
+This minimal example (no error checking for clarity, but fully functional) shows the driver's intended usage:
- create configuration
- create driver
- read from driver and wait for external termination
@verbatim
#include <gearbox/gbxnovatelacfr/driver.h>
-#include <stdlib.h>
+#include <cstdlib>
#include <iostream>
#include <memory>
#include <vector>
@@ -129,12 +131,21 @@
@endverbatim
@par References
--
-- http://www.novatel.com/Documents/Manuals/GPS+Reference.pdf
+This driver was programmed based on the protocoll/message descriptions in Novatel manuals, it does not contain any code from Novatel. The main source for information was:
+- http://www.novatel.com/Documents/Manuals/om-20000094.pdf (Novatel OEMV reference)
+- http://www.novatel.com/Documents/Manuals/om-20000104.pdf (SPAN-system manual)
+
+The following sources have also been helpful:
+- http://www.novatel.com/Documents/Manuals/GPS+Reference.pdf (a good overview about GPS: correct, complete, terse)
+- http://www.novatel.com/support/faqs.htm
+- http://www.novatel.com/support/applicationnotes.htm (more details on specific subjects than the manuals)
+
@par Limitations
- This is a Linux-only implementation (because of the serial library and the system-calls for timestamps)
+- Only supports a subset of the messages a NovatelSPAN system can provide.
+- Driver currently treats the hardware as data-source only, communication _to_ the hardware is possible only during initialization.
*/
/*!
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 11:21:33
|
Revision: 192
http://gearbox.svn.sourceforge.net/gearbox/?rev=192&view=rev
Author: rumataxyz
Date: 2008-06-19 04:20:53 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
More checks, more comments, more possibilites shown
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-19 11:19:11 UTC (rev 191)
+++ gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-19 11:20:53 UTC (rev 192)
@@ -101,25 +101,32 @@
cout << "|\tshow debug:\t" << showDebug << "\n";
cout << "-------------------------------------------------\n";
+ //create a config (the easy way)
auto_ptr<gna::Config > cfg;
auto_ptr<gna::SimpleConfig > simpleCfg;
auto_ptr<gna::GpsOnlyConfig > gpsOnlyCfg;
-
- //create a config (the easy way)
if(0 == mode.compare("ins")){
- //made up offset
- vector<double > offset(3,0.0);
+ vector<double > offset(3,0.0); //made up offset
simpleCfg.reset( new gna::SimpleConfig(port, baud, imuType, offset) );
cfg.reset( new gna::Config(*simpleCfg.get()) );
+ assert(0 != cfg.get());
+ // set up a couple of extra parameters
+ cfg->enableInsPhaseUpdate_ = true;
+ cfg->enableRTK_ = true;
}
else if(0 == mode.compare("gps")){
gpsOnlyCfg.reset( new gna::GpsOnlyConfig(port, baud) );
cfg.reset( new gna::Config(*gpsOnlyCfg.get()) );
+ assert(0 != cfg.get());
+ // set up a couple of extra parameters
+ cfg->enableSBAS_ = true;
+ cfg->enableCDGPS_ = true;
}
else{
cout << "invalid mode: " << mode << "\n";
return EXIT_FAILURE;
}
+ //check that it makes sense
if(!cfg->isValid()){
cout << "Invalid configuration!\n";
cout << cfg->toString();
@@ -128,11 +135,10 @@
//create the driver; this gets things rolling (opens the serial port, sets up the device)
auto_ptr<gna::Driver > driver;
- gbxutilacfr::TrivialTracer tracer(showDebug);
int errorCnt = 0;
do{
try{
- driver.reset( new gna::Driver(*(cfg.get()), tracer) );
+ driver.reset( new gna::Driver( *(cfg.get()) ) );
}
catch(std::exception &e){
cout << e.what() << "\n";
@@ -141,6 +147,7 @@
cout << "caught unknown exception!\n";
}
}while(0 == driver.get() && errorCnt++<5); // try up to 5 times
+ //check that we succeeded
if(0 == driver.get()){
cout << "failed to set up driver!\n";
return EXIT_FAILURE;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 11:19:11
|
Revision: 191
http://gearbox.svn.sourceforge.net/gearbox/?rev=191&view=rev
Author: rumataxyz
Date: 2008-06-19 04:19:11 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
overhauled the copy/paste docu
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
Modified: gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-19 11:18:09 UTC (rev 190)
+++ gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-19 11:19:11 UTC (rev 191)
@@ -13,18 +13,134 @@
@ingroup gbx_cpp
@ingroup gbx_linux
@ingroup gbx_hardware
-@defgroup gbx_library_novatel_acfr gbxnovatelacfr
-@author Michael Moser
-@brief A implementation for a NovatelSpan system
+@defgroup gbx_library_gbxnovatelacfr GbxNovatelAcfr
+@brief ACFR driver for a Novatel(Span) system
a proprietray integrated novatel navigation system comsisting out of a gps receiver and a imu
+for a full list of functions see @ref gbxnovatelacfr
+
+@par Header file
+
+@verbatim
+#include <gbxnovatelacfr/driver.h>
+@endverbatim
+
+@par Style
+ See http://orca-robotics.sourceforge.net/orca/orca_doc_style.html
+
+@par Units and Coordinate System
+ See http://orca-robotics.sourceforge.net/orca/orca_doc_units.html
+
+@par Copyright
+ Mathew Ridley, Ben Upcroft, Michael Moser
+
+@par Responsible Developer
+ Michael Moser
+
+@par License
+ LGPL
+
@par Dependencies.
+- @ref gbx_library_gbxserialacfr
-- libIceUtil (for timing)
-- libHydroSerial (serial comms)
-- libHydroNovatelUtil (Novatel binary message format/parsing)
+@par Example
-@see @ref gbx_library_novatel_acfr
+See test/test.cpp for a full blown usage-example and test/example.readme on how to compile the test program.
+
+To run the test program (assuming the device is connected to /dev/ttyS1) :
+@verbatim
+$ gbxnovatelacfrtest -p /dev/ttyS1
+@endverbatim
+
+To get a short usage description:
+@verbatim
+$ gbxnovatelacfrtest -h
+@endverbatim
+
+The test program reports back all messages received from the driver and prints out the data fields for each message (in verbose mode).
+
+This minimal example (no error checking for clarity, but compileabel/functional) shows the driver livecycle:
+- create configuration
+- create driver
+- read from driver and wait for external termination
+
+@verbatim
+#include <gearbox/gbxnovatelacfr/driver.h>
+#include <stdlib.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+
+namespace gna = gbxnovatelacfr;
+
+int main(void){
+
+ // create a valid configuration
+ std::vector<double> offSet(3,0.0);
+ gna::SimpleConfig sCfg(std::string("/dev/ttyS0"), 115200, std::string("IMU_HG1700_AG11"), offSet);
+ gna::Config cfg(sCfg);
+
+ // create the driver
+ gna::Driver driver(cfg);
+
+ while(0){
+ // read from the driver
+ std::auto_ptr<gna::GenericData > generic = driver.read();
+
+ // figure out what type of data we got
+ switch(generic->type()){
+ case gna::InsPva:
+ {
+ // process data
+ gna::InsPvaData *data = dynamic_cast<gna::InsPvaData *>(generic.get());
+ std::cout << data->toString() << "\n";
+ }
+ break;
+ case gna::BestGpsPos:
+ {
+ // process data
+ gna::BestGpsPosData *data = dynamic_cast<gna::BestGpsPosData *>(generic.get());
+ std::cout << data->toString() << "\n";
+ }
+ break;
+ case gna::BestGpsVel:
+ {
+ // process data
+ gna::BestGpsVelData *data = dynamic_cast<gna::BestGpsVelData *>(generic.get());
+ std::cout << data->toString() << "\n";
+ }
+ break;
+ case gna::RawImu:
+ {
+ // process data
+ gna::RawImuData *data = dynamic_cast<gna::RawImuData *>(generic.get());
+ std::cout << data->toString() << "\n";
+ }
+ break;
+ default:
+ std::cout << "Got unknown message!\n";
+ break;
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
+@endverbatim
+
+@par References
+-
+- http://www.novatel.com/Documents/Manuals/GPS+Reference.pdf
+
+@par Limitations
+
+- This is a Linux-only implementation (because of the serial library and the system-calls for timestamps)
+*/
+
+/*!
@namespace gbxnovatelacfr
+@brief Novatel GPS/INS driver
+
+This namespace contains the public interface of a library to access and run a NovatelSpan system.
+@see @ref gbx_library_gbxnovatelacfr
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-19 11:18:09
|
Revision: 190
http://gearbox.svn.sourceforge.net/gearbox/?rev=190&view=rev
Author: rumataxyz
Date: 2008-06-19 04:18:09 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
fixed the inline documentation, formating, added a simplified constructor to the driver (without Tracer, sets up TrivialTracer internally)
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
gearbox/trunk/submitted/gbxnovatelacfr/driver.h
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 08:41:58 UTC (rev 189)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-19 11:18:09 UTC (rev 190)
@@ -17,6 +17,7 @@
#include <gbxserialacfr/gbxserialacfr.h>
#include <gbxutilacfr/gbxutilacfr.h>
+#include <gbxutilacfr/trivialtracer.h>
#include <iostream>
#include <sstream>
@@ -70,13 +71,31 @@
namespace gbxnovatelacfr
{
+Driver::Driver( const Config& cfg) :
+ serial_(0),
+ baud_(115200),
+ config_(cfg),
+ tracer_(new gbxutilacfr::TrivialTracer())
+{
+ assert(0 != tracer_.get());
+ configure();
+ return;
+}
+
Driver::Driver( const Config& cfg,
- gbxutilacfr::Tracer &tracer) :
+ gbxutilacfr::Tracer* tracer) :
serial_(0),
baud_(115200),
config_(cfg),
tracer_(tracer)
{
+ assert(0 != tracer_.get());
+ configure();
+ return;
+}
+
+void
+Driver::configure( ) {
if(false == config_.isValid()){
throw (std::string("Invalid Configuration!"));
}
@@ -98,17 +117,18 @@
configureGps();
requestData();
serial_->flush();
- tracer_.info("Setup done, starting normal operation!");
+ tracer_->info("Setup done, starting normal operation!");
+ return;
}
Driver::~Driver() {
// just in case something is running... stops the novatel logging any messages
try{
- tracer_.info("Stopping NovatelSpan driver!");
+ tracer_->info("Stopping NovatelSpan driver!");
serial_->flush();
serial_->writeString( "unlogall\r\n" );
serial_->drain();
- tracer_.info("NovatelSpan driver stopped!");
+ tracer_->info("NovatelSpan driver stopped!");
}
catch(...){
//no throwing from destructors
@@ -181,7 +201,7 @@
put = serial_->writeString( ss.str().c_str() );
//force the IMU to re-align at every startup
//put = serial_->writeString( "inscommand reset\r\n" );
- //tracer_.info("Reset IMU; Waiting 5 seconds before continuing!");
+ //tracer_->info("Reset IMU; Waiting 5 seconds before continuing!");
//sleep(5);
}else{
// no IMU --> disable INS
@@ -256,25 +276,25 @@
// CDGPS
if(config_.enableCDGPS_){
- tracer_.info("Turning on CDGPS!");
+ tracer_->info("Turning on CDGPS!");
put = serial_->writeString( "ASSIGNLBAND CDGPS 1547547 4800\r\n" );
}
// turn SBAS on/off (essentially global DGPS)
if(config_.enableSBAS_){
- tracer_.info("Turning on SBAS!");
+ tracer_->info("Turning on SBAS!");
put = serial_->writeString( "SBASCONTROL ENABLE Auto 0 ZEROTOTWO\r\n");
//we try to use WAAS satellites even below the horizon
put = serial_->writeString( "WAASECUTOFF -5.0\r\n");
}
else{
- tracer_.info("Turning off SBAS!");
+ tracer_->info("Turning off SBAS!");
put = serial_->writeString( "SBASCONTROL DISABLE Auto 0 NONE\r\n");
}
// rtk
if(config_.enableRTK_){
- tracer_.info("Turning on RTK!");
+ tracer_->info("Turning on RTK!");
put = serial_->writeString( "com com2,9600,n,8,1,n,off,on\r\n" );
put = serial_->writeString( "interfacemode com2 rtca none\r\n" );
}
@@ -304,7 +324,7 @@
put = serial_->writeString(ss.str().c_str());
ss.str("");
ss << "Turning on GPS position at " << 1.0/config_.dtGpsPos_ << "Hz!";
- tracer_.info(ss.str().c_str());
+ tracer_->info(ss.str().c_str());
}
// gps velocity without ins
@@ -314,7 +334,7 @@
put = serial_->writeString(ss.str().c_str());
ss.str("");
ss << "Turning on GPS velocity at " << 1.0/config_.dtGpsVel_ << "Hz!";
- tracer_.info(ss.str().c_str());
+ tracer_->info(ss.str().c_str());
}
@@ -327,7 +347,7 @@
put = serial_->writeString(ss.str().c_str());
ss.str("");
ss << "Turning on INS position/velocity/orientation at " << 1.0/config_.dtInsPva_ << "Hz!";
- tracer_.info(ss.str().c_str());
+ tracer_->info(ss.str().c_str());
}
@@ -336,7 +356,7 @@
// raw accelerometer and gyro data
if(config_.enableRawImu_){
put = serial_->writeString( "log rawimusb onnew\r\n" );
- tracer_.info("Turning on raw imu data!");
+ tracer_->info("Turning on raw imu data!");
}
return;
@@ -374,7 +394,7 @@
ss << "Warning("<<__FILE__<<":"<< __LINE__
<<" : got unexpected message from receiver; id: " << msg.header.msgId << std::endl;
if(config_.ignoreUnknownMessages_){
- tracer_.warning(ss.str());
+ tracer_->warning(ss.str());
}else{
throw( ss.str() );
}
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 08:41:58 UTC (rev 189)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-19 11:18:09 UTC (rev 190)
@@ -28,6 +28,8 @@
class ImuDecoder;
}
+/** @ingroup gbx_library_novatel_acfr
+@{ */
namespace gbxnovatelacfr{
//! Minimum information to configure the receiver in INS mode
@@ -74,17 +76,19 @@
int baudRate_;
};
-//! All the information needed to configure the driver. The device itself has even more options, consult your manual.
+//! @brief All the information needed to configure the driver.
+//! The device itself has even more options, consult your manual.
//! If all these possibilities don't seem to be sufficient, consult your friendly developer for extension (better yet, send a patch)
+//! The easiest way to get a valid (and useful) Config, is to initialise it with a SimpleConfig (for INS operation) or GpsOnlyConfig (for GPS operation)
class Config{
public:
- Config(const SimpleConfig &simpleCfg); //!< yields a valid config, with reasonable defaults
- Config(const GpsOnlyConfig &gpsOnlyCfg); //!< yields a valid config, for gps only operation
- Config(); //!< disables everything, so you can set just the options you need
+ Config(const SimpleConfig &simpleCfg); //!< yields a valid config, with reasonable defaults (RawImu 100Hz, InsPva 50Hz, BestGpsPos/Vel 5Hz)
+ Config(const GpsOnlyConfig &gpsOnlyCfg); //!< yields a valid config, for gps only operation (BestGpsPos/Vel 20Hz)
+ Config(); //!< disables everything, so you can (and must) set just the options you need
//! Returns true if the configuration is sane. Checks include:
//! - a non-empty device name
- //! - baud rate is supported by device (9600, 19200, 38400, 115200, 230400)
+ //! - baud rate is supported by device (9600, 19200, 38400, 57600, 115200, 230400)
//! - imuType refers to a known type
//! - offset has size 3
//! - message rates are consistent and don't exceed serial-data-rate
@@ -107,26 +111,28 @@
//!@}
//!@name Data settings
+ //! First we disable all output in the ctor. Then all the messages set to true here are enabled.
//
- //!we disable all output in the ctor, and then enable the messages set to true here.
//!@{
bool enableInsPva_;
bool enableGpsPos_;
bool enableGpsVel_;
bool enableRawImu_;
bool ignoreUnknownMessages_; //!< normally we throw an exception, set this to "true" if you want to enable some other message permanently.
+
//!@}
//!@name Data rate settings
- //
//!Time between messages in seconds (i.e. 0.01 == 100Hz). RawImu can only be reported at
//!the "natural" rate of the IMU (100Hz or 200Hz, depending on model).
//!We check in isValid() if any of these don't make sense
+ //
//!@{
double dtInsPva_; //!< 100Hz max, if RawImu is enabled 50Hz max
double dtGpsPos_; //!< 20Hz max, 5Hz max if RawImu or InsPva is enabled
double dtGpsVel_; //!< 20Hz max, 5Hz max if RawImu or InsPva is enabled
- bool fixInvalidRateSettings_; //!< don't bitch about wrong rates, but change them to something sensible
+ bool fixInvalidRateSettings_; //!< Don't bitch about wrong rates, change them to something sensible
+
//!@}
//!@name INS settings
@@ -137,6 +143,7 @@
bool enableInsOffset_;
std::vector<double > insOffset_; //!< report INS position/velocity offset (xyz [m] in IMU coordinates) from the IMU center; useful e.g. to get data w.r. to robot's center of rotation
bool enableInsPhaseUpdate_; //!< tightly coupled (phase based vs position based) filter; Chance of better performance in adverse conditions
+
//!@}
//!@name GPS settings
@@ -146,6 +153,7 @@
bool enableSBAS_; //!< code-differential corrections over satellite on GPS frequencies (WAAS/EGNOS)
bool enableRTK_; //!< carrier-differential corrections (you need to set up your own base-station and wireless link), assumes RTCA corrections on COM2, 9600bps, 8N1 (hardcoded)
bool enableUseOfOmniStarCarrier_; //!< carrier-differential corrections OMNIStarXP/HP (you need to get a subscription with them)
+
//!@}
//!@name INS settings for fast (dynamic) alignment
@@ -160,23 +168,21 @@
bool enableVehicleBodyRotation_;
std::vector<double > vehicleBodyRotation_;
std::vector<double > vehicleBodyRotationUncertainty_; //!< optional (size 3 or 0)
+
//!@}
private:
};
//! possible Status Messages GenericData can contain
enum StatusMessagetype {
- //! Nothing new, no message
- NoMsg,
- //! All good, but something to say
- Ok,
- //! Problem, likely to go away
- Warning,
- //! Problem, probably fatal
- Fault
+ NoMsg, //!< Nothing new, no message
+ Initialising,//!< Nothing wrong, just not quite ready
+ Ok, //!< All good, but something to say
+ Warning, //!< Problem, likely to go away
+ Fault //!< Problem, probably fatal
};
-//! Novatel's different solution status types
+//! Novatel's different solution status types; explanations from the manual
enum GpsSolutionStatusType{
SolComputed, //!< Solution computed
InsufficientObs, //!< Insufficient observations
@@ -200,7 +206,7 @@
UnknownGpsSolutionStatusType
};
-//! Novatel's different fix types; sadly mixed for position/velocity with some INS gear thrown in
+//! Novatel's different fix types; sadly mixed for position/velocity with some INS gear thrown in; explanations from the manual
enum GpsPosVelType{
None, //!< No solution
FixedPos, //!< Position has been fixed by the FIX POSITION command or by position averaging
@@ -266,20 +272,30 @@
}
int gpsWeekNr; //
double secIntoWeek; //
- double latitude; //[deg] north positive WGS84
- double longitude; //[deg] east positive WGS84
- double height; //[m] above ellipsoid WGS84 (heigth_ellipsoid - undulation == height_geoid/AMSL)
- double northVelocity; //[m/s] south is negative; true north?
- double eastVelocity; //[m/s] west is negative; true east?
- double upVelocity; //[m/s] down is negative; geoid/ellipsoid vertical?
- //The default IMU axis definitions are:
- // Y - forward
- // Z - up
- // X - right hand side
- double roll; //[degree] right handed rotation from local level around y-axes
- double pitch; //[degree] right handed rotation from local level around x-axes
- double azimuth; //[degree] left handed around z-axes rotation from (true?) north clockwise
+ double latitude; //!< [deg] north positive WGS84
+ double longitude; //!< [deg] east positive WGS84
+ double height; //!< [m] above ellipsoid WGS84 (heigth_ellipsoid - undulation == height_geoid (aka AMSL)
+ //!@name Orientation
+ //!Relativ to true North/East and geoid vertical (I think)
+ //
+ //@{
+ double northVelocity; //!< [m/s] south is negative
+ double eastVelocity; //!< [m/s] west is negative
+ double upVelocity; //!< [m/s] down is negative
+
+ //@}
+
+ //!@name Orientation
+ //!The default IMU axis definitions are: Y - forward Z - up X - right hand side
+ //
+ //@{
+ double roll; //!< [degree] right handed rotation from local level around y-axes
+ double pitch; //!< [degree] right handed rotation from local level around x-axes
+ double azimuth; //!< [degree] left handed around z-axes rotation from (true?) north clockwise
+
+ //@}
+
StatusMessagetype statusMessageType;
std::string statusMessage;
@@ -297,24 +313,24 @@
return "implement me!";
}
int gpsWeekNr; //
- unsigned int msIntoWeek; //milliseconds from beginning of week
+ unsigned int msIntoWeek; //!< milliseconds from beginning of week
GpsSolutionStatusType solutionStatus; //
GpsPosVelType positionType; //
- double latitude; //[deg] north positive
- double longitude; //[deg] east positive
- double heightAMSL; //[m] AMSL == above mean sea level (geoid)
- float undulation; //[m] aka geoidal seperation: undulation == heigth_ellipsoid - height_geoid/AMSL
+ double latitude; //!< [deg] north positive
+ double longitude; //!< [deg] east positive
+ double heightAMSL; //!< [m] AMSL == above mean sea level (geoid)
+ float undulation; //!< [m] aka geoidal seperation: undulation == heigth_ellipsoid - height_geoid/AMSL
unsigned int datumId; //
- float sigmaLatitude; //[m? deg?] 1 standard deviation error estimate
- float sigmaLongitude; //[m? deg?] 1 standard deviation error estimate
- float sigmaHeight; //[m? deg?] 1 standard deviation error estimate
+ float sigmaLatitude; //!< [m? deg?] 1 standard deviation error estimate
+ float sigmaLongitude; //!< [m? deg?] 1 standard deviation error estimate
+ float sigmaHeight; //!< [m? deg?] 1 standard deviation error estimate
char baseStationId[4]; //
- float diffAge; //[s]
- float solutionAge; //[s]
- int numObservations; //number of observations tracked (?) L1 code/carrier/doppler + L2 code/carrier/doppler?
- int numL1Ranges; //number of L1 ranges used in computation (?)
- int numL1RangesRTK; //number of L1 ranges above the RTK mask angle (??) number of L1 carrier ranges used?
- int numL2RangesRTK; //number of L2 ranges above the RTK mask angle (??) number of L2 carrier ranges used?
+ float diffAge; //!< [s] how old the correction info from the basestation is
+ float solutionAge; //!< [s]
+ int numObservations; //!< number of observations tracked (?) L1 code/carrier/doppler + L2 code/carrier/doppler?
+ int numL1Ranges; //!< number of L1 ranges used in computation (?)
+ int numL1RangesRTK; //!< number of L1 ranges above the RTK mask angle (??) number of L1 carrier ranges used?
+ int numL2RangesRTK; //!< number of L2 ranges above the RTK mask angle (??) number of L2 carrier ranges used?
StatusMessagetype statusMessageType;
std::string statusMessage;
@@ -333,14 +349,14 @@
return "implement me!";
}
int gpsWeekNr; //
- unsigned int msIntoWeek; //milliseconds from beginning of week
+ unsigned int msIntoWeek; //!< milliseconds from beginning of week
GpsSolutionStatusType solutionStatus; //
GpsPosVelType positionType; //
- float latency; //[s]
- float diffAge; //[s]
- double horizontalSpeed; //[m/s]
- double trackOverGround; //[deg] w respect to true North
- double verticalSpeed; //[m/s]
+ float latency; //!< [s] gps speed can be calculated from instantanious or integrated doppler. The latter refers to the average speed over the last interval -> is delayed by half an interval
+ float diffAge; //!< [s]
+ double horizontalSpeed; //!< [m/s]
+ double trackOverGround; //!< [deg] "heading" of the speed vector w. respect to true North
+ double verticalSpeed; //!< [m/s]
StatusMessagetype statusMessageType;
std::string statusMessage;
@@ -360,13 +376,26 @@
}
int gpsWeekNr;
double secIntoWeek;
- double zDeltaV; //!< [m/s] change in speed, up positive
- double yDeltaV; //!< [m/s] change in speed, forward positive
- double xDeltaV; //!< [m/s] change in speed, right positive
- double zDeltaAng; //!< [rad] change in angle, right handed around z
- double yDeltaAng; //!< [rad] change in angle, right handed around y
- double xDeltaAng; //!< [rad] change in angle, right handed around x
+ //!@name Change in speed
+ //!The default IMU axis definitions are: Y - forward Z - up X - right hand side
+ //
+ //@{
+ double zDeltaV; //!< [m/s] up positive
+ double yDeltaV; //!< [m/s] forward positive
+ double xDeltaV; //!< [m/s] right positive
+ //@}
+
+ //!@name Change in orientation
+ //!The default IMU axis definitions are: Y - forward Z - up X - right hand side
+ //
+ //@{
+ double zDeltaAng; //!< [rad] right handed around z
+ double yDeltaAng; //!< [rad] right handed around y
+ double xDeltaAng; //!< [rad] right handed around x
+
+ //@}
+
StatusMessagetype statusMessageType;
std::string statusMessage;
@@ -374,43 +403,71 @@
int timeStampUSec; //!< in Computer time, beginning of message at serial port
};
+//! The actual Driver
+//! @brief the idea is to create one of these guys (with a valid Config), and then treat it as a data-source, i.e. call read() on it in some kind of loop
class Driver {
public:
- Driver( const Config &cfg, gbxutilacfr::Tracer& tracer);
+ //! @name Ctor:
+ //! @brief Trys to establish serial communication to the GPS receiver, then configures it
+ //
+ //!@{
+
+ //! @brief dumps tracing messages to the console
+ //
+ //! implements tracing internally as a gbxutilacfr::TrivialTracer
+ Driver( const Config &cfg);
+ //!@brief full control over tracing (e.g. to syslog)
+ //!@param tracer you need to provide this guy (via new), do NOT delete it, it will be deleted when your Driver object goes out of scope
+ Driver( const Config &cfg, gbxutilacfr::Tracer* tracer);
+ //!@}
~Driver();
- //! Blocking read, returns one message
- //! Throws gbxutilacfr::Exception when a problem is encountered.
- //!
- //
- //! @verbatim
- //! std::auto_ptr<gbxnovatelacfr::GenericData> data;
- //!
- //! try {
- //! data = device->read();
- //! }
- //! catch ( const std::exception& e ) {
- //! cout <<"Test: Failed to read data: "<<e.what()<<endl;
- //! }
- //! if(InsData == data.type()){
- //! InsData *insData = dynamic_cast<InsData *>(data.get());
- //! assert(insData);
- //! //process insData
- //! }
- //! @endverbatim
- //
+ /*! @brief Blocking read, returns one message
+
+ Throws gbxutilacfr::Exception when a problem is encountered (derives from std::exception).
+ Throws gbxutilacfr::HardwareException when a (fatal) problem with the hardware is encountered
+ @verbatim
+ std::auto_ptr<gbxnovatelacfr::GenericData> data;
+
+ while(1) { // read forever
+ try {
+ data = device->read();
+ }
+ catch ( const gbxutilacfr::HardwareException& e ) {
+ cout <<"Something wrong with the hardware: "<<e.what()<<endl;
+ cout <<"Giving up!\n";
+ throw e;
+ }
+ catch ( const std::exception& e ) {
+ cout <<"Failed to read data: "<<e.what()<<endl;
+ continue;
+ }
+ switch( data.type() ){
+ case InsPvaData:
+ InsData *insData = dynamic_cast<InsData *>(data.get());
+ assert(insData);
+ // process insData
+ break;
+ default:
+ // don't handle the other guys
+ break;
+ }
+ }
+ @endverbatim */
std::auto_ptr<GenericData> read();
private:
+ //! does the leg-work for the constructor (via the following guys)
+ void configure();
//! establish a serial connection to the receiver
int connectToHardware();
- //! transfer configuration parameters related to the IMU
+ //! set parameters related to the IMU
void configureImu();
- //! transfer configuration parameters related to the INS
+ //! set parameters related to the INS
void configureIns();
- //! transfer configuration parameters related to GPS
+ //! set parameters related to GPS
void configureGps();
//! turn on data messages we are interested in
void requestData();
@@ -421,9 +478,10 @@
int baud_;
Config config_;
- gbxutilacfr::Tracer& tracer_;
+ std::auto_ptr<gbxutilacfr::Tracer > tracer_;
};
} // namespace
+/** @} */
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rus...@us...> - 2008-06-19 08:41:51
|
Revision: 189
http://gearbox.svn.sourceforge.net/gearbox/?rev=189&view=rev
Author: russo2503v
Date: 2008-06-19 01:41:58 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
Modified Paths:
--------------
gearbox/trunk/doc/todo.dox
Modified: gearbox/trunk/doc/todo.dox
===================================================================
--- gearbox/trunk/doc/todo.dox 2008-06-19 01:17:21 UTC (rev 188)
+++ gearbox/trunk/doc/todo.dox 2008-06-19 08:41:58 UTC (rev 189)
@@ -31,6 +31,8 @@
@par New libraries
+- libGbxGarminAcfr
+
@par Updated libraries
- libGbxSickAcfr
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <bo...@us...> - 2008-06-19 01:17:23
|
Revision: 188
http://gearbox.svn.sourceforge.net/gearbox/?rev=188&view=rev
Author: borax00
Date: 2008-06-18 18:17:21 -0700 (Wed, 18 Jun 2008)
Log Message:
-----------
Modified Paths:
--------------
gearbox/trunk/src/gbxsickacfr/doc.dox
Modified: gearbox/trunk/src/gbxsickacfr/doc.dox
===================================================================
--- gearbox/trunk/src/gbxsickacfr/doc.dox 2008-06-18 12:20:25 UTC (rev 187)
+++ gearbox/trunk/src/gbxsickacfr/doc.dox 2008-06-19 01:17:21 UTC (rev 188)
@@ -66,6 +66,7 @@
An improvement would be to timestamp the start of each message,
remembering that timestamp for subsequent reads from the serial port
until the end of the message finally arrives.
+- Has only been tested with the LMS-291.
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-18 12:20:25
|
Revision: 187
http://gearbox.svn.sourceforge.net/gearbox/?rev=187&view=rev
Author: rumataxyz
Date: 2008-06-18 05:20:25 -0700 (Wed, 18 Jun 2008)
Log Message:
-----------
added isValid() to configurations, changed the default constructor a bit, added "verbose" option to the example
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
gearbox/trunk/submitted/gbxnovatelacfr/driver.h
gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 09:08:07 UTC (rev 186)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 12:20:25 UTC (rev 187)
@@ -408,6 +408,7 @@
dtGpsVel_(0.2),
fixInvalidRateSettings_(false),
imuToGpsOffset_(simpleCfg.imuToGpsOffset_),
+ imuToGpsOffsetUncertainty_(0,0.0),
enableInsOffset_(false),
enableInsPhaseUpdate_(true),
enableCDGPS_(true),
@@ -448,10 +449,10 @@
dtGpsPos_(1.0),
dtGpsVel_(1.0),
fixInvalidRateSettings_(false),
- imuToGpsOffset_(1,0.0),
- imuToGpsOffsetUncertainty_(1,0.0),
+ imuToGpsOffset_(0,0.0),
+ imuToGpsOffsetUncertainty_(0,0.0),
enableInsOffset_(false),
- insOffset_(1,0.0),
+ insOffset_(0,0.0),
enableInsPhaseUpdate_(false),
enableCDGPS_(false),
enableSBAS_(false),
@@ -460,14 +461,86 @@
enableSetImuOrientation_(false),
setImuOrientation_(0),
enableVehicleBodyRotation_(false),
- vehicleBodyRotation_(1,0.0),
- vehicleBodyRotationUncertainty_(1,0.0) {
+ vehicleBodyRotation_(0,0.0),
+ vehicleBodyRotationUncertainty_(0,0.0) {
}
bool
-Config::isValid() const {
- cout << __func__ << "implement me\n";
- return true;
+Config::isValid() {
+ bool valid = true;
+ //check serial setup
+ if( 0 == serialDevice_.compare("")
+ || (9600 != baudRate_
+ && 19200 != baudRate_
+ && 38400 != baudRate_
+ && 57600 != baudRate_
+ && 115200 != baudRate_
+ && 230400 != baudRate_)){
+ std::cout << "serial settings invalid\n";
+ valid = false;
+ }
+ //imu gear
+ if(enableImu_
+ && ( 0 == imuType_.compare("")
+ || 3 != imuToGpsOffset_.size()
+ || ( 3 != imuToGpsOffsetUncertainty_.size()
+ && 0 != imuToGpsOffsetUncertainty_.size()))){
+ std::cout << "imuType/imuToGpsOffset invalid\n";
+ valid = false;
+ }
+ if(enableImu_ && enableSetImuOrientation_
+ && ( 0 > setImuOrientation_
+ || 6 < setImuOrientation_)){
+ std::cout << "setImuOrientation invalid\n";
+ valid = false;
+ }
+ if(enableImu_ && enableVehicleBodyRotation_
+ && ( 3 != vehicleBodyRotation_.size()
+ || ( 3 != vehicleBodyRotationUncertainty_.size()
+ && 0 != vehicleBodyRotationUncertainty_.size()))){
+ std::cout << "vehicleBodyRotation invalid\n";
+ valid = false;
+ }
+ //ins gear
+ if(enableImu_ && enableInsOffset_
+ && 3 != insOffset_.size()){
+ std::cout << "insOffset invalid\n";
+ valid = false;
+ }
+ //data
+ if(false == (enableInsPva_ || enableGpsPos_ || enableGpsVel_ || enableRawImu_)){
+ std::cout << "data settings invalid, you need to enable at least one message\n";
+ valid = false;
+ }
+ if(enableRawImu_ && 0.02 > dtInsPva_){
+ if(fixInvalidRateSettings_){
+ std::cout << "data rate for InsPva too high; must be 50Hz or less if RawImu is enabled. FIXED!\n";
+ dtInsPva_ = 0.02;
+ }else{
+ std::cout << "data rate for InsPva too high; must be 50Hz or less if RawImu is enabled\n";
+ valid = false;
+ }
+ }
+ if( (enableRawImu_ || enableInsPva_) && 0.2 > dtGpsPos_ ){
+ if(fixInvalidRateSettings_){
+ std::cout << "data rate for BestGpsPos too high; must be 5Hz or less if RawImu or InsPva is enabled. FIXED!\n";
+ dtGpsPos_ = 0.2;
+ }else{
+ std::cout << "data rate for BestGpsPos too high; must be 5Hz or less if RawImu or InsPva is enabled\n";
+ valid = false;
+ }
+ }
+ if( (enableRawImu_ || enableInsPva_) && 0.2 > dtGpsVel_ ){
+ if(fixInvalidRateSettings_){
+ std::cout << "data rate for BestGpsVel too high; must be 5Hz or less if RawImu or InsPva is enabled. FIXED!\n";
+ dtGpsVel_ = 0.2;
+ }else{
+ std::cout << "data rate for BestGpsVel too high; must be 5Hz or less if RawImu or InsPva is enabled\n";
+ valid = false;
+ }
+ }
+
+ return valid;
}
std::string
@@ -505,8 +578,15 @@
bool
SimpleConfig::isValid() const {
- cout << __func__ << "implement me\n";
- return true;
+ return 0 != serialDevice_.compare("")
+ && imuType_.compare("")
+ && 3 == imuToGpsOffset_.size()
+ && (9600 == baudRate_
+ || 19200 == baudRate_
+ || 38400 == baudRate_
+ || 57600 != baudRate_
+ || 115200 == baudRate_
+ || 230400 == baudRate_) ;
}
std::string
@@ -521,8 +601,13 @@
bool
GpsOnlyConfig::isValid() const {
- cout << __func__ << "implement me\n";
- return true;
+ return 0 != serialDevice_.compare("")
+ && (9600 == baudRate_
+ || 19200 == baudRate_
+ || 38400 == baudRate_
+ || 57600 != baudRate_
+ || 115200 == baudRate_
+ || 230400 == baudRate_) ;
}
std::string
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-18 09:08:07 UTC (rev 186)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-18 12:20:25 UTC (rev 187)
@@ -88,7 +88,7 @@
//! - imuType refers to a known type
//! - offset has size 3
//! - message rates are consistent and don't exceed serial-data-rate
- bool isValid() const;
+ bool isValid(); //!< not const, since it has limited self-fixing capabilities
//! Dumps the config in human readable form
std::string toString();
Modified: gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-18 09:08:07 UTC (rev 186)
+++ gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-18 12:20:25 UTC (rev 187)
@@ -71,6 +71,9 @@
case 'd':
showDebug = true;
break;
+ case 'v':
+ verbose = true;
+ break;
case 'h':
usage(argv[0], optString);
return EXIT_SUCCESS;
@@ -94,6 +97,7 @@
cout << "|\tport:\t\t" << port << "\n";
cout << "|\tbaud:\t\t" << baud << "\n";
cout << "|\tImu:\t\t" << imuType << "\n";
+ cout << "|\tverbose:\t" << verbose << "\n";
cout << "|\tshow debug:\t" << showDebug << "\n";
cout << "-------------------------------------------------\n";
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-18 09:08:11
|
Revision: 186
http://gearbox.svn.sourceforge.net/gearbox/?rev=186&view=rev
Author: rumataxyz
Date: 2008-06-18 02:08:07 -0700 (Wed, 18 Jun 2008)
Log Message:
-----------
configurations toString() should now be complete
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 08:26:15 UTC (rev 185)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 09:08:07 UTC (rev 186)
@@ -64,6 +64,8 @@
std::auto_ptr<gna::GenericData> createExternalMsg(gnua::BestGpsPosLogB &bestGpsPos, struct timeval &timeStamp);
std::auto_ptr<gna::GenericData> createExternalMsg(gnua::BestGpsVelLogB &bestGpsVel, struct timeval &timeStamp);
std::auto_ptr<gna::GenericData> createExternalMsg(gnua::RawImuLogSB &rawImu, struct timeval &timeStamp, gnua::ImuDecoder *imuDecoder);
+
+ std::string doubleVectorToString(vector<double > &vec, std::string seperator = std::string(" "));
}
namespace gbxnovatelacfr
@@ -484,10 +486,10 @@
ss << "dtGpsPos_: " << dtGpsPos_ << " ";
ss << "dtGpsVel_: " << dtGpsVel_ << " ";
ss << "fixInvalidRateSettings_: " << fixInvalidRateSettings_ << " ";
- //ss << "imuToGpsOffset_: " << imuToGpsOffset_ << " ";
- //ss << "imuToGpsOffsetUncertainty_: " << imuToGpsOffsetUncertainty_ << " ";
+ ss << "imuToGpsOffset_: " << doubleVectorToString(imuToGpsOffset_) << " ";
+ ss << "imuToGpsOffsetUncertainty_: " << doubleVectorToString(imuToGpsOffsetUncertainty_) << " ";
ss << "enableInsOffset_: " << enableInsOffset_ << " ";
- //ss << "insOffset_: " << insOffset_ << " ";
+ ss << "insOffset_: " << doubleVectorToString(insOffset_) << " ";
ss << "enableInsPhaseUpdate_: " << enableInsPhaseUpdate_ << " ";
ss << "enableCDGPS_: " << enableCDGPS_ << " ";
ss << "enableSBAS_: " << enableSBAS_ << " ";
@@ -496,8 +498,8 @@
ss << "enableSetImuOrientation_: " << enableSetImuOrientation_ << " ";
ss << "setImuOrientation_: " << setImuOrientation_ << " ";
ss << "enableVehicleBodyRotation_: " << enableVehicleBodyRotation_ << " ";
- //ss << "vehicleBodyRotation_: " << vehicleBodyRotation_ << " ";
- //ss << "vehicleBodyRotationUncertainty_: " << vehicleBodyRotationUncertainty_;
+ ss << "vehicleBodyRotation_: " << doubleVectorToString(vehicleBodyRotation_) << " ";
+ ss << "vehicleBodyRotationUncertainty_: " << doubleVectorToString(vehicleBodyRotationUncertainty_);
return ss.str();
}
@@ -513,7 +515,7 @@
ss << "serialDevice_: " << serialDevice_ << " ";
ss << "baudRate_: " << baudRate_ << " ";
ss << "imuType_: " << imuType_ << " ";
- //ss << "imuToGpsOffset_: " << imuToGpsOffset_;
+ ss << "imuToGpsOffset_: " << doubleVectorToString(imuToGpsOffset_);
return ss.str();
}
@@ -843,4 +845,13 @@
}
return genericData;
}
+
+ std::string doubleVectorToString(vector<double > &vec, std::string seperator){
+ std::stringstream ss;
+ int max = vec.size();
+ for (int i=0; i<max; i++){
+ ss << vec[i] << seperator;
+ }
+ return ss.str();
+ }
}//namespace
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-18 08:26:34
|
Revision: 185
http://gearbox.svn.sourceforge.net/gearbox/?rev=185&view=rev
Author: rumataxyz
Date: 2008-06-18 01:26:15 -0700 (Wed, 18 Jun 2008)
Log Message:
-----------
added basic toString()s; still need to handle vectors
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 08:02:23 UTC (rev 184)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 08:26:15 UTC (rev 185)
@@ -470,8 +470,35 @@
std::string
Config::toString(){
- cout << __func__ << "implement me\n";
- return "";
+ std::stringstream ss;
+ ss << "serialDevice_: " << serialDevice_ << " ";
+ ss << "baudRate_: " << baudRate_ << " ";
+ ss << "enableImu_: " << enableImu_ << " ";
+ ss << "imuType_: " << imuType_ << " ";
+ ss << "enableInsPva_: " << enableInsPva_ << " ";
+ ss << "enableGpsPos_: " << enableGpsPos_ << " ";
+ ss << "enableGpsVel_: " << enableGpsVel_ << " ";
+ ss << "enableRawImu_: " << enableRawImu_ << " ";
+ ss << "ignoreUnknownMessages_: " << ignoreUnknownMessages_ << " ";
+ ss << "dtInsPva_: " << dtInsPva_ << " ";
+ ss << "dtGpsPos_: " << dtGpsPos_ << " ";
+ ss << "dtGpsVel_: " << dtGpsVel_ << " ";
+ ss << "fixInvalidRateSettings_: " << fixInvalidRateSettings_ << " ";
+ //ss << "imuToGpsOffset_: " << imuToGpsOffset_ << " ";
+ //ss << "imuToGpsOffsetUncertainty_: " << imuToGpsOffsetUncertainty_ << " ";
+ ss << "enableInsOffset_: " << enableInsOffset_ << " ";
+ //ss << "insOffset_: " << insOffset_ << " ";
+ ss << "enableInsPhaseUpdate_: " << enableInsPhaseUpdate_ << " ";
+ ss << "enableCDGPS_: " << enableCDGPS_ << " ";
+ ss << "enableSBAS_: " << enableSBAS_ << " ";
+ ss << "enableRTK_: " << enableRTK_ << " ";
+ ss << "enableUseOfOmniStarCarrier_: " << enableUseOfOmniStarCarrier_ << " ";
+ ss << "enableSetImuOrientation_: " << enableSetImuOrientation_ << " ";
+ ss << "setImuOrientation_: " << setImuOrientation_ << " ";
+ ss << "enableVehicleBodyRotation_: " << enableVehicleBodyRotation_ << " ";
+ //ss << "vehicleBodyRotation_: " << vehicleBodyRotation_ << " ";
+ //ss << "vehicleBodyRotationUncertainty_: " << vehicleBodyRotationUncertainty_;
+ return ss.str();
}
bool
@@ -482,8 +509,12 @@
std::string
SimpleConfig::toString(){
- cout << __func__ << "implement me\n";
- return "";
+ std::stringstream ss;
+ ss << "serialDevice_: " << serialDevice_ << " ";
+ ss << "baudRate_: " << baudRate_ << " ";
+ ss << "imuType_: " << imuType_ << " ";
+ //ss << "imuToGpsOffset_: " << imuToGpsOffset_;
+ return ss.str();
}
bool
@@ -494,8 +525,10 @@
std::string
GpsOnlyConfig::toString(){
- cout << __func__ << "implement me\n";
- return "";
+ std::stringstream ss;
+ ss << "serialDevice_: " << serialDevice_ << " ";
+ ss << "baudRate_: " << baudRate_;
+ return ss.str();
}
} //namespace
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-18 08:02:19
|
Revision: 184
http://gearbox.svn.sourceforge.net/gearbox/?rev=184&view=rev
Author: rumataxyz
Date: 2008-06-18 01:02:23 -0700 (Wed, 18 Jun 2008)
Log Message:
-----------
adjusted copy/paste licenses, added missing ones
Modified Paths:
--------------
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
gearbox/trunk/submitted/gbxnovatelacfr/driver.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.cpp
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/receiverstatusdecoder.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.cpp
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/test/crc32test.cpp
gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,9 +1,9 @@
/*
- * Orca-Robotics Project: Components for robotics
- * http://orca-robotics.sf.net/
- * Copyright (c) 2004-2008 Matthew Ridley, Ben Upcroft
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Matthew Ridley, Ben Upcroft, Michael Moser
*
- * This copy of Orca is licensed to you under the terms described in
+ * This distribution is licensed to you under the terms described in
* the LICENSE file included in this distribution.
*
*/
Modified: gearbox/trunk/submitted/gbxnovatelacfr/driver.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,9 +1,9 @@
/*
- * Orca-Robotics Project: Components for robotics
- * http://orca-robotics.sf.net/
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
* Copyright (c) 2004-2008 Matthew Ridley, Ben Upcroft, Michael Moser
*
- * This copy of Orca is licensed to you under the terms described in
+ * This distribution is licensed to you under the terms described in
* the LICENSE file included in this distribution.
*
*/
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#include "crc32.h"
////////////////////////////////////////////
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.h 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.h 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#include <cstddef> //for size_t
#include <stdint.h> //for fixed size integer types
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.cpp 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.cpp 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#include "imudecoder.h"
#include <gbxutilacfr/gbxutilacfr.h>
#include <sstream>
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.h 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.h 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#ifndef GBX_NOVATEL_IMUDECODER_H
#define GBX_NOVATEL_IMUDECODER_H
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#ifndef GBX_NOVATEL_MESSAGES_H
#define GBX_NOVATEL_MESSAGES_H
namespace gbxnovatelutilacfr{
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/receiverstatusdecoder.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/receiverstatusdecoder.h 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/receiverstatusdecoder.h 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#ifndef GBX_NOVATEL_RECEIVER_STATUS_DECODER_H
#define GBX_NOVATEL_RECEIVER_STATUS_DECODER_H
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.cpp 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.cpp 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#include <stdlib.h>
#include <unistd.h>
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.h 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.h 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
class gbxserialacfr::Serial;
// test connectivity to a [serial] device at a [baudrate];
Modified: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/test/crc32test.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/test/crc32test.cpp 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/test/crc32test.cpp 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#include <iostream>
#include <sstream>
#include <stdlib.h>
Modified: gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,7 +1,7 @@
/*
- * Orca-Robotics Project: Components for robotics
- * http://orca-robotics.sf.net/
- * Copyright (c) 2004-2008 Alex Brooks, Alexei Makarenko, Tobias Kaupp
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Matthew Ridley, Ben Upcroft, Michael Moser
*
* This distribution is licensed to you under the terms described in
* the LICENSE file included in this distribution.
Modified: gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-18 07:53:46 UTC (rev 183)
+++ gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp 2008-06-18 08:02:23 UTC (rev 184)
@@ -1,3 +1,12 @@
+/*
+ * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
+ * http://gearbox.sf.net/
+ * Copyright (c) 2004-2008 Michael Moser
+ *
+ * This distribution is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
#include <iostream>
#include <sstream>
#include <memory>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rum...@us...> - 2008-06-18 07:53:39
|
Revision: 183
http://gearbox.svn.sourceforge.net/gearbox/?rev=183&view=rev
Author: rumataxyz
Date: 2008-06-18 00:53:46 -0700 (Wed, 18 Jun 2008)
Log Message:
-----------
First commit of the novatel driver:
-compiles
-missing some functionality:
Config isValid() toString()
various data classes toString()
internal to external data types missing some conversions
-driver.h probably needs to be split into a config part and a data part
-NOT tested with hardware
Modified Paths:
--------------
gearbox/trunk/src/gbxsickacfr/CMakeLists.txt
gearbox/trunk/src/gbxsickacfr/gbxiceutilacfr/CMakeLists.txt
gearbox/trunk/submitted/CMakeLists.txt
Added Paths:
-----------
gearbox/trunk/submitted/gbxnovatelacfr/
gearbox/trunk/submitted/gbxnovatelacfr/CMakeLists.txt
gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
gearbox/trunk/submitted/gbxnovatelacfr/driver.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/CMakeLists.txt
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.cpp
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/receiverstatusdecoder.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.cpp
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.h
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/test/
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/test/CMakeLists.txt
gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/test/crc32test.cpp
gearbox/trunk/submitted/gbxnovatelacfr/novatel.dox
gearbox/trunk/submitted/gbxnovatelacfr/test/
gearbox/trunk/submitted/gbxnovatelacfr/test/CMakeLists.txt
gearbox/trunk/submitted/gbxnovatelacfr/test/example.cmake.in
gearbox/trunk/submitted/gbxnovatelacfr/test/example.readme
gearbox/trunk/submitted/gbxnovatelacfr/test/test.cpp
Modified: gearbox/trunk/src/gbxsickacfr/CMakeLists.txt
===================================================================
--- gearbox/trunk/src/gbxsickacfr/CMakeLists.txt 2008-06-18 07:12:28 UTC (rev 182)
+++ gearbox/trunk/src/gbxsickacfr/CMakeLists.txt 2008-06-18 07:53:46 UTC (rev 183)
@@ -5,18 +5,16 @@
GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )
GBX_REQUIRE_VAR( build LIB ${lib_name} GBX_OS_LINUX "only Linux OS is supported" )
-INCLUDE( ${GBX_CMAKE_DIR}/FindIceUtil.cmake )
-GBX_REQUIRE_VAR( build LIB ${lib_name} ICEUTIL_FOUND "libIceUtil not found" )
+ADD_SUBDIRECTORY( gbxiceutilacfr )
-SET( int_libs GbxUtilAcfr GbxSerialAcfr )
+SET( int_libs GbxUtilAcfr GbxIceUtilAcfr GbxSerialAcfr )
GBX_REQUIRE_TARGETS( build LIB ${lib_name} ${int_libs} )
# these are built internally
-SET( private_libs GbxIceUtilAcfr GbxSerialDeviceAcfr )
+SET( private_libs GbxSerialDeviceAcfr )
IF( build )
- ADD_SUBDIRECTORY( gbxiceutilacfr )
ADD_SUBDIRECTORY( gbxserialdeviceacfr )
INCLUDE( ${GBX_CMAKE_DIR}/UseBasicRules.cmake )
Modified: gearbox/trunk/src/gbxsickacfr/gbxiceutilacfr/CMakeLists.txt
===================================================================
--- gearbox/trunk/src/gbxsickacfr/gbxiceutilacfr/CMakeLists.txt 2008-06-18 07:12:28 UTC (rev 182)
+++ gearbox/trunk/src/gbxsickacfr/gbxiceutilacfr/CMakeLists.txt 2008-06-18 07:53:46 UTC (rev 183)
@@ -2,19 +2,14 @@
GBX_ADD_LICENSE( LGPL )
SET( build TRUE )
-# don't give user an option
-# GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )
-# this was already tested in the dir above
-# GBX_REQUIRE_VAR( build LIB ${lib_name} GBX_OS_LINUX "only Linux OS is supported" )
+GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )
-# this was already tested in the dir above
-# INCLUDE( ${GBX_CMAKE_DIR}/FindIceUtil.cmake )
-# GBX_REQUIRE_VAR( build LIB ${lib_name} ICEUTIL_FOUND "libIceUtil not found" )
+INCLUDE( ${GBX_CMAKE_DIR}/FindIceUtil.cmake )
+GBX_REQUIRE_VAR( build LIB ${lib_name} ICEUTIL_FOUND "libIceUtil not found" )
-# this lib is currently internal
SET( proj_libs GbxUtilAcfr )
-# GBX_REQUIRE_TARGETS( build LIB ${lib_name} ${proj_libs} )
+GBX_REQUIRE_TARGETS( build LIB ${lib_name} ${proj_libs} )
IF( build )
@@ -22,7 +17,7 @@
INCLUDE( ${GBX_CMAKE_DIR}/UseIceUtil.cmake )
FILE( GLOB hdrs *.h )
- FILE( GLOB srcs *.cpp ) # detail/*.cpp )
+ FILE( GLOB srcs *.cpp )
SET( dep_libs ${proj_libs} )
# for config.h
Modified: gearbox/trunk/submitted/CMakeLists.txt
===================================================================
--- gearbox/trunk/submitted/CMakeLists.txt 2008-06-18 07:12:28 UTC (rev 182)
+++ gearbox/trunk/submitted/CMakeLists.txt 2008-06-18 07:53:46 UTC (rev 183)
@@ -11,5 +11,6 @@
# Otherwise, maintain alphabetical order.
# E.g. ADD_SUBDIRECTORY( mydir )
+ ADD_SUBDIRECTORY( gbxnovatelacfr )
-ENDIF( GBX_BUILD_SUBMITTED )
\ No newline at end of file
+ENDIF( GBX_BUILD_SUBMITTED )
Added: gearbox/trunk/submitted/gbxnovatelacfr/CMakeLists.txt
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/CMakeLists.txt (rev 0)
+++ gearbox/trunk/submitted/gbxnovatelacfr/CMakeLists.txt 2008-06-18 07:53:46 UTC (rev 183)
@@ -0,0 +1,38 @@
+SET( lib_name GbxNovatelAcfr )
+GBX_ADD_LICENSE( LGPL )
+
+SET( build TRUE )
+GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )
+
+INCLUDE( ${GBX_CMAKE_DIR}/FindIceUtil.cmake )
+GBX_REQUIRE_VAR( build LIB ${lib_name} ICEUTIL_FOUND "libIceUtil not found" )
+
+SET( int_libs GbxUtilAcfr GbxSerialAcfr )
+GBX_REQUIRE_TARGETS( build LIB ${lib_name} ${int_libs} )
+
+# built internally
+SET( private_libs GbxNovatelUtilAcfr )
+
+IF( build )
+
+ ADD_SUBDIRECTORY( gbxnovatelutilacfr)
+
+ INCLUDE( ${GBX_CMAKE_DIR}/UseBasicRules.cmake )
+ INCLUDE( ${GBX_CMAKE_DIR}/UseIceUtil.cmake )
+
+ FILE( GLOB hdrs *.h )
+ FILE( GLOB srcs *.cpp )
+ SET( dep_libs ${int_libs} ${private_libs} )
+
+ GBX_ADD_LIBRARY( ${lib_name} SHARED ${srcs} )
+ TARGET_LINK_LIBRARIES( ${lib_name} ${dep_libs} )
+ GBX_ADD_PKGCONFIG( ${lib_name} "Drives NOVATEL hardware, directly connected to the computer." proj_libs int_libs "" "" )
+
+ GBX_ADD_HEADERS( gbxnovatelacfr ${hdrs} )
+
+ IF( GBX_BUILD_TESTS )
+ ADD_SUBDIRECTORY( test )
+ ENDIF( GBX_BUILD_TESTS )
+
+
+ENDIF( build )
Added: gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp (rev 0)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.cpp 2008-06-18 07:53:46 UTC (rev 183)
@@ -0,0 +1,813 @@
+/*
+ * Orca-Robotics Project: Components for robotics
+ * http://orca-robotics.sf.net/
+ * Copyright (c) 2004-2008 Matthew Ridley, Ben Upcroft
+ *
+ * This copy of Orca is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
+
+#include <gbxnovatelacfr/driver.h>
+#include <gbxnovatelacfr/gbxnovatelutilacfr/serialconnectivity.h>
+#include <gbxnovatelacfr/gbxnovatelutilacfr/novatelmessages.h>
+#include <gbxnovatelacfr/gbxnovatelutilacfr/imudecoder.h>
+#include <gbxnovatelacfr/gbxnovatelutilacfr/receiverstatusdecoder.h>
+#include <gbxnovatelacfr/gbxnovatelutilacfr/crc32.h>
+
+#include <gbxserialacfr/gbxserialacfr.h>
+#include <gbxutilacfr/gbxutilacfr.h>
+
+#include <iostream>
+#include <sstream>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+#include <vector>
+
+#include <sys/time.h>
+#include <time.h>
+
+using namespace std;
+using namespace gbxserialacfr;
+
+namespace gnua = gbxnovatelutilacfr;
+namespace gna = gbxnovatelacfr;
+
+namespace {
+// binary messages defined by novatel
+#pragma pack(push,1)
+ union novatelMessage{
+ struct{
+ gnua::Oem4BinaryHeader header;
+ char data[484];
+ };
+ struct{
+ gnua::Oem4ShortBinaryHeader shortHeader;
+ char shortData[500];
+ };
+ unsigned char rawMessage[512];
+
+ // these guys are used to directly decode messages;
+ // obviously fails on endian mismatch, any sort of size mismatch and is rather nasty in general;
+ // feel free to implement something better
+ gnua::BestGpsPosLogB bestGpsPos;
+ gnua::BestGpsVelLogB bestGpsVel;
+ gnua::InsPvaLogSB insPva;
+ gnua::RawImuLogSB rawImu;
+ };
+#pragma pack(pop)
+ int readNovatelMessage(union novatelMessage &msg, struct timeval &timeStamp, gbxserialacfr::Serial *serial);
+ std::auto_ptr<gna::GenericData> createExternalMsg(gnua::InsPvaLogSB &insPva, struct timeval &timeStamp);
+ std::auto_ptr<gna::GenericData> createExternalMsg(gnua::BestGpsPosLogB &bestGpsPos, struct timeval &timeStamp);
+ std::auto_ptr<gna::GenericData> createExternalMsg(gnua::BestGpsVelLogB &bestGpsVel, struct timeval &timeStamp);
+ std::auto_ptr<gna::GenericData> createExternalMsg(gnua::RawImuLogSB &rawImu, struct timeval &timeStamp, gnua::ImuDecoder *imuDecoder);
+}
+
+namespace gbxnovatelacfr
+{
+Driver::Driver( const Config& cfg,
+ gbxutilacfr::Tracer &tracer) :
+ serial_(0),
+ baud_(115200),
+ config_(cfg),
+ tracer_(tracer)
+{
+ if(false == config_.isValid()){
+ throw (std::string("Invalid Configuration!"));
+ }
+
+ // configure serial port
+ baud_ = config_.baudRate_;
+ std::string serialDevice = config_.serialDevice_;
+ serial_.reset(new Serial( serialDevice, baud_, Serial::Timeout(1,0) ));
+ serial_->setDebugLevel(0);
+ if(0 != connectToHardware() ){
+ throw (std::string("failed to connect to receiver!"));
+ }
+
+ // just in case something is running... stops the novatel logging any messages
+ serial_->writeString( "unlogall\r\n" );
+ serial_->drain();
+ configureImu();
+ configureIns();
+ configureGps();
+ requestData();
+ serial_->flush();
+ tracer_.info("Setup done, starting normal operation!");
+}
+
+Driver::~Driver() {
+ // just in case something is running... stops the novatel logging any messages
+ try{
+ tracer_.info("Stopping NovatelSpan driver!");
+ serial_->flush();
+ serial_->writeString( "unlogall\r\n" );
+ serial_->drain();
+ tracer_.info("NovatelSpan driver stopped!");
+ }
+ catch(...){
+ //no throwing from destructors
+ }
+}
+
+int
+Driver::connectToHardware() {
+ // baudrates we test for; this is
+ // _not_ all the baudrates the receiver
+ // can possible be set to
+ int baudrates[]={
+ 9600,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400
+ };
+ int currentBaudrate = 0;
+ bool correctBaudrate = false;
+
+ std::cout << "Trying to hook up to receiver at different Baudrates\n";
+ int maxTry = 4;
+ int successThresh = 4;
+ int timeOutMsec = 150;
+ std::string challenge("unlogall\r\n");
+ std::string ack("<OK");
+ size_t i=0;
+ while(false == correctBaudrate && i<sizeof baudrates/sizeof baudrates[0]){
+ currentBaudrate = baudrates[i];
+ correctBaudrate = gnua::testConnectivity( challenge, ack, *(serial_.get()), timeOutMsec, maxTry, successThresh, currentBaudrate);
+ i++;
+ }
+ if(false == correctBaudrate){
+ std::cout << "\n!Failed to establish a connection to the receiver!\n";
+ std::cout << "Check physical connections; Check manually (minicom) for Baudrates < 9600kb/s.\n\n";
+ return -1;
+ }
+ char str[256];
+ sprintf( str,"com com1 %d n 8 1 n off on\r\n", baud_ );
+ serial_->writeString( str );
+ std::cout << "*******************************\n"
+ << "** Current Speed " << currentBaudrate << "\n"
+ << "** Resetting to " << baud_ << "\n"
+ << "*******************************\n";
+ std::cout << "** Testing new setting\n** ";
+ if(true == gnua::testConnectivity( challenge, ack, *(serial_.get()), timeOutMsec, maxTry, successThresh, baud_)){
+ std::cout << "*******************************\n";
+ return 0;
+ }else{
+ std::cout << "*******************************\n";
+ return -1;
+ }
+}
+
+void
+Driver::configureImu() {
+ int put;
+
+ if(config_.enableImu_){
+ imuDecoder_.reset(gnua::createImuDecoder(config_.imuType_));
+ std::stringstream ss;
+ // tell the novatel what serial port the imu is attached to (com3 == aux)
+ put = serial_->writeString( "interfacemode com3 imu imu on\r\n" );
+ // the type of imu being used
+ ss << "setimutype "
+ << config_.imuType_
+ << "\r\n";
+ put = serial_->writeString( ss.str().c_str() );
+ //force the IMU to re-align at every startup
+ //put = serial_->writeString( "inscommand reset\r\n" );
+ //tracer_.info("Reset IMU; Waiting 5 seconds before continuing!");
+ //sleep(5);
+ }else{
+ // no IMU --> disable INS
+ put = serial_->writeString( "inscommand disable\r\n" );
+ }
+ return;
+}
+
+void
+Driver::configureIns() {
+ int put;
+ if(config_.enableSetImuOrientation_ && config_.enableImu_){
+ std::stringstream ss;
+ // imu orientation constant
+ // this tells the imu where its z axis (up) is pointing. constants defined in manual.
+ // with imu mounted upside down, constant is 6 and axes are remapped: x = y, y = x, -z = z
+ ss << "setimuorientation " << config_.setImuOrientation_ << "\r\n";
+ put = serial_->writeString( ss.str().c_str() );
+ }
+
+ if(config_.enableVehicleBodyRotation_ && config_.enableImu_){
+ std::stringstream ss;
+ // vehicle to imu body rotation
+ // angular offset from the vehicle to the imu body. unclear how this relates to imu orientation command
+ // the novatel docs are not especially clear on this stuff; It's highly recommended to mount the IMU
+ // exactly as advised by novatel and just ignore this
+ ss << "vehiclebodyrotation "
+ << config_.vehicleBodyRotation_[0]
+ << config_.vehicleBodyRotation_[1]
+ << config_.vehicleBodyRotation_[2];
+ if(3 == config_.vehicleBodyRotationUncertainty_.size()){
+ // optional, vehicle to imu body rotation uncertainty
+ ss << config_.vehicleBodyRotationUncertainty_[0]
+ << config_.vehicleBodyRotationUncertainty_[1]
+ << config_.vehicleBodyRotationUncertainty_[2];
+ }
+ ss << "\r\n";
+ put = serial_->writeString( ss.str().c_str() );
+ }
+
+ if(config_.enableImu_){
+ std::stringstream ss;
+ // The span system kalman fiter needs this info; make _sure_ you do this right
+ ss << "setimutoantoffset "
+ << config_.imuToGpsOffset_[0]
+ << config_.imuToGpsOffset_[1]
+ << config_.imuToGpsOffset_[2];
+
+ if( 3 == config_.imuToGpsOffsetUncertainty_.size() ){
+ ss << config_.imuToGpsOffsetUncertainty_[0]
+ << config_.imuToGpsOffsetUncertainty_[1]
+ << config_.imuToGpsOffsetUncertainty_[2];
+ }
+ ss << "\r\n";
+ put = serial_->writeString( ss.str().c_str() );
+ }
+ return;
+}
+
+void
+Driver::configureGps() {
+ // hardcoded settings first
+
+ // turn off posave as this command implements position averaging for base stations.
+ int put = serial_->writeString( "posave off\r\n" );
+ // make sure that fixposition has not been set
+ put = serial_->writeString( "fix none\r\n" );
+ // select the geodetic datum for operation of the receiver (wgs84 = default)
+ put = serial_->writeString( "datum wgs84\r\n" );
+ //Let the receiver figure out which range corrections are best
+ put = serial_->writeString( "PSRDIFFSOURCE AUTO\r\n" );
+
+ // CDGPS
+ if(config_.enableCDGPS_){
+ tracer_.info("Turning on CDGPS!");
+ put = serial_->writeString( "ASSIGNLBAND CDGPS 1547547 4800\r\n" );
+ }
+
+ // turn SBAS on/off (essentially global DGPS)
+ if(config_.enableSBAS_){
+ tracer_.info("Turning on SBAS!");
+ put = serial_->writeString( "SBASCONTROL ENABLE Auto 0 ZEROTOTWO\r\n");
+ //we try to use WAAS satellites even below the horizon
+ put = serial_->writeString( "WAASECUTOFF -5.0\r\n");
+ }
+ else{
+ tracer_.info("Turning off SBAS!");
+ put = serial_->writeString( "SBASCONTROL DISABLE Auto 0 NONE\r\n");
+ }
+
+ // rtk
+ if(config_.enableRTK_){
+ tracer_.info("Turning on RTK!");
+ put = serial_->writeString( "com com2,9600,n,8,1,n,off,on\r\n" );
+ put = serial_->writeString( "interfacemode com2 rtca none\r\n" );
+ }
+
+ if(config_.enableUseOfOmniStarCarrier_){
+ //Let the receiver figure out which rtk corrections are best
+ put = serial_->writeString( "RTKSOURCE AUTO\r\n" );
+ }else{
+ //We only use our own rtk corrections; _not_ OmniSTAR HP/XP
+ put = serial_->writeString( "RTKSOURCE RTCA ANY\r\n" );
+ }
+ return;
+}
+
+void
+Driver::requestData() {
+ //we assume that the config_ has been checked at this point (isValid())
+ //so we don't need to check that the rates make sense
+ int put;
+
+ // GPS messages
+
+ // gps position without ins
+ if(config_.enableGpsPos_){
+ std::stringstream ss;
+ ss << "log bestgpsposb ontime " << config_.dtGpsPos_ << "\r\n";
+ put = serial_->writeString(ss.str().c_str());
+ ss.str("");
+ ss << "Turning on GPS position at " << 1.0/config_.dtGpsPos_ << "Hz!";
+ tracer_.info(ss.str().c_str());
+ }
+
+ // gps velocity without ins
+ if(config_.enableGpsVel_){
+ std::stringstream ss;
+ ss << "log bestgpsvelb ontime " << config_.dtGpsVel_ << "\r\n";
+ put = serial_->writeString(ss.str().c_str());
+ ss.str("");
+ ss << "Turning on GPS velocity at " << 1.0/config_.dtGpsVel_ << "Hz!";
+ tracer_.info(ss.str().c_str());
+ }
+
+
+ // INS messages
+
+ // pva data in wgs84 coordinates
+ if(config_.enableInsPva_){
+ std::stringstream ss;
+ ss << "log inspvasb ontime " << config_.dtInsPva_ << "\r\n";
+ put = serial_->writeString(ss.str().c_str());
+ ss.str("");
+ ss << "Turning on INS position/velocity/orientation at " << 1.0/config_.dtInsPva_ << "Hz!";
+ tracer_.info(ss.str().c_str());
+ }
+
+
+ // IMU messages
+
+ // raw accelerometer and gyro data
+ if(config_.enableRawImu_){
+ put = serial_->writeString( "log rawimusb onnew\r\n" );
+ tracer_.info("Turning on raw imu data!");
+ }
+
+ return;
+}
+
+std::auto_ptr<GenericData>
+Driver::read(){
+ union novatelMessage msg;
+ std::auto_ptr<GenericData> data;
+ data.reset(0);
+ struct timeval timeStamp = {0,0};
+
+ // read msg from hardware
+ do{
+ // Timeouts are not adjusted once a serial call returns;
+ // So we could be stuck here for longer than the set timeout.
+ int ret = serial_->bytesAvailableWait();
+ if ( ret >= 0 ) {
+ switch(readNovatelMessage(msg, timeStamp, serial_.get())){
+ case gnua::InsPvaSBLogType:
+ data = createExternalMsg(msg.insPva, timeStamp);
+ break;
+ case gnua::BestGpsVelBLogType:
+ data = createExternalMsg(msg.bestGpsVel, timeStamp);
+ break;
+ case gnua::BestGpsPosBLogType:
+ data = createExternalMsg(msg.bestGpsPos, timeStamp);
+ break;
+ case gnua::RawImuSBLogType:
+ data = createExternalMsg(msg.rawImu, timeStamp, imuDecoder_.get());
+ break;
+ default:
+ {
+ std::stringstream ss;
+ ss << "Warning("<<__FILE__<<":"<< __LINE__
+ <<" : got unexpected message from receiver; id: " << msg.header.msgId << std::endl;
+ if(config_.ignoreUnknownMessages_){
+ tracer_.warning(ss.str());
+ }else{
+ throw( ss.str() );
+ }
+ }
+ break;
+ }
+ }
+ else {
+ std::stringstream ss;
+ ss << "Warning("<<__FILE__<<":"<< __LINE__
+ << "Timed out while waiting for data";
+ throw (ss.str());
+ }
+ }while(NULL == data.get()); // repeat till we get valid data
+
+ return data;
+}
+
+Config::Config(const SimpleConfig &simpleCfg) :
+ serialDevice_(simpleCfg.serialDevice_),
+ baudRate_(simpleCfg.baudRate_),
+ enableImu_(true),
+ imuType_(simpleCfg.imuType_),
+ enableInsPva_(true),
+ enableGpsPos_(true),
+ enableGpsVel_(true),
+ enableRawImu_(true),
+ ignoreUnknownMessages_(false),
+ dtInsPva_(0.02),
+ dtGpsPos_(0.2),
+ dtGpsVel_(0.2),
+ fixInvalidRateSettings_(false),
+ imuToGpsOffset_(simpleCfg.imuToGpsOffset_),
+ enableInsOffset_(false),
+ enableInsPhaseUpdate_(true),
+ enableCDGPS_(true),
+ enableSBAS_(true),
+ enableRTK_(true),
+ enableUseOfOmniStarCarrier_(false),
+ enableSetImuOrientation_(false),
+ enableVehicleBodyRotation_(false) {
+}
+Config::Config(const GpsOnlyConfig &gpsOnlyCfg) :
+ serialDevice_(gpsOnlyCfg.serialDevice_),
+ baudRate_(gpsOnlyCfg.baudRate_),
+ enableImu_(false),
+ enableInsPva_(false),
+ enableGpsPos_(true),
+ enableGpsVel_(true),
+ enableRawImu_(false),
+ ignoreUnknownMessages_(false),
+ dtGpsPos_(0.05),
+ dtGpsVel_(0.05),
+ fixInvalidRateSettings_(false),
+ enableCDGPS_(true),
+ enableSBAS_(true),
+ enableRTK_(true),
+ enableUseOfOmniStarCarrier_(false) {
+}
+Config::Config() :
+ serialDevice_(""),
+ baudRate_(0),
+ enableImu_(false),
+ imuType_(""),
+ enableInsPva_(false),
+ enableGpsPos_(false),
+ enableGpsVel_(false),
+ enableRawImu_(false),
+ ignoreUnknownMessages_(false),
+ dtInsPva_(1.0),
+ dtGpsPos_(1.0),
+ dtGpsVel_(1.0),
+ fixInvalidRateSettings_(false),
+ imuToGpsOffset_(1,0.0),
+ imuToGpsOffsetUncertainty_(1,0.0),
+ enableInsOffset_(false),
+ insOffset_(1,0.0),
+ enableInsPhaseUpdate_(false),
+ enableCDGPS_(false),
+ enableSBAS_(false),
+ enableRTK_(false),
+ enableUseOfOmniStarCarrier_(false),
+ enableSetImuOrientation_(false),
+ setImuOrientation_(0),
+ enableVehicleBodyRotation_(false),
+ vehicleBodyRotation_(1,0.0),
+ vehicleBodyRotationUncertainty_(1,0.0) {
+}
+
+bool
+Config::isValid() const {
+ cout << __func__ << "implement me\n";
+ return true;
+}
+
+std::string
+Config::toString(){
+ cout << __func__ << "implement me\n";
+ return "";
+}
+
+bool
+SimpleConfig::isValid() const {
+ cout << __func__ << "implement me\n";
+ return true;
+}
+
+std::string
+SimpleConfig::toString(){
+ cout << __func__ << "implement me\n";
+ return "";
+}
+
+bool
+GpsOnlyConfig::isValid() const {
+ cout << __func__ << "implement me\n";
+ return true;
+}
+
+std::string
+GpsOnlyConfig::toString(){
+ cout << __func__ << "implement me\n";
+ return "";
+}
+
+} //namespace
+
+namespace{
+ int
+ readNovatelMessage(union novatelMessage &msg, struct timeval &timeStamp, gbxserialacfr::Serial *serial) {
+ // read the three sync bytes which are always at the start of the message header
+ unsigned short id;
+ unsigned long crc;
+ unsigned long in_crc;
+ msg.header.sb1 = 0;
+ int skip = -1;
+ int got;
+
+ // read the first sync byte
+ do{
+ got = serial->readFull( &msg.header.sb1, 1 );
+ if ( got <= 0 ) {
+ return got;
+ }
+ if( got>0 ) {
+ skip++;
+ }
+ }while( msg.header.sb1 != 0xaa );
+
+ // get timestamp after the first byte for accuracy
+ gettimeofday(&timeStamp, NULL);
+
+ // read the second sync byte
+ do {
+ got = serial->readFull( &msg.header.sb2, 1 );
+ if ( got <= 0 ) {
+ return got;
+ }
+ }while( got!=1 );
+
+ if( msg.header.sb2 != 0x44 ) {
+ return -1;
+ }
+
+ // read the third sync byte
+ do {
+ got = serial->readFull( &msg.header.sb3, 1 );
+ if ( got <= 0 ) {
+ return got;
+ }
+ }while( got != 1 );
+
+ switch( msg.header.sb3 ) {
+ case 0x12: //long packet
+ if( // how long is the header ?
+ -1 == serial->readFull( &msg.header.headerLength, 1 )
+ // read all of the header...
+ || -1 == serial->readFull( &msg.header.msgId, msg.header.headerLength-4 )
+ // read the message data
+ || -1 == serial->readFull( &msg.data, msg.header.msgLength )
+ || -1 == serial->readFull( &in_crc, 4 )
+ ){
+ return -1;
+ }
+
+ id = msg.header.msgId;
+
+ crc = gnua::crc( msg.rawMessage,
+ msg.header.msgLength+msg.header.headerLength );
+ break;
+
+ case 0x13: //short packet
+ if( // read rest of the header 12 bytes - 3 bytes already read, then the actual data, then the CRC
+ -1 == serial->readFull( &msg.shortHeader.msgLength, 9 )
+ || -1 == serial->readFull( &msg.shortData, msg.shortHeader.msgLength )
+ || -1 == serial->readFull( &in_crc, 4 )
+ ){
+ return -1;
+ }
+
+ id = msg.shortHeader.msgId;
+
+ crc = gnua::crc( msg.rawMessage,msg.shortHeader.msgLength + 12 );
+ break;
+
+ default: //bollocks
+ return -1;
+ }
+
+ if(in_crc != crc) {
+ fprintf( stderr,"CRC Error: 0x%lx, 0x%lx\n",in_crc,crc );
+ throw std::string( "CRC Error" );
+ return -1;
+ }
+
+ return id;
+ }
+
+
+ std::auto_ptr<gna::GenericData>
+ createExternalMsg(gnua::InsPvaLogSB &insPva, struct timeval &timeStamp){
+ //static int cnt;
+ //if(0 == cnt++ % 1000) cout << __func__ << " ins; implement me properly!\n";
+ gna::InsPvaData *data = new gna::InsPvaData;
+ std::auto_ptr<gna::GenericData> genericData( data );
+
+ //data
+ data->gpsWeekNr = insPva.data.gpsWeekNr;
+ data->secIntoWeek = insPva.data.secIntoWeek;
+ data->latitude = insPva.data.latitude;
+ data->longitude = insPva.data.longitude;
+ data->height = insPva.data.height;
+ data->northVelocity = insPva.data.northVelocity;
+ data->eastVelocity = insPva.data.eastVelocity;
+ data->upVelocity = insPva.data.upVelocity;
+ data->roll = insPva.data.roll;
+ data->pitch = insPva.data.pitch;
+ data->azimuth = insPva.data.azimuth;
+
+ //timestamp
+ data->timeStampSec = timeStamp.tv_sec;
+ data->timeStampUSec = timeStamp.tv_usec;
+
+ //status
+ switch( insPva.data.insStatus ) {
+ case 0:
+ data->statusMessage = "Ins is inactive";
+ data->statusMessageType = gna::Fault;
+ break;
+ case 1:
+ data->statusMessage = "Ins is aligning";
+ data->statusMessageType = gna::Warning;
+ break;
+ case 2:
+ data->statusMessage = "Ins solution is bad";
+ data->statusMessageType = gna::Warning;
+ break;
+ case 3:
+ data->statusMessage = "Ins solution is good";
+ data->statusMessageType = gna::Ok;
+ break;
+ case 4://fallthrough
+ case 5:
+ {
+ stringstream ss;
+ ss << "Reserved value?? Check NovatelSpan manual for \"" << insPva.data.insStatus << "\" as INS status";
+ data->statusMessage = ss.str();
+ data->statusMessageType = gna::Warning;
+ }
+ break;
+ case 6:
+ data->statusMessage = "Bad Ins Gps agreement";
+ data->statusMessageType = gna::Warning;
+ break;
+ case 7:
+ data->statusMessage = "Ins alignment is complete but vehicle must perform maneuvers so that the attitude can converge";
+ data->statusMessageType = gna::Ok;
+ break;
+ default:
+ {
+ stringstream ss;
+ ss << "Unknown Ins Status. Check NovatelSpan manual for \"" << insPva.data.insStatus << "\" as INS status";
+ data->statusMessage = ss.str();
+ data->statusMessageType = gna::Warning;
+ }
+ break;
+ }
+
+ return genericData;
+ }
+
+ std::auto_ptr<gna::GenericData>
+ createExternalMsg(gnua::BestGpsPosLogB &bestGpsPos, struct timeval &timeStamp){
+ static int cnt;
+ if(0 == cnt++ % 100) cout << __func__ << " gpspos; implement me properly!\n";
+ gna::BestGpsPosData *data = new gna::BestGpsPosData;
+ std::auto_ptr<gna::GenericData> genericData( data );
+
+ //data
+ data->gpsWeekNr = bestGpsPos.header.gpsWeekNr;
+ data->msIntoWeek = bestGpsPos.header.msIntoWeek;
+ //data->solutionStatus = bestGpsPos.data.solutionStatus;
+ //data->positionType = bestGpsPos.data.positionType;
+ data->latitude = bestGpsPos.data.latitude;
+ data->longitude = bestGpsPos.data.longitude;
+ data->heightAMSL = bestGpsPos.data.heightAMSL;
+ data->undulation = bestGpsPos.data.undulation;
+ data->datumId = bestGpsPos.data.datumId;
+ data->sigmaLatitude = bestGpsPos.data.sigmaLatitude;
+ data->sigmaLongitude = bestGpsPos.data.sigmaLongitude;
+ data->sigmaHeight = bestGpsPos.data.sigmaHeight;
+ data->baseStationId[4] = bestGpsPos.data.baseStationId[4];
+ data->diffAge = bestGpsPos.data.diffAge;
+ data->solutionAge = bestGpsPos.data.solutionAge;
+ data->numObservations = bestGpsPos.data.numObservations;
+ data->numL1Ranges = bestGpsPos.data.numL1Ranges;
+ data->numL1RangesRTK = bestGpsPos.data.numL1RangesRTK;
+ data->numL2RangesRTK = bestGpsPos.data.numL2RangesRTK;
+
+ //time
+ data->timeStampSec = timeStamp.tv_sec;
+ data->timeStampUSec = timeStamp.tv_usec;
+
+ //status
+ static bool lastStatusWasGood = false;
+ if(true == gnua::receiverStatusIsGood(bestGpsPos.header.receiverStatus)){
+ if (true == lastStatusWasGood){
+ // still all good, no need to be chatty
+ data->statusMessageType = gna::NoMsg;
+ data->statusMessage = "";
+ lastStatusWasGood = true;
+ }else{
+ // we are good now, report it
+ data->statusMessageType = gna::Ok;
+ data->statusMessage = "all is good";
+ lastStatusWasGood = true;
+ }
+ }else{
+ //whoops
+ data->statusMessageType = gna::Fault; // warning?
+ data->statusMessage = gnua::receiverStatusToString(bestGpsPos.header.receiverStatus);
+ lastStatusWasGood = false;
+ }
+ return genericData;
+
+ }
+
+ std::auto_ptr<gna::GenericData>
+ createExternalMsg(gnua::BestGpsVelLogB &bestGpsVel, struct timeval &timeStamp){
+ static int cnt;
+ if(0 == cnt++ % 100) cout << __func__ << " gpsvel; implement me properly!\n";
+ gna::BestGpsVelData *data = new gna::BestGpsVelData;
+ std::auto_ptr<gna::GenericData> genericData( data );
+
+ //data
+ data->gpsWeekNr = bestGpsVel.header.gpsWeekNr;
+ data->msIntoWeek = bestGpsVel.header.msIntoWeek;
+ //data->solutionStatus = bestGpsVel.data.solutionStatus;
+ //data->velocityType = bestGpsVel.data.velocityType;
+ data->latency = bestGpsVel.data.latency;
+ data->diffAge = bestGpsVel.data.diffAge;
+ data->horizontalSpeed = bestGpsVel.data.horizontalSpeed;
+ data->trackOverGround = bestGpsVel.data.trackOverGround;
+ data->verticalSpeed = bestGpsVel.data.verticalSpeed;
+
+ //time
+ data->timeStampSec = timeStamp.tv_sec;
+ data->timeStampUSec = timeStamp.tv_usec;
+
+ //status
+ static bool lastStatusWasGood = false;
+ if(true == gnua::receiverStatusIsGood(bestGpsVel.header.receiverStatus)){
+ if (true == lastStatusWasGood){
+ // still all good, no need to be chatty
+ data->statusMessageType = gna::NoMsg;
+ data->statusMessage = "";
+ lastStatusWasGood = true;
+ }else{
+ // we are good now, report it
+ data->statusMessageType = gna::Ok;
+ data->statusMessage = "all is good";
+ lastStatusWasGood = true;
+ }
+ }else{
+ //whoops
+ data->statusMessageType = gna::Fault; // warning?
+ data->statusMessage = gnua::receiverStatusToString(bestGpsVel.header.receiverStatus);
+ lastStatusWasGood = false;
+ }
+ return genericData;
+ }
+
+ std::auto_ptr<gna::GenericData>
+ createExternalMsg(gnua::RawImuLogSB &rawImu, struct timeval &timeStamp, gnua::ImuDecoder *imuDecoder){
+ //static int cnt;
+ //if(0 == cnt++ % 500) cout << __func__ << " imu; implement me properly!\n";
+ gna::RawImuData *data = new gna::RawImuData;
+ std::auto_ptr<gna::GenericData> genericData( data );
+
+ //data
+ data->gpsWeekNr = rawImu.data.gpsWeekNr;
+ data->secIntoWeek = rawImu.data.secIntoWeek;
+ //accels
+ data->zDeltaV = imuDecoder->accelCnt2MperSec(rawImu.data.zAccelCnt);
+ data->yDeltaV = -1.0*imuDecoder->accelCnt2MperSec(rawImu.data.yNegativAccelCnt);
+ data->xDeltaV = imuDecoder->accelCnt2MperSec(rawImu.data.xAccelCnt);
+ //gyros
+ data->zDeltaAng = imuDecoder->gyroCnt2Rad(rawImu.data.zGyroCnt);
+ data->yDeltaAng = -1.0*imuDecoder->gyroCnt2Rad(rawImu.data.yNegativGyroCnt);
+ data->xDeltaAng = imuDecoder->gyroCnt2Rad(rawImu.data.xGyroCnt);
+
+ //time
+ data->timeStampSec = timeStamp.tv_sec;
+ data->timeStampUSec = timeStamp.tv_usec;
+
+ //status
+ static bool lastStatusWasGood = false;
+ if(true == imuDecoder->statusIsGood(rawImu.data.imuStatus)){
+ if (true == lastStatusWasGood){
+ // still all good, no need to be chatty
+ data->statusMessageType = gna::NoMsg;
+ data->statusMessage = "";
+ lastStatusWasGood = true;
+ }else{
+ // we are good now, report it
+ data->statusMessageType = gna::Ok;
+ data->statusMessage = "all is good";
+ lastStatusWasGood = true;
+ }
+ }else{
+ //whoops
+ data->statusMessageType = gna::Fault; // warning?
+ data->statusMessage = imuDecoder->statusToString(rawImu.data.imuStatus);
+ lastStatusWasGood = false;
+ }
+ return genericData;
+ }
+}//namespace
Added: gearbox/trunk/submitted/gbxnovatelacfr/driver.h
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/driver.h (rev 0)
+++ gearbox/trunk/submitted/gbxnovatelacfr/driver.h 2008-06-18 07:53:46 UTC (rev 183)
@@ -0,0 +1,429 @@
+/*
+ * Orca-Robotics Project: Components for robotics
+ * http://orca-robotics.sf.net/
+ * Copyright (c) 2004-2008 Matthew Ridley, Ben Upcroft, Michael Moser
+ *
+ * This copy of Orca is licensed to you under the terms described in
+ * the LICENSE file included in this distribution.
+ *
+ */
+
+#ifndef GBXNOVATELACFR_DRIVER_H
+#define GBXNOVATELACFR_DRIVER_H
+
+#include <cstdlib>
+#include <string>
+#include <memory>
+#include <vector>
+
+// forward declarations
+// users don't need to know about serial devices or Tracers or imu decoders
+namespace gbxserialacfr{
+ class Serial;
+}
+namespace gbxutilacfr{
+ class Tracer;
+}
+namespace gbxnovatelutilacfr{
+ class ImuDecoder;
+}
+
+namespace gbxnovatelacfr{
+
+//! Minimum information to configure the receiver in INS mode
+class SimpleConfig{
+public:
+ //! @parameter imuToGpsOffset: vector (xyz [m]) from IMU center to Antenna Phase Center
+ //! in IMU coordinates, vital for INS performance, make sure you get this right!
+ //! @parameter imuType: as expected by the "SETIMUTYPE" command (SPAN Technology for OEMV User Manual Rev 3, Table 15, page 64)
+ SimpleConfig(std::string serialDevice, int baudRate, std::string imuType, std::vector<double > &imuToGpsOffset):
+ serialDevice_(serialDevice),
+ baudRate_(baudRate),
+ imuType_(imuType),
+ imuToGpsOffset_(imuToGpsOffset) {};
+
+ //! Returns true if the configuration is sane. Checks include:
+ //! - a non-empty device name
+ //! - baud rate is supported by device (9600, 19200, 38400, 115200, 230400)
+ //! - imuType refers to a known type
+ //! - offset has size 3
+ bool isValid() const;
+ //! Dumps the config in human readable form
+ std::string toString();
+
+ std::string serialDevice_;
+ int baudRate_;
+ std::string imuType_;
+ std::vector<double > imuToGpsOffset_;
+};
+
+//! Minimum information needed to configure the receiver in GPS only mode
+class GpsOnlyConfig{
+public:
+ GpsOnlyConfig(std::string serialDevice, int baudRate):
+ serialDevice_(serialDevice),
+ baudRate_(baudRate) {};
+
+ //! Returns true if the configuration is sane. Checks include:
+ //! - a non-empty device name
+ //! - baud rate is supported by device (9600, 19200, 38400, 115200, 230400)
+ bool isValid() const;
+ std::string toString();
+
+ std::string serialDevice_;
+ int baudRate_;
+};
+
+//! All the information needed to configure the driver. The device itself has even more options, consult your manual.
+//! If all these possibilities don't seem to be sufficient, consult your friendly developer for extension (better yet, send a patch)
+class Config{
+public:
+ Config(const SimpleConfig &simpleCfg); //!< yields a valid config, with reasonable defaults
+ Config(const GpsOnlyConfig &gpsOnlyCfg); //!< yields a valid config, for gps only operation
+ Config(); //!< disables everything, so you can set just the options you need
+
+ //! Returns true if the configuration is sane. Checks include:
+ //! - a non-empty device name
+ //! - baud rate is supported by device (9600, 19200, 38400, 115200, 230400)
+ //! - imuType refers to a known type
+ //! - offset has size 3
+ //! - message rates are consistent and don't exceed serial-data-rate
+ bool isValid() const;
+ //! Dumps the config in human readable form
+ std::string toString();
+
+ //!@name Serial settings
+ //
+ //!@{
+ std::string serialDevice_;
+ int baudRate_;
+ //!@}
+
+ //!@name IMU settings
+ //
+ //!@{
+ bool enableImu_;
+ std::string imuType_;
+ //!@}
+
+ //!@name Data settings
+ //
+ //!we disable all output in the ctor, and then enable the messages set to true here.
+ //!@{
+ bool enableInsPva_;
+ bool enableGpsPos_;
+ bool enableGpsVel_;
+ bool enableRawImu_;
+ bool ignoreUnknownMessages_; //!< normally we throw an exception, set this to "true" if you want to enable some other message permanently.
+ //!@}
+
+ //!@name Data rate settings
+ //
+ //!Time between messages in seconds (i.e. 0.01 == 100Hz). RawImu can only be reported at
+ //!the "natural" rate of the IMU (100Hz or 200Hz, depending on model).
+ //!We check in isValid() if any of these don't make sense
+ //!@{
+ double dtInsPva_; //!< 100Hz max, if RawImu is enabled 50Hz max
+ double dtGpsPos_; //!< 20Hz max, 5Hz max if RawImu or InsPva is enabled
+ double dtGpsVel_; //!< 20Hz max, 5Hz max if RawImu or InsPva is enabled
+ bool fixInvalidRateSettings_; //!< don't bitch about wrong rates, but change them to something sensible
+ //!@}
+
+ //!@name INS settings
+ //
+ //!@{
+ std::vector<double > imuToGpsOffset_;
+ std::vector<double > imuToGpsOffsetUncertainty_; //!< optional (size 3 or 0)
+ bool enableInsOffset_;
+ std::vector<double > insOffset_; //!< report INS position/velocity offset (xyz [m] in IMU coordinates) from the IMU center; useful e.g. to get data w.r. to robot's center of rotation
+ bool enableInsPhaseUpdate_; //!< tightly coupled (phase based vs position based) filter; Chance of better performance in adverse conditions
+ //!@}
+
+ //!@name GPS settings
+ //
+ //!@{
+ bool enableCDGPS_; //!< code-differential corrections over satellite (North America/Canada)
+ bool enableSBAS_; //!< code-differential corrections over satellite on GPS frequencies (WAAS/EGNOS)
+ bool enableRTK_; //!< carrier-differential corrections (you need to set up your own base-station and wireless link), assumes RTCA corrections on COM2, 9600bps, 8N1 (hardcoded)
+ bool enableUseOfOmniStarCarrier_; //!< carrier-differential corrections OMNIStarXP/HP (you need to get a subscription with them)
+ //!@}
+
+ //!@name INS settings for fast (dynamic) alignment
+ //! !I'd strongly recommend that you read the manual _very_ closely!
+ //! These guys enbale the Span system to do an alignment while moving, they also allow you to mount the IMU in weird ways (e.g. upside down).
+ //! It's worth to accept a fair amount of pain to mount the IMU in the recommended way. Otherwise you'll probably need a good amount of
+ //! experimentation/calibration to get a parameter-set that works.
+ //
+ //!@{
+ bool enableSetImuOrientation_;
+ int setImuOrientation_;
+ bool enableVehicleBodyRotation_;
+ std::vector<double > vehicleBodyRotation_;
+ std::vector<double > vehicleBodyRotationUncertainty_; //!< optional (size 3 or 0)
+ //!@}
+private:
+};
+
+//! possible Status Messages GenericData can contain
+enum StatusMessagetype {
+ //! Nothing new, no message
+ NoMsg,
+ //! All good, but something to say
+ Ok,
+ //! Problem, likely to go away
+ Warning,
+ //! Problem, probably fatal
+ Fault
+};
+
+//! Novatel's different solution status types
+enum GpsSolutionStatusType{
+ SolComputed, //!< Solution computed
+ InsufficientObs, //!< Insufficient observations
+ NoConvergence, //!< No convergence
+ Singularity, //!< Singularity at parameters matrix
+ CovTrace, //!< Covariance trace exceeds maximum (trace > 1000 m)
+ TestDist, //!< Test distance exceeded (maximum of 3 rejections if distance > 10 km)
+ ColdStart, //!< Not yet converged from cold start
+ VHLimit, //!< Height or velocity limits exceeded (in accordance with COCOM export licensing restrictions)
+ Variance, //!< Variance exceeds limits
+ Residuals, //!< Residuals are too large
+ DeltaPos, //!< Delta position is too large
+ NegativeVar, //!< Negative variance
+ IntegrityWarning, //!< Large residuals make position unreliable
+ InsInactive, //!< INS has not started yet
+ InsAligning, //!< INS doing its coarse alignment
+ InsBad, //!< INS position is bad
+ ImuUnplugged, //!< No IMU detected
+ Pending, //!< When a FIX POSITION command is entered, the receiver computes its own position and determines if the fixed position is valid
+ InvalidFix, //!< The fixed position, entered using the FIX POSITION command, is not valid
+ UnknownGpsSolutionStatusType
+};
+
+//! Novatel's different fix types; sadly mixed for position/velocity with some INS gear thrown in
+enum GpsPosVelType{
+ None, //!< No solution
+ FixedPos, //!< Position has been fixed by the FIX POSITION command or by position averaging
+ FixedHeight, //!< Position has been fixed by the FIX HEIGHT, or FIX AUTO, command or by position averaging
+ FloatConv, //!< Solution from floating point carrier phase ambiguities
+ WideLane, //!< Solution from wide-lane ambiguities
+ NarrowLane, //!< Solution from narrow-lane ambiguities
+ DopplerVelocity, //!< Velocity computed using instantaneous Doppler
+ Single, //!< Single point position
+ PsrDiff, //!< Pseudorange differential solution
+ Waas, //!< Solution calculated using corrections from an SBAS
+ Propagated, //!< Propagated by a Kalman filter without new observations
+ Omnistar, //!< OmniSTAR VBS position (L1 sub-meter) a
+ L1Float, //!< Floating L1 ambiguity solution
+ IonoFreeFloat, //!< Floating ionospheric-free ambiguity solution
+ NarrowFloat, //!< Floating narrow-lane ambiguity solution
+ L1Int, //!< Integer L1 ambiguity solution
+ WideInt, //!< Integer wide-lane ambiguity solution
+ NarrowInt, //!< Integer narrow-lane ambiguity solution
+ RtkDirectIns, //!< RTK status where the RTK filter is directly initialized from the INS filter. b
+ Ins, //!< INS calculated position corrected for the antenna b
+ InsPsrSp, //!< INS pseudorange single point solution - no DGPS corrections b
+ InsPsrDiff, //!< INS pseudorange differential solution b
+ InsRtkFloat, //!< INS RTK floating point ambiguities solution b
+ InsRtkFixed, //!< INS RTK fixed ambiguities solution b
+ OmniStarHp, //!< OmniSTAR high precision a
+ OmniStarXp, //!< OmniSTAR extra precision a
+ CdGps, //!< Position solution using CDGPS corrections
+ UnknownGpsPosVelType
+};
+
+
+//! possible types GenericData can contain
+enum DataType {
+ //! GenericData is really InsPvaData
+ InsPva,
+ //! GenericData is really BestGpsPosData
+ BestGpsPos,
+ //! GenericData is really BestGpsVelData
+ BestGpsVel,
+ //! GenericData is really RawImuData
+ RawImu
+};
+
+//! Generic (base) type returned by a read
+class GenericData
+{
+ public:
+ virtual ~GenericData(){};
+ virtual DataType type() const=0;
+ virtual std::string toString() const=0;
+ private:
+};
+
+//! INS position/velocity/attitude information
+class InsPvaData : public GenericData {
+ public:
+ DataType type() const {
+ return InsPva;
+ }
+ std::string toString() const{
+ return "implement me!";
+ }
+ int gpsWeekNr; //
+ double secIntoWeek; //
+ double latitude; //[deg] north positive WGS84
+ double longitude; //[deg] east positive WGS84
+ double height; //[m] above ellipsoid WGS84 (heigth_ellipsoid - undulation == height_geoid/AMSL)
+ double northVelocity; //[m/s] south is negative; true north?
+ double eastVelocity; //[m/s] west is negative; true east?
+ double upVelocity; //[m/s] down is negative; geoid/ellipsoid vertical?
+ //The default IMU axis definitions are:
+ // Y - forward
+ // Z - up
+ // X - right hand side
+ double roll; //[degree] right handed rotation from local level around y-axes
+ double pitch; //[degree] right handed rotation from local level around x-axes
+ double azimuth; //[degree] left handed around z-axes rotation from (true?) north clockwise
+
+ StatusMessagetype statusMessageType;
+ std::string statusMessage;
+
+ int timeStampSec; //!< in Computer time, beginning of message at serial port
+ int timeStampUSec; //!< in Computer time, beginning of message at serial port
+};
+
+//! Gps position information
+class BestGpsPosData : public GenericData {
+ public:
+ DataType type() const {
+ return BestGpsPos;
+ }
+ std::string toString() const{
+ return "implement me!";
+ }
+ int gpsWeekNr; //
+ unsigned int msIntoWeek; //milliseconds from beginning of week
+ GpsSolutionStatusType solutionStatus; //
+ GpsPosVelType positionType; //
+ double latitude; //[deg] north positive
+ double longitude; //[deg] east positive
+ double heightAMSL; //[m] AMSL == above mean sea level (geoid)
+ float undulation; //[m] aka geoidal seperation: undulation == heigth_ellipsoid - height_geoid/AMSL
+ unsigned int datumId; //
+ float sigmaLatitude; //[m? deg?] 1 standard deviation error estimate
+ float sigmaLongitude; //[m? deg?] 1 standard deviation error estimate
+ float sigmaHeight; //[m? deg?] 1 standard deviation error estimate
+ char baseStationId[4]; //
+ float diffAge; //[s]
+ float solutionAge; //[s]
+ int numObservations; //number of observations tracked (?) L1 code/carrier/doppler + L2 code/carrier/doppler?
+ int numL1Ranges; //number of L1 ranges used in computation (?)
+ int numL1RangesRTK; //number of L1 ranges above the RTK mask angle (??) number of L1 carrier ranges used?
+ int numL2RangesRTK; //number of L2 ranges above the RTK mask angle (??) number of L2 carrier ranges used?
+
+ StatusMessagetype statusMessageType;
+ std::string statusMessage;
+
+ int timeStampSec; //!< in Computer time, beginning of message at serial port
+ int timeStampUSec; //!< in Computer time, beginning of message at serial port
+};
+
+//! Gps velocity information
+class BestGpsVelData : public GenericData {
+ public:
+ DataType type() const {
+ return BestGpsVel;
+ }
+ std::string toString() const{
+ return "implement me!";
+ }
+ int gpsWeekNr; //
+ unsigned int msIntoWeek; //milliseconds from beginning of week
+ GpsSolutionStatusType solutionStatus; //
+ GpsPosVelType positionType; //
+ float latency; //[s]
+ float diffAge; //[s]
+ double horizontalSpeed; //[m/s]
+ double trackOverGround; //[deg] w respect to true North
+ double verticalSpeed; //[m/s]
+
+ StatusMessagetype statusMessageType;
+ std::string statusMessage;
+
+ int timeStampSec; //!< in Computer time, beginning of message at serial port
+ int timeStampUSec; //!< in Computer time, beginning of message at serial port
+};
+
+//! Raw IMU information
+class RawImuData : public GenericData {
+ public:
+ DataType type() const {
+ return RawImu;
+ }
+ std::string toString() const{
+ return "implement me!";
+ }
+ int gpsWeekNr;
+ double secIntoWeek;
+ double zDeltaV; //!< [m/s] change in speed, up positive
+ double yDeltaV; //!< [m/s] change in speed, forward positive
+ double xDeltaV; //!< [m/s] change in speed, right positive
+ double zDeltaAng; //!< [rad] change in angle, right handed around z
+ double yDeltaAng; //!< [rad] change in angle, right handed around y
+ double xDeltaAng; //!< [rad] change in angle, right handed around x
+
+ StatusMessagetype statusMessageType;
+ std::string statusMessage;
+
+ int timeStampSec; //!< in Computer time, beginning of message at serial port
+ int timeStampUSec; //!< in Computer time, beginning of message at serial port
+};
+
+class Driver {
+public:
+
+ Driver( const Config &cfg, gbxutilacfr::Tracer& tracer);
+ ~Driver();
+
+ //! Blocking read, returns one message
+ //! Throws gbxutilacfr::Exception when a problem is encountered.
+ //!
+ //
+ //! @verbatim
+ //! std::auto_ptr<gbxnovatelacfr::GenericData> data;
+ //!
+ //! try {
+ //! data = device->read();
+ //! }
+ //! catch ( const std::exception& e ) {
+ //! cout <<"Test: Failed to read data: "<<e.what()<<endl;
+ //! }
+ //! if(InsData == data.type()){
+ //! InsData *insData = dynamic_cast<InsData *>(data.get());
+ //! assert(insData);
+ //! //process insData
+ //! }
+ //! @endverbatim
+ //
+ std::auto_ptr<GenericData> read();
+
+private:
+
+ //! establish a serial connection to the receiver
+ int connectToHardware();
+ //! transfer configuration parameters related to the IMU
+ void configureImu();
+ //! transfer configuration parameters related to the INS
+ void configureIns();
+ //! transfer configuration parameters related to GPS
+ void configureGps();
+ //! turn on data messages we are interested in
+ void requestData();
+
+ std::auto_ptr<gbxnovatelutilacfr::ImuDecoder> imuDecoder_;
+
+ std::auto_ptr<gbxserialacfr::Serial> serial_;
+ int baud_;
+
+ Config config_;
+ gbxutilacfr::Tracer& tracer_;
+};
+
+
+} // namespace
+#endif
Added: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/CMakeLists.txt
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/CMakeLists.txt (rev 0)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/CMakeLists.txt 2008-06-18 07:53:46 UTC (rev 183)
@@ -0,0 +1,34 @@
+SET( lib_name GbxNovatelUtilAcfr )
+GBX_ADD_LICENSE( LGPL )
+
+SET( build TRUE )
+# don't give user an option
+# GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )
+
+# this was already tested in the dir above
+# GBX_REQUIRE_VAR( build LIB ${lib_name} GBX_OS_LINUX "only Linux OS is supported" )
+
+# this was already tested in the dir above
+# INCLUDE( ${GBX_CMAKE_DIR}/FindIceUtil.cmake )
+# GBX_REQUIRE_VAR( build LIB ${lib_name} ICEUTIL_FOUND "libIceUtil not found" )
+
+IF( build )
+
+ INCLUDE( ${GBX_CMAKE_DIR}/UseBasicRules.cmake )
+
+ FILE( GLOB hdrs *.h )
+ FILE( GLOB srcs *.cpp )
+
+ # for config.h
+ INCLUDE_DIRECTORIES( ${PROJECT_BINARY_DIR} )
+
+ GBX_ADD_LIBRARY( ${lib_name} SHARED ${srcs} )
+ TARGET_LINK_LIBRARIES( ${lib_name} ${dep_libs} )
+
+ GBX_ADD_HEADERS( gbxnovatelacfr/gbxnovatelutilacfr ${hdrs} )
+
+ IF( GBX_BUILD_TESTS )
+ ADD_SUBDIRECTORY( test )
+ ENDIF( GBX_BUILD_TESTS )
+
+ENDIF( build )
Added: gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp
===================================================================
--- gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp (rev 0)
+++ gearbox/trunk/submitted/gbxnovatelacfr/gbxnovatelutilacfr/crc32.cpp 2008-06-18 07:53:46 UTC (rev 183)
@@ -0,0 +1,106 @@
+#include "crc32.h"
+
+////////////////////////////////////////////
+// I didn't use the implementation in the Novatel manuals. Reasons:
+// -makes assumptions that probably break for 64bit
+// -looks a bit akward
+// -potential copyright problem
+// -slow
+// Implementation adapted from here: http://www.ross.net/crc/download/crc_v3.txt (point 18)
+// This is also a good explanation of how crcs work.
+// Tested extensively against the Novatel implementation and for false positives/negatives.
+//
+// Code used to produce the crcLookup table:
+////////////////////////////////////////////
+//
+// CRC32Value() and CRC32_POLYNOMIAL are copied from:
+// OEMV Family Firmware Version 3.210 Reference Manual Rev 5, page 29
+// Types were adjusted to reflect actual size used (int -> uint8_t; unsigned long --> uint32_t).
+//
+// #define CRC32_POLYNOMIAL 0xEDB88320L
+// /* --------------------------------------------------------------------------
+// * Calculate a CRC value to be used by CRC calculation functions.
+// * -------------------------------------------------------------------------- */
+// uint32_t CRC32Value(uint8_t i)
+// {
+// int j;
+// uint32_t ulCRC;
+// ulCRC = i;
+// for ( j = 8 ; j > 0; j-- )
+// {
+// if ( ulCRC & 1 )
+// ulCRC = ( ulCRC >> 1 ) ^ CRC32_POLYNOMIAL;
+// else
+// ulCRC >>= 1;
+// }
+// return ulCRC;
+// }
+//
+// int main(void){
+// for (int i=0; i<256; i++){
+// uint32_t tmp = CRC32Value(i);
+// if(0==i%6){
+// printf("\n");
+// }else{
+// printf(" ");
+// }
+// printf("0x%08xL,", tmp);
+// }
+// return EXIT_SUCCESS;
+// }
+namespace gbxnovatelutilacfr {
+static const uint32_t crcTable[256] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL,
+ 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
+ 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L,
+ 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
+ 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
+ 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL,
+ 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
+ 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L,
+ 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L,
+ 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
+ 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL,
+ 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
+ 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
+ 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L,
+ 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
+ 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL,
+ 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L,
+ 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
+ 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L,
+ 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
+ 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
+ 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL,
+ 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
+ 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L,
+ 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4...
[truncated message content] |