DSObstacleAvoidance.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotAPI::ArmarXObjects::DSObstacleAvoidance
17 * @author Christian R. G. Dreher <c.dreher@kit.edu>
18 * @date 2020
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23
25
26
27// STD/STL
28#include <cmath>
29#include <fstream>
30#include <limits>
31#include <map>
32#include <memory>
33#include <mutex>
34#include <string>
35
36// Simox
37#include <SimoxUtility/json.h>
38#include <SimoxUtility/math/convert.h>
39#include <VirtualRobot/Robot.h>
40
41// Ice
42#include <Ice/Current.h>
43
44// DynamicObstacleAvoidance
45#include <DynamicObstacleAvoidance/Modulation.hpp>
46#include <DynamicObstacleAvoidance/Obstacle/Ellipsoid.hpp>
47#include <DynamicObstacleAvoidance/Utils/Plotting/PlottingTools.hpp>
48namespace doa = DynamicObstacleAvoidance;
49
50// ArmarX
53
54// RobotAPI
56
57namespace
58{
59
60 std::shared_ptr<doa::Obstacle>
61 create_doa_obstacle(const armarx::obstacledetection::Obstacle& obstacle)
62 {
63 Eigen::Vector3d pos(obstacle.posX, obstacle.posY, obstacle.posZ);
64 Eigen::Quaterniond ori{Eigen::AngleAxisd(obstacle.yaw, Eigen::Vector3d::UnitZ())};
65
66 std::shared_ptr<doa::Ellipsoid> obstacle_ptr =
67 std::make_shared<doa::Ellipsoid>(obstacle.name,
68 doa::State(pos / 1000, ori),
69 Eigen::Array3d(obstacle.safetyMarginX / 1000,
70 obstacle.safetyMarginY / 1000,
71 obstacle.safetyMarginZ / 1000));
72
73 obstacle_ptr->set_axis_lengths(
74 Eigen::Array3d(obstacle.axisLengthX, obstacle.axisLengthY, obstacle.axisLengthZ) /
75 1000);
76 obstacle_ptr->set_reference_position(
77 Eigen::Vector3d(obstacle.refPosX, obstacle.refPosY, obstacle.refPosZ) / 1000);
78 obstacle_ptr->set_curvature_factor(
79 Eigen::Array3d(obstacle.curvatureX, obstacle.curvatureY, obstacle.curvatureZ));
80
81 return obstacle_ptr;
82 }
83
84} // namespace
85
87{
88
89 void
90 from_json(const nlohmann::json& j, armarx::obstacledetection::Obstacle& obstacle)
91 {
92 j.at("name").get_to(obstacle.name);
93 j.at("posX").get_to(obstacle.posX);
94 j.at("posY").get_to(obstacle.posY);
95 if (j.find("posZ") != j.end())
96 {
97 j.at("posZ").get_to(obstacle.posZ);
98 }
99 j.at("yaw").get_to(obstacle.yaw);
100 j.at("axisLengthX").get_to(obstacle.axisLengthX);
101 j.at("axisLengthY").get_to(obstacle.axisLengthY);
102 if (j.find("axisLengthZ") != j.end())
103 {
104 j.at("axisLengthZ").get_to(obstacle.axisLengthZ);
105 }
106 j.at("refPosX").get_to(obstacle.refPosX);
107 j.at("refPosY").get_to(obstacle.refPosY);
108 if (j.find("refPosZ") != j.end())
109 {
110 j.at("refPosZ").get_to(obstacle.refPosZ);
111 }
112 if (j.find("safetyMarginX") != j.end())
113 {
114 j.at("safetyMarginX").get_to(obstacle.safetyMarginX);
115 }
116 if (j.find("safetyMarginY") != j.end())
117 {
118 j.at("safetyMarginY").get_to(obstacle.safetyMarginY);
119 }
120 if (j.find("safetyMarginZ") != j.end())
121 {
122 j.at("safetyMarginZ").get_to(obstacle.safetyMarginZ);
123 }
124 if (j.find("curvatureX") != j.end())
125 {
126 j.at("curvatureX").get_to(obstacle.curvatureX);
127 }
128 if (j.find("curvatureY") != j.end())
129 {
130 j.at("curvatureY").get_to(obstacle.curvatureY);
131 }
132 if (j.find("curvatureZ") != j.end())
133 {
134 j.at("curvatureZ").get_to(obstacle.curvatureZ);
135 }
136 }
137
138} // namespace armarx::obstacledetection
139
140const std::string armarx::DSObstacleAvoidance::default_name = "DSObstacleAvoidance";
141
143{
144 // DOA config.
145 m_doa.cfg.only_2d = true;
146 m_doa.cfg.aggregated = true;
147 m_doa.cfg.agent_safety_margin = 0;
148 m_doa.cfg.local_modulation = false;
149 m_doa.cfg.repulsion = true;
150 m_doa.cfg.planar_modulation = false;
151 m_doa.cfg.critical_distance = 1.0;
152 m_doa.cfg.weight_power = 2.0;
153}
154
155void
157{
158 ARMARX_DEBUG << "Initializing " << getName() << ".";
159
160 m_buf.needs_env_update = false;
161
162 m_doa.env.set_aggregated(m_doa.cfg.aggregated);
163
164 if (not m_doa.load_obstacles_from_file.empty())
165 {
166 const std::filesystem::path scene_obstacles_path =
167 ArmarXDataPath::getAbsolutePath(m_doa.load_obstacles_from_file);
168 std::ifstream ifs(scene_obstacles_path);
169 nlohmann::json j = nlohmann::json::parse(ifs);
170
171 std::vector<obstacledetection::Obstacle> obstacles = j;
172 for (obstacledetection::Obstacle& obstacle : obstacles)
173 {
174 if (m_doa.cfg.only_2d)
175 {
176 obstacle.posZ = 0;
177 obstacle.axisLengthZ = 0;
178 obstacle.refPosZ = 0;
179 obstacle.safetyMarginZ = 0;
180 obstacle.curvatureZ = 1;
181 }
182
183 sanity_check_obstacle(obstacle);
184
185 m_doa.env.add_obstacle(::create_doa_obstacle(obstacle));
186 }
187
188 m_doa.env.update();
189 }
190
191 writeDebugPlots("doa_upstart");
192
193 ARMARX_DEBUG << "Initialized " << getName() << ".";
194}
195
196void
198{
199 ARMARX_DEBUG << "Connecting " << getName() << ".";
200
201 if (m_vis.enabled)
202 {
203 m_vis.task = new PeriodicTask<DSObstacleAvoidance>(
204 this, &DSObstacleAvoidance::run_visualization, m_vis.task_interval);
205 m_vis.task->start();
206 }
207
208 if (m_watchdog.enabled)
209 {
210 m_watchdog.task = new PeriodicTask<DSObstacleAvoidance>(
211 this, &DSObstacleAvoidance::run_watchdog, m_watchdog.task_interval);
212 m_watchdog.task->start();
213 }
214
215 ARMARX_DEBUG << "Connected " << getName() << ".";
216}
217
218void
220{
221 ARMARX_DEBUG << "Disconnecting " << getName() << ".";
222
223 if (m_vis.enabled)
224 {
225 m_vis.task->stop();
226 }
227
228 if (m_watchdog.enabled)
229 {
230 m_watchdog.task->stop();
231 }
232
233 ARMARX_DEBUG << "Disconnected " << getName() << ".";
234}
235
236void
238{
239 ARMARX_DEBUG << "Exiting " << getName() << ".";
240
241 ARMARX_DEBUG << "Exited " << getName() << ".";
242}
243
244std::string
249
250armarx::dsobstacleavoidance::Config
252{
253 return m_doa.cfg;
254}
255
256void
257armarx::DSObstacleAvoidance::updateObstacle(const armarx::obstacledetection::Obstacle& obstacle,
258 const Ice::Current&)
259{
260 ARMARX_DEBUG << "Adding/updating obstacle: " << obstacle.name << ".";
261
262 std::unique_lock l{m_buf.mutex};
263
264 sanity_check_obstacle(obstacle);
265
266 buffer::update update;
267 update.time = IceUtil::Time::now();
268 update.name = obstacle.name;
269 update.type = buffer::update_type::update;
270
271 m_buf.update_log.push_back(update);
272 m_buf.obstacles[obstacle.name] = obstacle;
273 m_buf.needs_env_update = true;
274
275 ARMARX_DEBUG << "Added/updated obstacle: " << obstacle.name << ".";
276}
277
278void
279armarx::DSObstacleAvoidance::removeObstacle(const std::string& obstacle_name, const Ice::Current&)
280{
281 ARMARX_DEBUG << "Removing obstacle: " << obstacle_name << ".";
282
283 std::unique_lock l{m_buf.mutex};
284
285 buffer::update update;
286 update.time = IceUtil::Time::now();
287 update.name = obstacle_name;
288 update.type = buffer::update_type::removal;
289
290 m_buf.update_log.push_back(update);
291 m_buf.needs_env_update = true;
292
293 ARMARX_DEBUG << "Removed obstacle: " << obstacle_name << ".";
294}
295
296std::vector<armarx::obstacledetection::Obstacle>
298{
299 ARMARX_DEBUG << "Get Obstacles";
300 std::shared_lock l{m_doa.mutex};
301
302 std::vector<obstacledetection::Obstacle> obstacle_list;
303
304 for (auto& [doa_name, doa_obstacle] : m_doa.env)
305 {
306 ARMARX_DEBUG << "Got an obtascle";
307 std::shared_ptr<doa::Ellipsoid> doa_ellipsoid =
308 std::dynamic_pointer_cast<doa::Ellipsoid>(doa_obstacle);
309 obstacledetection::Obstacle obstacle;
310
311 obstacle.name = doa_name;
312 obstacle.posX = doa_ellipsoid->get_position()(0) * 1000;
313 obstacle.posY = doa_ellipsoid->get_position()(1) * 1000;
314 obstacle.posZ = doa_ellipsoid->get_position()(2) * 1000;
315 obstacle.yaw = simox::math::mat3f_to_rpy(
316 doa_ellipsoid->get_orientation().toRotationMatrix().cast<float>())
317 .z();
318 obstacle.axisLengthX = doa_ellipsoid->get_axis_lengths(0) * 1000;
319 obstacle.axisLengthY = doa_ellipsoid->get_axis_lengths(1) * 1000;
320 obstacle.axisLengthZ = doa_ellipsoid->get_axis_lengths(2) * 1000;
321 obstacle.refPosX = doa_ellipsoid->get_reference_position()(0) * 1000;
322 obstacle.refPosY = doa_ellipsoid->get_reference_position()(1) * 1000;
323 obstacle.refPosZ = doa_ellipsoid->get_reference_position()(2) * 1000;
324 obstacle.safetyMarginX = doa_ellipsoid->get_safety_margin()(0) * 1000;
325 obstacle.safetyMarginY = doa_ellipsoid->get_safety_margin()(1) * 1000;
326 obstacle.safetyMarginZ = doa_ellipsoid->get_safety_margin()(2) * 1000;
327 obstacle.curvatureX = doa_ellipsoid->get_curvature_factor()(0);
328 obstacle.curvatureY = doa_ellipsoid->get_curvature_factor()(1);
329 obstacle.curvatureZ = doa_ellipsoid->get_curvature_factor()(2);
330
331 ARMARX_DEBUG << "push back " << obstacle.name;
332 obstacle_list.push_back(std::move(obstacle));
333 }
334
335 ARMARX_DEBUG << "Return obstacle list";
336 return obstacle_list;
337}
338
339Eigen::Vector3f
340armarx::DSObstacleAvoidance::modulateVelocity(const obstacleavoidance::Agent& agent,
341 const Ice::Current&)
342{
343
344 ARMARX_DEBUG << "Modulate velocity";
345 std::shared_lock l{m_doa.mutex};
346
347 // Create and initialize agent.
348 doa::Agent doa_agent{agent.safety_margin};
349 {
350 Eigen::Vector3d agent_global_position = agent.pos.cast<double>() / 1000;
351 Eigen::Vector3d agent_velocity = agent.desired_vel.cast<double>() / 1000;
352
353 if (m_doa.cfg.only_2d)
354 {
355 agent_global_position(2) = 0;
356 agent_velocity(2) = 0;
357 }
358
359 doa_agent.set_position(agent_global_position);
360 doa_agent.set_linear_velocity(agent_velocity);
361 }
362
363 // Modulate velocity given the agent, the environment, and additional parameters.
364 Eigen::Vector3d modulated_vel = doa::Modulation::modulate_velocity(doa_agent,
365 m_doa.env,
366 m_doa.cfg.local_modulation,
367 m_doa.cfg.repulsion,
368 m_doa.cfg.planar_modulation,
369 m_doa.cfg.critical_distance,
370 m_doa.cfg.weight_power);
371
372 // Convert output back to mm.
373 modulated_vel *= 1000;
374
375 // Set Z-component to 0 in 2D mode.
376 if (m_doa.cfg.only_2d)
377 {
378 modulated_vel(2) = 0;
379 }
380
381 ARMARX_DEBUG << deactivateSpam(0.3) << "Target vel: " << modulated_vel;
382
383 return modulated_vel.cast<float>();
384}
385
386void
388{
389 ARMARX_VERBOSE << "Updating environment.";
390 std::lock_guard l2{m_vis.mutex};
391 std::lock_guard l{m_doa.mutex};
392
393 // Make working copies of the updates and free them again.
394 std::vector<buffer::update> update_log;
395 std::map<std::string, obstacledetection::Obstacle> obstacles;
396 {
397 std::lock_guard l{m_buf.mutex};
398
399 if (not m_buf.needs_env_update)
400 {
401 ARMARX_DEBUG << "Nothing to do.";
402 return;
403 }
404
405 update_log = m_buf.update_log;
406 obstacles = m_buf.obstacles;
407 m_buf.update_log.clear();
408 m_buf.obstacles.clear();
409 m_buf.needs_env_update = false;
410 m_buf.last_env_update = IceUtil::Time::now();
411 }
412
413 // Update environment.
415 for (const buffer::update& update : update_log)
416 {
417 doa::Environment::iterator it = m_doa.env.find(update.name);
418
419 switch (update.type)
420 {
421 case buffer::update_type::removal:
422 {
423 ARMARX_DEBUG << "Removing obstacle " << update.name << ".";
424 if (it != m_doa.env.end())
425 {
426 m_doa.env.erase(update.name);
427 }
428 else
429 {
430 ARMARX_WARNING << "Tried to remove obstacle " << update.name << ", but this "
431 << "obstacle is unknown to the environment.";
432 }
433 }
434 break;
435 case buffer::update_type::update:
436 {
437 if (it != m_doa.env.end())
438 {
439 ARMARX_DEBUG << "Updating obstacle " << update.name << " with new values.";
440 m_doa.env.erase(update.name);
441 }
442 else
443 {
444 ARMARX_DEBUG << "Adding obstacle " << update.name << ".";
445 }
446
447 const obstacledetection::Obstacle& obstacle = obstacles.at(update.name);
448 m_doa.env.add_obstacle(::create_doa_obstacle(obstacle));
449 }
450 break;
451 }
452 }
453 ARMARX_DEBUG << "Calling update on environment now.";
454 m_doa.env.update();
455
456 {
457 m_vis.needs_update = true;
458 }
459
460 ARMARX_VERBOSE << "Updating environment with " << update_log.size() << " updates took "
461 << sw.stop() << ".";
462}
463
464void
465armarx::DSObstacleAvoidance::writeDebugPlots(const std::string& filename, const Ice::Current&)
466{
467 ARMARX_DEBUG << "Write debug plots";
468 std::shared_lock l{m_doa.mutex};
469
470 const std::string filename_annotated = getName() + "_" + filename;
471 ARMARX_DEBUG << "Writing debug plots to `/tmp/" << filename_annotated << ".png`.";
472
473 const bool show = false;
474 try
475 {
476 doa::PlottingTools::plot_configuration(
477 m_doa.env.get_obstacle_list(), filename_annotated, show, not m_doa.cfg.only_2d);
478 }
479 catch (...)
480 {
481 ARMARX_WARNING << "Tried to write debug plots but failed, probably because "
482 << "`python3-matplotlib` are not installed.";
483 }
484}
485
486void
487armarx::DSObstacleAvoidance::sanity_check_obstacle(
488 const armarx::obstacledetection::Obstacle& obstacle) const
489{
490 ARMARX_DEBUG << "Sanity checking obstacle `" << obstacle.name << "`.";
491
492 const std::string curvature_error = "Curvature must be greater than or equal to 1.";
493 const std::string z_comps_set_error = "2D mode activated. Z-component values must not be set.";
494
495 ARMARX_CHECK_GREATER_EQUAL(obstacle.curvatureX, 1) << curvature_error;
496 ARMARX_CHECK_GREATER_EQUAL(obstacle.curvatureY, 1) << curvature_error;
497 ARMARX_CHECK_GREATER_EQUAL(obstacle.curvatureZ, 1) << curvature_error;
498
499 if (m_doa.cfg.only_2d)
500 {
501 ARMARX_DEBUG << "Additionally sanity checking obstacle `" << obstacle.name
502 << "` for 2D compliance.";
503
504 ARMARX_CHECK_EQUAL(obstacle.posZ, 0) << z_comps_set_error;
505 ARMARX_CHECK_EQUAL(obstacle.refPosZ, 0) << z_comps_set_error;
506 ARMARX_CHECK_EQUAL(obstacle.axisLengthZ, 0) << z_comps_set_error;
507 ARMARX_CHECK_EQUAL(obstacle.safetyMarginZ, 0) << z_comps_set_error;
508 }
509}
510
511void
512armarx::DSObstacleAvoidance::run_visualization()
513{
514 //ARMARX_DEBUG << "Run visualization";
515 using namespace armarx::viz;
516
517 std::lock_guard l{m_vis.mutex};
518 if (not m_vis.needs_update)
519 {
520 return;
521 }
522
523 Layer layer_obs = arviz.layer("obstacles");
524 Layer layer_sms = arviz.layer("safety_margins");
525 Layer layer_rps = arviz.layer("reference_points");
526 Layer layer_bbs = arviz.layer("bounding_boxes");
527
528 for (const obstacledetection::Obstacle& obstacle : getObstacles())
529 {
530 Color color = Color::orange(255, 128);
531 Color color_m = Color::orange(255, 64);
532
533 if (obstacle.name == "human")
534 {
535 color = Color::red(255, 128);
536 color_m = Color::red(255, 64);
537 }
538 else if (not m_doa.cfg.only_2d)
539 {
540 color = Color::blue(255, 128);
541 color_m = Color::blue(255, 64);
542 }
543
544 const double safetyMarginZ = m_doa.cfg.only_2d ? 1 : obstacle.safetyMarginZ;
545 const double posZ = m_doa.cfg.only_2d ? 1 : obstacle.posZ;
546 const double refPosZ = m_doa.cfg.only_2d ? 1 : obstacle.refPosZ;
547 const double axisLengthZ = m_doa.cfg.only_2d ? 1 : obstacle.axisLengthZ;
548
549 const Eigen::Matrix4f pose =
550 simox::math::pos_rpy_to_mat4f(obstacle.posX, obstacle.posY, posZ, 0, 0, obstacle.yaw);
551 const Eigen::Vector3f dim(obstacle.axisLengthX, obstacle.axisLengthY, axisLengthZ);
552 const Eigen::Vector3f sm(obstacle.safetyMarginX, obstacle.safetyMarginY, safetyMarginZ);
553 const Eigen::Vector3f curv(obstacle.curvatureX, obstacle.curvatureY, obstacle.curvatureZ);
554
555 if (m_doa.cfg.only_2d)
556 {
557
558 layer_obs.add(Cylindroid{obstacle.name}
559 .pose(pose)
560 .axisLengths(dim.head<2>())
561 .height(dim(2))
562 .curvature(curv.head<2>())
563 .color(color));
564
565 layer_sms.add(Cylindroid{obstacle.name + "_sm"}
566 .pose(pose)
567 .axisLengths((dim + sm).head<2>())
568 .height(dim(2) + sm(2))
569 .curvature(curv.head<2>())
570 .color(color_m));
571 }
572 else
573 {
574 layer_obs.add(
575 Ellipsoid{obstacle.name}.pose(pose).axisLengths(dim).curvature(curv).color(color));
576
577 layer_sms.add(Ellipsoid{obstacle.name + "_sm"}
578 .pose(pose)
579 .axisLengths(dim + sm)
580 .curvature(curv)
581 .color(color_m));
582 }
583
584 layer_rps.add(Sphere{obstacle.name + "_rp"}
585 .position(Eigen::Vector3f(obstacle.refPosX, obstacle.refPosY, refPosZ))
586 .radius(35)
587 .color(Color::green()));
588
589 layer_bbs.add(Box{obstacle.name + "_bb"}.pose(pose).size(dim).color(color));
590 }
591
592 m_vis.needs_update = false;
593
594 arviz.commit({layer_obs, layer_sms, layer_rps});
595 //arviz.commit(layer_bbs); // Do not render bounding boxes by default.
596}
597
598void
599armarx::DSObstacleAvoidance::run_watchdog()
600{
601 bool needs_env_update;
602 bool was_recently_updated;
603 {
604 std::unique_lock l{m_buf.mutex};
605 needs_env_update = m_buf.needs_env_update;
606 was_recently_updated = IceUtil::Time::now() - m_buf.last_env_update <= m_watchdog.threshold;
607 }
608
609 if (needs_env_update and not was_recently_updated)
610 {
611 ARMARX_WARNING << "Environment has not been updated for over " << m_watchdog.threshold
612 << ". Have you forgotten to call "
613 << "`updateEnvironment()` after adding, updating or removing obstacles? "
614 << "Forcing update now.";
615
616 updateEnvironment();
617 }
618}
619
622{
624
625 def->optional(m_vis.enabled, "visualize", "Enable/disable visualization.");
626 def->optional(m_watchdog.enabled, "udpate_watchdog", "Run environment update watchdog.");
627 def->optional(m_doa.load_obstacles_from_file,
628 "load_obstacles_from",
629 "Path to JSON file to load initial obstacles from.");
630
631 // "doa" namespace for properties that directly configure the library.
632 def->optional(m_doa.cfg.only_2d, "doa.only_2d", "Only consider 2D.");
633 def->optional(m_doa.cfg.aggregated, "doa.aggregated", "Aggregated environment.");
634 def->optional(m_doa.cfg.agent_safety_margin, "doa.agent_safety_margin", "Agent safety margin.");
635 def->optional(m_doa.cfg.local_modulation, "doa.local_modulation", "Local modulation on/off.");
636 def->optional(m_doa.cfg.repulsion, "doa.repulsion", "Repulsion on/off.");
637 def->optional(
638 m_doa.cfg.planar_modulation, "doa.planar_modulation", "Planar modulation on/off.");
639 def->optional(m_doa.cfg.critical_distance, "doa.critical_distance", "Critical distance.");
640 def->optional(m_doa.cfg.weight_power, "doa.weight_power", "Weight power");
641
642 return def;
643}
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
Default component property definition container.
Definition Component.h:70
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
dsobstacleavoidance::Config getConfig(const Ice::Current &=Ice::emptyCurrent) override
void updateObstacle(const obstacledetection::Obstacle &obstacle, const Ice::Current &=Ice::emptyCurrent) override
static const std::string default_name
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void updateEnvironment(const Ice::Current &=Ice::emptyCurrent) override
void writeDebugPlots(const std::string &filename, const Ice::Current &=Ice::emptyCurrent) override
Eigen::Vector3f modulateVelocity(const obstacleavoidance::Agent &agent, const Ice::Current &=Ice::emptyCurrent) override
void removeObstacle(const std::string &obstacle_name, const Ice::Current &=Ice::emptyCurrent) override
std::string getDefaultName() const override
std::vector< obstacledetection::Obstacle > getObstacles(const Ice::Current &=Ice::emptyCurrent) override
std::string getName() const
Retrieve name of object.
The periodic task executes one thread method repeatedly using the time period specified in the constr...
Measures the passed time between the construction or calling reset() and stop().
Definition StopWatch.h:42
Duration stop()
Stops the timer and returns the measured duration.
Definition StopWatch.cpp:39
uint32_t Color
RGBA color.
Definition color.h:8
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
Quaternion< double, 0 > Quaterniond
void from_json(const nlohmann::json &j, armarx::obstacledetection::Obstacle &obstacle)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void add(ElementT const &element)
Definition Layer.h:31