[Positioning] Stock::generate_reference_point()
Create the function Stock::generate_reference_point(Point3D) from regenerate_reference_points().
This commit is contained in:
parent
4c9a3070ac
commit
dcf425fce5
|
@ -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?
|
||||
|
|
|
@ -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 ¤t_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(¤t_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 ¤t_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(¤t_rp) ;
|
||||
|
||||
store_calibration_request(cr) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** CalibrationRequest operations *** */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue