util.cpp
Go to the documentation of this file.
1 #include "util.hpp"
2 
3 #include <astra/capi/astra.h>
4 
5 // #include <sensor_msgs/Image.h>
7 
8 #include <stdexcept>
9 #include <unordered_map>
10 #include <sstream>
11 
12 #include <eigen3/Eigen/Dense>
13 
14 #include "visualization.hpp"
15 
16 namespace std
17 {
18  template<>
19  struct hash<astra_status_t>
20  {
21  std::size_t operator() (astra_status_t status) const
22  {
23  return static_cast<std::size_t>(status);
24  }
25  };
26 }
27 
28 namespace
29 {
30  __attribute__((destructor))
31  static void terminate()
32  {
33  astra_terminate();
34  }
35 
36 
37  struct Encoding
38  {
39  Encoding(const std::string &type, const std::uint32_t byte_length)
40  : type(type)
41  , byte_length(byte_length)
42  {
43  }
44 
45  std::string type;
46  std::uint32_t byte_length;
47  };
48 
49  const static std::unordered_map<astra_pixel_format_t, Encoding> ENCODING_MAPPING {
50  { ASTRA_PIXEL_FORMAT_GRAY8, Encoding(sensor_msgs::image_encodings::MONO8, 1) },
51  { ASTRA_PIXEL_FORMAT_GRAY16, Encoding(sensor_msgs::image_encodings::MONO16, 2) },
52  { ASTRA_PIXEL_FORMAT_RGB888, Encoding(sensor_msgs::image_encodings::RGB8, 3) },
53  { ASTRA_PIXEL_FORMAT_RGBA, Encoding(sensor_msgs::image_encodings::RGBA8, 4) },
54  };
55 
56  const static std::unordered_map<astra_status_t, std::string> STATUS_STRINGS {
57  { ASTRA_STATUS_SUCCESS, "Success" },
58  { ASTRA_STATUS_INVALID_PARAMETER, "Invalid Parameter" },
59  { ASTRA_STATUS_DEVICE_ERROR, "Device Error" },
60  { ASTRA_STATUS_TIMEOUT, "Timeout" },
61  { ASTRA_STATUS_INVALID_PARAMETER_TOKEN, "Invalid Parameter Token" },
62  { ASTRA_STATUS_INVALID_OPERATION, "Invalid Operation" },
63  { ASTRA_STATUS_INTERNAL_ERROR, "Internal Error" },
64  { ASTRA_STATUS_UNINITIALIZED, "Uninitialized" }
65  };
66 }
67 
68 const std::string &astra_ros::statusToString(const astra_status_t status)
69 {
70  const auto it = STATUS_STRINGS.find(status);
71  if (it == STATUS_STRINGS.cend()) throw std::runtime_error("Unknown astra_status_t value");
72  return it->second;
73 }
74 
75 sensor_msgs::Image astra_ros::toRos(const std::uint8_t *const data, const std::size_t length, const astra_image_metadata_t &metadata)
76 {
77  sensor_msgs::Image ret;
78  ret.height = metadata.height;
79  ret.width = metadata.width;
80  const auto it = ENCODING_MAPPING.find(metadata.pixelFormat);
81  if (it == ENCODING_MAPPING.cend()) throw std::runtime_error("Can't convert pixel format to sensor_msgs::Image");
82  ret.encoding = it->second.type;
83  ret.is_bigendian = false;
84  ret.step = ret.width * it->second.byte_length;
85  ret.data.insert(ret.data.end(), data, data + length);
86  return ret;
87 }
88 
89 sensor_msgs::Image astra_ros::toRos(const std::int16_t *const data, const std::size_t length, const astra_image_metadata_t &metadata)
90 {
91  sensor_msgs::Image ret;
92  ret.height = metadata.height;
93  ret.width = metadata.width;
95  ret.is_bigendian = false;
96  ret.step = ret.width * 2;
97 
98  // TODO: Verify endianess?
99  ret.data.insert(ret.data.end(), reinterpret_cast<const std::uint8_t *>(data), reinterpret_cast<const std::uint8_t *>(data) + length);
100  return ret;
101 }
102 
103 sensor_msgs::Image astra_ros::toRos(const astra_rgba_pixel_t *const data, const std::size_t length, const astra_image_metadata_t &metadata)
104 {
105  sensor_msgs::Image ret;
106  ret.height = metadata.height;
107  ret.width = metadata.width;
108 
110  ret.is_bigendian = false;
111  ret.step = ret.width * 4;
112 
113  // astra_rgba_pixel_t isn't packed, so we have to manually copy
114  ret.data.reserve(length * 4);
115  for (std::size_t i = 0; i < length; ++i)
116  {
117  ret.data.push_back(data[i].r);
118  ret.data.push_back(data[i].g);
119  ret.data.push_back(data[i].b);
120  ret.data.push_back(data[i].alpha);
121  }
122 
123  return ret;
124 }
125 
126 sensor_msgs::Image astra_ros::toRos(const astra_floormask_t &floor_mask)
127 {
128  sensor_msgs::Image ret;
129  ret.height = floor_mask.height;
130  ret.width = floor_mask.width;
132  ret.is_bigendian = false;
133  ret.step = ret.width;
134 
135  const std::size_t size = floor_mask.height * floor_mask.width;
136  ret.data.reserve(size);
137  for (std::size_t i = 0; i < size; ++i)
138  {
139  ret.data.push_back(floor_mask.data[i] ? 0xFF : 0x00);
140  }
141 
142  return ret;
143 }
144 
145 astra_ros::Body astra_ros::toRos(const astra_body_t &body, const std_msgs::Header &header)
146 {
147  Body ret;
148  ret.header = header;
149  ret.id = body.id;
150  ret.status = static_cast<std::uint8_t>(body.status);
151  ret.center_of_mass.x = body.centerOfMass.x / 1000.0;
152  ret.center_of_mass.y = -body.centerOfMass.y / 1000.0;
153  ret.center_of_mass.z = body.centerOfMass.z / 1000.0;
154  ret.is_tracking_joints = body.features & ASTRA_BODY_TRACKING_JOINTS;
155  ret.is_tracking_hand_poses = body.features & ASTRA_BODY_TRACKING_HAND_POSES;
156 
157  for (std::size_t i = 0; i < ASTRA_MAX_JOINTS; ++i)
158  {
159  if (body.joints[i].type == ASTRA_JOINT_UNKNOWN) continue;
160 
161  Joint joint;
162  joint.type = static_cast<std::uint8_t>(body.joints[i].type);
163  joint.status = static_cast<std::uint8_t>(body.joints[i].status);
164  joint.depth_position.x = body.joints[i].depthPosition.x;
165  joint.depth_position.y = body.joints[i].depthPosition.y;
166  joint.pose.position.x = body.joints[i].worldPosition.x / 1000.0;
167  joint.pose.position.y = -body.joints[i].worldPosition.y / 1000.0;
168  joint.pose.position.z = body.joints[i].worldPosition.z / 1000.0;
169 
170  const auto &orientation = body.joints[i].orientation;
171 
172  Eigen::Matrix3f mat;
173  mat << orientation.m00, orientation.m01, orientation.m02,
174  orientation.m10, orientation.m11, orientation.m12,
175  orientation.m20, orientation.m21, orientation.m22;
176 
177  // We convert from the left-handed Z-up coordinate system of the Astra SDK
178  // to the right-handed Z-up coordinate system of ROS
179  Eigen::Matrix3f P;
180  P << 1, 0 , 0,
181  0, -1, 0,
182  0, 0 , 1;
183 
184  Eigen::Quaternionf q(mat * P);
185  q.normalize();
186  joint.pose.orientation.x = q.x();
187  joint.pose.orientation.y = q.y();
188  joint.pose.orientation.z = q.z();
189  joint.pose.orientation.w = q.w();
190 
191 
192  ret.joints.push_back(joint);
193  }
194 
195  ret.left_hand_pose = static_cast<std::uint8_t>(body.handPoses.leftHand);
196  ret.right_hand_pose = static_cast<std::uint8_t>(body.handPoses.rightHand);
197  return ret;
198 }
199 
200 
201 std::vector<astra_ros::Body> astra_ros::toRos(const astra_body_list_t &body_list, const std_msgs::Header &header)
202 {
203  std::vector<Body> ret;
204  ret.reserve(body_list.count);
205  for (std::int32_t i = 0; i < body_list.count; ++i)
206  {
207  ret.push_back(toRos(body_list.bodies[i], header));
208  }
209 
210  return ret;
211 }
212 
213 astra_ros::Plane astra_ros::toRos(const astra_plane_t &plane)
214 {
215  Plane ret;
216  ret.a = plane.a;
217  ret.b = plane.b;
218  ret.c = plane.c;
219  ret.d = plane.d;
220  return ret;
221 }
222 
223 
224 astra_ros::ImageStreamMode astra_ros::toRos(const astra_ros::Device::ImageStreamMode &image_stream_mode)
225 {
226  ImageStreamMode ret;
227  ret.width = image_stream_mode.width.get_value_or(0);
228  ret.height = image_stream_mode.height.get_value_or(0);
229  ret.fps = image_stream_mode.fps.get_value_or(0);
230  ret.pixel_format = static_cast<std::uint32_t>(image_stream_mode.pixel_format.get_value_or(ASTRA_PIXEL_FORMAT_UNKNOWN));
231  return ret;
232 }
233 
234 astra_ros::Device::ImageStreamMode astra_ros::fromRos(const astra_ros::ImageStreamMode &image_stream_mode)
235 {
236  Device::ImageStreamMode ret;
237  if (image_stream_mode.width != 0) ret.width = image_stream_mode.width;
238  if (image_stream_mode.height != 0) ret.height = image_stream_mode.height;
239  if (image_stream_mode.fps != 0) ret.fps = image_stream_mode.fps;
240  if (image_stream_mode.pixel_format != ImageStreamMode::PIXEL_FORMAT_UNKNOWN) ret.pixel_format = static_cast<astra_pixel_format_t>(image_stream_mode.pixel_format);
241  return ret;
242 }
image_encodings.h
astra_ros::fromRos
Device::ImageStreamMode fromRos(const ImageStreamMode &image_stream_mode)
visualization.hpp
sensor_msgs::image_encodings::RGBA8
const std::string RGBA8
astra_ros::statusToString
const std::string & statusToString(const astra_status_t status)
Definition: util.cpp:68
astra_ros::Device::ImageStreamMode::fps
boost::optional< std::uint8_t > fps
Definition: Device.hpp:51
sensor_msgs::image_encodings::RGB8
const std::string RGB8
astra_ros::toRos
sensor_msgs::Image toRos(const std::uint8_t *const data, const std::size_t length, const astra_image_metadata_t &metadata)
Definition: util.cpp:75
astra_ros::Device::ImageStreamMode::height
boost::optional< std::uint32_t > height
Definition: Device.hpp:41
astra_ros::Device::ImageStreamMode
Represents a potential stream configuration.
Definition: Device.hpp:31
astra_ros::Device::ImageStreamMode::width
boost::optional< std::uint32_t > width
Definition: Device.hpp:36
std
sensor_msgs::image_encodings::MONO8
const std::string MONO8
sensor_msgs::image_encodings::MONO16
const std::string MONO16
length
TF2SIMD_FORCE_INLINE tf2Scalar length(const Quaternion &q)
header
const std::string header
astra_ros::Device::ImageStreamMode::pixel_format
boost::optional< astra_pixel_format_t > pixel_format
Definition: Device.hpp:46
util.hpp


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