[Positioner] explicit ReferencePoint(Point3D&)

Make ReferencePoint's Point3D copy constructor explicit. This implied
the following changes:

* Stock::get_reference_point(ReferencePoint&) becomes
  get_reference_point(Point3D&). Reference points were always
  retrieved by their coordinates only in the Stock anyway.

* Stock::find_create_reference_point(Point3D&) was added, since it can
  have a different outcome than its (ReferencePoint&) counterpart.

* The unit tests for Stock were improved.
This commit is contained in:
Matteo Cypriani 2016-11-04 22:02:30 -04:00
parent c0db11a890
commit 243dc321b9
5 changed files with 99 additions and 6 deletions

View File

@ -37,6 +37,7 @@ protected:
/** @name Read accessors */
//@{
/// Returns all the measurements of all the calibration #requests
std::unordered_map<std::string, Measurement>
get_all_measurements(void) const ;
/// Returns all the measurements sent by the given mobile
@ -49,7 +50,7 @@ public:
const float _y = 0,
const float _z = 0): Point3D(_x, _y, _z) {}
ReferencePoint(const Point3D &p): Point3D(p) {}
explicit ReferencePoint(const Point3D &p): Point3D(p) {}
ReferencePoint(const ReferencePoint &source):
Point3D(source), requests(source.requests) {}

View File

