DebugDrawerTopic.cpp
Go to the documentation of this file.
1#include "DebugDrawerTopic.h"
2
3#include <SimoxUtility/color/hsv.h>
4#include <VirtualRobot/Visualization/TriMeshModel.h>
5#include <VirtualRobot/math/Helpers.h>
6
8
9#include "../Pose.h"
10#include "GlasbeyLUT.h"
11
12namespace armarx
13{
14
18
20 {
21 }
22
23 DebugDrawerTopic::VisuID::VisuID(const std::string& layer, const std::string& name) :
25 {
26 }
27
29 DebugDrawerTopic::VisuID::withName(const std::string& newName) const
30 {
31 return VisuID(this->layer, newName);
32 }
33
34 std::ostream&
35 operator<<(std::ostream& os, const DebugDrawerTopic::VisuID& rhs)
36 {
37 os << "Visu '" << rhs.name << "' on layer '" << rhs.layer << "'";
38 return os;
39 }
40
41 const std::string DebugDrawerTopic::TOPIC_NAME = "DebugDrawerUpdates";
42 const std::string DebugDrawerTopic::DEFAULT_LAYER = "debug";
44
45 DebugDrawerTopic::DebugDrawerTopic(const std::string& layer) : _layer(layer)
46 {
47 }
48
50 const std::string& layer) :
51 topic(topic), _layer(layer)
52 {
53 }
54
55 void
57 {
58 this->topic = topic;
59 }
60
63 {
64 return topic;
65 }
66
67 void
69 {
70 this->_enabled = enabled;
71 }
72
73 bool
75 {
76 return _enabled && topic;
77 }
78
79 void
81 const std::string& topicNameOverride) const
82 {
83 component.offeringTopic(topicNameOverride.empty() ? TOPIC_NAME : topicNameOverride);
84 }
85
86 void
87 DebugDrawerTopic::getTopic(ManagedIceObject& component, const std::string& topicNameOverride)
88 {
90 topicNameOverride.empty() ? TOPIC_NAME : topicNameOverride));
91 }
92
93 const std::string&
95 {
96 return _layer;
97 }
98
99 void
100 DebugDrawerTopic::setLayer(const std::string& layer)
101 {
102 this->_layer = layer;
103 }
104
105 float
107 {
108 return _lengthScale;
109 }
110
111 void
113 {
114 this->_lengthScale = scale;
115 }
116
117 void
122
123 void
128
129 float
131 {
132 return _poseScale;
133 }
134
135 void
137 {
138 this->_poseScale = scale;
139 }
140
141 void
146
147 void
152
153 void
155 {
156 this->sleepFor(_shortSleepDuration);
157 }
158
159 void
161 {
162 if (enabled())
163 {
164 topic->clearAll();
165 if (sleep)
166 {
167 shortSleep();
168 }
169 }
170 }
171
172 void
174 {
175 clearLayer(_layer, sleep);
176 }
177
178 void
179 DebugDrawerTopic::clearLayer(const std::string& layer, bool sleep)
180 {
181 if (enabled())
182 {
183 topic->clearLayer(layer);
184 if (sleep)
185 {
186 shortSleep();
187 }
188 }
189 }
190
191 void
193 const Eigen::Vector3f& position,
194 const std::string& text,
195 int size,
196 const DrawColor color,
197 bool ignoreLengthScale)
198 {
199 if (enabled())
200 {
201 const float scale = lengthScale(ignoreLengthScale);
202 topic->setTextVisu(layer(id), id.name, text, scaled(scale, position), color, size);
203 }
204 }
205
206 void
208 const Eigen::Vector3f& position,
209 const Eigen::Quaternionf& orientation,
210 const Eigen::Vector3f& extents,
211 const DrawColor& color,
212 bool ignoreLengthScale)
213 {
214 if (enabled())
215 {
216 const float scale = lengthScale(ignoreLengthScale);
217 topic->setBoxVisu(layer(id),
218 id.name,
219 new Pose(scaled(scale, position), new Quaternion(orientation)),
220 scaled(scale, extents),
221 color);
222 }
223 }
224
225 void
227 const Eigen::Matrix4f& pose,
228 const Eigen::Vector3f& extents,
229 const DrawColor& color,
230 bool ignoreLengthScale)
231 {
232 drawBox(id,
233 ::math::Helpers::Position(pose),
234 Eigen::Quaternionf(::math::Helpers::Orientation(pose)),
235 extents,
236 color,
237 ignoreLengthScale);
238 }
239
240 void
242 const VirtualRobot::BoundingBox& boundingBox,
243 const DrawColor& color,
244 bool ignoreLengthScale)
245 {
246 drawBox(id, boundingBox, Eigen::Matrix4f::Identity(), color, ignoreLengthScale);
247 }
248
249 void
251 const VirtualRobot::BoundingBox& boundingBox,
252 const Eigen::Matrix4f& pose,
253 const DrawColor& color,
254 bool ignoreLengthScale)
255 {
256 const Eigen::Vector3f center = .5 * (boundingBox.getMin() + boundingBox.getMax());
257 drawBox(id,
258 ::math::Helpers::TransformPosition(pose, center),
259 Eigen::Quaternionf(::math::Helpers::Orientation(pose)),
260 boundingBox.getMax() - boundingBox.getMin(),
261 color,
262 ignoreLengthScale);
263 }
264
265 void
267 {
268 if (enabled())
269 {
270 topic->removeBoxVisu(layer(id), id.name);
271 }
272 }
273
274 void
276 const Eigen::Vector3f& position,
277 const Eigen::Quaternionf& orientation,
278 const Eigen::Vector3f& extents,
279 float width,
280 const DrawColor& color,
281 bool ignoreLengthScale)
282 {
283 drawBoxEdges(id,
284 ::math::Helpers::Pose(position, orientation),
285 extents,
286 width,
287 color,
288 ignoreLengthScale);
289 }
290
291 void
293 const Eigen::Matrix4f& pose,
294 const Eigen::Vector3f& extents,
295 float width,
296 const DrawColor& color,
297 bool ignoreLengthScale)
298 {
299 if (!enabled())
300 {
301 return;
302 }
303
304 std::vector<Eigen::Vector3f> points;
305
307 bb.col(0) = -extents / 2;
308 bb.col(1) = extents / 2;
309
310 auto addLine = [&](int x1, int y1, int z1, int x2, int y2, int z2)
311 {
312 Eigen::Vector3f start = {bb.col(x1).x(), bb.col(y1).y(), bb.col(z1).z()};
313 Eigen::Vector3f end = {bb.col(x2).x(), bb.col(y2).y(), bb.col(z2).z()};
314
315 start = ::math::Helpers::TransformPosition(pose, start);
316 end = ::math::Helpers::TransformPosition(pose, end);
317
318 points.push_back(start);
319 points.push_back(end);
320 };
321
322 /* 001 +-----+ 011
323 * /| 111/|
324 * 101 +-----+ |
325 * | +---|-+ 010
326 * |/000 |/
327 * 100 +-----+ 110
328 */
329
330 // 000 -> 100, 010, 001
331 addLine(0, 0, 0, 1, 0, 0);
332 addLine(0, 0, 0, 0, 1, 0);
333 addLine(0, 0, 0, 0, 0, 1);
334
335 // 111 -> 011, 101, 110
336 addLine(1, 1, 1, 0, 1, 1);
337 addLine(1, 1, 1, 1, 0, 1);
338 addLine(1, 1, 1, 1, 1, 0);
339
340 // 100 -> 101, 110
341 addLine(1, 0, 0, 1, 0, 1);
342 addLine(1, 0, 0, 1, 1, 0);
343
344 // 010 -> 110, 011
345 addLine(0, 1, 0, 1, 1, 0);
346 addLine(0, 1, 0, 0, 1, 1);
347
348 // 001 -> 101, 011
349 addLine(0, 0, 1, 1, 0, 1);
350 addLine(0, 0, 1, 0, 1, 1);
351
352 drawLineSet(id, points, width, color, ignoreLengthScale);
353 }
354
355 void
357 const VirtualRobot::BoundingBox& boundingBox,
358 float width,
359 const DrawColor& color,
360 bool ignoreLengthScale)
361 {
362 drawBoxEdges(id, boundingBox, Eigen::Matrix4f::Identity(), width, color, ignoreLengthScale);
363 }
364
365 void
367 const Eigen::Matrix32f& aabb,
368 float width,
369 const DrawColor& color,
370 bool ignoreLengthScale)
371 {
372 drawBoxEdges(id, aabb, Eigen::Matrix4f::Identity(), width, color, ignoreLengthScale);
373 }
374
375 void
377 const VirtualRobot::BoundingBox& boundingBox,
378 const Eigen::Matrix4f& pose,
379 float width,
380 const DrawColor& color,
381 bool ignoreLengthScale)
382 {
383 const Eigen::Vector3f center = .5 * (boundingBox.getMin() + boundingBox.getMax());
384
385 drawBoxEdges(id,
386 ::math::Helpers::Pose(::math::Helpers::TransformPosition(pose, center),
387 ::math::Helpers::Orientation(pose)),
388 boundingBox.getMax() - boundingBox.getMin(),
389 width,
390 color,
391 ignoreLengthScale);
392 }
393
394 void
396 const Eigen::Matrix32f& aabb,
397 const Eigen::Matrix4f& pose,
398 float width,
399 const DrawColor& color,
400 bool ignoreLengthScale)
401 {
402 const Eigen::Vector3f center = 0.5 * (aabb.col(0) + aabb.col(1));
403
404 drawBoxEdges(id,
405 ::math::Helpers::Pose(::math::Helpers::TransformPosition(pose, center),
406 ::math::Helpers::Orientation(pose)),
407 aabb.col(1) - aabb.col(0),
408 width,
409 color,
410 ignoreLengthScale);
411 }
412
413 void
418
419 void
421 const Eigen::Vector3f& center,
422 const Eigen::Vector3f& direction,
423 float length,
424 float radius,
425 const DrawColor& color,
426 bool ignoreLengthScale)
427 {
428 if (enabled())
429 {
430 const float scale = lengthScale(ignoreLengthScale);
431 topic->setCylinderVisu(layer(id),
432 id.name,
433 scaled(scale, center),
434 new Vector3(direction),
435 scaled(scale, length),
436 scaled(scale, radius),
437 color);
438 }
439 }
440
441 void
443 const Eigen::Vector3f& center,
444 const Eigen::Quaternionf& orientation,
445 float length,
446 float radius,
447 const DrawColor& color,
448 bool ignoreLengthScale)
449 {
450 drawCylinder(id,
451 center,
452 orientation * Eigen::Vector3f::UnitY(),
453 radius,
454 length,
455 color,
456 ignoreLengthScale);
457 }
458
459 void
461 const Eigen::Vector3f& from,
462 const Eigen::Vector3f& to,
463 float radius,
464 const DrawColor& color,
465 bool ignoreLengthScale)
466 {
467 if (enabled())
468 {
469 const Eigen::Vector3f dir = (to - from); // no need for scaling at this point
470 const float length = dir.norm();
472 id, .5 * (from + to), dir / length, radius, length, color, ignoreLengthScale);
473 }
474 }
475
476 void
478 {
479 if (enabled())
480 {
481 topic->removeCylinderVisu(layer(id), id.name);
482 }
483 }
484
485 void
487 const Eigen::Vector3f& center,
488 float radius,
489 const DrawColor& color,
490 bool ignoreLengthScale)
491 {
492 if (enabled())
493 {
494 const float scale = lengthScale(ignoreLengthScale);
495 topic->setSphereVisu(
496 layer(id), id.name, scaled(scale, center), color, scaled(scale, radius));
497 }
498 }
499
500 void
502 {
503 if (enabled())
504 {
505 topic->removeSphereVisu(layer(id), id.name);
506 }
507 }
508
509 void
511 const Eigen::Vector3f& position,
512 const Eigen::Vector3f& direction,
513 float length,
514 float width,
515 const DrawColor& color,
516 bool ignoreLengthScale)
517 {
518 if (enabled())
519 {
520 const float scale = lengthScale(ignoreLengthScale);
521 topic->setArrowVisu(layer(id),
522 id.name,
523 scaled(scale, position),
524 new Vector3(direction),
525 color,
526 scaled(scale, length),
527 scaled(scale, width));
528 }
529 }
530
531 void
533 const Eigen::Vector3f& from,
534 const Eigen::Vector3f& to,
535 float width,
536 const DrawColor& color,
537 bool ignoreLengthScale)
538 {
539 if (enabled())
540 {
541 const Eigen::Vector3f dir = (to - from); // no need for scaling at this point
542 const float length = dir.norm();
543 drawArrow(id, from, dir / length, length, width, color, ignoreLengthScale);
544 }
545 }
546
547 void
549 {
550 if (enabled())
551 {
552 topic->removeArrowVisu(layer(id), id.name);
553 }
554 }
555
556 void
558 const std::vector<Eigen::Vector3f>& points,
559 const DrawColor& colorFace,
560 float lineWidth,
561 const DrawColor& colorEdge,
562 bool ignoreLengthScale)
563 {
564 if (enabled())
565 {
566 const float scale = lengthScale(ignoreLengthScale);
567
568 PolygonPointList polyPoints;
569 polyPoints.reserve(points.size());
570
571 for (const auto& point : points)
572 {
573 polyPoints.push_back(scaled(scale, point));
574 }
575
576 topic->setPolygonVisu(layer(id), id.name, polyPoints, colorFace, colorEdge, lineWidth);
577 }
578 }
579
580 void
582 {
583 if (enabled())
584 {
585 topic->removePolygonVisu(layer(id), id.name);
586 }
587 }
588
589 void
591 const Eigen::Vector3f& from,
592 const Eigen::Vector3f& to,
593 float width,
594 const DrawColor& color,
595 bool ignoreLengthScale)
596 {
597 if (enabled())
598 {
599 const float scale = lengthScale(ignoreLengthScale);
600
601 topic->setLineVisu(
602 layer(id), id.name, scaled(scale, from), scaled(scale, to), width, color);
603 }
604 }
605
606 void
608 {
609 if (enabled())
610 {
611 topic->removeLineVisu(layer(id), id.name);
612 }
613 }
614
615 void
617 const DebugDrawerLineSet& lineSet,
618 bool ignoreLengthScale)
619 {
620 if (enabled())
621 {
622 const float scale = lengthScale(ignoreLengthScale);
623
624 if (1.f <= scale && scale <= 1.f)
625 {
626 // Can use lineSet directly.
627 topic->setLineSetVisu(layer(id), id.name, lineSet);
628 }
629 else
630 {
631 // Need to scale line set, hence, reconstruct it.
632 DebugDrawerLineSet scaledLineSet = lineSet;
633 for (auto& point : scaledLineSet.points)
634 {
635 scaleXYZ(scale, point);
636 }
637 topic->setLineSetVisu(layer(id), id.name, scaledLineSet);
638 }
639 }
640 }
641
642 void
644 const std::vector<Eigen::Vector3f>& points,
645 float width,
646 const DrawColor& color,
647 bool ignoreLengthScale)
648 {
649 if (enabled())
650 {
651 const float scale = lengthScale(ignoreLengthScale);
652
653 DebugDrawerLineSet lineSet;
654 for (const auto& point : points)
655 {
656 lineSet.points.push_back(scaledT<DebugDrawerPointCloudElement>(scale, point));
657 }
658
659 lineSet.lineWidth = width;
660 lineSet.colorNoIntensity = lineSet.colorFullIntensity = color;
661 lineSet.intensities.assign(points.size() / 2, 0.);
662
663 topic->setLineSetVisu(layer(id), id.name, lineSet);
664 }
665 }
666
667 void
669 const std::vector<Eigen::Vector3f>& points,
670 float width,
671 const DrawColor& colorA,
672 const DrawColor& colorB,
673 const std::vector<float>& intensitiesB,
674 bool ignoreLengthScale)
675 {
676 if (enabled())
677 {
678 const float scale = lengthScale(ignoreLengthScale);
679
680 DebugDrawerLineSet lineSet;
681 for (const auto& point : points)
682 {
683 lineSet.points.push_back(scaledT<DebugDrawerPointCloudElement>(scale, point));
684 }
685
686 lineSet.lineWidth = width;
687 lineSet.colorNoIntensity = colorA;
688 lineSet.colorFullIntensity = colorB;
689 lineSet.intensities = intensitiesB;
690
691 topic->setLineSetVisu(layer(id), id.name, lineSet);
692 }
693 }
694
695 void
697 {
698 if (enabled())
699 {
700 topic->removeLineSetVisu(layer(id), id.name);
701 }
702 }
703
704 void
706 const Eigen::Matrix4f& pose,
707 bool ignoreLengthScale)
708 {
709 drawPose(id, pose, _poseScale, ignoreLengthScale);
710 }
711
712 void
714 const Eigen::Vector3f& pos,
715 const Eigen::Quaternionf& ori,
716 bool ignoreLengthScale)
717 {
718 drawPose(id, ::math::Helpers::Pose(pos, ori), _poseScale, ignoreLengthScale);
719 }
720
721 void
723 const Eigen::Matrix4f& pose,
724 float scale,
725 bool ignoreLengthScale)
726 {
727 if (enabled())
728 {
729 const float lenghtScale = lengthScale(ignoreLengthScale);
730
731 if (scale >= 1 && scale <= 1) // squelch compiler warning that == is unsafe
732 {
733 topic->setPoseVisu(layer(id), id.name, scaled(lenghtScale, pose));
734 }
735 else
736 {
737 topic->setScaledPoseVisu(layer(id), id.name, scaled(lenghtScale, pose), scale);
738 }
739 }
740 }
741
742 void
744 const Eigen::Vector3f& pos,
745 const Eigen::Quaternionf& ori,
746 float scale,
747 bool ignoreLengthScale)
748 {
749 drawPose(id, ::math::Helpers::Pose(pos, ori), scale, ignoreLengthScale);
750 }
751
752 void
754 {
755 if (enabled())
756 {
757 topic->removePoseVisu(layer(id), id.name);
758 }
759 }
760
761 void
763 const std::string& robotFile,
764 const std::string& armarxProject,
765 DrawStyle drawStyle)
766 {
767 if (enabled())
768 {
769 topic->setRobotVisu(layer(id), id.name, robotFile, armarxProject, drawStyle);
770 }
771 }
772
773 void
775 const Eigen::Matrix4f& pose,
776 bool ignoreScale)
777 {
778 if (enabled())
779 {
780 topic->updateRobotPose(layer(id), id.name, scaled(lengthScale(ignoreScale), pose));
781 }
782 }
783
784 void
786 const Eigen::Vector3f& pos,
787 const Eigen::Quaternionf& ori,
788 bool ignoreScale)
789 {
790 updateRobotPose(id, ::math::Helpers::Pose(pos, ori), ignoreScale);
791 }
792
793 void
795 const std::map<std::string, float>& config)
796 {
797 if (enabled())
798 {
799 topic->updateRobotConfig(layer(id), id.name, config);
800 }
801 }
802
803 void
805 {
806 if (enabled())
807 {
808 topic->updateRobotColor(layer(id), id.name, color);
809 }
810 }
811
812 void
814 const std::string& nodeName,
815 const DrawColor& color)
816 {
817 if (enabled())
818 {
819 topic->updateRobotNodeColor(layer(id), id.name, nodeName, color);
820 }
821 }
822
823 void
825 {
826 if (enabled())
827 {
828 topic->removeRobotVisu(layer(id), id.name);
829 }
830 }
831
832 void
834 const VirtualRobot::TriMeshModel& triMesh,
835 const DrawColor& color,
836 bool ignoreLengthScale)
837 {
838 if (!enabled())
839 {
840 return;
841 }
842
843 const float scale = lengthScale(ignoreLengthScale);
844
845 DebugDrawerTriMesh dd;
846 dd.colors.push_back(color);
847
848 for (const auto& vertex : triMesh.vertices)
849 {
850 auto scaled = vertex * scale;
851 dd.vertices.push_back({scaled.x(), scaled.y(), scaled.z()});
852 }
853
854 const std::size_t normalBase = dd.vertices.size();
855 for (const auto& normal : triMesh.normals)
856 {
857 dd.vertices.push_back({normal.x(), normal.y(), normal.z()});
858 }
859
860 for (const auto& face : triMesh.faces)
861 {
862 DebugDrawerFace ddf;
863 ddf.vertex1.vertexID = static_cast<Ice::Int>(face.id1);
864 ddf.vertex2.vertexID = static_cast<Ice::Int>(face.id2);
865 ddf.vertex3.vertexID = static_cast<Ice::Int>(face.id3);
866
867 ddf.vertex1.colorID = ddf.vertex2.colorID = ddf.vertex3.colorID = 0;
868 ddf.vertex1.normalID = ddf.vertex2.normalID = ddf.vertex3.normalID = -1;
869
870 bool validNormalIDs = true;
871 for (const auto& id : {face.idNormal1, face.idNormal2, face.idNormal3})
872 {
873 validNormalIDs &= id < triMesh.normals.size();
874 }
875
876 if (validNormalIDs)
877 {
878 ddf.vertex1.normalID = static_cast<Ice::Int>(normalBase + face.idNormal1);
879 ddf.vertex2.normalID = static_cast<Ice::Int>(normalBase + face.idNormal2);
880 ddf.vertex3.normalID = static_cast<Ice::Int>(normalBase + face.idNormal3);
881 }
882 else
883 {
884 const Eigen::Vector3f& normal = face.normal;
885 ddf.normal = {normal.x(), normal.y(), normal.z()};
886 }
887
888 dd.faces.push_back(ddf);
889 }
890
891 topic->setTriMeshVisu(layer(id), id.name, dd);
892 }
893
894 void
896 const VirtualRobot::TriMeshModel& trimesh,
897 const DrawColor& colorFace,
898 float lineWidth,
899 const DrawColor& colorEdge,
900 bool ignoreLengthScale)
901 {
903 trimesh,
904 Eigen::Matrix4f::Identity(),
905 colorFace,
906 lineWidth,
907 colorEdge,
908 ignoreLengthScale);
909 }
910
911 void
913 const VirtualRobot::TriMeshModel& trimesh,
914 const Eigen::Matrix4f& pose,
915 const DrawColor& colorFace,
916 float lineWidth,
917 const DrawColor& colorEdge,
918 bool ignoreLengthScale)
919 {
920 if (!enabled())
921 {
922 return;
923 }
924
925 const float scale = lengthScale(ignoreLengthScale);
926 bool isIdentity = pose.isIdentity();
927
928 auto toVector3 = [&scale, &isIdentity, &pose](const Eigen::Vector3f& v)
929 { return scaled(scale, isIdentity ? v : ::math::Helpers::TransformPosition(pose, v)); };
930
931 ARMARX_INFO << "Drawing trimesh as polygons";
932
933 int counter = 0;
934 for (std::size_t i = 0; i < trimesh.faces.size(); ++i)
935 {
936 const auto& face = trimesh.faces[i];
937 PolygonPointList points{toVector3(trimesh.vertices.at(face.id1)),
938 toVector3(trimesh.vertices.at(face.id2)),
939 toVector3(trimesh.vertices.at(face.id3))};
940
941 topic->setPolygonVisu(layer(id),
942 id.name + "_" + std::to_string(counter),
943 points,
944 colorFace,
945 colorEdge,
946 lineWidth);
947 ++counter;
948 }
949 }
950
951 void
953 const VirtualRobot::TriMeshModel& trimesh,
954 const std::vector<DrawColor>& faceColorsInner,
955 float lineWidth,
956 const DrawColor& colorEdge,
957 bool ignoreLengthScale)
958 {
959 if (!enabled())
960 {
961 return;
962 }
963
964 //ARMARX_INFO << "Drawing trimesh as polygons colored by area";
965 const float scale = lengthScale(ignoreLengthScale);
966
967 for (std::size_t i = 0; i < trimesh.faces.size(); ++i)
968 {
969 const auto& face = trimesh.faces[i];
970 PolygonPointList points{scaled(scale, trimesh.vertices[face.id1]),
971 scaled(scale, trimesh.vertices[face.id2]),
972 scaled(scale, trimesh.vertices[face.id3])};
973
974 topic->setPolygonVisu(layer(id),
975 id.name + "_" + std::to_string(i),
976 points,
977 faceColorsInner.at(i),
978 colorEdge,
979 lineWidth);
980 }
981 }
982
983 void
985 const DebugDrawerPointCloud& pointCloud)
986 {
987 if (enabled())
988 {
989 topic->setPointCloudVisu(id.layer, id.name, pointCloud);
990 }
991 }
992
993 void
995 const DebugDrawerColoredPointCloud& pointCloud)
996 {
997 if (enabled())
998 {
999 topic->setColoredPointCloudVisu(id.layer, id.name, pointCloud);
1000 }
1001 }
1002
1003 void
1005 const DebugDrawer24BitColoredPointCloud& pointCloud)
1006 {
1007 if (enabled())
1008 {
1009 topic->set24BitColoredPointCloudVisu(id.layer, id.name, pointCloud);
1010 }
1011 }
1012
1013 void
1015 {
1016 // Draw an empty point cloud.
1017 drawPointCloud(id, DebugDrawerColoredPointCloud{});
1018 }
1019
1020 void
1022 const Eigen::Vector3f& at,
1023 const Eigen::Vector3f& up,
1024 float size,
1025 const DrawColor& color,
1026 bool ignoreLengthScale)
1027 {
1028 if (!enabled())
1029 {
1030 return;
1031 }
1032
1033 Eigen::Vector3f seed = seed.UnitX();
1034 if (std::abs(up.dot(seed)) <= 1e-6f)
1035 {
1036 seed = seed.UnitY();
1037 }
1038
1039 /* ^ b
1040 * | 3---0
1041 * | | + |
1042 * | 2---1
1043 * +--------> a
1044 */
1045
1046 const float halfSize = size / 2;
1047
1048 const Eigen::Vector3f a = halfSize * up.cross(seed).normalized();
1049 const Eigen::Vector3f b = halfSize * up.cross(a).normalized();
1050
1051 std::vector<Eigen::Vector3f> points;
1052 points.push_back(at + a + b);
1053 points.push_back(at + a - b);
1054 points.push_back(at - a - b);
1055 points.push_back(at - a + b);
1056
1057 drawPolygon(id, points, color, ignoreLengthScale);
1058 }
1059
1060 const std::string&
1061 DebugDrawerTopic::layer(const std::string& passedLayer) const
1062 {
1063 return passedLayer.empty() ? _layer : passedLayer;
1064 }
1065
1066 const std::string&
1067 DebugDrawerTopic::layer(const VisuID& id) const
1068 {
1069 return layer(id.layer);
1070 }
1071
1072 float
1073 DebugDrawerTopic::lengthScale(bool ignore) const
1074 {
1075 return ignore ? 1 : _lengthScale;
1076 }
1077
1078 float
1079 DebugDrawerTopic::scaled(float scale, float value)
1080 {
1081 return scale * value;
1082 }
1083
1084 Vector3BasePtr
1085 DebugDrawerTopic::scaled(float scale, const Eigen::Vector3f& vector)
1086 {
1087 if (scale >= 1 && scale <= 1)
1088 {
1089 return new Vector3(vector);
1090 }
1091 else
1092 {
1093 return new Vector3((vector * scale).eval());
1094 }
1095 }
1096
1097 PoseBasePtr
1098 DebugDrawerTopic::scaled(float scale, const Eigen::Matrix4f& pose)
1099 {
1100 if (scale >= 1 && scale <= 1)
1101 {
1102 return new Pose(pose);
1103 }
1104 else
1105 {
1106 Eigen::Matrix4f out = pose;
1107 ::math::Helpers::Position(out) *= scale;
1108 return new Pose(out);
1109 }
1110 }
1111
1112 DebugDrawerTopic::operator bool() const
1113 {
1114 return enabled();
1115 }
1116
1117 armarx::DebugDrawerTopic::operator DebugDrawerInterfacePrx&()
1118 {
1119 return topic;
1120 }
1121
1122 armarx::DebugDrawerTopic::operator const DebugDrawerInterfacePrx&() const
1123 {
1124 return topic;
1125 }
1126
1129 {
1130 return topic;
1131 }
1132
1135 {
1136 return topic;
1137 }
1138
1139 Eigen::Vector3f
1140 DebugDrawerTopic::rgb2hsv(const Eigen::Vector3f& rgb)
1141 {
1142 return simox::color::rgb_to_hsv(rgb);
1143 }
1144
1145 Eigen::Vector3f
1146 DebugDrawerTopic::hsv2rgb(const Eigen::Vector3f& hsv)
1147 {
1148 return simox::color::hsv_to_rgb(hsv);
1149 }
1150
1151 DrawColor
1153 {
1154 return GlasbeyLUT::at(id, alpha);
1155 }
1156
1157 DrawColor
1159 {
1160 return GlasbeyLUT::at(id, alpha);
1161 }
1162
1163 DrawColor
1164 DebugDrawerTopic::getGlasbeyLUTColor(std::size_t id, float alpha)
1165 {
1166 return GlasbeyLUT::at(id, alpha);
1167 }
1168
1169
1170} // namespace armarx
void removeLine(const VisuID &id)
Remove a line.
void drawLine(const VisuID &id, const Eigen::Vector3f &from, const Eigen::Vector3f &to, float width, const DrawColor &color=DEFAULTS.colorLine, bool ignoreLengthScale=false)
Draw a line from start to end.
void updateRobotColor(const VisuID &id, const DrawColor &color)
Update / set the robot color.
void shortSleep()
Sleep for the shortSleepDuration. Useful after clearing.
static DrawColor getGlasbeyLUTColor(int id, float alpha=1.f)
Get a color from the Glasbey look-up-table.
void drawCylinderFromTo(const VisuID &id, const Eigen::Vector3f &from, const Eigen::Vector3f &to, float radius, const DrawColor &color=DEFAULTS.colorCylinder, bool ignoreLengthScale=false)
Draw a cylinder from start to end.
void setEnabled(bool enabled)
Set whether drawing is enabled.
const std::string & getLayer() const
Get the default layer (used if no layer is passed to a method).
float getLengthScale() const
Get the scaling for positions, lengths and distances.
DebugDrawerTopic(const std::string &layer=DEFAULT_LAYER)
Construct without topic, and optional layer.
void removeSphere(const VisuID &id)
Remove a sphere.
void drawPolygon(const VisuID &id, const std::vector< Eigen::Vector3f > &points, const DrawColor &colorFace, float lineWidth=0, const DrawColor &colorEdge=DEFAULTS.colorPolygonEdge, bool ignoreLengthScale=false)
Draw a polygon.
void removePolygon(const VisuID &id)
Remove a polygon.
void drawArrow(const VisuID &id, const Eigen::Vector3f &position, const Eigen::Vector3f &direction, float length, float width, const DrawColor &color=DEFAULTS.colorArrow, bool ignoreLengthScale=false)
Draw an arrow with position (start) and direction.
void sleepFor(const DurationT &duration)
If enabled, sleep for the given duration (e.g. a chrono duration).
void setLayer(const std::string &layer)
Set the default layer (used if no layer is passed to a method).
void setPoseScaleMeters()
Set the pose scale to 0.001 (good when drawing in meters).
void drawTriMeshAsPolygons(const VisuID &id, const VirtualRobot::TriMeshModel &trimesh, const DrawColor &colorFace=DEFAULTS.colorPolygonFace, float lineWidth=0, const DrawColor &colorEdge=DEFAULTS.colorPolygonEdge, bool ignoreLengthScale=false)
Draw a TriMeshModel as individual polygons.
void removeArrow(const VisuID &id)
Remove an arrow.
void drawFloor(const VisuID &id={"floor"}, const Eigen::Vector3f &at=Eigen::Vector3f::Zero(), const Eigen::Vector3f &up=Eigen::Vector3f::UnitZ(), float size=5, const DrawColor &color=DEFAULTS.colorFloor, bool ignoreLengthScale=false)
Draw a quad representing the floor.
void drawPointCloud(const VisuID &id, const PointCloudT &pointCloud, const DrawColor &color=DEFAULTS.colorPointCloud, float pointSize=DEFAULTS.pointCloudPointSize, bool ignoreLengthScale=false)
Draw a unicolored point cloud.
void removePose(const VisuID &id)
Remove a pose.
void clearLayer(bool sleep=false)
Clear the (set default) layer.
void updateRobotNodeColor(const VisuID &id, const std::string &nodeName, const DrawColor &color)
Update / set the color of a robot node.
void drawLineSet(const VisuID &id, const DebugDrawerLineSet &lineSet, bool ignoreLengthScale=false)
Draw a line set.
void drawArrowFromTo(const VisuID &id, const Eigen::Vector3f &from, const Eigen::Vector3f &to, float width, const DrawColor &color=DEFAULTS.colorArrow, bool ignoreLengthScale=false)
Draw an arrow with start and end.
void drawPose(const VisuID &id, const Eigen::Matrix4f &pose, bool ignoreLengthScale=false)
Draw a pose (with the preset scale).
void drawSphere(const VisuID &id, const Eigen::Vector3f &center, float radius, const DrawColor &color=DEFAULTS.colorSphere, bool ignoreLengthScale=false)
Draw a sphere.
void drawCylinder(const VisuID &id, const Eigen::Vector3f &center, const Eigen::Vector3f &direction, float length, float radius, const DrawColor &color=DEFAULTS.colorCylinder, bool ignoreLengthScale=false)
Draw a cylinder with center and direction.
void setLengthScaleMetersToMillimeters()
Set the scale for positions, lengths and distances to 1000.
void setPoseScale(float scale)
Set the scale for pose visualization. This value will be used for all successive calls to drawPose().
void setPoseScaleMillimeters()
Set the pose scale to 1 (good when drawing in millimeters).
static const Defaults DEFAULTS
void removeboxEdges(const VisuID &id)
Remove box edges (as a line set).
DebugDrawerInterfacePrx getTopic() const
Get the topic.
void drawText(const VisuID &id, const Eigen::Vector3f &position, const std::string &text, int size=10, const DrawColor color=DEFAULTS.colorText, bool ignoreLengthScale=false)
Draw text at the specified position.
void removeBox(const VisuID &id)
Remove a box.
void drawBoxEdges(const VisuID &id, const Eigen::Vector3f &position, const Eigen::Quaternionf &orientation, const Eigen::Vector3f &extents, float width=DEFAULTS.boxEdgesWidth, const DrawColor &color=DEFAULTS.boxEdgesColor, bool ignoreLengthScale=false)
Draw box edges (as a line set).
void removeCylinder(const VisuID &id)
Remove a cylinder.
void setTopic(const DebugDrawerInterfacePrx &topic)
Set the topic.
void updateRobotPose(const VisuID &id, const Eigen::Matrix4f &pose, bool ignoreScale=false)
Update / set the robot pose.
void removeLineSet(const VisuID &id)
Remove a line set.
void removeRobot(const VisuID &id)
Remove a robot visualization.
void clearColoredPointCloud(const VisuID &id)
Forces the "deletion" of a point cloud by drawing an empty one.
void clearAll(bool sleep=false)
Clear all layers.
void setLengthScale(float scale)
Set the scale for positions, lengths and distances.
static Eigen::Vector3f hsv2rgb(const Eigen::Vector3f &hsv)
Convert a HSV color RGB.
static Eigen::Vector3f rgb2hsv(const Eigen::Vector3f &rgb)
Convert a RGB color to HSV.
float getPoseScale() const
Get the scale for pose visualization.
void updateRobotConfig(const VisuID &id, const std::map< std::string, float > &config)
Update / set the robot configuration (joint angles).
DebugDrawerInterfacePrx & operator->()
Pointer member access operator to access the raw debug drawer proxy.
void drawRobot(const VisuID &id, const std::string &robotFile, const std::string &armarxProject, armarx::DrawStyle drawStyle=armarx::DrawStyle::FullModel)
Draw a robot.
bool enabled() const
Indicate whether visualization is enabled, i.e. a topic is set and enabled flag is set.
void drawTriMesh(const VisuID &id, const VirtualRobot::TriMeshModel &triMesh, const DrawColor &color={.5,.5,.5, 1}, bool ignoreLengthScale=false)
Draw a TriMeshModel as DebugDrawerTriMesh.
void drawBox(const VisuID &id, const Eigen::Vector3f &position, const Eigen::Quaternionf &orientation, const Eigen::Vector3f &extents, const DrawColor &color=DEFAULTS.colorBox, bool ignoreLengthScale=false)
Draw a box.
void offeringTopic(ManagedIceObject &component, const std::string &topicNameOverride="") const
Call offeringTopic([topicName]) on the given component.
void setLengthScaleMillimetersToMeters()
Set the scale for positions, lengths and distances to 0.001.
static DrawColor at(std::size_t id, float alpha=1.f)
The ManagedIceObject is the base class for all ArmarX objects.
The Pose class.
Definition Pose.h:243
The Quaternion class.
Definition Pose.h:174
The Vector3 class.
Definition Pose.h:113
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
Quaternion< float, 0 > Quaternionf
Matrix< float, 3, 2 > Matrix32f
A 3x2 matrix.
Eigen::Isometry3f Pose
Definition basic_types.h:31
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::ostream & operator<<(std::ostream &os, const PythonApplicationManager::Paths &paths)
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
std::shared_ptr< Value > value()
Definition cxxopts.hpp:855
Eigen::Vector3d Vector3
Definition kbm.h:43
Default values for drawing functions.
VisuID withName(const std::string &name) const
Get a VisuID with the given name and same layer as `*this.
std::string layer
The layer name (empty by default).
std::string name
The visu name (empty by default).