visualization.cpp
Go to the documentation of this file.
1 #include "visualization.hpp"
2 
3 #include "color.hpp"
4 #include "math.hpp"
5 
6 
7 #include <sstream>
8 #include <unordered_map>
9 
10 using namespace astra_ros;
11 
12 namespace
13 {
14  const static std::vector<std::pair<std::uint8_t, std::uint8_t>> JOINT_PAIRS {
15  { Joint::TYPE_SHOULDER_SPINE, Joint::TYPE_HEAD },
16  { Joint::TYPE_SHOULDER_SPINE, Joint::TYPE_RIGHT_SHOULDER },
17  { Joint::TYPE_SHOULDER_SPINE, Joint::TYPE_LEFT_SHOULDER },
18  { Joint::TYPE_LEFT_SHOULDER, Joint::TYPE_LEFT_ELBOW },
19  { Joint::TYPE_LEFT_ELBOW, Joint::TYPE_LEFT_WRIST },
20  { Joint::TYPE_LEFT_WRIST, Joint::TYPE_LEFT_HAND },
21  { Joint::TYPE_RIGHT_SHOULDER, Joint::TYPE_RIGHT_ELBOW },
22  { Joint::TYPE_RIGHT_ELBOW, Joint::TYPE_RIGHT_WRIST },
23  { Joint::TYPE_RIGHT_WRIST, Joint::TYPE_RIGHT_HAND },
24  { Joint::TYPE_MID_SPINE, Joint::TYPE_SHOULDER_SPINE },
25  { Joint::TYPE_BASE_SPINE, Joint::TYPE_MID_SPINE },
26  { Joint::TYPE_LEFT_HIP, Joint::TYPE_BASE_SPINE },
27  { Joint::TYPE_LEFT_KNEE, Joint::TYPE_LEFT_HIP },
28  { Joint::TYPE_LEFT_FOOT, Joint::TYPE_LEFT_KNEE },
29  { Joint::TYPE_RIGHT_HIP, Joint::TYPE_BASE_SPINE },
30  { Joint::TYPE_RIGHT_KNEE, Joint::TYPE_RIGHT_HIP },
31  { Joint::TYPE_RIGHT_FOOT, Joint::TYPE_RIGHT_KNEE },
32  };
33 
34  const static std::unordered_map<std::uint8_t, float> STATUS_OPACITIES {
35  { Joint::STATUS_NOT_TRACKED, 0.2 },
36  { Joint::STATUS_LOW_CONFIDENCE, 0.7 },
37  { Joint::STATUS_TRACKED, 1.0 },
38  };
39 }
40 
41 namespace
42 {
43  const static ros::Duration MARKER_LIFETIME(0.5);
44 
45 
46 }
47 
48 visualization_msgs::MarkerArray astra_ros::toMarkerArray(const astra_ros::Body &body)
49 {
50  using namespace visualization_msgs;
51 
52  std::size_t id_iter = 0;
53 
54  MarkerArray ret;
55 
56  std::ostringstream o;
57  o << "astra_ros/" << static_cast<std::size_t>(body.id);
58  const std::string ns = o.str();
59 
60  // Helper function that creates a marker
61  const auto create_marker = [&](const std::int32_t type) -> Marker {
62  Marker ret;
63  ret.header = body.header;
64  ret.ns = ns;
65  ret.id = id_iter++;
66  ret.type = type;
67  ret.action = Marker::MODIFY;
68  ret.frame_locked = false;
69  ret.lifetime = MARKER_LIFETIME;
70  return ret;
71  };
72 
73  std::unordered_map<std::uint8_t, const Joint *> lookup_map;
74 
75  // Helper function to look up a joint with caching (to avoid O(n^2)),
76  // though with hashmap allocation the performance might not be
77  // better for n = number of joints.
78  const auto lookup = [&](std::uint8_t type) -> const Joint * {
79  const auto it = lookup_map.find(type);
80  if (it != lookup_map.cend()) return it->second;
81 
82  for (const auto &joint : body.joints)
83  {
84  if (joint.type != type) continue;
85 
86  lookup_map[type] = &joint;
87  return &joint;
88  }
89 
90  return nullptr;
91  };
92 
93  const Rgb color = indexColor(body.id).toRgb();
94 
95  // Center of mass
96  Marker center_of_mass = create_marker(Marker::SPHERE);
97  center_of_mass.scale.x = center_of_mass.scale.y = center_of_mass.scale.z = 0.1;
98  center_of_mass.pose.position.x = body.center_of_mass.x;
99  center_of_mass.pose.position.y = body.center_of_mass.y;
100  center_of_mass.pose.position.z = body.center_of_mass.z;
101  center_of_mass.pose.orientation.w = 1.0;
102  center_of_mass.color = color;
103  ret.markers.push_back(center_of_mass);
104 
105  // Joints
106  for (const auto &joint : body.joints)
107  {
108  Marker marker = create_marker(Marker::CUBE);
109  marker.scale.x = marker.scale.y = marker.scale.z = 0.05;
110  const auto it = STATUS_OPACITIES.find(joint.status);
111  marker.color = color.toRgba(it == STATUS_OPACITIES.cend() ? 0.0 : it->second);
112  marker.pose = joint.pose;
113  ret.markers.push_back(marker);
114  }
115 
116 
117  // Draw cylinders between all joint pairs
118  for (const auto &joint_pair : JOINT_PAIRS)
119  {
120  const Joint *const left = lookup(joint_pair.first);
121  const Joint *const right = lookup(joint_pair.second);
122 
123  if (left == nullptr || right == nullptr) continue;
124 
125  Marker link = create_marker(Marker::CYLINDER);
126 
127  const auto &left_position = left->pose.position;
128  const auto &right_position = right->pose.position;
129 
130  link.scale.z = link.scale.y = 0.01;
131 
132  // Scale the cylinder along the X axis to be able to touch both joints
133  link.scale.x = distance(left_position, right_position);
134 
135  // Place the origin of the cyliner directly in the middle of the two joints
136  link.pose.position = (left_position + right_position) / 2.0;
137 
138  link.pose.orientation = fromEigen(lookAt(
139  toEigen(link.pose.position),
140  toEigen(left_position),
141  Eigen::Vector3d::UnitX(),
142  Eigen::Vector3d::UnitZ()
143  ));
144 
145  const auto left_it = STATUS_OPACITIES.find(left->status);
146  const auto right_it = STATUS_OPACITIES.find(right->status);
147  link.color = color.toRgba(std::min(
148  left_it == STATUS_OPACITIES.cend() ? 0.0f : left_it->second,
149  right_it == STATUS_OPACITIES.cend() ? 0.0f : right_it->second
150  ));
151  ret.markers.push_back(link);
152  }
153 
154  return ret;
155 }
156 
157 visualization_msgs::MarkerArray astra_ros::toMarkerArray(const std::vector<astra_ros::Body> &bodies)
158 {
159  visualization_msgs::MarkerArray ret;
160 
161  for (const auto &body : bodies)
162  {
163  const auto body_markers = toMarkerArray(body);
164  ret.markers.insert(ret.markers.end(), body_markers.markers.cbegin(), body_markers.markers.cend());
165  }
166 
167  return ret;
168 }
astra_ros::Rgb
Definition: color.hpp:60
astra_ros::toMarkerArray
visualization_msgs::MarkerArray toMarkerArray(const Body &body)
astra_ros::indexColor
Hsv indexColor(const std::size_t i)
Definition: color.cpp:291
visualization.hpp
astra_ros::distance
double distance(const geometry_msgs::Point &lhs, const geometry_msgs::Point &rhs)
Definition: math.cpp:12
astra_ros::Rgb::toRgba
Rgba toRgba() const
Definition: color.cpp:242
astra_ros::lookAt
Eigen::Quaterniond lookAt(const Eigen::Vector3d &source_point, const Eigen::Vector3d &dest_point, const Eigen::Vector3d &forward, const Eigen::Vector3d &up)
Definition: math.cpp:115
astra_ros::Hsv::toRgb
Rgb toRgb() const
Definition: color.cpp:271
color.hpp
astra_ros::fromEigen
geometry_msgs::Point fromEigen(const Eigen::Vector3d &point)
Definition: math.cpp:75
math.hpp
ros::Duration
astra_ros::toEigen
Eigen::Vector3d toEigen(const geometry_msgs::Point &point)
Definition: math.cpp:54
astra_ros
Definition: Device.hpp:14


astra_ros
Author(s): Braden McDorman
autogenerated on Wed Mar 2 2022 00:53:06