[Positioning] Stock::generate_reference_point()

Create the function Stock::generate_reference_point(Point3D) from
regenerate_reference_points().
This commit is contained in:
Matteo Cypriani 2011-07-30 20:23:50 +02:00
parent 4c9a3070ac
commit dcf425fce5
3 changed files with 164 additions and 154 deletions

View File

@ -16,8 +16,7 @@
ReferencePoint::delete_requests()).
- Refactoring
° Split Stock::regenerate_reference_points() into several
functions.
° Split Stock::generate_reference_point() into several functions.
° Synchronise InputCSV & InputUDPSocket (calibration requests),
factorise code into InputMedium.
° Write a class for Request::type?

View File

@ -424,18 +424,6 @@ closest_reference_point(const Request &request)
}
/**
* Each reference point P we want to generate will end-up containing
* as many calibration requests as the total number of APs.
* For each of these requests, we consider a transmitter TRX (which is
* a virtual mobile) and a receiver RX (the current AP).
* To generate the signal strength (SS) received in P by RX from TRX,
* we first select two reference APs REF1 and REF2. Then, we average
* the real measurements REF1->RX and REF2->RX, weighting in function
* of the angles REF-RX-TRX and the distance from RX to TRX to compute
* the SS.
* Hope this is clear enough
*/
void Stock::regenerate_reference_points()
{
assert(! aps.empty()) ;
@ -472,150 +460,167 @@ void Stock::regenerate_reference_points()
//for (float z = start.get_z() ; z <= stop.get_z() ; z += step_z)
{
Point3D current_point(x,y,z) ;
// If the point is the coordinates of an existing AP, we don't
// need to generate it
if (is_ap_coordinate(current_point))
continue ;
/* Get/create the reference point */
const ReferencePoint &current_rp =
find_create_reference_point(current_point) ;
/* Create the timestamp */
Timestamp time_sent ;
time_sent.now() ;
/* Create the measurement list */
unordered_map<string, Measurement> measurements ;
/* Prepare the virtual mobile */
string vmob_mac(PosUtil::int_to_mac(nb_virtual_mobiles++)) ;
// The gain and trx power of the mobile will be the average of
// those of all the known APs (could be better, probably)
double vmob_gain = 0 ;
double vmob_pow = 0 ;
for (unordered_map<string, AccessPoint>::const_iterator
rx = aps.begin() ; rx != aps.end() ; ++rx)
{
/* Update the mobile's attributes */
vmob_gain += rx->second.get_antenna_gain() / aps.size() ;
vmob_pow += rx->second.get_trx_power() / aps.size() ;
/* Choose the 2 nearest APs in angle */
const Point3D &rx_coord =
rx->second.get_coordinates() ;
multimap<double,
unordered_map<string, AccessPoint>::const_iterator>
sorted_angles ;
for (unordered_map<string, AccessPoint>::const_iterator
ref = aps.begin() ; ref != aps.end() ; ++ref)
{
if (ref == rx)
continue ;
const Point3D &ref_coord =
ref->second.get_coordinates() ;
// Skip the AP if the associated reference point does
// not exist yet:
if (! reference_point_exists(ref_coord))
continue ;
double angle =
rx_coord.angle(current_point, ref_coord) ;
pair<double,
unordered_map<string, AccessPoint>::const_iterator>
angle_ap(angle, ref) ;
sorted_angles.insert(angle_ap) ;
}
assert(sorted_angles.size() > 1) ;
/* Compute the angle weight of the 2 reference APs */
map<double,
unordered_map<string, AccessPoint>::const_iterator>
::const_iterator s = sorted_angles.begin() ;
// Angle REF1-RX-P
double ref1_angle = s->first ;
const AccessPoint &ref1 = s->second->second ;
++s ;
const AccessPoint &ref2 = s->second->second ;
// Angle REF1-RX-REF2
const Point3D &ref1_coord = ref1.get_coordinates() ;
const Point3D &ref2_coord = ref2.get_coordinates() ;
double reference_angle =
rx_coord.angle(ref1_coord, ref2_coord) ;
double ref1_percent, ref2_percent ;
if (reference_angle == 0)
ref1_percent = ref2_percent = 50 ;
else
{
ref1_percent = ref1_angle * 100 / reference_angle ;
if (ref1_percent > 100)
ref1_percent = 100 ;
ref2_percent = 100 - ref1_percent ;
}
/* Compute the SS that would be received from a mobile at
* distance of RX-P, in the direction of each reference AP */
// Distance RX-P
float current_point_dst =
rx_coord.distance(current_point) ;
// Constants & common data
double wavelength =
static_cast<double>(PosUtil::LIGHT_SPEED) /
rx->second.get_frequency() ;
double common_ss =
rx->second.get_antenna_gain() +
20 * log10(wavelength) -
20 * log10(4 * M_PI) ;
// SS for REF1
const ReferencePoint &ref1_rp =
get_reference_point(ref1_coord) ;
double friis_index =
ref1_rp.friis_index_for_ap(rx->second.get_mac_addr()) ;
double ref1_ss =
common_ss +
ref1.get_trx_power() +
ref1.get_antenna_gain() -
10 * friis_index * log10(current_point_dst) ;
// SS for REF2
const ReferencePoint &ref2_rp =
get_reference_point(ref2_coord) ;
friis_index =
ref2_rp.friis_index_for_ap(rx->second.get_mac_addr()) ;
double ref2_ss =
common_ss +
ref2.get_trx_power() +
ref2.get_antenna_gain() -
10 * friis_index * log10(current_point_dst) ;
/* Compute the SS */
ref1_ss = ref1_ss * ref1_percent / 100 ;
ref2_ss = ref2_ss * ref2_percent / 100 ;
double rx_ss = ref1_ss + ref2_ss ;
/* Create the measurement, add it to the list */
Measurement m(&rx->second) ;
m.add_ss(rx_ss) ;
measurements[rx->second.get_mac_addr()] = m ;
}
/* Create the virtual mobile */
Mobile vmob("", vmob_mac, vmob_gain, vmob_pow) ;
const Mobile &mobile = find_create_mobile(vmob) ;
/* Create the calibration request */
CalibrationRequest cr(OWL_REQUEST_GENERATED) ;
cr.set_time_sent(time_sent) ;
cr.set_mobile(&mobile) ;
cr.set_measurements(measurements) ;
cr.set_reference_point(&current_rp) ;
store_calibration_request(cr) ;
generate_reference_point(current_point) ;
}
}
/**
* The reference point P we want to generate will end-up containing
* as many calibration requests as the total number of APs.
* For each of these requests, we consider a transmitter TRX (which is
* a virtual mobile) and a receiver RX (the current AP).
* To generate the signal strength (SS) received in P by RX from TRX,
* we first select two reference APs REF1 and REF2. Then, we average
* the real measurements REF1->RX and REF2->RX, weighting in function
* of the angles REF-RX-TRX and the distance from RX to TRX to compute
* the SS.
* Hope this is clear enough
*/
void Stock::generate_reference_point(const Point3D &point)
{
// If the point is the coordinates of an existing AP, we don't
// need to generate it
if (is_ap_coordinate(point))
return ;
/* Get/create the reference point */
const ReferencePoint &current_rp =
find_create_reference_point(point) ;
/* Create the timestamp */
Timestamp time_sent ;
time_sent.now() ;
/* Create the measurement list */
unordered_map<string, Measurement> measurements ;
/* Prepare the virtual mobile */
string vmob_mac(PosUtil::int_to_mac(nb_virtual_mobiles++)) ;
// The gain and trx power of the mobile will be the average of
// those of all the known APs (could be better, probably)
double vmob_gain = 0 ;
double vmob_pow = 0 ;
for (unordered_map<string, AccessPoint>::const_iterator
rx = aps.begin() ; rx != aps.end() ; ++rx)
{
/* Update the mobile's attributes */
vmob_gain += rx->second.get_antenna_gain() / aps.size() ;
vmob_pow += rx->second.get_trx_power() / aps.size() ;
/* Choose the 2 nearest APs in angle */
const Point3D &rx_coord =
rx->second.get_coordinates() ;
multimap<double,
unordered_map<string, AccessPoint>::const_iterator>
sorted_angles ;
for (unordered_map<string, AccessPoint>::const_iterator
ref = aps.begin() ; ref != aps.end() ; ++ref)
{
if (ref == rx)
continue ;
const Point3D &ref_coord =
ref->second.get_coordinates() ;
// Skip the AP if the associated reference point does
// not exist yet:
if (! reference_point_exists(ref_coord))
continue ;
double angle =
rx_coord.angle(point, ref_coord) ;
pair<double,
unordered_map<string, AccessPoint>::const_iterator>
angle_ap(angle, ref) ;
sorted_angles.insert(angle_ap) ;
}
assert(sorted_angles.size() > 1) ;
/* Compute the angle weight of the 2 reference APs */
map<double,
unordered_map<string, AccessPoint>::const_iterator>
::const_iterator s = sorted_angles.begin() ;
// Angle REF1-RX-P
double ref1_angle = s->first ;
const AccessPoint &ref1 = s->second->second ;
++s ;
const AccessPoint &ref2 = s->second->second ;
// Angle REF1-RX-REF2
const Point3D &ref1_coord = ref1.get_coordinates() ;
const Point3D &ref2_coord = ref2.get_coordinates() ;
double reference_angle =
rx_coord.angle(ref1_coord, ref2_coord) ;
double ref1_percent, ref2_percent ;
if (reference_angle == 0)
ref1_percent = ref2_percent = 50 ;
else
{
ref1_percent = ref1_angle * 100 / reference_angle ;
if (ref1_percent > 100)
ref1_percent = 100 ;
ref2_percent = 100 - ref1_percent ;
}
/* Compute the SS that would be received from a mobile at
* distance of RX-P, in the direction of each reference AP */
// Distance RX-P
float point_dst =
rx_coord.distance(point) ;
// Constants & common data
double wavelength =
static_cast<double>(PosUtil::LIGHT_SPEED) /
rx->second.get_frequency() ;
double common_ss =
rx->second.get_antenna_gain() +
20 * log10(wavelength) -
20 * log10(4 * M_PI) ;
// SS for REF1
const ReferencePoint &ref1_rp =
get_reference_point(ref1_coord) ;
double friis_index =
ref1_rp.friis_index_for_ap(rx->second.get_mac_addr()) ;
double ref1_ss =
common_ss +
ref1.get_trx_power() +
ref1.get_antenna_gain() -
10 * friis_index * log10(point_dst) ;
// SS for REF2
const ReferencePoint &ref2_rp =
get_reference_point(ref2_coord) ;
friis_index =
ref2_rp.friis_index_for_ap(rx->second.get_mac_addr()) ;
double ref2_ss =
common_ss +
ref2.get_trx_power() +
ref2.get_antenna_gain() -
10 * friis_index * log10(point_dst) ;
/* Compute the SS */
ref1_ss = ref1_ss * ref1_percent / 100 ;
ref2_ss = ref2_ss * ref2_percent / 100 ;
double rx_ss = ref1_ss + ref2_ss ;
/* Create the measurement, add it to the list */
Measurement m(&rx->second) ;
m.add_ss(rx_ss) ;
measurements[rx->second.get_mac_addr()] = m ;
}
/* Create the virtual mobile */
Mobile vmob("", vmob_mac, vmob_gain, vmob_pow) ;
const Mobile &mobile = find_create_mobile(vmob) ;
/* Create the calibration request */
CalibrationRequest cr(OWL_REQUEST_GENERATED) ;
cr.set_time_sent(time_sent) ;
cr.set_mobile(&mobile) ;
cr.set_measurements(measurements) ;
cr.set_reference_point(&current_rp) ;
store_calibration_request(cr) ;
}
/* *** CalibrationRequest operations *** */

View File

@ -41,6 +41,12 @@ private:
/// List of known CalibrationRequest
static std::tr1::unordered_set<CalibrationRequest> calibration_requests ;
/** @name ReferencePoint operations */
//@{
/// Generates a single reference point
static void generate_reference_point(const Point3D &point) ;
//@}
/** @name CalibrationRequest operations */
//@{
/// Delete calibration requests that do not come from the APs