YARP
Yet Another Robot Platform
fakeLaser.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #define _USE_MATH_DEFINES
7 
8 #include "fakeLaser.h"
9 
10 #include <yarp/os/Time.h>
11 #include <yarp/os/Log.h>
12 #include <yarp/os/LogStream.h>
13 #include <yarp/os/ResourceFinder.h>
14 #include <yarp/math/Vec2D.h>
15 #include <iostream>
16 #include <limits>
17 #include <cstring>
18 #include <cstdlib>
19 #include <cmath>
20 
21 //#define LASER_DEBUG
22 #ifndef DEG2RAD
23 #define DEG2RAD M_PI/180.0
24 #endif
25 
26 YARP_LOG_COMPONENT(FAKE_LASER, "yarp.devices.fakeLaser")
27 
28 using namespace yarp::os;
29 using namespace yarp::dev;
30 using namespace yarp::dev::Nav2D;
31 
32 // see FakeLaser.h for device documentation
33 
34 bool FakeLaser::open(yarp::os::Searchable& config)
35 {
36  m_info = "Fake Laser device for test/debugging";
37  m_device_status = DEVICE_OK_STANBY;
38 
39 #ifdef LASER_DEBUG
40  yCDebug(FAKE_LASER) << "%s\n", config.toString().c_str());
41 #endif
42 
43  if (config.check("help"))
44  {
45  yCInfo(FAKE_LASER,"Some examples:");
46  yCInfo(FAKE_LASER,"yarpdev --device fakeLaser --help");
47  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test no_obstacles");
48  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_pattern");
49  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_constant --const_distance 0.5");
50  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_constant --const_distance 0.5 --SENSOR::resolution 0.5 --SKIP::min 0 50 --SKIP::max 10 60");
51  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map");
52  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_port /fakeLaser/location:i");
53  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_server /localizationServer");
54  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_client /fakeLaser/localizationClient --localization_server /localizationServer");
55  yCInfo(FAKE_LASER,"yarpdev --device Rangefinder2DWrapper --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_context context --map_file mymap.map");
56  return false;
57  }
58 
59  bool br = config.check("GENERAL");
60  if (br != false)
61  {
62  yarp::os::Searchable& general_config = config.findGroup("GENERAL");
63  m_period = general_config.check("Period", Value(50), "Period of the sampling thread").asInt32() / 1000.0;
64  }
65 
66  std::string string_test_mode = config.check("test", Value(std::string("use_pattern")), "string to select test mode").asString();
67  if (string_test_mode == "no_obstacles") { m_test_mode = NO_OBSTACLES; }
68  else if (string_test_mode == "use_pattern") { m_test_mode = USE_PATTERN; }
69  else if (string_test_mode == "use_mapfile") { m_test_mode = USE_MAPFILE; }
70  else if (string_test_mode == "use_constant") { m_test_mode = USE_CONSTANT_VALUE; }
71  else { yCError(FAKE_LASER) << "invalid/unknown value for param 'test'"; return false; }
72 
73  //parse all the parameters related to the linear/angular range of the sensor
74  if (this->parseConfiguration(config) == false)
75  {
76  yCError(FAKE_LASER) << ": error parsing parameters";
77  return false;
78  }
79 
80  //the different fake laser modalities
81  else if (m_test_mode == USE_CONSTANT_VALUE)
82  {
83  if (config.check("const_distance"))
84  {
85  m_const_value = config.check("const_distance", Value(1.0), "default constant distance").asFloat64();
86  }
87  }
88  else if (m_test_mode == USE_MAPFILE)
89  {
90  std::string map_file;
91  if (config.check("map_context") && config.check("map_file"))
92  {
94  std::string tmp_filename = config.find("map_file").asString();
95  std::string tmp_contextname = config.find("map_context").asString();
96  rf.setDefaultContext(tmp_contextname);
97  rf.setDefaultConfigFile(tmp_filename);
98  bool b = rf.configure(0, nullptr);
99  if (b)
100  {
101  map_file = rf.findFile(tmp_filename);
102  if (map_file == "")
103  {
104  yCWarning(FAKE_LASER, "Unable to find file: %s from context: %s\n", tmp_filename.c_str(), tmp_contextname.c_str());
105  }
106  }
107  else
108  {
109  yCWarning(FAKE_LASER, "Unable to find file: %s from context: %s\n", tmp_filename.c_str(), tmp_contextname.c_str());
110  }
111  }
112  else if (config.check("map_file"))
113  {
114  map_file = config.check("map_file", Value(std::string("map.yaml")), "map filename").asString();
115  }
116  else
117  {
118  yCError(FAKE_LASER) << "Missing `map_file` or `map_context`+`map_file` parameters";
119  return false;
120  }
121 
122  if (map_file=="")
123  {
124  yCError(FAKE_LASER) << "File not found";
125  return false;
126  }
127  bool ret = m_originally_loaded_map.loadFromFile(map_file);
128  if (ret == false)
129  {
130  yCError(FAKE_LASER) << "A problem occurred while opening:" << map_file;
131  return false;
132  }
133  m_map = m_originally_loaded_map;
134 
135  if (config.check("localization_port"))
136  {
137  std::string localization_port_name = config.check("localization_port", Value(std::string("/fakeLaser/location:i")), "name of localization input port").asString();
139  m_loc_port->open(localization_port_name);
140  yCInfo(FAKE_LASER) << "Robot localization will be obtained from port" << localization_port_name;
141  m_loc_mode = LOC_FROM_PORT;
142  }
143  else if (config.check("localization_client") ||
144  config.check("localization_server" ))
145  {
146  Property loc_options;
147  std::string localization_client_name = config.check("localization_client", Value(std::string("/fakeLaser/localizationClient")), "local name of localization client device").asString();
148  std::string localization_server_name = config.check("localization_server", Value(std::string("/localizationServer")), "the name of the remote localization server device").asString();
149  loc_options.put("device", "localization2DClient");
150  loc_options.put("local", localization_client_name);
151  loc_options.put("remote", localization_server_name);
152  loc_options.put("period", 10);
153  m_pLoc = new PolyDriver;
154  if (m_pLoc->open(loc_options) == false)
155  {
156  yCError(FAKE_LASER) << "Unable to open localization driver";
157  return false;
158  }
159  m_pLoc->view(m_iLoc);
160  if (m_iLoc == nullptr)
161  {
162  yCError(FAKE_LASER) << "Unable to open localization interface";
163  return false;
164  }
165  yCInfo(FAKE_LASER) << "Robot localization will be obtained from localization server: " << localization_server_name;
166  m_loc_mode = LOC_FROM_CLIENT;
167  }
168  else
169  {
170  yCInfo(FAKE_LASER) << "No localization method selected. Robot location set to 0,0,0";
171  m_loc_mode = LOC_NOT_SET;
172  }
173 
174  m_robot_loc_x=0;
175  m_robot_loc_y=0;
176  m_robot_loc_t=0;
177  }
178 
179  yCInfo(FAKE_LASER) << "Starting debug mode";
180  yCInfo(FAKE_LASER) << "test mode:"<< m_test_mode;
181 
182  if (!m_rpcPort.open("/fakeLaser/rpc:i"))
183  {
184  yCError(FAKE_LASER, "Failed to open port %s", "/fakeLaser/rpc:i");
185  return false;
186  }
187  m_rpcPort.setReader(*this);
188 
189  return PeriodicThread::start();
190 }
191 
193 {
194  PeriodicThread::stop();
195 
196  driver.close();
197 
198  if (m_loc_port)
199  {
201  m_loc_port->close();
202  }
203  return true;
204 }
205 
206 bool FakeLaser::setDistanceRange(double min, double max)
207 {
208  m_mutex.lock();
209  m_min_distance = min;
210  m_max_distance = max;
211  m_mutex.unlock();
212  return true;
213 }
214 
215 bool FakeLaser::setScanLimits(double min, double max)
216 {
217  m_mutex.lock();
218  m_min_angle = min;
219  m_max_angle = max;
220  m_mutex.unlock();
221  return true;
222 }
223 
225 {
226  m_mutex.lock();
227  m_resolution = step;
228  m_mutex.unlock();
229  return true;
230 }
231 
232 bool FakeLaser::setScanRate(double rate)
233 {
234  m_mutex.lock();
235  m_period = (1.0 / rate);
236  m_mutex.unlock();
237  return false;
238 }
239 
241 {
242 #ifdef LASER_DEBUG
243  yCDebug(FAKE_LASER)<<"thread initialising...\n");
244  yCDebug(FAKE_LASER)<<"... done!\n");
245 #endif
246 
247  return true;
248 }
249 
250 
251 bool FakeLaser::LiangBarsky_clip(int edgeLeft, int edgeRight, int edgeTop, int edgeBottom,
253  XYCell& src_clipped, XYCell& dst_clipped)
254 {
255  double t0 = 0.0; double t1 = 1.0;
256  double xdelta = double(dst.x - src.x);
257  double ydelta = double(dst.y - src.y);
258  double p, q, r;
259 
260  for (int edge = 0; edge < 4; edge++)
261  {
262  if (edge == 0) { p = -xdelta; q = -(edgeLeft - src.x); }
263  if (edge == 1) { p = xdelta; q = (edgeRight - src.x); }
264  if (edge == 2) { p = -ydelta; q = -(edgeTop - src.y); }
265  if (edge == 3) { p = ydelta; q = (edgeBottom - src.y); }
266  r = q / p;
267  if (p == 0 && q < 0) {return false;} //line is outside (parallel)
268 
269  if (p < 0)
270  {
271  if (r > t1) {return false;} //line is outside.
272  else if (r > t0) {t0 = r;} //line is clipped
273  }
274  else if (p > 0)
275  {
276  if (r < t0) {return false;} //line is outside.
277  else if (r < t1) {t1 = r;} //line is clipped
278  }
279  }
280 
281  src_clipped.x = size_t(double(src.x) + t0 * xdelta);
282  src_clipped.y = size_t(double(src.y) + t0 * ydelta);
283  dst_clipped.x = size_t(double(src.x) + t1 * xdelta);
284  dst_clipped.y = size_t(double(src.y) + t1 * ydelta);
285 
286  return true; //line is clipped
287 }
288 
290 {
292  double t = yarp::os::Time::now();
293  static double t_orig = yarp::os::Time::now();
294  double size = (t - (t_orig));
295 
296  static int test_count = 0;
297  static int test = 0;
298 
299  if (m_test_mode == USE_PATTERN)
300  {
301  for (size_t i = 0; i < m_sensorsNum; i++)
302  {
303  double value = 0;
304  if (test == 0)
305  {
306  value = i / 100.0;
307  }
308  else if (test == 1)
309  {
310  value = size * 2;
311  }
312  else if (test == 2)
313  {
314  if (i <= 10) { value = 1.0 + i / 20.0; }
315  else if (i >= 90 && i <= 100) { value = 2.0 + (i - 90) / 20.0; }
316  else { value = m_min_distance; }
317  }
318  m_laser_data.push_back(value);
319  }
320 
321  test_count++;
322  if (test_count == 60)
323  {
324  test_count = 0; test++; if (test > 2) { test = 0; }
325  t_orig = yarp::os::Time::now();
326  }
327  }
328  else if (m_test_mode == NO_OBSTACLES)
329  {
330  for (size_t i = 0; i < m_sensorsNum; i++)
331  {
332  m_laser_data.push_back(std::numeric_limits<double>::infinity());
333  }
334  }
335  else if (m_test_mode == USE_CONSTANT_VALUE)
336  {
337  for (size_t i = 0; i < m_sensorsNum; i++)
338  {
340  }
341  }
342  else if (m_test_mode == USE_MAPFILE)
343  {
344  if (m_loc_mode == LOC_NOT_SET)
345  {
346  //do nothing
347  }
348  else if (m_loc_mode == LOC_FROM_PORT)
349  {
350  Bottle* b = m_loc_port->read(false);
351  if (b)
352  {
353  m_robot_loc_x = b->get(0).asFloat64();
354  m_robot_loc_y = b->get(1).asFloat64();
355  m_robot_loc_t = b->get(2).asFloat64();
356  }
357  }
358  else if (m_loc_mode == LOC_FROM_CLIENT)
359  {
360  Map2DLocation loc;
361  if (m_iLoc->getCurrentPosition(loc))
362  {
363  m_robot_loc_x = loc.x;
364  m_robot_loc_y = loc.y;
365  m_robot_loc_t = loc.theta;
366  }
367  else
368  {
369  yCError(FAKE_LASER) << "Error occurred while getting current position from localization server";
370  }
371  }
372  else
373  {
374  yCDebug(FAKE_LASER) << "No localization mode selected. This branch should be not reachable.";
375  }
376 
377  for (size_t i = 0; i < m_sensorsNum; i++)
378  {
379  //compute the ray in the robot reference frame
380  double ray_angle = i * m_resolution + m_min_angle;
381  double ray_target_x = m_max_distance * cos(ray_angle * DEG2RAD);
382  double ray_target_y = m_max_distance * sin(ray_angle * DEG2RAD);
383 
384  //transforms the ray from the robot to the world reference frame
385  XYWorld ray_world;
386  ray_world.x = ray_target_x * cos(m_robot_loc_t * DEG2RAD) - ray_target_y * sin(m_robot_loc_t * DEG2RAD) + m_robot_loc_x;
387  ray_world.y = ray_target_x * sin(m_robot_loc_t * DEG2RAD) + ray_target_y * cos(m_robot_loc_t * DEG2RAD) + m_robot_loc_y;
389 
390  //beware! src is the robot position and it is always inside the image.
391  //dst is the end of the ray, and it can be out of the image!
392  //for this reason i am not going to call world2Cell() on dst, because that functions clips the point to the border without
393  //knowing the angular coefficient of the ray. I thus need the unclipped value, and run the LiangBarsky algorithm
394  //(which knows the angular coefficient of the ray) on it.
395  XYWorld ray_world_rot;
396  XYCell_unbounded dst;
397  ray_world_rot.x = ray_world.x * m_map.m_origin.get_ca() - ray_world.y * m_map.m_origin.get_sa();
398  ray_world_rot.y = ray_world.x * m_map.m_origin.get_sa() + ray_world.y * m_map.m_origin.get_ca();
399  dst.x = int((+ray_world_rot.x - this->m_map.m_origin.get_x()) / this->m_map.m_resolution) + 0;
400  dst.y = int((-ray_world_rot.y + this->m_map.m_origin.get_y()) / this->m_map.m_resolution) + (int)m_map.m_height - 1;
401 
402  XYCell newsrc;
403  XYCell newdst;
404  double distance;
405  if (LiangBarsky_clip(0, (int)m_map.width(), 0, (int)m_map.height(),
406  XYCell_unbounded(src.x, src.y), dst, newsrc, newdst))
407  {
408  distance = checkStraightLine(src, newdst);
409  double simulated_noise = (*m_dis)(*m_gen);
410  m_laser_data.push_back(distance + simulated_noise);
411  }
412  else
413  {
414  //This should never happen, unless the robot is outside the map!
415  yDebug() << "Robot is outside the map?!";
416  m_laser_data.push_back(std::numeric_limits<double>::infinity());
417  }
418 
419  }
420  }
421 
422  //set the device status
424 
425  return true;
426 }
427 
429 {
430  m_mutex.lock();
431  updateLidarData();
432  m_mutex.unlock();
433  return;
434 }
435 
436 void FakeLaser::wall_the_robot(double siz, double dist)
437 {
438  //double res;
439  //m_map.getResolution(res);
440  //size_t siz_cell = siz / res;
441  //size_t dist_cell = dist / res;
443 
444  XYWorld ray_start;
445  XYWorld start (0+dist, 0 - siz);
446  ray_start.x = start.x * cos(m_robot_loc_t * DEG2RAD) - start.y * sin(m_robot_loc_t * DEG2RAD) + m_robot_loc_x;
447  ray_start.y = start.x * sin(m_robot_loc_t * DEG2RAD) + start.y * cos(m_robot_loc_t * DEG2RAD) + m_robot_loc_y;
448  XYCell start_cell = m_map.world2Cell(ray_start);
449 
450  XYWorld ray_end;
451  XYWorld end(0 + dist, 0 + siz);
452  ray_end.x = end.x * cos(m_robot_loc_t * DEG2RAD) - end.y * sin(m_robot_loc_t * DEG2RAD) + m_robot_loc_x;
453  ray_end.y = end.x * sin(m_robot_loc_t * DEG2RAD) + end.y * cos(m_robot_loc_t * DEG2RAD) + m_robot_loc_y;
454  XYCell end_cell = m_map.world2Cell(ray_end);
455 
456  drawStraightLine(start_cell,end_cell);
457 }
458 
459 void FakeLaser::obst_the_robot(double siz, double dist)
460 {
461  //NOT YET IMPLEMENTED
462  /*double res;
463  m_map.getResolution(res);
464  size_t siz_cell = size_t(siz / res);
465  size_t dist_cell = size_t(dist / res);
466  XYCell robot = m_map.world2Cell(XYWorld(m_robot_loc_x, m_robot_loc_y));*/
467 }
468 
469 void FakeLaser::trap_the_robot(double siz)
470 {
471  double res;
472  m_map.getResolution(res);
473  size_t siz_cell = size_t(siz / res);
475  for (size_t x= robot.x- siz_cell; x< robot.x + siz_cell; x++)
476  {
477  size_t y=robot.y- siz_cell;
478  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
479  }
480  for (size_t x = robot.x - siz_cell; x < robot.x + siz_cell; x++)
481  {
482  size_t y = robot.y + siz_cell;
483  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
484  }
485  for (size_t y = robot.y - siz_cell; y < robot.y + siz_cell; y++)
486  {
487  size_t x = robot.x - siz_cell;
488  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
489  }
490  for (size_t y = robot.y - siz_cell; y < robot.y + siz_cell; y++)
491  {
492  size_t x = robot.x + siz_cell;
493  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
494  }
495 }
496 
497 void FakeLaser::free_the_robot()
498 {
500 }
501 
503 {
504  yarp::os::Bottle command;
505  yarp::os::Bottle reply;
506  bool ok = command.read(connection);
507  if (!ok) {
508  return false;
509  }
510  reply.clear();
511 
512  if (command.get(0).asString() == "trap")
513  {
514  if (command.size() == 1)
515  {
516  trap_the_robot();
517  reply.addVocab32(VOCAB_OK);
518  }
519  else if (command.size() == 2)
520  {
521  trap_the_robot(command.get(1).asFloat64());
522  reply.addVocab32(VOCAB_OK);
523  }
524  else
525  {
526  reply.addVocab32(VOCAB_ERR);
527  }
528  }
529  else if (command.get(0).asString() == "wall")
530  {
531  if (command.size() == 1)
532  {
533  wall_the_robot(1.0, 1.0);
534  wall_the_robot(1.0, 1.05);
535  reply.addVocab32(VOCAB_OK);
536  }
537  else if (command.size() == 2)
538  {
539  wall_the_robot(command.get(1).asFloat64(), 1.0);
540  wall_the_robot(command.get(1).asFloat64(), 1.05);
541  reply.addVocab32(VOCAB_OK);
542  }
543  else if (command.size() == 3)
544  {
545  wall_the_robot(command.get(1).asFloat64(), command.get(2).asFloat64());
546  wall_the_robot(command.get(1).asFloat64(), command.get(2).asFloat64()+0.05);
547  reply.addVocab32(VOCAB_OK);
548  }
549  else
550  {
551  reply.addVocab32(VOCAB_ERR);
552  }
553  }
554  else if (command.get(0).asString() == "free")
555  {
556  free_the_robot();
557  reply.addVocab32(VOCAB_OK);
558  }
559  else if (command.get(0).asString() == "help")
560  {
561  reply.addVocab32("many");
562  reply.addString("wall <size> <distance>: creates a wall in front of the robot");
563  reply.addString("trap <size>: traps the robot in a box obstacle");
564  reply.addString("free: removes all generated obstacles");
565  }
566  else
567  {
568  yCError(FAKE_LASER) << "Invalid command";
569  reply.addVocab32(VOCAB_ERR);
570  }
571 
572  yarp::os::ConnectionWriter* returnToSender = connection.getWriter();
573  if (returnToSender != nullptr)
574  {
575  reply.write(*returnToSender);
576  }
577  return true;
578 }
579 
580 
581 void FakeLaser::drawStraightLine(XYCell src, XYCell dst)
582 {
583  long int x, y;
584  long int dx, dy, dx1, dy1, px, py, xe, ye, i;
585  dx = (long int)dst.x - (long int)src.x;
586  dy = (long int)dst.y - (long int)src.y;
587  dx1 = abs(dx);
588  dy1 = abs(dy);
589  px = 2 * dy1 - dx1;
590  py = 2 * dx1 - dy1;
591  if (dy1 <= dx1)
592  {
593  if (dx >= 0)
594  {
595  x = (long int)src.x;
596  y = (long int)src.y;
597  xe = (long int)dst.x;
598  }
599  else
600  {
601  x = (long int)dst.x;
602  y = (long int)dst.y;
603  xe = (long int)src.x;
604  }
605  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
606  for (i = 0; x < xe; i++)
607  {
608  x = x + 1;
609  if (px < 0)
610  {
611  px = px + 2 * dy1;
612  }
613  else
614  {
615  if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
616  {
617  y = y + 1;
618  }
619  else
620  {
621  y = y - 1;
622  }
623  px = px + 2 * (dy1 - dx1);
624  }
625  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
626  }
627  }
628  else
629  {
630  if (dy >= 0)
631  {
632  x = (long int)src.x;
633  y = (long int)src.y;
634  ye = (long int)dst.y;
635  }
636  else
637  {
638  x = (long int)dst.x;
639  y = (long int)dst.y;
640  ye = (long int)src.y;
641  }
642  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
643  for (i = 0; y < ye; i++)
644  {
645  y = y + 1;
646  if (py <= 0)
647  {
648  py = py + 2 * dx1;
649  }
650  else
651  {
652  if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
653  {
654  x = x + 1;
655  }
656  else
657  {
658  x = x - 1;
659  }
660  py = py + 2 * (dx1 - dy1);
661  }
662  m_map.setMapFlag(XYCell(x, y), yarp::dev::Nav2D::MapGrid2D::map_flags::MAP_CELL_WALL);
663  }
664  }
665 }
666 
667 double FakeLaser::checkStraightLine(XYCell src, XYCell dst)
668 {
669  //BEWARE: src and dest must be already clipped and >0 in this function
670  XYCell test_point;
671  test_point.x = src.x;
672  test_point.y = src.y;
673 
674  //here using the fast Bresenham algorithm
675  int dx = abs(int(dst.x - src.x));
676  int dy = abs(int(dst.y - src.y));
677  int err = dx - dy;
678 
679  int sx;
680  int sy;
681  if (src.x < dst.x) { sx = 1; } else { sx = -1; }
682  if (src.y < dst.y) { sy = 1; } else { sy = -1; }
683 
684  while (true)
685  {
686  //the test point is going to move from src until it reaches dst OR
687  //if it reaches the boundaries of the image
688  if (test_point.x==0 || test_point.y ==0 || test_point.x>=m_map.width() || test_point.y>=m_map.height())
689  {
690  break;
691  }
692 
693  //if (m_map.isFree(src) == false)
694  if (m_map.isWall(XYCell(test_point.x,test_point.y)))
695  {
696  XYWorld world_start = m_map.cell2World(src);
697  XYWorld world_end = m_map.cell2World(XYCell(test_point.x, test_point.y));
698  double dist = sqrt(pow(world_start.x - world_end.x, 2) + pow(world_start.y - world_end.y, 2));
699  return dist;
700  }
701 
702  if (test_point.x == dst.x && test_point.y == dst.y)
703  {
704  break;
705  }
706 
707  int e2 = err * 2;
708  if (e2 > -dy)
709  {
710  err = err - dy;
711  test_point.x += sx;
712  }
713  if (e2 < dx)
714  {
715  err = err + dx;
716  test_point.y += sy;
717  }
718  }
719  return std::numeric_limits<double>::infinity();
720 }
721 
723 {
724 #ifdef LASER_DEBUG
725  yCDebug(FAKE_LASER) << "FakeLaser Thread releasing...");
726  yCDebug(FAKE_LASER) << "... done.");
727 #endif
728 }
float t
constexpr yarp::conf::vocab32_t VOCAB_OK
Definition: GenericVocabs.h:15
constexpr yarp::conf::vocab32_t VOCAB_ERR
Definition: GenericVocabs.h:17
bool ret
#define yDebug(...)
Definition: Log.h:234
fakeLaser : fake sensor device driver for testing purposes and reference for IRangefinder2D devices.
Definition: fakeLaser.h:62
double m_robot_loc_y
Definition: fakeLaser.h:80
double m_robot_loc_x
Definition: fakeLaser.h:79
double m_period
Definition: fakeLaser.h:71
void run() override
Loop function.
Definition: fakeLaser.cpp:428
yarp::dev::Nav2D::MapGrid2D m_map
Definition: fakeLaser.h:73
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
Definition: fakeLaser.cpp:502
bool setDistanceRange(double min, double max) override
set the device detection range.
Definition: fakeLaser.cpp:206
double m_robot_loc_t
Definition: fakeLaser.h:81
@ USE_CONSTANT_VALUE
Definition: fakeLaser.h:64
@ NO_OBSTACLES
Definition: fakeLaser.h:64
@ USE_MAPFILE
Definition: fakeLaser.h:64
@ USE_PATTERN
Definition: fakeLaser.h:64
bool acquireDataFromHW() override final
This method should be implemented by the user, and contain the logic to grab data from the hardware.
Definition: fakeLaser.cpp:289
yarp::dev::Nav2D::ILocalization2D * m_iLoc
Definition: fakeLaser.h:76
localization_mode_t m_loc_mode
Definition: fakeLaser.h:69
bool threadInit() override
Initialization method.
Definition: fakeLaser.cpp:240
yarp::os::BufferedPort< yarp::os::Bottle > * m_loc_port
Definition: fakeLaser.h:74
yarp::dev::PolyDriver driver
Definition: fakeLaser.h:67
test_mode_t m_test_mode
Definition: fakeLaser.h:68
bool setScanRate(double rate) override
set the scan rate (scans per seconds)
Definition: fakeLaser.cpp:232
bool setScanLimits(double min, double max) override
set the scan angular range.
Definition: fakeLaser.cpp:215
bool close() override
Close the DeviceDriver.
Definition: fakeLaser.cpp:192
void threadRelease() override
Release method.
Definition: fakeLaser.cpp:722
yarp::dev::Nav2D::MapGrid2D m_originally_loaded_map
Definition: fakeLaser.h:72
@ LOC_NOT_SET
Definition: fakeLaser.h:65
@ LOC_FROM_CLIENT
Definition: fakeLaser.h:65
@ LOC_FROM_PORT
Definition: fakeLaser.h:65
bool setHorizontalResolution(double step) override
get the angular step between two measurments (if available)
Definition: fakeLaser.cpp:224
double m_const_value
Definition: fakeLaser.h:86
virtual bool updateLidarData()
This utility method calls in sequence: grabDataFromHW(), updateTimestamp and applyLimitsOnLaserData()...
yarp::dev::IRangefinder2D::Device_status m_device_status
virtual bool getCurrentPosition(yarp::dev::Nav2D::Map2DLocation &loc)=0
Gets the current position of the robot w.r.t world reference frame.
XYCell world2Cell(XYWorld world) const
XYWorld cell2World(XYCell cell) const
MapGrid2DOrigin m_origin
pose of the map frame w.r.t. the bottom left corner of the map image
Definition: MapGrid2DInfo.h:57
size_t height() const
Retrieves the map height, expressed in cells.
Definition: MapGrid2D.cpp:177
bool setMapFlag(XYCell cell, map_flags flag)
Set the flag of a specific cell of the map.
Definition: MapGrid2D.cpp:1136
size_t width() const
Retrieves the map width, expressed in cells.
Definition: MapGrid2D.cpp:182
bool isWall(XYCell cell) const
Checks if a specific cell of the map contains a wall.
Definition: MapGrid2D.cpp:164
void getResolution(double &resolution) const
Retrieves the resolution of the map, i.e.
Definition: MapGrid2D.cpp:1069
A container for a device driver.
Definition: PolyDriver.h:24
bool close() override
Close the DeviceDriver.
Definition: PolyDriver.cpp:173
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:74
void addVocab32(yarp::conf::vocab32_t x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:164
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:251
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:240
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:246
void clear()
Empties the bottle of any objects it contains.
Definition: Bottle.cpp:121
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
Definition: Bottle.cpp:230
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:170
void close() override
Stop port activity.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void interrupt() override
Interrupt any current reads or writes attached to the port.
T * read(bool shouldWait=true) override
Read an available object from the port.
An interface for reading from a network connection.
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
An interface for writing to a network connection.
bool start()
Call this to start the thread.
void step()
Call this to "step" the thread rather than starting it.
A class for storing options and configuration information.
Definition: Property.h:34
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:1015
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Property.cpp:1041
Helper class for finding config files and other external resources.
bool setDefaultContext(const std::string &contextName)
Sets the context for the current ResourceFinder object.
bool configure(int argc, char *argv[], bool skipFirstArgument=true)
Sets up the ResourceFinder.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
std::string findFile(const std::string &name)
Find the full path to a file.
bool setDefaultConfigFile(const std::string &fname)
Provide a default value for the configuration file (can be overridden from command line with the –fro...
A base class for nested structures that can be searched.
Definition: Searchable.h:66
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
A single value (typically within a Bottle).
Definition: Value.h:45
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition: Value.cpp:222
virtual std::string asString() const
Get string value.
Definition: Value.cpp:234
void push_back(const T &elem)
Push a new element in the vector: size is changed.
Definition: Vector.h:250
const yarp::os::LogComponent & FAKE_LASER()
Definition: fakeLaser.cpp:26
#define DEG2RAD
Definition: fakeLaser.cpp:23
#define yCInfo(component,...)
Definition: LogComponent.h:132
#define yCError(component,...)
Definition: LogComponent.h:154
#define yCWarning(component,...)
Definition: LogComponent.h:143
#define yCDebug(component,...)
Definition: LogComponent.h:109
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:77
yarp::math::Vec2D< size_t > XYCell
Definition: NavTypes.h:21
yarp::math::Vec2D< double > XYWorld
Definition: NavTypes.h:22
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:121
The main, catch-all namespace for YARP.
Definition: dirs.h:16