/* * 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 #include 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(const_cast(¤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) ; }