[Positioner] Handle the packet numbering

In Measurement, the SSs are now stored in a map (instead of a vector),
along with their packet IDs.
This commit is contained in:
Matteo Cypriani 2011-10-28 17:13:04 +02:00
parent 5ab5b4f22f
commit 1533852a1f
10 changed files with 156 additions and 87 deletions

View File

@ -56,8 +56,8 @@ bool InputCSV::fill_current_request()
current_request->set_mobile(&mobile) ;
// Read request type
uint8_t type ;
uint16_t type_r ;
uint_fast8_t type ;
uint_fast16_t type_r ;
if (! file.read_field(type_r))
{
// Wrong number of fields
@ -68,6 +68,17 @@ bool InputCSV::fill_current_request()
type = type_r ;
current_request->set_type(type) ;
// Read the number of packets
uint_fast16_t nb_packets ;
if (! file.read_field(nb_packets))
{
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read the number of packets.\n" ;
return false ;
}
current_request->set_nb_packets(nb_packets) ;
// Read Timestamp field
Timestamp timestamp ;
if (! file.read_timestamp(timestamp))
@ -108,12 +119,21 @@ bool InputCSV::fill_current_request()
string mac_ap ;
while (file.read_field(mac_ap))
{
int ss ;
uint_fast16_t packet_id ;
if (! file.read_field(packet_id))
{
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read the packet ID.\n" ;
return false ;
}
int_fast16_t ss ;
if (! file.read_field(ss))
{
// Wrong number of fields
if (Configuration::is_configured("verbose"))
cerr << "InputCSV: cannot read mac_ap.\n" ;
cerr << "InputCSV: cannot read the signal strength.\n" ;
return false ;
}
PosUtil::to_upper(mac_ap) ;
@ -124,7 +144,7 @@ bool InputCSV::fill_current_request()
const AccessPoint &ap = Stock::find_create_ap(mac_ap) ;
measurements[mac_ap].set_ap(&ap) ;
measurements[mac_ap].add_ss(ss) ;
measurements[mac_ap].add_ss(packet_id, ss) ;
}
if (measurements.empty())
return false ;

View File

@ -16,7 +16,8 @@
/// Reads \link Request requests \endlink from a CSV file
/**
* CSV format is:
* Mobile_MAC;Timestamp;X;Y;Z;Direction;AP_MAC_1;SS_1;;AP_MAC_n;SS_n
* Mobile_MAC;Request_type;Number_of_packets;Timestamp;X;Y;Z;Direction;
* AP_MAC_1;Packet_ID_1;SS_1;;AP_MAC_n;Packet_ID_n;SS_n
*/
class InputCSV: public InputMedium
{

View File

@ -28,6 +28,7 @@ const string InputLogCSV::request_to_csv(const Request &request) const
csv_line << request.get_mobile()->get_mac_addr() ;
csv_line
<< ';' << static_cast<uint_fast16_t>(request.get_type())
<< ';' << request.get_nb_packets()
<< ';' << request.get_time_sent()
<< ';' ;
@ -48,18 +49,7 @@ const string InputLogCSV::request_to_csv(const Request &request) const
request.get_measurements() ;
for (unordered_map<string, Measurement>::const_iterator i
= measurements.begin() ; i != measurements.end() ; ++i)
{
const vector<ss_t> &ss_list = i->second.get_ss_list() ;
const string &ap_mac = i->second.get_ap() != NULL
? i->second.get_ap()->get_mac_addr()
: "" ;
for (vector<ss_t>::const_iterator i = ss_list.begin() ;
i != ss_list.end() ; ++i)
{
csv_line << ';' << ap_mac ;
csv_line << ';' << *i ;
}
}
csv_line << i->second.to_csv() ;
csv_line << '\n' ;
return csv_line.str() ;

View File

@ -104,6 +104,7 @@ bool InputUDPSocket::fill_current_request()
}
// Endianess conversions
request.nb_packets = ntohs(request.nb_packets) ;
owl_ntoh_timestamp(&request.request_time) ;
request.nb_info = ntohs(request.nb_info) ;
request.x_position = owl_ntohf(request.x_position) ;
@ -120,6 +121,7 @@ bool InputUDPSocket::fill_current_request()
cout
<< "*** Request received from the aggregator ***"
<< "\n\tType: " << static_cast<uint_fast16_t>(request.type)
<< "\n\tNumber of packets: " << request.nb_packets
<< "\n\tMobile MAC: " << mac_mobile
<< "\n\tRequest timestamp: " << Timestamp(request.request_time)
<< "\n\tPosition X: " << request.x_position
@ -146,6 +148,9 @@ bool InputUDPSocket::fill_current_request()
// Request type
current_request->set_type(request.type) ;
// Number of packets
current_request->set_nb_packets(request.nb_packets) ;
// Timestamp
current_request->set_time_sent(Timestamp(request.request_time)) ;
@ -167,6 +172,8 @@ bool InputUDPSocket::fill_current_request()
return false ;
}
uint_fast16_t packet_id = ntohs(request_info.packet_id) ;
string mac_ap(
owl_mac_bytes_to_string(request_info.ap_mac_addr_bytes)) ;
PosUtil::to_upper(mac_ap) ;
@ -179,6 +186,7 @@ bool InputUDPSocket::fill_current_request()
if (Configuration::is_configured("verbose"))
cout
<< "\t* Packet received from the aggregator:"
<< "\n\t\tPacket number: " << packet_id
<< "\n\t\tAP MAC: " << mac_ap
<< "\n\t\tSignal: "
<< ss << " dBm"
@ -195,7 +203,7 @@ bool InputUDPSocket::fill_current_request()
const AccessPoint &ap = Stock::find_create_ap(mac_ap) ;
measurements[mac_ap].set_ap(&ap) ;
measurements[mac_ap].add_ss(ss) ;
measurements[mac_ap].add_ss(packet_id, ss) ;
}
if (measurements.empty())
return false ;

