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