owlps/owlps-positioner/autocalibration.cc

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
* https://code.lm7.fr/mcy/owlps/src/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
&current_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(const_cast<ReferencePoint*>(&current_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) ;
}