[Positioning] Add InputDataReader & TopologyReaderCSV
InputDataReader handles all data input, i.e. data needed to prepare computation (topology, calibration measurements, etc.). TopologyReaderCSV reads topology from a CSV file (just Building and Area for the moment). cfg/topo.csv: change format (add building name and reorder coordinates). UserInterface: add data input options. posexcept: add data input exceptions.
This commit is contained in:
parent
a30b08ac3c
commit
208c989c53
|
@ -57,6 +57,8 @@ OBJ_LIST = \
|
|||
realposition.o \
|
||||
configuration.o \
|
||||
userinterface.o \
|
||||
inputdatareader.o \
|
||||
topologyreadercsv.o \
|
||||
textfilereader.o \
|
||||
csvfilereader.o \
|
||||
textfilewriter.o \
|
||||
|
@ -109,8 +111,19 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc $(SRC_DIR)/%.hh
|
|||
$(LD) $(LDFLAGS) -o $@ $^
|
||||
|
||||
# Dependencies
|
||||
$(OBJ_DIR)/owlps-positioning.o: \
|
||||
$(OBJ_DIR)/userinterface.o \
|
||||
$(OBJ_DIR)/inputdatareader.o \
|
||||
$(OBJ_DIR)/stock.o \
|
||||
$(OBJ_DIR)/positioning.o
|
||||
$(OBJ_DIR)/userinterface.o: \
|
||||
$(OBJ_DIR)/configuration.o
|
||||
$(OBJ_DIR)/inputdatareader.o: \
|
||||
$(OBJ_DIR)/topologyreadercsv.o \
|
||||
$(OBJ_DIR)/configuration.o \
|
||||
$(OBJ_DIR)/posexcept.o
|
||||
$(OBJ_DIR)/topologyreadercsv.o: \
|
||||
$(OBJ_DIR)/textfilereader.o
|
||||
$(OBJ_DIR)/referencepoint.o: \
|
||||
$(OBJ_DIR)/point3d.o
|
||||
$(OBJ_DIR)/waypoint.o: \
|
||||
|
@ -184,6 +197,7 @@ $(OBJ_DIR)/realposition.o: \
|
|||
$(OBJ_DIR)/calibrationrequest.o \
|
||||
$(OBJ_DIR)/referencepoint.o
|
||||
$(OBJ_DIR)/positioning.o: \
|
||||
$(OBJ_DIR)/inputdatareader.o \
|
||||
$(OBJ_DIR)/input.o \
|
||||
$(OBJ_DIR)/realposition.o \
|
||||
$(OBJ_DIR)/output.o \
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
- Tests unitaires
|
||||
° Finir le test de InputDataReader.
|
||||
° Finir le test de Input.
|
||||
° Finir le test de Output.
|
||||
° Finir le test de Positioning.
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
# Liste des zones homogènes du bâtiment (pièces).
|
||||
# Liste des bâtiments et de leurs zones homogènes (pièces).
|
||||
# Chaque ligne définit une zone, de la forme :
|
||||
# Nom de la pièce;X1;Y1;X2;Y2;Z1;Z2
|
||||
# Nom du bâtiment;Nom de la pièce;X1;Y1;X2;Y2;Z1;Z2
|
||||
|
||||
|
||||
### Rez-de-chaussée ###
|
||||
#
|
||||
0140;1.00;7.28;6.05;3.70;0.00;2.99
|
||||
0130;1.00;10.88;6.05;7.28;0.00;2.99
|
||||
0120;1.00;14.48;6.05;10.88;0.00;2.99
|
||||
0110;1.00;18.12;6.05;14.48;0.00;2.99
|
||||
0100;1.00;21.66;6.05;18.12;0.00;2.99
|
||||
0090;1.00;25.32;6.05;21.66;0.00;2.99
|
||||
0080;1.00;29.00;6.05;25.32;0.00;2.99
|
||||
0070;1.00;32.00;6.05;29.00;0.00;2.99
|
||||
WC N0;8.20;5.30;10.00;0.50;0.00;2.99
|
||||
0085;8.20;9.00;10.00;5.30;0.00;2.99
|
||||
0075;8.20;10.88;10.00;9.00;0.00;2.99
|
||||
Palier N0;5.00;3.70;8.20;0.50;0.00;2.99
|
||||
Couloir N0 A;6.05;30.00;8.20;3.70;0.00;2.99
|
||||
Couloir N0 B;8.20;16.50;10.00;10.88;0.00;2.99
|
||||
Couloir N0 C;8.20;24.80;10.00;22.60;0.00;2.99
|
||||
Numerica;0140;1.00;7.28;6.05;3.70;0.00;2.99
|
||||
Numerica;0130;1.00;10.88;6.05;7.28;0.00;2.99
|
||||
Numerica;0120;1.00;14.48;6.05;10.88;0.00;2.99
|
||||
Numerica;0110;1.00;18.12;6.05;14.48;0.00;2.99
|
||||
Numerica;0100;1.00;21.66;6.05;18.12;0.00;2.99
|
||||
Numerica;0090;1.00;25.32;6.05;21.66;0.00;2.99
|
||||
Numerica;0080;1.00;29.00;6.05;25.32;0.00;2.99
|
||||
Numerica;0070;1.00;32.00;6.05;29.00;0.00;2.99
|
||||
Numerica;WC N0;8.20;5.30;10.00;0.50;0.00;2.99
|
||||
Numerica;0085;8.20;9.00;10.00;5.30;0.00;2.99
|
||||
Numerica;0075;8.20;10.88;10.00;9.00;0.00;2.99
|
||||
Numerica;Palier N0;5.00;3.70;8.20;0.50;0.00;2.99
|
||||
Numerica;Couloir N0 A;6.05;30.00;8.20;3.70;0.00;2.99
|
||||
Numerica;Couloir N0 B;8.20;16.50;10.00;10.88;0.00;2.99
|
||||
Numerica;Couloir N0 C;8.20;24.80;10.00;22.60;0.00;2.99
|
||||
|
||||
|
||||
### Escaliers N0 / N1 ###
|
||||
#
|
||||
# TODO : affiner la hauteur, etc.
|
||||
Escalier N0-N1 A;8.20;22.60;10.00;16.50;0.00;6.00
|
||||
Escalier N0-N1 B1;2.50;2.00;5.00;0.50;0.00;6.00
|
||||
Escalier N0-N1 B palier;1.00;3.70;2.50;0.50;1.50;6.00
|
||||
Escalier N0-N1 B2;2.50;3.70;5.00;2.00;1.50;6.00
|
||||
Numerica;Escalier N0-N1 A;8.20;22.60;10.00;16.50;0.00;6.00
|
||||
Numerica;Escalier N0-N1 B1;2.50;2.00;5.00;0.50;0.00;6.00
|
||||
Numerica;Escalier N0-N1 B palier;1.00;3.70;2.50;0.50;1.50;6.00
|
||||
Numerica;Escalier N0-N1 B2;2.50;3.70;5.00;2.00;1.50;6.00
|
||||
|
||||
|
||||
### Premier étage ###
|
||||
#
|
||||
1100;1.00;7.28;6.05;3.70;3.00;6.00
|
||||
0190;1.00;10.88;6.05;7.28;3.00;6.00
|
||||
0180;1.00;14.48;6.05;10.88;3.00;6.00
|
||||
1070;1.00;18.12;6.05;14.48;3.00;6.00
|
||||
1060;1.00;25.32;6.05;18.12;3.00;6.00
|
||||
1050;1.00;31.40;6.05;25.32;3.00;6.00
|
||||
WC N1;8.20;9.00;10.00;0.50;3.00;6.00
|
||||
1105;8.20;10.88;10.00;9.00;3.00;6.00
|
||||
1095;8.20;29.30;10.00;24.80;3.00;6.00
|
||||
Palier N1;5.00;3.70;8.20;0.50;3.00;6.00
|
||||
Couloir N1 A;6.05;29.50;8.20;3.70;3.00;6.00
|
||||
Couloir N1 B;8.20;16.50;10.00;10.88;3.00;6.00
|
||||
Couloir N1 C;8.20;24.80;10.00;22.60;3.00;6.00
|
||||
Numerica;1100;1.00;7.28;6.05;3.70;3.00;6.00
|
||||
Numerica;0190;1.00;10.88;6.05;7.28;3.00;6.00
|
||||
Numerica;0180;1.00;14.48;6.05;10.88;3.00;6.00
|
||||
Numerica;1070;1.00;18.12;6.05;14.48;3.00;6.00
|
||||
Numerica;1060;1.00;25.32;6.05;18.12;3.00;6.00
|
||||
Numerica;1050;1.00;31.40;6.05;25.32;3.00;6.00
|
||||
Numerica;WC N1;8.20;9.00;10.00;0.50;3.00;6.00
|
||||
Numerica;1105;8.20;10.88;10.00;9.00;3.00;6.00
|
||||
Numerica;1095;8.20;29.30;10.00;24.80;3.00;6.00
|
||||
Numerica;Palier N1;5.00;3.70;8.20;0.50;3.00;6.00
|
||||
Numerica;Couloir N1 A;6.05;29.50;8.20;3.70;3.00;6.00
|
||||
Numerica;Couloir N1 B;8.20;16.50;10.00;10.88;3.00;6.00
|
||||
Numerica;Couloir N1 C;8.20;24.80;10.00;22.60;3.00;6.00
|
||||
|
|
|
|
@ -0,0 +1,50 @@
|
|||
#include "inputdatareader.hh"
|
||||
#include "configuration.hh"
|
||||
#include "posexcept.hh"
|
||||
#include "topologyreadercsv.hh"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
|
||||
/* *** Constructors *** */
|
||||
|
||||
|
||||
InputDataReader::InputDataReader()
|
||||
{
|
||||
initialise_topology_media() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Operations *** */
|
||||
|
||||
|
||||
void InputDataReader::initialise_topology_media()
|
||||
{
|
||||
if (! Configuration::is_configured("data-input.topology-medium"))
|
||||
return ;
|
||||
|
||||
const vector<string> &media_names =
|
||||
Configuration::string_vector_value("data-input.topology-medium") ;
|
||||
|
||||
for (vector<string>::const_iterator i = media_names.begin() ;
|
||||
i != media_names.end() ; ++i)
|
||||
{
|
||||
if (*i == "CSV")
|
||||
initialise_topology_csv() ;
|
||||
|
||||
else
|
||||
throw topology_input_medium_type_unknown(*i) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InputDataReader::initialise_topology_csv()
|
||||
{
|
||||
if (! Configuration::is_configured("data-input.areas-csv-file"))
|
||||
throw no_topology_input_csv_file() ;
|
||||
|
||||
TopologyReaderCSV(
|
||||
Configuration::string_value("data-input.areas-csv-file")) ;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef _OWLPS_POSITIONING_INPUTDATAREADER_HH_
|
||||
#define _OWLPS_POSITIONING_INPUTDATAREADER_HH_
|
||||
|
||||
/// Read input data using parameters in Configuration
|
||||
class InputDataReader
|
||||
{
|
||||
protected:
|
||||
void initialise_topology_media(void) ;
|
||||
void initialise_topology_csv(void) ;
|
||||
|
||||
public:
|
||||
InputDataReader(void) ;
|
||||
|
||||
~InputDataReader(void) {}
|
||||
} ;
|
||||
|
||||
#endif // _OWLPS_POSITIONING_INPUTDATAREADER_HH_
|
|
@ -1,12 +1,13 @@
|
|||
#include "userinterface.hh"
|
||||
#include "inputdatareader.hh"
|
||||
#include "stock.hh"
|
||||
#include "positioning.hh"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
UserInterface *ui = new UserInterface(argc, argv) ;
|
||||
delete ui ; // We don't need it any more
|
||||
delete new UserInterface(argc, argv) ;
|
||||
delete new InputDataReader() ;
|
||||
|
||||
Positioning positioning ;
|
||||
|
||||
|
|
|
@ -24,6 +24,26 @@ element_not_found(const string &_explanation) throw():
|
|||
|
||||
|
||||
|
||||
/* *** Data input *** */
|
||||
|
||||
|
||||
topology_input_medium_type_unknown::
|
||||
topology_input_medium_type_unknown(const string &medium_name) throw():
|
||||
posexcept("The specified topology input medium « "+ medium_name +
|
||||
" » is unknown!") {}
|
||||
|
||||
|
||||
no_topology_input_csv_file::no_topology_input_csv_file() throw():
|
||||
posexcept(
|
||||
"No topologyinput CSV file specified in the configuration!") {}
|
||||
|
||||
|
||||
malformed_topology::
|
||||
malformed_topology(const string &_explanation) throw():
|
||||
posexcept("Error reading the topology:" + _explanation) {}
|
||||
|
||||
|
||||
|
||||
/* *** Input *** */
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,32 @@ public:
|
|||
|
||||
|
||||
|
||||
/* *** Data input *** */
|
||||
|
||||
|
||||
class topology_input_medium_type_unknown: public posexcept
|
||||
{
|
||||
public:
|
||||
topology_input_medium_type_unknown(
|
||||
const std::string &medium_name) throw() ;
|
||||
} ;
|
||||
|
||||
|
||||
class no_topology_input_csv_file: public posexcept
|
||||
{
|
||||
public:
|
||||
no_topology_input_csv_file(void) throw() ;
|
||||
} ;
|
||||
|
||||
|
||||
class malformed_topology: public posexcept
|
||||
{
|
||||
public:
|
||||
malformed_topology(const std::string &_explanation) throw() ;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
/* *** Input *** */
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
#include "topologyreadercsv.hh"
|
||||
#include "posexcept.hh"
|
||||
#include "stock.hh"
|
||||
#include "point3d.hh"
|
||||
#include "area.hh"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
|
||||
/* *** Constructors *** */
|
||||
|
||||
|
||||
TopologyReaderCSV::TopologyReaderCSV(const string &filename):
|
||||
file(filename)
|
||||
{
|
||||
read_topology() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Operations *** */
|
||||
|
||||
|
||||
void TopologyReaderCSV::read_topology()
|
||||
{
|
||||
while (file.next_line())
|
||||
process_line() ;
|
||||
}
|
||||
|
||||
|
||||
void TopologyReaderCSV::process_line()
|
||||
{
|
||||
string building_name ;
|
||||
if (! file.read_field(building_name))
|
||||
throw malformed_topology("Cannot read building name!") ;
|
||||
Building &building = const_cast<Building&>(
|
||||
Stock::find_create_building(building_name)) ;
|
||||
|
||||
string name ;
|
||||
if (! file.read_field(name))
|
||||
throw malformed_topology("Cannot read area name!") ;
|
||||
|
||||
Point3D p_min(read_point()) ;
|
||||
Point3D p_max(read_point()) ;
|
||||
|
||||
Area *area = new Area(&building, name, p_min, p_max) ;
|
||||
building.add_area(area) ;
|
||||
}
|
||||
|
||||
|
||||
Point3D TopologyReaderCSV::read_point()
|
||||
{
|
||||
float coord[3] ;
|
||||
for (unsigned int i = 0 ; i < 3 ; ++i)
|
||||
if (! file.read_field(coord[i]))
|
||||
throw malformed_topology("Cannot read a whole Point3D!") ;
|
||||
|
||||
return Point3D(coord) ;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef _OWLPS_POSITIONING_TOPOLOGYREADERCSV_HH_
|
||||
#define _OWLPS_POSITIONING_TOPOLOGYREADERCSV_HH_
|
||||
|
||||
class Point3D ;
|
||||
|
||||
#include "csvfilereader.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
/// Reads and registers to the Stock an Area list from a CSV file
|
||||
/**
|
||||
* CSV format is:
|
||||
* Building name;Room name;X1;Y1;Z1;X2;Y2;Z2
|
||||
*/
|
||||
class TopologyReaderCSV
|
||||
{
|
||||
protected:
|
||||
CSVFileReader file ;
|
||||
|
||||
void read_topology(void) ;
|
||||
void process_line(void) ;
|
||||
Point3D read_point(void) ;
|
||||
|
||||
public:
|
||||
TopologyReaderCSV(const std::string &filename) ;
|
||||
|
||||
~TopologyReaderCSV(void) {}
|
||||
} ;
|
||||
|
||||
#endif // _OWLPS_POSITIONING_TOPOLOGYREADERCSV_HH_
|
|
@ -82,6 +82,7 @@ void UserInterface::fill_cli_options()
|
|||
void UserInterface::fill_file_options()
|
||||
{
|
||||
fill_server_options() ;
|
||||
fill_data_input_options() ;
|
||||
fill_input_options() ;
|
||||
fill_log_options() ;
|
||||
fill_positioning_options() ;
|
||||
|
@ -103,6 +104,27 @@ void UserInterface::fill_server_options()
|
|||
}
|
||||
|
||||
|
||||
void UserInterface::fill_data_input_options()
|
||||
{
|
||||
po::options_description options("Data input options") ;
|
||||
|
||||
options.add_options()
|
||||
("data-input.topology-medium,T", po::value< vector<string> >()
|
||||
->composing(),
|
||||
"Medium from which topology (buildings, areas and waypoints) is \
|
||||
read. You can specify this option more than once. Allowed: CSV.")
|
||||
("data-input.areas-csv-file,A", po::value<string>(),
|
||||
"CSV file to use for topology input (when \
|
||||
data-input.topology-medium = CSV).")
|
||||
("data-input.waypoints-csv-file,W", po::value<string>(),
|
||||
"CSV file to use for waypoints input (when \
|
||||
data-input.topology-medium = CSV).")
|
||||
;
|
||||
|
||||
file_options->add(options) ;
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::fill_input_options()
|
||||
{
|
||||
po::options_description options("Input options") ;
|
||||
|
|
|
@ -25,6 +25,7 @@ protected:
|
|||
/// the configuration file
|
||||
void fill_file_options(void) ;
|
||||
void fill_server_options(void) ;
|
||||
void fill_data_input_options(void) ;
|
||||
void fill_input_options(void) ;
|
||||
void fill_log_options(void) ;
|
||||
void fill_positioning_options(void) ;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "inputdatareader.hh"
|
||||
|
||||
class InputDataReader_test: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
|
||||
void test_constructor(void)
|
||||
{
|
||||
// TODO: test with a mock Configuration?
|
||||
InputDataReader inputdatareader1 ;
|
||||
}
|
||||
|
||||
} ;
|
|
@ -0,0 +1,83 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "topologyreadercsv.hh"
|
||||
|
||||
class TopologyReaderCSV_test: public CxxTest::TestSuite
|
||||
{
|
||||
private:
|
||||
std::string topology_file_name ;
|
||||
|
||||
public:
|
||||
|
||||
TopologyReaderCSV_test(void):
|
||||
topology_file_name("/tmp/TopologyReaderCSV_topology_file.csv")
|
||||
{
|
||||
Stock::clear() ;
|
||||
|
||||
std::ofstream topology_file(topology_file_name.c_str()) ;
|
||||
topology_file
|
||||
<< "My building;My room #1;1;2;3;9;8;7\n"
|
||||
<< "My building;Room #2;4;5;6;6;5;4\n"
|
||||
<< "Building #2;My room #1;1;2;3;9;8;7\n"
|
||||
<< "My building;Room #2;4;5;6;6;5;4\n"
|
||||
<< "My building;Room #2;4;5;6;6;5;4\n" ;
|
||||
topology_file.close() ;
|
||||
}
|
||||
|
||||
|
||||
~TopologyReaderCSV_test(void)
|
||||
{
|
||||
Stock::clear() ;
|
||||
TestUtil::remove_file(topology_file_name) ;
|
||||
}
|
||||
|
||||
|
||||
static TopologyReaderCSV_test* createSuite(void)
|
||||
{
|
||||
return new TopologyReaderCSV_test() ;
|
||||
}
|
||||
|
||||
|
||||
static void destroySuite(TopologyReaderCSV_test *suite)
|
||||
{
|
||||
delete suite ;
|
||||
}
|
||||
|
||||
|
||||
void test_topologyreadercsv(void)
|
||||
{
|
||||
TS_ASSERT_THROWS_NOTHING(
|
||||
TopologyReaderCSV toporeader(topology_file_name)) ;
|
||||
|
||||
Building *building1 ;
|
||||
TS_ASSERT_THROWS_NOTHING(
|
||||
building1 = const_cast<Building*>(
|
||||
&Stock::get_building("My building"))) ;
|
||||
Building *building2 ;
|
||||
TS_ASSERT_THROWS_NOTHING(
|
||||
building2 = const_cast<Building*>(
|
||||
&Stock::get_building("Building #2"))) ;
|
||||
|
||||
TS_ASSERT_EQUALS(building1->get_areas().size(), 2u) ;
|
||||
|
||||
Area *area_ptr ;
|
||||
area_ptr = building1->get_areas().find("My room #1")->second ;
|
||||
Area area1(building1, "My room #1",
|
||||
Point3D(1,2,3), Point3D(9,8,7)) ;
|
||||
assert(area_ptr) ;
|
||||
TS_ASSERT_EQUALS(*area_ptr, area1) ;
|
||||
|
||||
area_ptr = building1->get_areas().find("Room #2")->second ;
|
||||
assert(area_ptr) ;
|
||||
Area area2(building1, "Room #2",
|
||||
Point3D(4,5,6), Point3D(6,5,4)) ;
|
||||
TS_ASSERT_EQUALS(*area_ptr, area2) ;
|
||||
|
||||
TS_ASSERT_EQUALS(building2->get_areas().size(), 1u) ;
|
||||
area1.set_building(building2) ;
|
||||
area_ptr = building2->get_areas().find("My room #1")->second ;
|
||||
assert(area_ptr) ;
|
||||
TS_ASSERT_EQUALS(*area_ptr, area1) ;
|
||||
}
|
||||
|
||||
} ;
|
Loading…
Reference in New Issue