ObstacleAwarePlatformUnit.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::ObstacleAwarePlatformUnit
17 * @author Christian R. G. Dreher <c.dreher@kit.edu>
18 * @date 2021
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 <algorithm>
29#include <cmath>
30#include <limits>
31
32// Eigen
33#include <Eigen/Core>
34#include <Eigen/Geometry>
35
36// Simox
37#include <SimoxUtility/math.h>
38#include <VirtualRobot/Nodes/RobotNode.h>
39#include <VirtualRobot/Safety.h>
40
41// ArmarX
43
44namespace
45{
46
47 void
48 invalidate(float& v)
49 {
50 v = std::numeric_limits<float>::infinity();
51 }
52
53 void
54 invalidate(Eigen::Vector2f& v)
55 {
56 v.x() = std::numeric_limits<float>::infinity();
57 v.y() = std::numeric_limits<float>::infinity();
58 }
59
60 void
61 invalidate(Eigen::Vector3f& v)
62 {
63 v.x() = std::numeric_limits<float>::infinity();
64 v.y() = std::numeric_limits<float>::infinity();
65 v.z() = std::numeric_limits<float>::infinity();
66 }
67
68 template <typename T>
69 void
70 invalidate(std::deque<T>& d)
71 {
72 d.clear();
73 }
74
75 std::string
77 {
78 switch (mode)
79 {
81 return "position";
83 return "velocity";
85 default:
86 return "unset";
87 }
88 }
89
90} // namespace
91
92const std::string armarx::ObstacleAwarePlatformUnit::default_name = "ObstacleAwarePlatformUnit";
93
94
96
97
99
100void
102{
103 ARMARX_DEBUG << "Initializing " << getName() << ".";
104
105 ARMARX_DEBUG << "Initialized " << getName() << ".";
106}
107
108void
110{
111 ARMARX_DEBUG << "Starting " << getName() << ".";
112
113 if (!hasRobot("robot"))
114 {
115 m_robot = addRobot("robot", VirtualRobot::RobotIO::eStructure);
116 }
117
118 invalidate(m_control_data.target_vel);
119 invalidate(m_control_data.target_rot_vel);
120 invalidate(m_control_data.target_pos);
121 invalidate(m_control_data.target_ori);
122 invalidate(m_viz.start);
123
124 ARMARX_DEBUG << "Started " << getName() << ".";
125}
126
127void
129{
130 ARMARX_DEBUG << "Exiting " << getName() << ".";
131
132 schedule_high_level_control_loop(control_mode::none);
133
134 ARMARX_DEBUG << "Exited " << getName() << ".";
135}
136
137std::string
142
143void
145 const float target_pos_y,
146 const float target_ori,
147 const float pos_reached_threshold,
148 const float ori_reached_threshold,
149 const Ice::Current&)
150{
151 using namespace simox::math;
152
153 std::scoped_lock l{m_control_data.mutex};
154
155 m_control_data.target_pos = Eigen::Vector2f{target_pos_x, target_pos_y};
156 m_control_data.target_ori = periodic_clamp<float>(target_ori, -M_PI, M_PI);
157 m_control_data.pos_reached_threshold = pos_reached_threshold;
158 m_control_data.ori_reached_threshold = ori_reached_threshold;
159
160 invalidate(m_control_data.target_vel);
161 invalidate(m_control_data.target_rot_vel);
162
163 m_rot_pid_controller.reset();
164
165 schedule_high_level_control_loop(control_mode::position);
166}
167
168void
170 const float target_vel_y,
171 const float target_rot_vel,
172 const Ice::Current&)
173{
174 using namespace simox::math;
175
176 std::scoped_lock l{m_control_data.mutex};
177
178 m_control_data.target_vel = Eigen::Vector2f{target_vel_x, target_vel_y};
179 m_control_data.target_rot_vel = periodic_clamp<float>(target_rot_vel, -M_PI, M_PI);
180
181 invalidate(m_control_data.target_pos);
182 invalidate(m_control_data.target_ori);
183
184 ARMARX_CHECK(m_control_data.target_vel.allFinite());
185 ARMARX_CHECK(std::isfinite(m_control_data.target_rot_vel));
186
187 schedule_high_level_control_loop(control_mode::velocity);
188}
189
190void
192 const float target_pos_delta_y,
193 const float target_delta_ori,
194 const float pos_reached_threshold,
195 const float ori_reached_threshold,
196 const Ice::Current& current)
197{
198 using namespace simox::math;
199
200 // Transform relative to global.
201 std::unique_lock lock{m_control_data.mutex};
202 synchronizeLocalClone(m_robot);
203 const Eigen::Vector2f agent_pos = m_robot->getGlobalPosition().head<2>();
204 const float agent_ori = mat4f_to_rpy(m_robot->getGlobalPose()).z();
205 lock.unlock();
206
207 // Use moveTo.
208 moveTo(agent_pos.x() + target_pos_delta_x,
209 agent_pos.y() + target_pos_delta_y,
210 agent_ori + target_delta_ori,
211 pos_reached_threshold,
212 ori_reached_threshold,
213 current);
214}
215
216void
218 float max_rot_vel,
219 const Ice::Current&)
220{
221 // ensure positiveness
222 max_pos_vel = std::max(max_pos_vel, 0.F);
223 max_rot_vel = std::max(max_rot_vel, 0.F);
224
225 std::scoped_lock l{m_control_data.mutex};
226 m_control_data.max_vel = max_pos_vel;
227 m_control_data.max_rot_vel = max_rot_vel;
228 m_platform->setMaxVelocities(max_pos_vel, max_rot_vel);
229}
230
231void
233{
234 schedule_high_level_control_loop(control_mode::none);
235 m_platform->stopPlatform();
236}
237
238void
239armarx::ObstacleAwarePlatformUnit::schedule_high_level_control_loop(control_mode mode)
240{
241 std::scoped_lock l{m_control_loop.mutex};
242
243 // If the control mode didn't change, there's nothing to do.
244 if (m_control_loop.mode == mode)
245 {
246 return;
247 }
248
249 // If a control loop is runnung, stop it and wait for termination.
250 if (m_control_loop.mode != mode and m_control_loop.task)
251 {
252 ARMARX_VERBOSE << "Stopping " << ::to_string(m_control_loop.mode) << " control.";
253 const bool join = true;
254 m_control_loop.task->stop(join);
255 }
256
257 // If the new control mode is none, no new control loop needs to be created.
258 if (mode == control_mode::none)
259 {
260 ARMARX_VERBOSE << "Going into stand-by.";
261 return;
262 }
263
264 // Start next control loop.
265 ARMARX_VERBOSE << "Starting " << ::to_string(mode) << " control.";
266 m_control_loop.mode = mode;
267 m_control_loop.task = new RunningTask<ObstacleAwarePlatformUnit>(
268 this, &ObstacleAwarePlatformUnit::high_level_control_loop);
269 m_control_loop.task->start();
270}
271
272void
273armarx::ObstacleAwarePlatformUnit::high_level_control_loop()
274{
275 const control_mode mode = m_control_loop.mode;
276 ARMARX_VERBOSE << "Started " << ::to_string(mode) << " control.";
277
278 try
279 {
280 CycleUtil cu{m_control_loop.cycle_time};
281 while (not m_control_loop.task->isStopped())
282 {
283 const velocities vels = get_velocities();
284
285 // Debug.
287 m["err_dist"] = new Variant{vels.err_dist};
288 m["err_angular_dist"] = new Variant{vels.err_angular_dist};
289
290 m["target_global_x"] = new Variant{vels.target_global.x()};
291 m["target_global_y"] = new Variant{vels.target_global.y()};
292 m["target_global_abs"] = new Variant{vels.target_global.norm()};
293
294 m["target_local_x"] = new Variant{vels.target_local.x()};
295 m["target_local_y"] = new Variant{vels.target_local.y()};
296 m["target_local_abs"] = new Variant(vels.target_local.norm());
297 m["target_rot"] = new Variant{vels.target_rot};
298
299 m["modulated_global_x"] = new Variant{vels.modulated_global.x()};
300 m["modulated_global_y"] = new Variant{vels.modulated_global.y()};
301 m["modulated_global_abs"] = new Variant{vels.modulated_global.norm()};
302
303 m["modulated_local_x"] = new Variant{vels.modulated_local.x()};
304 m["modulated_local_y"] = new Variant{vels.modulated_local.y()};
305 m["modulated_local_abs"] = new Variant{vels.modulated_local.norm()};
306
307 // m["max_rot_vel"] = new Variant{m_control_data.max_rot_vel};
308 // m["max_lin_vel"] = new Variant{m_control_data.max_vel};
309
310 // m["rot_desired"] = new Variant{m_control_data.target_ori};
311 // m["rot_measured"] = new Variant{m_control_data.agent_ori};
312
313 // m["pos_x_desired"] = new Variant{m_control_data.target_pos.x()};
314 // m["pos_x_measured"] = new Variant{m_control_data.agent_pos.y()};
315
316 // m["pos_y_desired"] = new Variant{m_control_data.target_pos.x()};
317 // m["pos_y_measured"] = new Variant{m_control_data.agent_pos.y()};
318
319 setDebugObserverChannel("ObstacleAwarePlatformCtrl", m);
320
321 m_platform->move(vels.modulated_local.x(), vels.modulated_local.y(), vels.target_rot);
322 visualize(vels);
323 cu.waitForCycleDuration();
324 }
325 }
326 catch (const std::exception& e)
327 {
328 ARMARX_ERROR << "Error occured while running control loop.\n" << e.what();
329 }
330 catch (...)
331 {
332 ARMARX_ERROR << "Unknown error occured while running control loop.";
333 }
334
335 m_platform->move(0, 0, 0);
336 m_platform->stopPlatform();
337 m_control_loop.mode = control_mode::none;
338
339 visualize();
340
341 ARMARX_VERBOSE << "Stopped " << ::to_string(mode) << " control.";
342}
343
344armarx::ObstacleAwarePlatformUnit::velocities
345armarx::ObstacleAwarePlatformUnit::get_velocities()
346{
347 using namespace simox::math;
348
349 // Acquire control_data mutex to ensure data remains consistent.
350 std::scoped_lock l{m_control_data.mutex};
351 // Update agent and get target velocities.
352 update_agent_dependent_values();
353 const Eigen::Vector2f target_vel = get_target_velocity();
354 const float target_rot_vel = get_target_rotational_velocity();
355
356 const Eigen::Vector2f extents =
357 Eigen::Affine3f(m_robot->getRobotNode("PlatformCornerFrontLeft")->getPoseInRootFrame())
358 .translation()
359 .head<2>();
360
361 // Apply obstacle avoidance and apply post processing to get the modulated velocity.
362 const Eigen::Vector2f modulated_vel = [this, &target_vel, &extents]
363 {
364 const VirtualRobot::Circle circle = VirtualRobot::projectedBoundingCircle(*m_robot);
365 ARMARX_DEBUG << "Circle approximation: " << circle.radius;
366 m_viz.boundingCircle = circle;
367 const float distance = m_obsman->distanceToObstacle(
368 m_control_data.agent_pos /*circle.center*/, circle.radius, m_control_data.target_pos);
369
370 ARMARX_DEBUG << "Distance to obstacle: " << distance;
371
372 // https://www.wolframalpha.com/input/?i=line+through+%281000%2C+0%29+and+%282000%2C+1%29
373 float modifier = std::clamp((distance / 1000) - 1., 0.0, 1.0);
374
375 const Eigen::Vector2f vel = modifier * target_vel;
376 return vel.norm() > 20 ? vel : Eigen::Vector2f{0, 0};
377 }();
378
379 ARMARX_CHECK(modulated_vel.allFinite()) << "Velocity contains non-finite values.";
380 ARMARX_CHECK(std::isfinite(target_rot_vel)) << "Rotation velocity is non-finite.";
381
382 ARMARX_DEBUG << "Target velocity: " << target_vel.transpose()
383 << "; norm: " << target_vel.norm() << "; " << target_rot_vel;
384 ARMARX_DEBUG << "Modulated velocity: " << modulated_vel.transpose() << modulated_vel.norm();
385
386 const auto r = Eigen::Rotation2D(m_control_data.agent_ori).toRotationMatrix().inverse();
387
388 velocities vels;
389 vels.target_local = r * target_vel;
390 vels.target_global = target_vel;
391 vels.modulated_local = r * modulated_vel;
392 vels.modulated_global = modulated_vel;
393 vels.target_rot = target_rot_vel;
394 vels.err_dist = m_control_data.target_dist;
395 vels.err_angular_dist = m_control_data.target_angular_dist;
396
397 return vels;
398}
399
400Eigen::Vector2f
401armarx::ObstacleAwarePlatformUnit::get_target_velocity() const
402{
403 using namespace simox::math;
404
405 Eigen::Vector2f uncapped_target_vel = Eigen::Vector2f::Zero();
406
407 if (m_control_loop.mode == control_mode::position /*and not target_position_reached()*/)
408 {
409 uncapped_target_vel =
410 (m_control_data.target_pos - m_control_data.agent_pos) * m_control_data.kp;
411 }
412 else if (m_control_loop.mode == control_mode::velocity)
413 {
414 uncapped_target_vel = m_control_data.target_vel;
415 }
416
417 ARMARX_CHECK(uncapped_target_vel.allFinite());
418
419 return norm_max(uncapped_target_vel, m_control_data.max_vel);
420}
421
422float
423armarx::ObstacleAwarePlatformUnit::get_target_rotational_velocity() const
424{
425 using namespace simox::math;
426
427 float uncapped_target_rot_vel = 0;
428
429 if (m_control_loop.mode == control_mode::position /*and not target_orientation_reached()*/)
430 {
431 m_rot_pid_controller.update(m_control_data.agent_ori, m_control_data.target_ori);
432 uncapped_target_rot_vel = m_rot_pid_controller.getControlValue();
433 }
434 else if (m_control_loop.mode == control_mode::velocity)
435 {
436 uncapped_target_rot_vel = m_control_data.target_rot_vel;
437 }
438
439 ARMARX_CHECK(std::isfinite(uncapped_target_rot_vel));
440
441 return std::clamp(
442 uncapped_target_rot_vel, -m_control_data.max_rot_vel, m_control_data.max_rot_vel);
443
444 // return std::copysign(std::min(std::fabs(uncapped_target_rot_vel), m_control_data.max_rot_vel),
445 // uncapped_target_rot_vel);
446}
447
448void
449armarx::ObstacleAwarePlatformUnit::update_agent_dependent_values()
450{
451 using namespace simox::math;
452
453 synchronizeLocalClone(m_robot);
454 m_control_data.agent_pos = m_robot->getGlobalPosition().head<2>();
455 m_control_data.agent_ori =
456 periodic_clamp<float>(mat4f_to_rpy(m_robot->getGlobalPose()).z(), -M_PI, M_PI);
457
458 ARMARX_CHECK_GREATER(m_control_data.agent_ori, -M_PI);
459 ARMARX_CHECK_LESS(m_control_data.agent_ori, M_PI);
460
461 // Update distances in position mode.
462 if (m_control_loop.mode == control_mode::position)
463 {
464 ARMARX_CHECK_GREATER(m_control_data.target_ori, -M_PI);
465 ARMARX_CHECK_LESS(m_control_data.target_ori, M_PI);
466 ARMARX_CHECK(m_control_data.target_pos.allFinite());
467 ARMARX_CHECK(std::isfinite(m_control_data.target_ori));
468
469 m_control_data.target_dist = (m_control_data.target_pos - m_control_data.agent_pos).norm();
470 m_control_data.target_angular_dist = periodic_clamp<float>(
471 m_control_data.target_ori - m_control_data.agent_ori, -M_PI, M_PI);
472
473 ARMARX_CHECK_GREATER(m_control_data.target_angular_dist, -M_PI);
474 ARMARX_CHECK_LESS(m_control_data.target_angular_dist, M_PI);
475
476 ARMARX_DEBUG << "Distance to target: " << m_control_data.target_dist << " mm and "
477 << m_control_data.target_angular_dist << " rad.";
478 }
479 // Otherwise invalidate them.
480 else
481 {
482 invalidate(m_control_data.target_dist);
483 invalidate(m_control_data.target_angular_dist);
484 }
485}
486
487bool
488armarx::ObstacleAwarePlatformUnit::target_position_reached() const
489{
490 if (m_control_loop.mode == control_mode::position)
491 {
492 return m_control_data.target_dist < m_control_data.pos_reached_threshold;
493 }
494
495 // Cannot reach any target in non-position mode.
496 return false;
497}
498
499bool
500armarx::ObstacleAwarePlatformUnit::target_orientation_reached() const
501{
502 if (m_control_loop.mode == control_mode::position)
503 {
504 return std::fabs(m_control_data.target_angular_dist) < m_control_data.ori_reached_threshold;
505 }
506
507 // Cannot reach any target in non-position mode.
508 return false;
509}
510
511bool
512armarx::ObstacleAwarePlatformUnit::target_reached() const
513{
514 if (m_control_loop.mode == control_mode::position)
515 {
516 return target_position_reached() and target_orientation_reached();
517 }
518
519 return false;
520}
521
522bool
523armarx::ObstacleAwarePlatformUnit::is_near_target(
524 const Eigen::Vector2f& control_velocity) const noexcept
525{
526 if (m_control_data.target_dist < m_control_data.pos_near_threshold)
527 {
528 const Eigen::Vector2f target_direction =
529 m_control_data.target_pos - m_control_data.agent_pos;
530 const Eigen::Vector2f control_direction = control_velocity / control_velocity.norm();
531
532 const float sim = simox::math::cosine_similarity(target_direction, control_direction);
533
534 // if almost pointing into same direction
535 if (sim > cos(M_PI_4))
536 {
537 return true;
538 }
539 }
540
541 return false;
542}
543
544void
545armarx::ObstacleAwarePlatformUnit::visualize()
546{
547 const Eigen::Vector2f zero = Eigen::Vector2f::Zero();
548 velocities vels;
549 vels.target_local = zero;
550 vels.target_global = zero;
551 vels.modulated_local = zero;
552 vels.modulated_global = zero;
553 vels.target_rot = 0;
554
555 visualize(vels);
556}
557
558void
559armarx::ObstacleAwarePlatformUnit::visualize(const velocities& vels)
560{
561 using namespace armarx::viz;
562
563 if (not m_viz.enabled)
564 {
565 return;
566 }
567
568 Eigen::Vector3f agent_pos{m_control_data.agent_pos.x(), m_control_data.agent_pos.y(), 0};
569
570 // Progress. Only draw in position control mode.
571 Layer l_prog = arviz.layer("progress");
572 if (m_control_loop.mode == control_mode::position)
573 {
574 const float min_keypoint_dist = 50;
575
576 {
577 l_prog.add(Cylinder{"boundingCylinder"}
578 .position(agent_pos)
579 .color(Color::cyan(255, 64))
580 .pose(simox::math::pos_rpy_to_mat4f(agent_pos, -M_PI_2, 0, 0) *
581 Eigen::Isometry3f(Eigen::Translation3f(0, -1000, 0)).matrix())
582 .radius(m_viz.boundingCircle.radius)
583 .height(2000));
584 }
585
586 // If no start is set, use current agent pos.
587 if (not m_viz.start.allFinite())
588 {
589 m_viz.start = agent_pos;
590 }
591
592 const Eigen::Vector3f& last_keypoint_pos =
593 m_viz.path.size() >= 1 ? m_viz.path.back() : m_viz.start;
594
595 // Keep a certain distance between path keypoints.
596 if ((last_keypoint_pos - agent_pos).norm() > min_keypoint_dist)
597 {
598 m_viz.path.push_back(agent_pos);
599 }
600
601 // Draw path.
602 if (not target_reached())
603 {
604 // Start.
605 l_prog.add(
606 Sphere{"start"}.position(m_viz.start).color(Color::cyan(255, 64)).radius(40));
607
608 // Path.
609 for (unsigned i = 0; i < m_viz.path.size(); ++i)
610 {
611 l_prog.add(Sphere{"path_" + std::to_string(i + 1)}
612 .position(m_viz.path[i])
613 .color(Color::magenta(255, 128))
614 .radius(20));
615 }
616
617 // Goal.
618 const Eigen::Vector3f target{
619 m_control_data.target_pos.x(), m_control_data.target_pos.y(), 0};
620 l_prog.add(
621 Arrow{"goal"}
622 .fromTo(target + Eigen::Vector3f{0, 0, 220}, target + Eigen::Vector3f{0, 0, 40})
623 .color(Color::red(255, 128))
624 .width(20));
625 }
626 else
627 {
628 m_viz.path.clear();
629 invalidate(m_viz.start);
630 }
631 }
632
633 // Velocities.
634 Layer l_vels = arviz.layer("velocities");
635 if (m_control_loop.mode != control_mode::none)
636 {
637 const float min_velocity = 15;
638 const Eigen::Vector3f from1{agent_pos + Eigen::Vector3f{0, 0, 2000}};
639 const Eigen::Vector3f from2 = from1 + Eigen::Vector3f{0, 0, 200};
640 const Eigen::Vector3f original{vels.target_global.x(), vels.target_global.y(), 0};
641 const Eigen::Vector3f modulated{vels.modulated_global.x(), vels.modulated_global.y(), 0};
642
643 if (original.norm() > min_velocity)
644 {
645 l_vels.add(Arrow{"original"}
646 .fromTo(from1, from1 + original * 5)
647 .color(Color::green(255, 128))
648 .width(25));
649 }
650
651 if (modulated.norm() > min_velocity)
652 {
653 l_vels.add(Arrow{"modulated"}
654 .fromTo(from2, from2 + modulated * 5)
655 .color(Color::cyan(255, 128))
656 .width(25));
657 }
658
659 // TODO rotation arrow
660 }
661
662 // Agent.
663 Layer l_agnt = arviz.layer("agent");
664 if (m_control_loop.mode != control_mode::none)
665 {
666 l_agnt.add(Sphere{"agent"}.position(agent_pos).color(Color::red(255, 128)).radius(50));
667
668 // Agent safety margin.
669 if (m_control_data.agent_safety_margin > 0)
670 {
671 l_agnt.add(Cylinder{"agent_safety_margin"}
672 .pose(simox::math::pos_rpy_to_mat4f(agent_pos, -M_PI_2, 0, 0))
673 .color(Color::red(255, 64))
674 .radius(m_control_data.agent_safety_margin)
675 .height(2));
676 }
677 }
678
679 arviz.commit({l_prog, l_vels, l_agnt});
680}
681
684{
686
687 def->component(m_platform, "Platform");
688 def->component(m_obsman, "ObstacleAvoidingPlatformUnit");
689
690 // Settings.
691 def->optional(m_control_data.min_vel_near_target,
692 "min_vel_near_target",
693 "Velocity in [mm/s] "
694 "the robot should at least set when near the target");
695 def->optional(m_control_data.min_vel_general,
696 "min_vel_general",
697 "Velocity in [mm/s] the robot "
698 "should at least set on general");
699 def->optional(m_control_data.pos_near_threshold,
700 "pos_near_threshold",
701 "Distance in [mm] after "
702 "which the robot is considered to be near the target for min velocity, "
703 "smoothing, etc.");
704
705 // Control parameters.
706 def->optional(m_control_data.kp, "control.pos.kp");
707 def->optional(m_rot_pid_controller.Kp, "control.rot.kp");
708 def->optional(m_rot_pid_controller.Ki, "control.rot.ki");
709 def->optional(m_rot_pid_controller.Kd, "control.rot.kd");
710 def->optional(m_control_loop.cycle_time, "control.pose.cycle_time", "Control loop cycle time.");
711
712 // Obstacle avoidance parameter.
713 def->optional(m_control_data.agent_safety_margin, "doa.agent_safety_margin");
714
715 return def;
716}
std::string to_string(BLEProthesisInterface::State s)
#define M_PI
Definition MathTools.h:17
This util class helps with keeping a cycle time during a control cycle.
Definition CycleUtil.h:41
std::string getName() const
Retrieve name of object.
void moveRelative(float target_pos_delta_x, float target_pos_delta_y, float target_delta_ori, float pos_reached_threshold, float ori_reached_threshold, const Ice::Current &=Ice::Current{}) override
PropertyDefinitionsPtr createPropertyDefinitions() override
void stopPlatform(const Ice::Current &=Ice::Current{}) override
void move(float target_vel_x, float target_vel_y, float target_rot_vel, const Ice::Current &=Ice::Current{}) override
void setMaxVelocities(float max_pos_vel, float max_rot_vel, const Ice::Current &=Ice::Current{}) override
std::string getDefaultName() const override
Retrieve default name of component.
void moveTo(float target_pos_x, float target_pos_y, float target_ori, float pos_reached_threshold, float ori_reached_threshold, const Ice::Current &=Ice::Current{}) override
PropertyDefinitionsPtr createPropertyDefinitions() override
bool synchronizeLocalClone(const VirtualRobot::RobotPtr &robot) const
VirtualRobot::RobotPtr addRobot(const std::string &id, const VirtualRobot::RobotPtr &robot, const VirtualRobot::RobotNodeSetPtr &rns={}, const VirtualRobot::RobotNodePtr &node={})
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_LESS(lhs, rhs)
This macro evaluates whether lhs is less (<) than rhs and if it turns out to be false it will throw a...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
double v(double t, double v0, double a0, double j)
Definition CtrlUtil.h:39
void visualize(const algorithms::Costmap &costmap, viz::Layer &layer, const std::string &name, const float zOffset)
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
const std::string & to_string(const std::string &s)
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
bool isfinite(const std::vector< T, Ts... > &v)
Definition algorithm.h:366
double norm(const Point &a)
Definition point.hpp:102
double distance(const Point &a, const Point &b)
Definition point.hpp:95
void add(ElementT const &element)
Definition Layer.h:31