YARP
Yet Another Robot Platform
Map2DArea.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #include <yarp/dev/api.h>
10 #include <yarp/dev/Map2DArea.h>
11 #include <yarp/os/Bottle.h>
14 #include <sstream>
15 #include <string>
16 #include <vector>
17 #include <cassert>
18 #include <yarp/os/LogStream.h>
19 #include <random>
20 #include <algorithm>
21 
22 using namespace yarp::dev;
23 using namespace yarp::dev::Nav2D;
24 using namespace yarp::sig;
25 using namespace yarp::os;
26 using namespace yarp::math;
27 using namespace std;
28 
29 int pnpoly(std::vector<yarp::math::Vec2D<double>> points, double testx, double testy)
30 {
31  size_t i, j;
32  int c = 0;
33  for (i = 0, j = points.size() - 1; i < points.size(); j = i++)
34  {
35  if (((points[i].y>testy) != (points[j].y>testy)) &&
36  (testx < (points[j].x - points[i].x) * (testy - points[i].y) / (points[j].y - points[i].y) + points[i].x))
37  {
38  c = !c;
39  }
40  }
41  return c;
42 }
43 
44 Map2DArea::Map2DArea(const std::string& map_name, const std::vector<yarp::math::Vec2D<double>> area_points)
45 {
46  map_id = map_name;
47  points = area_points;
48 }
49 
50 Map2DArea::Map2DArea(const std::string& map_name, const std::vector<Map2DLocation> area_points)
51 {
52  map_id = map_name;
53  for (auto it = area_points.begin(); it != area_points.end(); it++)
54  {
55 #if 0
56  yAssert(it->map_id == map_name);
57 #else
58  if (it->map_id != map_name)
59  {
60  map_id = "";
61  points.clear();
62  yError() << "all area_points must belong to the same map:" << map_name;
63  return;
64  }
65 #endif
66  points.push_back(yarp::math::Vec2D<double>(it->x, it->y));
67  }
68 }
69 
71 {
72  map_id = "";
73 }
74 
76 {
77  // auto-convert text mode interaction
78  connection.convertTextMode();
79 
80  //[[maybe_unused]] int32_t dummy; //@@@FIXME To be used as soon as C++17 becomes available
81  int32_t dummy;
82 
83  dummy = connection.expectInt32();
84  assert(dummy == BOTTLE_TAG_LIST);
85  dummy = connection.expectInt32();
86 
87  dummy = connection.expectInt32();
88  assert(dummy == BOTTLE_TAG_STRING);
89  int string_size = connection.expectInt32();
90  this->map_id.resize(string_size);
91  connection.expectBlock(const_cast<char*>(this->map_id.data()), string_size);
92 
93  dummy = connection.expectInt32();
94  assert(dummy == BOTTLE_TAG_INT32);
95  size_t siz = connection.expectInt32();
96 
97  this->points.clear();
98  for (size_t i = 0; i < siz; i++)
99  {
100  dummy = connection.expectInt32();
101  assert(dummy == BOTTLE_TAG_FLOAT64);
102  double x = connection.expectFloat64();
103  dummy = connection.expectInt32();
104  assert(dummy == BOTTLE_TAG_FLOAT64);
105  double y = connection.expectFloat64();
106  this->points.push_back(yarp::math::Vec2D<double>(x, y));
107  }
108 
109  return !connection.isError();
110 }
111 
113 {
114  size_t siz = this->points.size();
115 
116  connection.appendInt32(BOTTLE_TAG_LIST);
117  connection.appendInt32(2+siz*2);
118 
119  connection.appendInt32(BOTTLE_TAG_STRING);
120  connection.appendString(map_id);
121 
122  connection.appendInt32(BOTTLE_TAG_INT32);
123  connection.appendInt32(siz);
124 
125  for (size_t i = 0; i < siz; i++)
126  {
127  connection.appendInt32(BOTTLE_TAG_FLOAT64);
128  connection.appendFloat64(this->points[i].x);
129  connection.appendInt32(BOTTLE_TAG_FLOAT64);
130  connection.appendFloat64(this->points[i].y);
131  }
132 
133  connection.convertTextMode();
134  return !connection.isError();
135 }
136 
137 std::string Map2DArea::toString() const
138 {
139  std::ostringstream stringStream;
140  stringStream.precision(-1);
141  stringStream.width(-1);
142  stringStream << std::string("map_id:") << map_id << " ";
143  for (size_t i = 0; i<points.size(); i++)
144  {
145  stringStream << " point " << i << "(" << points[i].x << "," << points[i].y << ")";
146  }
147  return stringStream.str();
148 }
149 
151 {
152  if (loc.map_id != this->map_id) return false;
153  if (points.size() < 3) return false;
154  if (pnpoly(points, loc.x, loc.y) > 0) return true;
155  return false;
156 }
157 
158 bool Map2DArea::operator!=(const Map2DArea& r) const
159 {
160  if (
161  map_id != r.map_id ||
162  points != r.points
163  )
164  {
165  return true;
166  }
167  return false;
168 }
169 
170 bool Map2DArea::operator==(const Map2DArea& r) const
171 {
172  if (
173  map_id == r.map_id &&
174  points == r.points
175  )
176  {
177  return true;
178  }
179  return false;
180 }
181 
182 bool Map2DArea::isValid() const
183 {
184  if (points.size() < 3) return false;
185  if (map_id == "") return false;
186  return true;
187 }
188 
190 {
191  lt.map_id = rb.map_id = this->map_id;
192  lt.x = lt.y = std::numeric_limits<double>::max();
193  rb.x = rb.y = std::numeric_limits<double>::min();
194  if (isValid() == false) return false;
195  for (auto it = points.begin(); it != points.end(); it++)
196  {
197  if (it->x > rb.x) { rb.x = it->x; }
198  if (it->y > rb.y) { rb.y = it->y; }
199  if (it->x < lt.x) { lt.x = it->x; }
200  if (it->y < lt.y) { lt.y = it->y; }
201  }
202  return true;
203 }
204 
206 {
207  Map2DLocation lt;
208  Map2DLocation rb;
209  if (findAreaBounds(lt, rb) == false)
210  return false;
211 
212  std::random_device rd;
213  std::mt19937 gen(rd());
214  std::uniform_real_distribution<double> dis_x(lt.x, rb.x);
215  std::uniform_real_distribution<double> dis_y(lt.y, rb.y);
216 
217  size_t count_trials = 0;
218  do
219  {
220  double rnd_x = dis_x(gen);
221  double rnd_y = dis_y(gen);
222 
223  loc.map_id = this->map_id;
224  loc.x = rnd_x;
225  loc.y = rnd_y;
226  loc.theta = 0;
227  count_trials++;
228  if (this->checkLocationInsideArea(loc)) break;
229  } while (count_trials < 20);
230 
231  if (count_trials >= 20)
232  {
233  yError() << "Problem found in Map2DArea::getRandomLocation()";
234  return false;
235  }
236 
237  return true;
238 }
239 
241 {
242  this->map_id = "";
243  this->points.clear();
244 }
245 
247 {
248  //std::vector::at() function performs bound check, throwing exception.
249  //[] operator, instead, not.
250  return points.at(index);
251 }
LogStream.h
yarp::dev::Nav2D::Map2DArea::map_id
std::string map_id
Definition: Map2DArea.h:113
Map2DArea.h
contains the definition of a Map2DArea type
yarp::dev::Map2DLocationData::y
double y
Definition: Map2DLocationData.h:32
yarp::sig
Signal processing.
Definition: Image.h:25
BOTTLE_TAG_LIST
#define BOTTLE_TAG_LIST
Definition: Bottle.h:30
yarp::os::ConnectionWriter::appendFloat64
virtual void appendFloat64(yarp::conf::float64_t data)=0
Send a representation of a 64-bit floating point number to the network connection.
ConnectionWriter.h
yarp::os::Time::isValid
bool isValid()
Check if time is valid (non-zero).
Definition: Time.cpp:317
BOTTLE_TAG_STRING
#define BOTTLE_TAG_STRING
Definition: Bottle.h:28
yarp::dev::Nav2D::Map2DArea::getRandomLocation
bool getRandomLocation(yarp::dev::Nav2D::Map2DLocation &loc)
get a random Map2DLocation inside the Map2DArea @loc the computed Map2DLocation
Definition: Map2DArea.cpp:205
yarp::dev::Nav2D::Map2DArea::Map2DArea
Map2DArea()
Default constructor: the map name is empty, coordinates are set to zero.
Definition: Map2DArea.cpp:70
yarp::dev::Nav2D::Map2DArea::operator==
bool operator==(const Map2DArea &r) const
Compares two Map2DArea.
Definition: Map2DArea.cpp:170
pnpoly
int pnpoly(std::vector< yarp::math::Vec2D< double >> points, double testx, double testy)
Definition: Map2DArea.cpp:29
yarp::dev::Nav2D::Map2DArea::toString
std::string toString() const
Returns text representation of the area.
Definition: Map2DArea.cpp:137
yarp::math
Definition: FrameTransform.h:18
yError
#define yError(...)
Definition: Log.h:282
yarp::dev::Map2DLocationData::theta
double theta
Definition: Map2DLocationData.h:33
yarp::dev::Nav2D::Map2DArea::findAreaBounds
bool findAreaBounds(yarp::dev::Nav2D::Map2DLocation &lt, yarp::dev::Nav2D::Map2DLocation &rb)
retrieves two Map2DLocations representing the bounding box of the Map2DArea @lt the left-top vertex @...
Definition: Map2DArea.cpp:189
yarp::math::Vec2D< double >
yarp::dev
An interface for the device drivers.
Definition: audioBufferSizeData.cpp:17
BOTTLE_TAG_INT32
#define BOTTLE_TAG_INT32
Definition: Bottle.h:23
yarp::os::ConnectionReader::expectFloat64
virtual yarp::conf::float64_t expectFloat64()=0
Read a 64-bit floating point number from the network connection.
yarp::os::ConnectionWriter::isError
virtual bool isError() const =0
yarp::os::ConnectionReader::expectInt32
virtual std::int32_t expectInt32()=0
Read a 32-bit integer from the network connection.
yarp::os::ConnectionWriter
An interface for writing to a network connection.
Definition: ConnectionWriter.h:40
yarp::dev::Nav2D::Map2DArea::points
std::vector< yarp::math::Vec2D< double > > points
Definition: Map2DArea.h:114
yarp::os::ConnectionReader::isError
virtual bool isError() const =0
yarp::dev::Nav2D::Map2DArea::clear
void clear()
Remove all elements from the path.
Definition: Map2DArea.cpp:240
yarp::os::ConnectionReader::convertTextMode
virtual bool convertTextMode()=0
Reads in a standard description in text mode, and converts it to a standard description in binary.
yarp::dev::Nav2D
Definition: ILocalization2D.h:21
yarp::os::ConnectionWriter::convertTextMode
virtual bool convertTextMode()=0
Converts a standard description in binary into a textual description, if the connection is in text-mo...
yarp::dev::Nav2D::Map2DArea::operator!=
bool operator!=(const Map2DArea &r) const
Compares two Map2DAreas.
Definition: Map2DArea.cpp:158
yarp::os::ConnectionWriter::appendInt32
virtual void appendInt32(std::int32_t data)=0
Send a representation of a 32-bit integer to the network connection.
yarp::dev::Nav2D::Map2DLocation
Definition: Map2DLocation.h:30
yarp::os::ConnectionReader
An interface for reading from a network connection.
Definition: ConnectionReader.h:40
BOTTLE_TAG_FLOAT64
#define BOTTLE_TAG_FLOAT64
Definition: Bottle.h:27
yarp::dev::Nav2D::Map2DArea::read
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
Definition: Map2DArea.cpp:75
yarp::dev::Nav2D::Map2DArea::operator[]
yarp::math::Vec2D< double > & operator[](size_t index)
Returns a vertex of the area.
Definition: Map2DArea.cpp:246
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::dev::Nav2D::Map2DArea::isValid
bool isValid() const
Checks if the Map2DArea is valid return true if the Map2DArea is valid.
Definition: Map2DArea.cpp:182
yarp::os::ConnectionWriter::appendString
virtual void appendString(const char *str, const char terminate='\n') final
Send a character sequence to the network connection.
Definition: ConnectionWriter.h:131
yarp::dev::Nav2D::Map2DArea
Definition: Map2DArea.h:30
yarp::dev::Map2DLocationData::x
double x
Definition: Map2DLocationData.h:31
yarp::os::ConnectionReader::expectBlock
virtual bool expectBlock(char *data, size_t len)=0
Read a block of data from the network connection.
yarp::dev::Nav2D::Map2DArea::write
bool write(yarp::os::ConnectionWriter &connection) const override
Write a map2DArea to a connection.
Definition: Map2DArea.cpp:112
yarp::dev::Map2DLocationData::map_id
std::string map_id
Definition: Map2DLocationData.h:30
api.h
yAssert
#define yAssert(x)
Definition: Log.h:297
Bottle.h
yarp::dev::Nav2D::Map2DArea::checkLocationInsideArea
bool checkLocationInsideArea(yarp::dev::Nav2D::Map2DLocation loc)
Check if a Map2DLocation is inside a Map2DArea.
Definition: Map2DArea.cpp:150
ConnectionReader.h