/* * This file is part of the Owl Positioning System (OwlPS). * OwlPS is a project of the University of Franche-Comte * (Université de Franche-Comté), France. * * Copyright © Université de Franche-Comté 2007-2012. * * Corresponding author: Matteo Cypriani * *********************************************************************** * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL: * http://www.cecill.info * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided * only with a limited warranty and the software's authors, the holder * of the economic rights, and the successive licensors have only * limited liability. * * In this respect, the user's attention is drawn to the risks * associated with loading, using, modifying and/or developing or * reproducing the software by the user in light of its specific status * of free software, that may mean that it is complicated to manipulate, * and that also therefore means that it is reserved for developers and * experienced professionals having in-depth computer knowledge. Users * are therefore encouraged to load and test the software's suitability * as regards their requirements in conditions enabling the security of * their systems and/or data to be ensured and, more generally, to use * and operate it in the same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. * *********************************************************************** */ #include "positioning.hh" #include "realposition.hh" #include "fbcm.hh" #include "frbhmbasic.hh" #include "interlinknetworks.hh" #include "nss.hh" #include "resultlist.hh" #include "configuration.hh" #include "posexcept.hh" #include "stock.hh" #include #include #include using namespace std ; using std::tr1::unordered_set ; /* *** Constructors *** */ Positioning::Positioning() { initialise_algorithms() ; loop() ; } Positioning::~Positioning() { for (vector::const_iterator i = algorithms.begin() ; i != algorithms.end() ; ++i) delete *i ; algorithms.clear() ; } /* *** Operations *** */ void Positioning::initialise_algorithms() { if (! Configuration::is_configured("positioning.algorithm")) throw missing_configuration( "No positioning algorithm specified in configuration!") ; const vector &algo_names = Configuration::string_vector_value("positioning.algorithm") ; // We will store the names of the stored algorithms in a set, to // avoid multiple occurrences of the same algorithm: unordered_set stored_algos ; for (vector::const_iterator i = algo_names.begin() ; i != algo_names.end() ; ++i) { if (*i == "Real") { pair::iterator, bool> stored = stored_algos.insert("Real") ; if (stored.second) // Check if there was no previous instance algorithms.insert(algorithms.begin(), new RealPosition) ; /* Note: in order to compute the errors of the other * algorithms, Real must be the first for each request, * so we add it at the begining. */ } else if (*i == "FBCM") { pair::iterator, bool> stored = stored_algos.insert("FBCM") ; if (stored.second) // Check if there was no previous instance { /* Generate the Friis indexes only if the autocalibration * is not activated (if it is, Friis indexes will be * regenerated each time FBCM wants to computes a position) */ if (! Configuration::autocalibration_enabled()) Stock::update_all_friis_indexes() ; algorithms.push_back(new FBCM) ; } } else if (*i == "FRBHMBasic") { pair::iterator, bool> stored = stored_algos.insert("FRBHMBasic") ; if (stored.second) // Check if there was no previous instance algorithms.push_back(new FRBHMBasic) ; // TODO: Pre-compute all per-ReferencePoint friis indexes? } else if (*i == "InterlinkNetworks") { pair::iterator, bool> stored = stored_algos.insert("InterlinkNetworks") ; if (stored.second) // Check if there was no previous instance algorithms.push_back(new InterlinkNetworks) ; } else if (*i == "NSS") { pair::iterator, bool> stored = stored_algos.insert("NSS") ; if (stored.second) // Check if there was no previous instance algorithms.push_back(new NSS) ; } else throw bad_configuration( "The specified positioning_algorithm \""+ *i + "\" is unknown!") ; } } void Positioning::loop() { vector::const_iterator algo ; while (! input.eof() && owl_run) { const Request &request = input.get_next_request() ; if (! request) continue ; Point3D real_position ; bool compute_error = false ; ResultList results(&request) ; for (algo = algorithms.begin() ; algo != algorithms.end() ; ++algo) { Result res ; try { res = (*algo)->compute(request) ; } catch (exception &e) { cerr << "Cannot compute with algorithm " << (*algo)->get_name() << ": \"" << e.what() << "\"\n" ; continue ; } if (compute_error) res.compute_error(real_position) ; else if ((*algo)->get_name() == "Real") { compute_error = true ; real_position = res.get_position() ; } results.add(res) ; } output.write(results) ; } }