@ -380,9 +380,14 @@ bool Stock::reference_point_exists(const ReferencePoint &point)
* given coordinates.
*/
const ReferencePoint& Stock::
get_reference_point(const ReferencePoint &point)
get_reference_point(const Point3D &point)
{
auto i = reference_points.find(point) ;
/* Note that we can look up a ReferencePoint in the unordered_set
* #reference_points using only its coordinates (Point3D) only because
* we defined `hash` and `equal_to` to take into consideration only
* the coordinates of the ReferencePoint (see referencepoint.hh).
*/
auto i = reference_points.find(ReferencePoint(point));
if (i != reference_points.end())
return *i ;
throw element_not_found("No ReferencePoint with coordinates " +

View File

@ -168,10 +168,14 @@ public:
static bool reference_point_exists(const ReferencePoint &point) ;
/// Returns the ReferencePoint at the given coordinates
static const ReferencePoint&
get_reference_point(const ReferencePoint &point) ;
get_reference_point(const Point3D &point) ;
/// Searches for a ReferencePoint and adds it if it does not exist
static const ReferencePoint&
find_create_reference_point(const ReferencePoint &point) ;
/// Searches for a ReferencePoint at the given coordinates and adds it
/// if it doesn't exist
static const ReferencePoint&
find_create_reference_point(const Point3D &point);
/// Searches for the closest ReferencePoint (in the signal strength
/// space) to a given Request
static const ReferencePoint&
@ -302,6 +306,14 @@ inline unsigned int Stock::nb_reference_points()
}
inline const ReferencePoint&
Stock::find_create_reference_point(const Point3D &point)
{
return find_create_reference_point(ReferencePoint(point));
}
/* *** CalibrationRequest operations *** */

View File

@ -15,6 +15,7 @@
#include "referencepoint.hh"
#include "calibrationrequest.hh"
#include "stock.hh"
class ReferencePoint_test: public CxxTest::TestSuite
{

View File

@ -13,6 +13,7 @@
#include <cxxtest/TestSuite.h>
#include "calibrationrequest.hh"
#include "stock.hh"
#include "posexcept.hh"
@ -122,9 +123,20 @@ public:
// TODO: implement that
}
void test_reference_points(void)
/*
* This test creates a ReferencePoint, then retrieves it from its
* coordinates (Point3D).
*/
void test_reference_points_1(void)
{
ReferencePoint referencepoint1(3,5,7) ;
Point3D point1(3,5,7);
ReferencePoint referencepoint1(point1);
CalibrationRequest cr1(42); // 42 is obviously not a valid request type
referencepoint1.add_request(&cr1);
TS_ASSERT_THROWS(Stock::get_reference_point(point1), element_not_found);
TS_ASSERT_THROWS(Stock::get_reference_point(referencepoint1),
element_not_found);
const ReferencePoint &referencepoint1_ref1 =
Stock::find_create_reference_point(referencepoint1) ;
@ -137,6 +149,68 @@ public:
TS_ASSERT_DIFFERS(&referencepoint1, &referencepoint1_ref2) ;
TS_ASSERT_EQUALS(&referencepoint1_ref1, &referencepoint1_ref2) ;
const ReferencePoint &referencepoint1_ref3 =
Stock::get_reference_point(referencepoint1);
TS_ASSERT_EQUALS(referencepoint1, referencepoint1_ref3) ;
TS_ASSERT_DIFFERS(&referencepoint1, &referencepoint1_ref3) ;
/* Now let's use the Point3D to look up the ReferencePoint */
const ReferencePoint &referencepoint1_ref4 =
Stock::get_reference_point(point1);
TS_ASSERT_EQUALS(referencepoint1, referencepoint1_ref4);
const ReferencePoint &referencepoint1_ref5 =
Stock::find_create_reference_point(point1);
TS_ASSERT_EQUALS(referencepoint1, referencepoint1_ref5);
}
/*
* This test creates a ReferencePoint using a Point3D in the first
* place, and compares to a ReferencePoint created from a
* ReferencePoint.
*/
void test_reference_points_2(void)
{
// Create with Point3D, retrieve with ReferencePoint
Point3D p1(1,2,3);
const ReferencePoint &rp1_ref1 = Stock::find_create_reference_point(p1);
ReferencePoint rp1(1,2,3);
const ReferencePoint &rp1_ref2 = Stock::get_reference_point(rp1);
const ReferencePoint &rp1_ref3 = Stock::find_create_reference_point(rp1);
TS_ASSERT_EQUALS(&rp1_ref1, &rp1_ref2);
TS_ASSERT_EQUALS(&rp1_ref1, &rp1_ref3);
TS_ASSERT_EQUALS(rp1, rp1_ref1);
// Create with ReferencePoint, retrieve with Point3D
ReferencePoint rp2(4,5,6);
const ReferencePoint &rp2_ref1 = Stock::find_create_reference_point(rp2);
Point3D p2(4,5,6);
const ReferencePoint &rp2_ref2 = Stock::get_reference_point(p2);
const ReferencePoint &rp2_ref3 = Stock::find_create_reference_point(p2);
TS_ASSERT_EQUALS(&rp2_ref1, &rp2_ref2);
TS_ASSERT_EQUALS(&rp2_ref1, &rp2_ref3);
TS_ASSERT_EQUALS(rp2, rp2_ref1);
/* Now with a request in the reference point */
// Create with Point3D, retrieve with ReferencePoint
Point3D p3(7,8,9);
const ReferencePoint &rp3_ref1 = Stock::find_create_reference_point(p3);
ReferencePoint rp3(7,8,9);
CalibrationRequest cr3(42); // 42 is obviously not a valid request type
rp3.add_request(&cr3);
const ReferencePoint &rp3_ref2 = Stock::get_reference_point(rp3);
const ReferencePoint &rp3_ref3 = Stock::find_create_reference_point(rp3);
TS_ASSERT_EQUALS(&rp3_ref1, &rp3_ref2);
TS_ASSERT_EQUALS(&rp3_ref1, &rp3_ref3);
TS_ASSERT_DIFFERS(rp3, rp3_ref1); /* the ReferencePoint in the stock doesn't
* have the CalibrationRequest */
ReferencePoint &rp3_ref_rw =
const_cast<ReferencePoint&>(Stock::get_reference_point(rp3));
rp3_ref_rw.add_request(&cr3);
TS_ASSERT_EQUALS(rp3, rp3_ref1);
}
void test_closest_reference_point(void)