122 lines
3.5 KiB
C++
122 lines
3.5 KiB
C++
/*
|
|
* This file is part of the Owl Positioning System (OwlPS) project.
|
|
* It is subject to the copyright notice and license terms in the
|
|
* COPYRIGHT.t2t file found in the top-level directory of this
|
|
* distribution and at
|
|
* http://code.lm7.fr/p/owlps/source/tree/master/COPYRIGHT.t2t
|
|
* No part of the OwlPS Project, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms
|
|
* contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be
|
|
* distributed along with this file, either separately or by replacing
|
|
* this notice by the COPYRIGHT.t2t file's contents.
|
|
*/
|
|
|
|
|
|
#include "autocalibration.hh"
|
|
|
|
#include "stock.hh"
|
|
#include "configuration.hh"
|
|
#include "posexcept.hh"
|
|
|
|
#include <string>
|
|
#include <iostream>
|
|
|
|
using namespace std ;
|
|
|
|
|
|
|
|
/* *** Static attribute definitions *** */
|
|
|
|
uint32_t Autocalibration::nb_virtual_mobiles = 0 ;
|
|
|
|
|
|
|
|
/* *** Operations *** */
|
|
|
|
|
|
/**
|
|
* The reference point P we want to generate will end up containing
|
|
* as many calibration requests as the total number of CPs.
|
|
* For each of these requests, we consider a transmitter TRX (which is
|
|
* a virtual mobile located in P) and a receiver RX (the current CP).
|
|
* To generate the signal strength (SS) received by RX from TRX,
|
|
* we first select two reference CPs 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 Autocalibration::generate_reference_point()
|
|
{
|
|
// If the point is the coordinates of an existing CP, we don't
|
|
// need to generate it
|
|
if (Stock::is_cp_coordinate(point))
|
|
return ;
|
|
|
|
/* Get/create the reference point */
|
|
const ReferencePoint
|
|
¤t_rp = Stock::find_create_reference_point(point) ;
|
|
|
|
/* 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 CPs (could be better, probably)
|
|
vmob_gain = 0 ;
|
|
vmob_pow = 0 ;
|
|
|
|
/* Generate the SS(s) for each CP */
|
|
for (rx = Stock::cps.begin() ; rx != Stock::cps.end() ; ++rx)
|
|
{
|
|
if (init_ss_generation())
|
|
generate_ss() ;
|
|
}
|
|
assert(! measurements.empty()) ;
|
|
|
|
/* Create the virtual mobile */
|
|
Mobile vmob("", vmob_mac, vmob_gain, vmob_pow) ;
|
|
const Mobile &mobile = Stock::find_create_mobile(vmob) ;
|
|
|
|
/* Create the calibration request */
|
|
CalibrationRequest cr(OWL_REQUEST_GENERATED) ;
|
|
cr.set_time_sent(cr.get_time_received()) ;
|
|
cr.set_mobile(&mobile) ;
|
|
cr.set_measurements(measurements) ;
|
|
cr.set_reference_point(¤t_rp) ;
|
|
|
|
Stock::store_calibration_request(cr) ;
|
|
}
|
|
|
|
|
|
/**
|
|
* @returns `true` if the SS can be generated.
|
|
* @returns `false` in case of error.
|
|
*/
|
|
bool Autocalibration::init_ss_generation()
|
|
{
|
|
/* Update the mobile's attributes */
|
|
vmob_gain += rx->second.get_antenna_gain() / Stock::cps.size() ;
|
|
vmob_pow += rx->second.get_trx_power() / Stock::cps.size() ;
|
|
|
|
/* Skip the RX CP if it is not at the same floor as the point
|
|
* to generate */
|
|
const Point3D &rx_coord = rx->second.get_coordinates() ;
|
|
if (rx_coord.get_z() != point.get_z())
|
|
return false ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
|
|
/**
|
|
* This function is a simple wrapper around compute_single_packet_ss()
|
|
* and compute_multi_packet_ss(), depending on the configuration.
|
|
*/
|
|
void Autocalibration::compute_ss()
|
|
{
|
|
if (Configuration::
|
|
bool_value("positioning.generate-multi-packet-reference-points"))
|
|
compute_multi_packet_ss() ;
|
|
else
|
|
compute_single_packet_ss(0) ;
|
|
}
|