View File

@ -8,6 +8,9 @@
#include "measurement.hh"
#include "posexcept.hh"
#include <iostream>
#include <sstream>
using namespace std ;
@ -15,23 +18,6 @@ using namespace std ;
/* *** Constructors *** */
Measurement::Measurement(const AccessPoint *_ap):
ap(const_cast<AccessPoint*>(_ap)), average_ss(0)
{
ss_list.reserve(10) ;
}
Measurement::Measurement(const AccessPoint *_ap,
const vector<ss_t> &_ss_list):
ap(const_cast<AccessPoint*>(_ap)), ss_list(_ss_list)
{
ss_list.reserve(10) ;
update_average_ss() ;
}
/**
* Note that values pointed by #ap are not deleted.
*/
@ -46,31 +32,48 @@ Measurement::~Measurement()
/**
* @param packet_id The sequence number of the packet in the request,
* as sent by the mobile.
* @param ss_dbm The signal strength to add to #ss_list (in dBm).
*/
void Measurement::add_ss(const ss_t &ss_dbm)
void Measurement::
add_ss(const uint_fast16_t packet_id, const ss_t ss_dbm)
{
unsigned int ss_list_size = ss_list.size() ;
// Add the new value (in dBm) along with the packet identifier:
pair<uint_fast16_t, ss_t> packet(make_pair(packet_id, ss_dbm)) ;
if (! ss_list.insert(packet).second)
{
cerr
<< "Cannot insert the packet (#" << packet_id << ", "
<< static_cast<int_fast16_t>(ss_dbm) << " dBm)\n" ;
return ;
}
// Update the average with the new value
double total_ss_mwatts =
pow(10, static_cast<double>(ss_dbm) / 10.0) + // New SS in mW
(ss_list.size() * pow(10, average_ss / 10.0)) ; // Other values in mW
ss_list.push_back(ss_dbm) ; // Add new value (dBm)
// Update average converting back in dBm
(ss_list_size * pow(10, average_ss / 10.0)) ; // Other values in mW
// Convert the average back in dBm:
average_ss = 10.0 * log10(total_ss_mwatts / ss_list.size()) ;
}
void Measurement::set_ss_list(const std::vector<ss_t> &_ss_list)
/**
* Add an SS list to the current Measurement's SS list.
* If the new SS list contains a packet with the same ID, the old one
* is overwritten.
*/
void Measurement::
add_ss_list(const map<uint_fast16_t, ss_t> &_ss_list)
{
ss_list = _ss_list ;
update_average_ss() ;
}
// We cannot use insert() here because we want to overwrite the
// previous values with the same ID, if any.
for (map<uint_fast16_t, ss_t>::const_iterator
i = _ss_list.begin() ; i != _ss_list.end() ; ++i)
ss_list[i->first] = i->second ;
void Measurement::add_ss_list(const std::vector<ss_t> &_ss_list)
{
ss_list.insert(ss_list.end(), _ss_list.begin(), _ss_list.end()) ;
update_average_ss() ;
}
@ -117,10 +120,10 @@ void Measurement::update_average_ss()
double total_ss_mwatts = 0 ;
for (vector<ss_t>::const_iterator i = ss_list.begin() ;
i != ss_list.end() ; ++i)
for (map<uint_fast16_t, ss_t>::const_iterator
i = ss_list.begin() ; i != ss_list.end() ; ++i)
// Add the current value in mW to the total
total_ss_mwatts += pow(10, static_cast<double>(*i) / 10.0) ;
total_ss_mwatts += pow(10, static_cast<double>(i->second) / 10.0) ;
// Compute the average in mW and convert it to dBm
average_ss = 10 * log10(total_ss_mwatts / ss_list.size()) ;
@ -157,23 +160,51 @@ bool Measurement::operator==(const Measurement &m) const
const string Measurement::to_csv() const
{
ostringstream csv_line ;
if (ss_list.empty())
return "" ;
string mac_ap("") ;
if (ap)
mac_ap = ap->get_mac_addr() ;
for (map<uint_fast16_t, ss_t>::const_iterator
i = ss_list.begin() ; i != ss_list.end() ; ++i)
{
if (i != ss_list.begin())
csv_line << ';' ;
csv_line
<< mac_ap << ';'
<< i->first << ';'
<< static_cast<int_fast16_t>(i->second) ;
}
return csv_line.str() ;
}
ostream &operator<<(ostream &os, const Measurement &m)
{
// MAC address
os
<< "AP: " << (m.ap != NULL ? m.ap->get_mac_addr() : "Unknown_AP")
<< "AP: " << (m.ap ? m.ap->get_mac_addr() : "Unknown_AP")
<< ": " ;
// List of SS
if (m.ss_list.empty())
os << "No values" ;
else
for (vector<ss_t>::const_iterator i = m.ss_list.begin() ;
i != m.ss_list.end() ; ++i)
for (map<uint_fast16_t, ss_t>::const_iterator
i = m.ss_list.begin() ; i != m.ss_list.end() ; ++i)
{
os << *i ;
if (i != m.ss_list.end() - 1)
os << ";" ;
if (i != m.ss_list.begin())
os << ';' ;
os << static_cast<int_fast16_t>(i->second)
<< '(' << i->first << ')' ;
}
os << " [AVG=" << m.average_ss << "]" ;

View File

@ -10,7 +10,7 @@
#include "accesspoint.hh"
#include <vector>
#include <map>
#include <ostream>
#include <cmath>
@ -23,7 +23,7 @@ protected:
/// The AccessPoint that performed the measurement
AccessPoint *ap ;
/// List of signal strengths captured (in dBm)
std::vector<ss_t> ss_list ;
std::map<uint_fast16_t, ss_t> ss_list ;
/// Average of all signal strength captured (dBm)
double average_ss ;
@ -35,10 +35,8 @@ protected:
public:
Measurement(const AccessPoint *_ap = NULL) ;
Measurement(const AccessPoint *_ap,
const std::vector<ss_t> &_ss_list) ;
Measurement(const AccessPoint *_ap = NULL):
ap(const_cast<AccessPoint*>(_ap)), average_ss(0) {}
Measurement(const Measurement &source):
ap(source.ap), ss_list(source.ss_list),
@ -49,7 +47,6 @@ public:
/** @name Read accessors */
//@{
AccessPoint* get_ap() const ;
const std::vector<ss_t>& get_ss_list() const ;
double get_average_ss() const ;
int get_ss_list_size() const ;
//@}
@ -57,11 +54,10 @@ public:
/** @name Write accessors */
//@{
void set_ap(const AccessPoint *_ap) ;
void set_ss_list(const std::vector<ss_t> &_ss_list) ;
/// Adds a signal strength to #ss_list
void add_ss(const ss_t &ss_dbm) ;
void add_ss(const uint_fast16_t packet_id, const ss_t ss_dbm) ;
/// Adds several signal strengths to #ss_list
void add_ss_list(const std::vector<ss_t> &_ss_list) ;
void add_ss_list(const std::map<uint_fast16_t, ss_t> &_ss_list) ;
/// Merges a given Measurement into the current Measurement
void merge(const Measurement &source) ;
void clear(void) ;
@ -83,6 +79,12 @@ public:
operator bool(void) const ;
//@}
/** @name Conversion accessors */
//@{
/// Converts to a CSV string
const std::string to_csv(void) const ;
//@}
/// Displays a Measurement
friend std::ostream &operator<<(std::ostream &os, const Measurement &m) ;
} ;
@ -98,12 +100,6 @@ inline AccessPoint* Measurement::get_ap() const
}
inline const std::vector<ss_t>& Measurement::get_ss_list() const
{
return ss_list ;
}
inline double Measurement::get_average_ss() const
{
return average_ss ;

View File

@ -48,7 +48,7 @@ void PosUtil::complete_with_dummy_measurements(
assert(! measurements2.empty()) ;
Measurement dummy ;
dummy.add_ss(-98) ; // FIXME: should be the smallest possible value
dummy.add_ss(1, -98) ; // FIXME: should be the smallest possible value
for (unordered_map<string, Measurement>::const_iterator i =
measurements1.begin() ; i != measurements1.end() ; ++i)

View File

@ -49,6 +49,8 @@ void Request::set_real_position(const Point3D &_real_position)
/**
* - #nb_packets is set to 1 (this is the default value when
* constructing a Request).
* - #mobile is NULLified, but the value it pointed to is not deleted.
* - The fields of #time_sent are initialised to 0.
* - #measurements is cleared.
@ -56,6 +58,7 @@ void Request::set_real_position(const Point3D &_real_position)
void Request::clear()
{
type = OWL_REQUEST_UNDEFINED ;
nb_packets = 1 ;
mobile = NULL ;
time_sent.clear() ;
measurements.clear() ;
@ -91,6 +94,7 @@ Request& Request::operator=(const Request &source)
return *this ;
type = source.type ;
nb_packets = source.nb_packets ;
mobile = source.mobile ;
time_sent = source.time_sent ;
measurements = source.measurements ;
@ -116,6 +120,7 @@ bool Request::operator==(const Request &source) const
return
real_position_equal &&
type == source.type &&
nb_packets == source.nb_packets &&
mobile == source.mobile &&
time_sent == source.time_sent &&
measurements == source.measurements ;
@ -134,6 +139,7 @@ ostream& operator<<(ostream &os, const Request &r)
// MAC address
os
<< "Type: " << static_cast<uint_fast16_t>(r.type)
<< ", Number of packets sent: " << r.nb_packets
<< ", Mobile: "
<< (r.mobile != NULL ? r.mobile->get_mac_addr() : "Unknown_Mobile")
<< ":" ;
@ -160,6 +166,7 @@ size_t hash_value(const Request &source)
size_t seed = 0 ;
boost::hash_combine(seed, source.type) ;
boost::hash_combine(seed, source.nb_packets) ;
boost::hash_combine(seed, source.time_sent) ;
if (source.mobile)
boost::hash_combine(seed, source.mobile->get_mac_addr()) ;

View File

@ -25,6 +25,8 @@ class Request
protected:
/// Type of the request
uint_fast8_t type ;
/// Number of packets sent by the mobile for this request
uint_fast16_t nb_packets ;
/// The mobile that sent the request
Mobile *mobile ;
/// Local date of the request on the mobile
@ -48,25 +50,25 @@ public:
const std::tr1::unordered_map<std::string, Measurement>
&_measurements =
std::tr1::unordered_map<std::string, Measurement>()):
type(OWL_REQUEST_UNDEFINED),
type(OWL_REQUEST_UNDEFINED), nb_packets(1),
mobile(const_cast<Mobile*>(_mobile)), time_sent(_time_sent),
measurements(_measurements), real_position(NULL) {}
Request(const std::tr1::unordered_map<std::string, Measurement>
&_measurements):
type(OWL_REQUEST_UNDEFINED),
type(OWL_REQUEST_UNDEFINED), nb_packets(1),
mobile(NULL), measurements(_measurements), real_position(NULL) {}
Request(const Timestamp &_time_sent,
const std::tr1::unordered_map<std::string, Measurement>
&_measurements =
std::tr1::unordered_map<std::string, Measurement>()):
type(OWL_REQUEST_UNDEFINED),
type(OWL_REQUEST_UNDEFINED), nb_packets(1),
mobile(NULL), time_sent(_time_sent),
measurements(_measurements), real_position(NULL) {}
Request(const Request &source):
type(source.type),
type(source.type), nb_packets(1),
mobile(source.mobile), time_sent(source.time_sent),
measurements(source.measurements), real_position(NULL) {}
@ -74,7 +76,8 @@ public:
/** @name Read accessors */
//@{
uint8_t get_type(void) const ;
uint_fast8_t get_type(void) const ;
uint_fast16_t get_nb_packets(void) const ;
Mobile* get_mobile(void) const ;
const Timestamp& get_time_sent(void) const ;
const std::tr1::unordered_map<std::string, Measurement>&
@ -84,7 +87,8 @@ public:
/** @name Write accessors */
//@{
void set_type(const uint8_t _type) ;
void set_type(const uint_fast8_t _type) ;
void set_nb_packets(const uint_fast16_t _nb_packets) ;
void set_mobile(const Mobile *_mobile) ;
void set_time_sent(const Timestamp &_time_sent) ;
void set_measurements(const std::tr1::unordered_map
@ -121,12 +125,18 @@ public:
inline uint8_t Request::get_type() const
inline uint_fast8_t Request::get_type() const
{
return type ;
}
inline uint_fast16_t Request::get_nb_packets() const
{
return nb_packets ;
}
inline Mobile* Request::get_mobile() const
{
return mobile ;
@ -156,12 +166,18 @@ inline const Point3D* Request::get_real_position(void) const
/* *** Write accessors *** */
inline void Request::set_type(const uint8_t _type)
inline void Request::set_type(const uint_fast8_t _type)
{
type = _type ;
}
inline void Request::set_nb_packets(const uint_fast16_t _nb_packets)
{
nb_packets = _nb_packets ;
}
inline void Request::set_mobile(const Mobile *_mobile)
{
mobile = const_cast<Mobile*>(_mobile) ;
@ -194,8 +210,8 @@ inline bool Request::operator!=(const Request &comp) const
/**
* @return \em false if the Request is empty.
* @return \em true if at least one attribute (other than #type) is
* initialised.
* @return \em true if at least one attribute (other than #type and
* #nb_packets) is initialised.
*/
inline Request::operator bool() const
{

View File

@ -598,7 +598,7 @@ void Stock::generate_reference_point(const Point3D &point)
/* Create the measurement, add it to the list */
Measurement m(&rx->second) ;
m.add_ss(rx_ss) ;
m.add_ss(1, rx_ss) ;
measurements[rx->second.get_mac_addr()] = m ;
}