[Positioning] Add class Timestamp
Add a class Timestamp that boxes the structure timespec from <ctime>. timespec manipulation functions are removed from PosUtil.
This commit is contained in:
parent
0bce0ad2bd
commit
b921263795
|
@ -31,9 +31,10 @@ LIBS = -lpq -lboost_program_options-mt
|
|||
|
||||
TARGET = owlps-positioning
|
||||
#HEADER = owlps-positioning.hh
|
||||
OBJ = posutil.o point3d.o referencepoint.o waypoint.o building.o \
|
||||
area.o wifidevice.o accesspoint.o mobile.o measurement.o \
|
||||
calibrationmeasurement.o request.o inputcsv.o stock.o
|
||||
OBJ = posutil.o stock.o timestamp.o point3d.o referencepoint.o \
|
||||
waypoint.o building.o area.o wifidevice.o accesspoint.o \
|
||||
mobile.o measurement.o calibrationmeasurement.o request.o \
|
||||
inputcsv.o
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
|
@ -48,6 +49,7 @@ $(TEST_DIR)/%_test.o: %.o
|
|||
|
||||
posutil.o: posutil.hh
|
||||
stock.o: stock.hh
|
||||
timestamp.o: timestamp.hh
|
||||
point3d.o: point3d.hh
|
||||
referencepoint.o : referencepoint.hh point3d.o
|
||||
waypoint.o: waypoint.hh point3d.o building.o
|
||||
|
@ -58,7 +60,7 @@ accesspoint.o: accesspoint.hh wifidevice.o point3d.o
|
|||
mobile.o: mobile.hh wifidevice.o
|
||||
measurement.o: measurement.hh accesspoint.o
|
||||
calibrationmeasurement.o: calibrationmeasurement.hh measurement.o referencepoint.o
|
||||
request.o: request.hh measurement.o
|
||||
request.o: request.hh timestamp.o measurement.o
|
||||
inputcsv.o: inputcsv.hh inputmedium.hh request.o stock.o
|
||||
#libowlps-positioning.o: libowlps-positioning.hh
|
||||
#positioning.o: point.hh referencepoint.hh accesspoint.hh area.hh measurement.hh libowlps-positioning.hh
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
|
||||
- Timestamp
|
||||
Faire une classe Timestamp qui englobe struct timespec et les
|
||||
méthodes de PosUtil associées.
|
||||
|
||||
- InputCSV
|
||||
° Différencier une requête normale d'une requête de calibration, en
|
||||
utilisant les champs de direction.
|
||||
|
@ -29,9 +25,6 @@
|
|||
les Waypoint. Si oui, faut-il aussi les enlever des listes dans
|
||||
Stock ? (Pour l'instant ils ne sont pas dans Stock.)
|
||||
|
||||
- PosUtil
|
||||
Remplacer timespec_equals() par operator==(timespec, timespec) ?
|
||||
|
||||
- AccessPoint
|
||||
Attribut float friis_index ?
|
||||
|
||||
|
@ -47,3 +40,8 @@
|
|||
Réserver l'espace mémoire des vector avec reserve(). 217
|
||||
Utiliser hash_map plutôt que map s'il n'y a pas besoin de trier. 252
|
||||
Copie de conteneur vers un flux (cas de certains operator<<). 275
|
||||
|
||||
- Timestamp
|
||||
Dans les tests, il y a une probabilité de 1/1000000 que la valeur
|
||||
en ns et la valeur arrondie en ms soient identiques. Dans ce cas,
|
||||
certains tests peuvent échouer.
|
||||
|
|
|
@ -151,7 +151,7 @@ const Request& InputCSV::get_next_request()
|
|||
}
|
||||
try
|
||||
{
|
||||
current_request.set_timestamp(PosUtil::ms_to_timespec
|
||||
current_request.set_timestamp(Timestamp
|
||||
(lexical_cast<uint64_t>(*ti))) ;
|
||||
}
|
||||
catch (bad_lexical_cast &e)
|
||||
|
|
|
@ -58,44 +58,3 @@ unsigned int PosUtil::channel_to_frequency(const int &channel)
|
|||
|
||||
return 0 ; // Error: wrong channel value
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* d.tv_nsec precision is set to ms, but the value is still in ns.
|
||||
* @param d The date to round.
|
||||
*/
|
||||
void PosUtil::timespec_round_to_ms(struct timespec &d)
|
||||
{
|
||||
d.tv_nsec = d.tv_nsec / 1000000 * 1000000 ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return \em true if the two dates are equals.
|
||||
* @return \em false if they are different.
|
||||
*/
|
||||
bool PosUtil::timespec_equals(const struct timespec &d1,
|
||||
const struct timespec &d2)
|
||||
{
|
||||
return
|
||||
d1.tv_sec == d2.tv_sec &&
|
||||
d1.tv_nsec == d2.tv_nsec ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint64_t PosUtil::timespec_to_ms(const struct timespec &d)
|
||||
{
|
||||
return d.tv_sec * 1000 + d.tv_nsec / 1000000 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct timespec PosUtil::ms_to_timespec(const uint64_t &tms)
|
||||
{
|
||||
struct timespec d ;
|
||||
d.tv_sec = tms / 1000 ;
|
||||
d.tv_nsec = (tms - d.tv_sec * 1000) * 1000000 ;
|
||||
return d ;
|
||||
}
|
||||
|
|
|
@ -29,19 +29,6 @@ public:
|
|||
/// Converts a Wi-Fi channel to the corresponding frequency in Hz
|
||||
static unsigned int channel_to_frequency(const int &channel) ;
|
||||
//@}
|
||||
|
||||
/** @name Time & Dates */
|
||||
//@{
|
||||
/// Lowers the precision of a \em timespec to ms
|
||||
static void timespec_round_to_ms(struct timespec &d) ;
|
||||
/// Compares two struct timespec
|
||||
static bool timespec_equals(const struct timespec &d1,
|
||||
const struct timespec &d2) ;
|
||||
/// Converts a struct timespec into a value in milliseconds
|
||||
static uint64_t timespec_to_ms(const struct timespec &d) ;
|
||||
/// Converts a time value in milliseconds into a struct timespec
|
||||
static struct timespec ms_to_timespec(const uint64_t &tms) ;
|
||||
//@}
|
||||
} ;
|
||||
|
||||
#endif // _OWLPS_POSITIONING_POSUTIL_HH_
|
||||
|
|
|
@ -12,13 +12,11 @@ using std::tr1::unordered_map ;
|
|||
Request::Request(const unordered_map<string, Measurement> &_measurements)
|
||||
{
|
||||
mobile = NULL ;
|
||||
timestamp.tv_sec = 0 ;
|
||||
timestamp.tv_nsec = 0 ;
|
||||
measurements = _measurements ;
|
||||
}
|
||||
|
||||
|
||||
Request::Request(const struct timespec &_timestamp,
|
||||
Request::Request(const Timestamp &_timestamp,
|
||||
const unordered_map<string, Measurement> &_measurements)
|
||||
{
|
||||
mobile = NULL ;
|
||||
|
@ -27,7 +25,7 @@ Request::Request(const struct timespec &_timestamp,
|
|||
}
|
||||
|
||||
|
||||
Request::Request(const Mobile *_mobile, const struct timespec &_timestamp,
|
||||
Request::Request(const Mobile *_mobile, const Timestamp &_timestamp,
|
||||
const unordered_map<string, Measurement> &_measurements)
|
||||
{
|
||||
mobile = const_cast<Mobile*>(_mobile) ;
|
||||
|
@ -66,8 +64,7 @@ Request::~Request()
|
|||
void Request::clear()
|
||||
{
|
||||
mobile = NULL ;
|
||||
timestamp.tv_sec = 0 ;
|
||||
timestamp.tv_nsec = 0 ;
|
||||
timestamp.set_timestamp_ms(0) ;
|
||||
measurements.clear() ;
|
||||
}
|
||||
|
||||
|
@ -96,7 +93,7 @@ bool Request::operator==(const Request &comp) const
|
|||
|
||||
return
|
||||
mobile == comp.mobile &&
|
||||
PosUtil::timespec_equals(timestamp, comp.timestamp) &&
|
||||
timestamp == comp.timestamp &&
|
||||
measurements == comp.measurements ;
|
||||
}
|
||||
|
||||
|
@ -106,7 +103,7 @@ ostream &operator<<(ostream &os, const Request &r)
|
|||
{
|
||||
// Timestamp
|
||||
os
|
||||
<< "At " << PosUtil::timespec_to_ms(r.timestamp) << "; " ;
|
||||
<< "At " << r.timestamp << "; " ;
|
||||
|
||||
// MAC address
|
||||
os
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
class Mobile ;
|
||||
|
||||
#include "measurement.hh"
|
||||
#include "timestamp.hh"
|
||||
|
||||
#include <ctime>
|
||||
#include <boost/tr1/unordered_map.hpp>
|
||||
|
@ -16,7 +17,7 @@ protected:
|
|||
/// The mobile that sent the request
|
||||
Mobile *mobile ;
|
||||
/// Local date of the request on the mobile
|
||||
struct timespec timestamp ;
|
||||
Timestamp timestamp ;
|
||||
/// List of Measurement of the request
|
||||
/** Note that this is not a pointer list, values are actually stored.
|
||||
The \em string parameter is the MAC address of the AP. */
|
||||
|
@ -27,12 +28,12 @@ public:
|
|||
Request(const std::tr1::unordered_map<std::string, Measurement> &_measurements
|
||||
= std::tr1::unordered_map<std::string, Measurement>()) ;
|
||||
/// Constructs a Request from a timestamp and (possibly) a Measurement list
|
||||
Request(const struct timespec &_timestamp,
|
||||
Request(const Timestamp &_timestamp,
|
||||
const std::tr1::unordered_map<std::string, Measurement> &_measurements
|
||||
= std::tr1::unordered_map<std::string, Measurement>()) ;
|
||||
/// \brief Constructs a request from a mobile and a timestamp and (possibly)
|
||||
/// a Measurement list
|
||||
Request(const Mobile *_mobile, const struct timespec &_timestamp,
|
||||
Request(const Mobile *_mobile, const Timestamp &_timestamp,
|
||||
const std::tr1::unordered_map<std::string, Measurement> &_measurements
|
||||
= std::tr1::unordered_map<std::string, Measurement>()) ;
|
||||
/// Copy constructor
|
||||
|
@ -45,7 +46,7 @@ public:
|
|||
/// #mobile read accessor
|
||||
Mobile* get_mobile(void) const ;
|
||||
/// #timestamp read accessor
|
||||
const struct timespec& get_timestamp(void) const ;
|
||||
const Timestamp& get_timestamp(void) const ;
|
||||
/// #measurements read accessor
|
||||
const std::tr1::unordered_map<std::string, Measurement>&
|
||||
get_measurements(void) const ;
|
||||
|
@ -56,7 +57,7 @@ public:
|
|||
/// #mobile write accessor
|
||||
void set_mobile(const Mobile *_mobile) ;
|
||||
/// #timestamp write accessor
|
||||
void set_timestamp(const struct timespec &_timestamp) ;
|
||||
void set_timestamp(const Timestamp &_timestamp) ;
|
||||
/// #measurements write accessor
|
||||
void set_measurements(const std::tr1::unordered_map
|
||||
<std::string, Measurement> &_measurements) ;
|
||||
|
@ -87,7 +88,7 @@ inline Mobile* Request::get_mobile() const
|
|||
}
|
||||
|
||||
|
||||
inline const struct timespec& Request::get_timestamp() const
|
||||
inline const Timestamp& Request::get_timestamp() const
|
||||
{
|
||||
return timestamp ;
|
||||
}
|
||||
|
@ -110,7 +111,7 @@ inline void Request::set_mobile(const Mobile *_mobile)
|
|||
}
|
||||
|
||||
|
||||
inline void Request::set_timestamp(const struct timespec &_timestamp)
|
||||
inline void Request::set_timestamp(const Timestamp &_timestamp)
|
||||
{
|
||||
timestamp = _timestamp ;
|
||||
}
|
||||
|
@ -141,7 +142,7 @@ inline Request::operator bool() const
|
|||
{
|
||||
return
|
||||
mobile != NULL ||
|
||||
timestamp.tv_sec != 0 ||
|
||||
timestamp.get_timestamp_ms() != 0 ||
|
||||
measurements.size() > 0 ;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ aa:bb:cc:dd:ee:77;1265120911234;0.00;0.00;0.00;0\
|
|||
request1 = inputcsv1.get_next_request() ;
|
||||
TS_ASSERT_EQUALS(request1.get_mobile()->get_mac_addr(),
|
||||
"aa:bb:cc:dd:ee:ff") ;
|
||||
TS_ASSERT_EQUALS(PosUtil::timespec_to_ms(request1.get_timestamp()),
|
||||
TS_ASSERT_EQUALS(request1.get_timestamp().get_timestamp_ms(),
|
||||
1265120910725llu) ;
|
||||
|
||||
measurements[aps[0].get_mac_addr()].add_ss(-58) ;
|
||||
|
@ -144,7 +144,7 @@ aa:bb:cc:dd:ee:77;1265120911234;0.00;0.00;0.00;0\
|
|||
request1 = inputcsv1.get_next_request() ;
|
||||
TS_ASSERT_EQUALS(request1.get_mobile()->get_mac_addr(),
|
||||
"aa:bb:cc:dd:ee:77") ;
|
||||
TS_ASSERT_EQUALS(PosUtil::timespec_to_ms(request1.get_timestamp()),
|
||||
TS_ASSERT_EQUALS(request1.get_timestamp().get_timestamp_ms(),
|
||||
1265120911234llu) ;
|
||||
|
||||
measurements.clear() ;
|
||||
|
@ -173,7 +173,7 @@ aa:bb:cc:dd:ee:77;1265120911234;0.00;0.00;0.00;0\
|
|||
request1 = inputcsv1.get_next_request() ;
|
||||
TS_ASSERT_EQUALS(request1.get_mobile()->get_mac_addr(),
|
||||
"aa:bb:cc:dd:ee:ff") ;
|
||||
TS_ASSERT_EQUALS(PosUtil::timespec_to_ms(request1.get_timestamp()),
|
||||
TS_ASSERT_EQUALS(request1.get_timestamp().get_timestamp_ms(),
|
||||
1265120912345llu) ;
|
||||
|
||||
measurements.clear() ;
|
||||
|
|
|
@ -20,48 +20,4 @@ public:
|
|||
PosUtil::channel_to_frequency(i) <= 2477) ;
|
||||
}
|
||||
|
||||
void test_time(void)
|
||||
{
|
||||
// Zero tests
|
||||
struct timespec ts1 ;
|
||||
ts1.tv_sec = 0 ;
|
||||
ts1.tv_nsec = 0 ;
|
||||
uint64_t msec = 0 ; // ms time value
|
||||
struct timespec ts2 = PosUtil::ms_to_timespec(msec) ;
|
||||
TS_ASSERT(PosUtil::timespec_equals(ts1, ts2)) ;
|
||||
TS_ASSERT_EQUALS(PosUtil::timespec_to_ms(ts1), msec) ;
|
||||
|
||||
// Non-zero tests
|
||||
uint64_t sec = 1234567 ;
|
||||
uint64_t nsec = 891234567 ; // Do not put a value >= 1 sec. for the test!
|
||||
ts1.tv_sec = sec ;
|
||||
ts1.tv_nsec = nsec ;
|
||||
msec = sec * 1000 + nsec / 1000000 ;
|
||||
TS_ASSERT_EQUALS(PosUtil::timespec_to_ms(ts1), msec) ;
|
||||
ts2 = PosUtil::ms_to_timespec(msec) ;
|
||||
TS_ASSERT_EQUALS(PosUtil::timespec_to_ms(ts2), msec) ;
|
||||
|
||||
// timespec_round_to_ms()
|
||||
struct timespec ts3 = ts1 ;
|
||||
PosUtil::timespec_round_to_ms(ts1) ;
|
||||
TS_ASSERT_EQUALS(ts1.tv_sec, ts3.tv_sec) ;
|
||||
TS_ASSERT_EQUALS(ts1.tv_nsec, ts3.tv_nsec / 1000000 * 1000000) ;
|
||||
TS_ASSERT(PosUtil::timespec_equals(ts1, ts2)) ;
|
||||
|
||||
// Current time test
|
||||
struct timespec current_time ;
|
||||
if (clock_gettime(CLOCK_REALTIME, ¤t_time))
|
||||
TS_FAIL("Error calling clock_gettime()!") ;
|
||||
else
|
||||
{
|
||||
ts1 = current_time ;
|
||||
PosUtil::timespec_round_to_ms(current_time) ;
|
||||
TS_ASSERT(! PosUtil::timespec_equals(current_time, ts1)) ;
|
||||
msec = PosUtil::timespec_to_ms(current_time) ;
|
||||
ts2 = PosUtil::ms_to_timespec(msec) ;
|
||||
TS_ASSERT_EQUALS(PosUtil::timespec_to_ms(ts2), msec) ;
|
||||
TS_ASSERT(PosUtil::timespec_equals(current_time, ts2)) ;
|
||||
}
|
||||
}
|
||||
|
||||
} ;
|
||||
|
|
|
@ -30,16 +30,16 @@ public:
|
|||
void test_accessors(void)
|
||||
{
|
||||
// Simple read accessors
|
||||
struct timespec current_time ;
|
||||
Timestamp current_time ;
|
||||
current_time.now() ;
|
||||
AccessPoint ap1(Point3D(1,2,3), "192.168.0.1", "aa:bb:cc:dd:ee:ff") ;
|
||||
Measurement meas1(&ap1) ;
|
||||
std::tr1::unordered_map<std::string, Measurement> measurements ;
|
||||
measurements["aa:bb:cc:dd:ee:ff"] = meas1 ;
|
||||
clock_gettime(CLOCK_REALTIME, ¤t_time) ;
|
||||
Mobile mob1 ;
|
||||
Request r1(&mob1, current_time, measurements) ;
|
||||
TS_ASSERT_EQUALS(r1.get_mobile(), &mob1) ;
|
||||
TS_ASSERT(PosUtil::timespec_equals(r1.get_timestamp(), current_time)) ;
|
||||
TS_ASSERT_EQUALS(r1.get_timestamp(), current_time) ;
|
||||
//TS_ASSERT_EQUALS(r1.get_measurements(), measurements) ;
|
||||
|
||||
// Write & read accessors
|
||||
|
@ -47,9 +47,9 @@ public:
|
|||
r1.set_mobile(&mob2) ;
|
||||
TS_ASSERT_EQUALS(r1.get_mobile(), &mob2) ;
|
||||
|
||||
current_time.tv_sec += 10 ;
|
||||
current_time.set_timestamp_ms(current_time.get_timestamp_ms() + 10) ;
|
||||
r1.set_timestamp(current_time) ;
|
||||
TS_ASSERT(PosUtil::timespec_equals(r1.get_timestamp(), current_time)) ;
|
||||
TS_ASSERT_EQUALS(r1.get_timestamp(), current_time) ;
|
||||
|
||||
AccessPoint ap2(Point3D(3,2,1), "192.168.0.2", "aa:bb:cc:dd:ee:02") ;
|
||||
Measurement meas2(&ap2) ;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "timestamp.hh"
|
||||
|
||||
|
||||
// Allows to test equality of two struct timespec
|
||||
bool operator==(const struct timespec &d1,
|
||||
const struct timespec &d2)
|
||||
{
|
||||
return
|
||||
d1.tv_sec == d2.tv_sec &&
|
||||
d1.tv_nsec == d2.tv_nsec ;
|
||||
}
|
||||
|
||||
|
||||
class Timestamp_test: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
|
||||
void test_zero(void)
|
||||
{
|
||||
// Default constructor
|
||||
Timestamp timestamp1 ;
|
||||
|
||||
// struct timespec constructor
|
||||
struct timespec timespec1 ;
|
||||
timespec1.tv_sec = 0 ;
|
||||
timespec1.tv_nsec = 0 ;
|
||||
Timestamp timestamp2(timespec1) ;
|
||||
TS_ASSERT_EQUALS(timestamp1, timestamp2) ;
|
||||
|
||||
// ms constructor
|
||||
uint64_t msec = 0 ; // ms time value
|
||||
Timestamp timestamp3(msec) ;
|
||||
TS_ASSERT_EQUALS(timestamp1, timestamp3) ;
|
||||
|
||||
// Read accessors
|
||||
TS_ASSERT_EQUALS(timestamp1.get_timestamp(), timespec1) ;
|
||||
TS_ASSERT_EQUALS(timestamp1.get_timestamp_ms(), msec) ;
|
||||
}
|
||||
|
||||
void test_non_zero(void)
|
||||
{
|
||||
uint64_t sec = 1234567 ;
|
||||
uint64_t nsec = 891234567 ; // Do not put a value >= 1 sec. for the test!
|
||||
uint64_t msec = sec * 1000 + nsec / 1000000 ;
|
||||
struct timespec timespec1 ;
|
||||
timespec1.tv_sec = sec ;
|
||||
timespec1.tv_nsec = nsec ;
|
||||
|
||||
// struct timespec constructor
|
||||
Timestamp timestamp1(timespec1) ;
|
||||
timespec1.tv_nsec = nsec / 1000000 * 1000000 ; // Round to ms
|
||||
TS_ASSERT_EQUALS(timestamp1.get_timestamp(), timespec1) ;
|
||||
TS_ASSERT_EQUALS(timestamp1.get_timestamp_ms(), msec) ;
|
||||
|
||||
// ms constructor
|
||||
Timestamp timestamp2(msec) ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), timespec1) ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
|
||||
TS_ASSERT_EQUALS(timestamp1, timestamp2) ;
|
||||
}
|
||||
|
||||
void test_current_time(void)
|
||||
{
|
||||
Timestamp timestamp1 ;
|
||||
struct timespec current_time ;
|
||||
|
||||
if (! timestamp1.now() ||
|
||||
clock_gettime(CLOCK_REALTIME, ¤t_time))
|
||||
{
|
||||
TS_FAIL("Error getting current time!") ;
|
||||
return ;
|
||||
}
|
||||
|
||||
Timestamp timestamp2(current_time) ;
|
||||
|
||||
TS_ASSERT_DELTA(timestamp1.get_timestamp_ms(),
|
||||
timestamp2.get_timestamp_ms(),
|
||||
100) ;
|
||||
|
||||
// The following tests may fail if the ns value is a ms
|
||||
TS_ASSERT_DIFFERS(timestamp1.get_timestamp(), current_time) ;
|
||||
TS_ASSERT_DIFFERS(timestamp2.get_timestamp(), current_time) ;
|
||||
}
|
||||
|
||||
void test_accessors(void)
|
||||
{
|
||||
struct timespec current_time ;
|
||||
if (clock_gettime(CLOCK_REALTIME, ¤t_time))
|
||||
{
|
||||
TS_FAIL("Error calling clock_gettime()!") ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// struct timespec constructor
|
||||
Timestamp timestamp1(current_time) ;
|
||||
TS_ASSERT_DIFFERS(timestamp1.get_timestamp(), current_time) ;
|
||||
|
||||
// ms constructor
|
||||
current_time.tv_nsec = current_time.tv_nsec / 1000000 * 1000000 ;
|
||||
uint64_t msec = timestamp1.get_timestamp_ms() ;
|
||||
Timestamp timestamp2(msec) ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), current_time) ;
|
||||
|
||||
// Accessors
|
||||
++current_time.tv_sec ;
|
||||
timestamp2.set_timestamp(current_time) ;
|
||||
TS_ASSERT_DIFFERS(timestamp1, timestamp2) ;
|
||||
msec = timestamp2.get_timestamp_ms() ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), current_time) ;
|
||||
|
||||
msec = 1234567891234567ull ;
|
||||
timestamp2.set_timestamp_ms(msec) ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
|
||||
current_time = timestamp2.get_timestamp() ;
|
||||
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), current_time) ;
|
||||
}
|
||||
|
||||
} ;
|
|
@ -0,0 +1,136 @@
|
|||
#include "timestamp.hh"
|
||||
|
||||
|
||||
|
||||
/* *** Constructors *** */
|
||||
|
||||
|
||||
Timestamp::Timestamp()
|
||||
{
|
||||
timestamp.tv_sec = 0 ;
|
||||
timestamp.tv_nsec = 0 ;
|
||||
}
|
||||
|
||||
|
||||
Timestamp::Timestamp(const struct timespec &source)
|
||||
{
|
||||
set_timestamp(source) ;
|
||||
round_to_ms() ;
|
||||
}
|
||||
|
||||
|
||||
Timestamp::Timestamp(const uint64_t source_ms)
|
||||
{
|
||||
set_timestamp_ms(source_ms) ;
|
||||
}
|
||||
|
||||
|
||||
Timestamp::Timestamp(const Timestamp &source)
|
||||
{
|
||||
timestamp.tv_sec = source.timestamp.tv_sec ;
|
||||
timestamp.tv_nsec = source.timestamp.tv_nsec ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Read accessors *** */
|
||||
|
||||
|
||||
uint64_t Timestamp::get_timestamp_ms(void) const
|
||||
{
|
||||
return timestamp.tv_sec * 1000 + timestamp.tv_nsec / 1000000 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Write accessors *** */
|
||||
|
||||
|
||||
void Timestamp::set_timestamp_ms(const uint64_t source_ms)
|
||||
{
|
||||
timestamp.tv_sec = source_ms / 1000 ;
|
||||
timestamp.tv_nsec = (source_ms - timestamp.tv_sec * 1000) * 1000000 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Operations *** */
|
||||
|
||||
|
||||
bool Timestamp::now_ns()
|
||||
{
|
||||
if (clock_gettime(CLOCK_REALTIME, ×tamp))
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* #timestamp nanosecond field precision is set to ms, but the value
|
||||
* is still in ns.
|
||||
*/
|
||||
void Timestamp::round_to_ms()
|
||||
{
|
||||
timestamp.tv_nsec = timestamp.tv_nsec / 1000000 * 1000000 ;
|
||||
}
|
||||
|
||||
|
||||
bool Timestamp::now()
|
||||
{
|
||||
if (! now_ns())
|
||||
return false ;
|
||||
|
||||
round_to_ms() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Operators *** */
|
||||
|
||||
|
||||
const Timestamp& Timestamp::operator=(const Timestamp &source)
|
||||
{
|
||||
if (this == &source)
|
||||
return *this ;
|
||||
|
||||
timestamp.tv_sec = source.timestamp.tv_sec ;
|
||||
timestamp.tv_nsec = source.timestamp.tv_nsec ;
|
||||
|
||||
return *this ;
|
||||
}
|
||||
|
||||
|
||||
bool Timestamp::operator==(const Timestamp &source) const
|
||||
{
|
||||
if (this == &source)
|
||||
return true ;
|
||||
|
||||
return
|
||||
timestamp.tv_sec == source.timestamp.tv_sec &&
|
||||
timestamp.tv_nsec == source.timestamp.tv_nsec ;
|
||||
}
|
||||
|
||||
|
||||
bool Timestamp::operator<(const Timestamp &source) const
|
||||
{
|
||||
if (timestamp.tv_sec < source.timestamp.tv_sec)
|
||||
return true ;
|
||||
|
||||
if (timestamp.tv_sec > source.timestamp.tv_sec)
|
||||
return false ;
|
||||
|
||||
// Second values are equal
|
||||
if (timestamp.tv_nsec < source.timestamp.tv_nsec)
|
||||
return true ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream &os, const Timestamp &t)
|
||||
{
|
||||
os << t.get_timestamp_ms() ;
|
||||
return os ;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
#ifndef _OWLPS_POSITIONING_TIMESTAMP_HH_
|
||||
#define _OWLPS_POSITIONING_TIMESTAMP_HH_
|
||||
|
||||
#include <ctime>
|
||||
#include <stdint.h> // <cstdint> is not C++ 98 compliant
|
||||
#include <ostream>
|
||||
|
||||
/// Represents a timestamp with a millisecond precision
|
||||
/**
|
||||
* This class boxes <em>struct timespec</em> from <ctime> to integrate
|
||||
* time manipulation functions.
|
||||
*/
|
||||
class Timestamp
|
||||
{
|
||||
protected:
|
||||
/// Time data
|
||||
struct timespec timestamp ;
|
||||
|
||||
/** @name Operations */
|
||||
//@{
|
||||
/// \brief Initialises #timestamp at the current time whith a
|
||||
/// nanosecond precision
|
||||
bool now_ns(void) ;
|
||||
/// Lowers the precision of #timestamp to ms
|
||||
void round_to_ms(void) ;
|
||||
//@}
|
||||
|
||||
|
||||
public:
|
||||
/// Default constructor
|
||||
Timestamp(void) ;
|
||||
/// Constructs a Timestamp from a struct timespec
|
||||
Timestamp(const struct timespec &source) ;
|
||||
/// Constructs a Timsestamp from a value in milliseconds
|
||||
Timestamp(const uint64_t source_ms) ;
|
||||
/// Copy constructor
|
||||
Timestamp(const Timestamp &source) ;
|
||||
|
||||
~Timestamp(void) {} ///< Destructor (do nothing)
|
||||
|
||||
/** @name Read accessors */
|
||||
//@{
|
||||
/// #timestamp read accessor
|
||||
const struct timespec& get_timestamp(void) const ;
|
||||
/// Get the #timestamp in milliseconds
|
||||
uint64_t get_timestamp_ms(void) const ;
|
||||
//@}
|
||||
|
||||
/** @name Write accessors */
|
||||
//@{
|
||||
/// #timestamp write accessor
|
||||
void set_timestamp(const struct timespec &source) ;
|
||||
/// #timestamp write accessor with a value in milliseconds
|
||||
void set_timestamp_ms(const uint64_t source_ms) ;
|
||||
//@}
|
||||
|
||||
/** @name Operations */
|
||||
//@{
|
||||
/// \brief Initialises #timestamp to the current time with a
|
||||
/// millisecond precision
|
||||
bool now(void) ;
|
||||
//@}
|
||||
|
||||
/** @name Operators */
|
||||
//@{
|
||||
const Timestamp& operator=(const Timestamp &source) ;
|
||||
bool operator==(const Timestamp &source) const ;
|
||||
bool operator!=(const Timestamp &source) const ;
|
||||
bool operator<(const Timestamp &source) const ;
|
||||
bool operator>(const Timestamp &source) const ;
|
||||
bool operator<=(const Timestamp &source) const ;
|
||||
bool operator>=(const Timestamp &source) const ;
|
||||
//@}
|
||||
|
||||
/// Display a Timestamp
|
||||
friend std::ostream& operator<<(std::ostream &os, const Timestamp &t) ;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
/* *** Read accessors *** */
|
||||
|
||||
|
||||
inline const struct timespec& Timestamp::get_timestamp() const
|
||||
{
|
||||
return timestamp ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Write accessors *** */
|
||||
|
||||
|
||||
inline void Timestamp::set_timestamp(const struct timespec &source)
|
||||
{
|
||||
timestamp = source ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Operators *** */
|
||||
|
||||
|
||||
inline bool Timestamp::operator!=(const Timestamp &source) const
|
||||
{
|
||||
return !(*this == source) ;
|
||||
}
|
||||
|
||||
|
||||
inline bool Timestamp::operator>(const Timestamp &source) const
|
||||
{
|
||||
return source < *this ;
|
||||
}
|
||||
|
||||
|
||||
inline bool Timestamp::operator<=(const Timestamp &source) const
|
||||
{
|
||||
return *this == source || *this < source ;
|
||||
}
|
||||
|
||||
|
||||
inline bool Timestamp::operator>=(const Timestamp &source) const
|
||||
{
|
||||
return source <= *this ;
|
||||
}
|
||||
|
||||
|
||||
#endif // _OWLPS_POSITIONING_TIMESTAMP_HH_
|
Loading…
Reference in New Issue