os1_ros.cpp
Go to the documentation of this file.
2 
3 #include "ouster/os1.h"
4 #include "ouster/os1_packet.h"
6 
7 namespace ouster_driver {
8 namespace OS1 {
9 
10 using namespace ouster::OS1;
11 
12 static std::string _pointcloud_mode = "NATIVE";
13 
15  return ns(imu_gyro_ts(pm.buf.data()));
16 }
17 
19  return ns(col_timestamp(nth_col(0, pm.buf.data())));
20 }
21 
22 bool read_imu_packet(const client& cli, PacketMsg& m) {
23  m.buf.resize(imu_packet_bytes + 1);
24  return read_imu_packet(cli, m.buf.data());
25 }
26 
27 bool read_lidar_packet(const client& cli, PacketMsg& m) {
28  m.buf.resize(lidar_packet_bytes + 1);
29  return read_lidar_packet(cli, m.buf.data());
30 }
31 
32 sensor_msgs::Imu packet_to_imu_msg(const PacketMsg& p, const std::string& frame) {
33  const double standard_g = 9.80665;
34  sensor_msgs::Imu m;
35  const uint8_t* buf = p.buf.data();
36 
37  m.header.stamp.fromNSec(imu_gyro_ts(buf));
41  //m.header.frame_id = "os1_imu"; // original code of OS1 driver
42  m.header.frame_id = frame; //using defined message frame name
43 
44  m.orientation.x = 0;
45  m.orientation.y = 0;
46  m.orientation.z = 0;
47  m.orientation.w = 0;
48 
49  m.linear_acceleration.x = imu_la_x(buf) * standard_g;
50  m.linear_acceleration.y = imu_la_y(buf) * standard_g;
51  m.linear_acceleration.z = imu_la_z(buf) * standard_g;
52 
53  m.angular_velocity.x = imu_av_x(buf) * M_PI / 180.0;
54  m.angular_velocity.y = imu_av_y(buf) * M_PI / 180.0;
55  m.angular_velocity.z = imu_av_z(buf) * M_PI / 180.0;
56 
57  for (int i = 0; i < 9; i++) {
58  m.orientation_covariance[i] = -1;
59  m.angular_velocity_covariance[i] = 0;
60  m.linear_acceleration_covariance[i] = 0;
61  }
62  for (int i = 0; i < 9; i += 4) {
63  m.linear_acceleration_covariance[i] = 0.01;
64  m.angular_velocity_covariance[i] = 6e-4;
65  }
66 
67  return m;
68 }
69 
70 sensor_msgs::PointCloud2 cloud_to_cloud_msg(const CloudOS1& cloud, ns timestamp,
71  const std::string& frame) {
72  sensor_msgs::PointCloud2 msg;
73 
74  //pcl::toROSMsg(cloud, msg); //<-- original code of OS1 driver
78  if (_pointcloud_mode == "XYZ") {
79  CloudOS1XYZ cloud_aux;
80  convert2XYZ(cloud, cloud_aux);
81  pcl::toROSMsg(cloud_aux, msg);
82  } else if (_pointcloud_mode == "XYZI") {
83  CloudOS1XYZI cloud_aux;
84  convert2XYZI(cloud, cloud_aux);
85  pcl::toROSMsg(cloud_aux, msg);
86  } else if (_pointcloud_mode == "XYZIR") {
87  CloudOS1XYZIR cloud_aux;
88  convert2XYZIR(cloud, cloud_aux);
89  pcl::toROSMsg(cloud_aux, msg);
90  } else if (_pointcloud_mode == "XYZIF") {
91  CloudOS1XYZIF cloud_aux;
92  convert2XYZIF(cloud, cloud_aux);
93  pcl::toROSMsg(cloud_aux, msg);
94  } else if (_pointcloud_mode == "XYZIRF") {
95  CloudOS1XYZIRF cloud_aux;
96  convert2XYZIRF(cloud, cloud_aux);
97  pcl::toROSMsg(cloud_aux, msg);
98  } else if (_pointcloud_mode == "XYZIFN") {
99  CloudOS1XYZIFN cloud_aux;
100  convert2XYZIFN(cloud, cloud_aux);
101  pcl::toROSMsg(cloud_aux, msg);
102  } else if (_pointcloud_mode == "XYZIRFN") {
103  CloudOS1XYZIRFN cloud_aux;
104  convert2XYZIRFN(cloud, cloud_aux);
105  pcl::toROSMsg(cloud_aux, msg);
106  } else { //"NATIVE"
107  pcl::toROSMsg(cloud, msg);
108  }
109 
110  msg.header.frame_id = frame;
114  //msg.header.stamp.fromNSec(timestamp.count()); //<-- original code of OS1 driver
115  msg.header.stamp = ros::Time::now(); //<-- prefered time mode in Autoware
116  return msg;
117 }
118 
119 static PointOS1 nth_point(int ind, const uint8_t* col_buf) {
120  float h_angle_0 = col_h_angle(col_buf);
121  auto tte = trig_table[ind];
122  const uint8_t* px_buf = nth_px(ind, col_buf);
123  float r = px_range(px_buf) / 1000.0;
124  float h_angle = tte.beam_azimuth_angles + h_angle_0;
125 
126  PointOS1 point;
127  point.reflectivity = px_reflectivity(px_buf);
128  point.intensity = px_signal_photons(px_buf);
129  point.noise = px_noise_photons(px_buf); //added to extract ambient noise data
130  point.x = -r * tte.cos_beam_altitude_angles * cosf(h_angle);
131  point.y = r * tte.cos_beam_altitude_angles * sinf(h_angle);
132  point.z = r * tte.sin_beam_altitude_angles;
133  point.ring = ind;
134 
135  return point;
136 }
137 void add_packet_to_cloud(ns scan_start_ts, ns scan_duration,
138  const PacketMsg& pm, CloudOS1& cloud) {
139  const uint8_t* buf = pm.buf.data();
140  for (int icol = 0; icol < columns_per_buffer; icol++) {
141  const uint8_t* col_buf = nth_col(icol, buf);
142  float ts = (col_timestamp(col_buf) - scan_start_ts.count()) /
143  (float)scan_duration.count();
144 
145  for (int ipx = 0; ipx < pixels_per_column; ipx++) {
146  auto p = nth_point(ipx, col_buf);
147  p.t = ts;
148  cloud.push_back(p);
149  }
150  }
151 }
152 
153 void spin(const client& cli,
154  const std::function<void(const PacketMsg& pm)>& lidar_handler,
155  const std::function<void(const PacketMsg& pm)>& imu_handler) {
156  PacketMsg lidar_packet, imu_packet;
157  lidar_packet.buf.resize(lidar_packet_bytes + 1);
158  imu_packet.buf.resize(imu_packet_bytes + 1);
159 
160  while (ros::ok()) {
161  auto state = poll_client(cli);
162  if (state & ERROR) {
163  ROS_ERROR("spin: poll_client returned error");
164  return;
165  }
166  if (state & LIDAR_DATA) {
167  if (read_lidar_packet(cli, lidar_packet.buf.data()))
168  lidar_handler(lidar_packet);
169  }
170  if (state & IMU_DATA) {
171  if (read_imu_packet(cli, imu_packet.buf.data()))
172  imu_handler(imu_packet);
173  }
174  ros::spinOnce();
175  }
176 }
177 
178 static ns nearest_scan_dur(ns scan_dur, ns ts) {
179  return ns((ts.count() / scan_dur.count()) * scan_dur.count());
180 };
181 
182 std::function<void(const PacketMsg&)> batch_packets(
183  ns scan_dur, const std::function<void(ns, const CloudOS1&)>& f) {
184  auto cloud = std::make_shared<OS1::CloudOS1>();
185  auto scan_ts = ns(-1L);
186 
187  return [=](const PacketMsg& pm) mutable {
188  ns packet_ts = OS1::timestamp_of_lidar_packet(pm);
189  if (scan_ts.count() == -1L)
190  scan_ts = nearest_scan_dur(scan_dur, packet_ts);
191 
192  OS1::add_packet_to_cloud(scan_ts, scan_dur, pm, *cloud);
193 
194  auto batch_dur = packet_ts - scan_ts;
195  if (batch_dur >= scan_dur || batch_dur < ns(0)) {
196  f(scan_ts, *cloud);
197 
198  cloud->clear();
199  scan_ts = ns(-1L);
200  }
201  };
202 }
203 
207 void set_point_mode(std::string mode_xyzir)
208 {
209  _pointcloud_mode = mode_xyzir;
210 }
211 
212 void convert2XYZ(const CloudOS1& in, CloudOS1XYZ& out)
213 {
214  out.points.clear();
215  pcl::PointXYZ q;
216  for (auto p : in.points) {
217  q.x = p.x;
218  q.y = p.y;
219  q.z = p.z;
220  out.points.push_back(q);
221  }
222 }
223 
224 void convert2XYZI(const CloudOS1& in, CloudOS1XYZI& out)
225 {
226  out.points.clear();
227  pcl::PointXYZI q;
228  for (auto p : in.points) {
229  q.x = p.x;
230  q.y = p.y;
231  q.z = p.z;
232  q.intensity = p.intensity;
233  out.points.push_back(q);
234  }
235 }
236 
240 void convert2XYZIR(const CloudOS1& in, CloudOS1XYZIR& out)
241 {
242  out.points.clear();
243  PointXYZIR q;
244  for (auto p : in.points) {
245  q.x = p.x;
246  q.y = p.y;
247  q.z = p.z;
248  q.intensity = ((float)p.intensity/65535.0)*255.0; //velodyne uses values in [0..255] range
249  q.ring = pixels_per_column - p.ring; //reverse the ring order to match Velodyne's (except NATIVE mode which respects Ouster original ring order)
250  out.points.push_back(q);
251  }
252 }
253 
257 void convert2XYZIF(const CloudOS1& in, CloudOS1XYZIF& out)
258 {
259  out.points.clear();
260  PointXYZIF q;
261  for (auto p : in.points) {
262  q.x = p.x;
263  q.y = p.y;
264  q.z = p.z;
265  q.intensity = p.intensity;
266  q.reflectivity = p.reflectivity;
267  out.points.push_back(q);
268  }
269 }
270 
274 void convert2XYZIRF(const CloudOS1& in, CloudOS1XYZIRF& out)
275 {
276  out.points.clear();
277  PointXYZIRF q;
278  for (auto p : in.points) {
279  q.x = p.x;
280  q.y = p.y;
281  q.z = p.z;
282  q.intensity = p.intensity;
283  q.ring = pixels_per_column - p.ring; //reverse the ring order to match Velodyne's (except NATIVE mode which respects Ouster original ring order)
284  q.reflectivity = p.reflectivity;
285  out.points.push_back(q);
286  }
287 }
288 
292 void convert2XYZIFN(const CloudOS1& in, CloudOS1XYZIFN& out)
293 {
294  out.points.clear();
295  PointXYZIFN q;
296  for (auto p : in.points) {
297  q.x = p.x;
298  q.y = p.y;
299  q.z = p.z;
300  q.intensity = p.intensity;
301  q.reflectivity = p.reflectivity;
302  q.noise = p.noise;
303  out.points.push_back(q);
304  }
305 }
306 
311 {
312  out.points.clear();
313  PointXYZIRFN q;
314  for (auto p : in.points) {
315  q.x = p.x;
316  q.y = p.y;
317  q.z = p.z;
318  q.intensity = p.intensity;
319  q.ring = pixels_per_column - p.ring; //reverse the ring order to match Velodyne's (except NATIVE mode which respects Ouster original ring order)
320  q.reflectivity = p.reflectivity;
321  q.noise = p.noise;
322  out.points.push_back(q);
323  }
324 }
325 
326 }
327 }
pcl::PointCloud< PointXYZIF > CloudOS1XYZIF
Definition: os1_ros.h:27
f
float imu_la_x(const uint8_t *imu_buf)
Definition: os1_packet.h:152
float imu_av_y(const uint8_t *imu_buf)
Definition: os1_packet.h:177
static ns nearest_scan_dur(ns scan_dur, ns ts)
Definition: os1_ros.cpp:178
bool read_imu_packet(const ouster::OS1::client &cli, PacketMsg &pm)
Definition: os1_ros.cpp:22
float col_h_angle(const uint8_t *col_buf)
Definition: os1_packet.h:78
const size_t imu_packet_bytes
Definition: os1.h:15
pcl::PointCloud< PointXYZIRFN > CloudOS1XYZIRFN
Definition: os1_ros.h:30
uint16_t px_noise_photons(const uint8_t *px_buf)
Definition: os1_packet.h:126
uint64_t imu_gyro_ts(const uint8_t *imu_buf)
Definition: os1_packet.h:145
pcl::PointCloud< PointOS1 > CloudOS1
Definition: os1_ros.h:23
void convert2XYZIRF(const CloudOS1 &in, CloudOS1XYZIRF &out)
Definition: os1_ros.cpp:274
void convert2XYZIFN(const CloudOS1 &in, CloudOS1XYZIFN &out)
Definition: os1_ros.cpp:292
void convert2XYZ(const CloudOS1 &in, CloudOS1XYZ &out)
Definition: os1_ros.cpp:212
uint64_t col_timestamp(const uint8_t *col_buf)
Definition: os1_packet.h:72
void set_point_mode(std::string mode_xyzir)
Definition: os1_ros.cpp:207
float imu_la_y(const uint8_t *imu_buf)
Definition: os1_packet.h:158
ouster_driver::PacketMsg PacketMsg
Definition: os1_node.cpp:34
pcl::PointCloud< pcl::PointXYZI > CloudOS1XYZI
Definition: os1_ros.h:25
void convert2XYZIR(const CloudOS1 &in, CloudOS1XYZIR &out)
Definition: os1_ros.cpp:240
ns timestamp_of_imu_packet(const PacketMsg &pm)
Definition: os1_ros.cpp:14
const uint8_t * nth_col(int n, const uint8_t *udp_buf)
Definition: os1_packet.h:68
ns timestamp_of_lidar_packet(const PacketMsg &pm)
Definition: os1_ros.cpp:18
void spin(const ouster::OS1::client &cli, const std::function< void(const PacketMsg &pm)> &lidar_handler, const std::function< void(const PacketMsg &pm)> &imu_handler)
Definition: os1_ros.cpp:153
uint16_t px_reflectivity(const uint8_t *px_buf)
Definition: os1_packet.h:114
std::function< void(const PacketMsg &)> batch_packets(ns scan_dur, const std::function< void(ns, const CloudOS1 &)> &f)
Definition: os1_ros.h:120
std::chrono::nanoseconds ns
Definition: os1_ros.h:31
pcl::PointCloud< PointXYZIR > CloudOS1XYZIR
Definition: os1_ros.h:26
float imu_av_x(const uint8_t *imu_buf)
Definition: os1_packet.h:171
ROSCPP_DECL bool ok()
void convert2XYZIF(const CloudOS1 &in, CloudOS1XYZIF &out)
Definition: os1_ros.cpp:257
const size_t lidar_packet_bytes
Definition: os1.h:14
float intensity
laser intensity reading
Definition: point_os1.h:20
void convert2XYZI(const CloudOS1 &in, CloudOS1XYZI &out)
Definition: os1_ros.cpp:224
static std::string _pointcloud_mode
Definition: os1_ros.cpp:12
const uint8_t * nth_px(int n, const uint8_t *col_buf)
Definition: os1_packet.h:103
sensor_msgs::Imu packet_to_imu_msg(const PacketMsg &pm, const std::string &frame="os1_imu")
Definition: os1_ros.cpp:32
client_state poll_client(const client &cli)
Definition: os1.cpp:279
bool read_lidar_packet(const ouster::OS1::client &cli, PacketMsg &pm)
Definition: os1_ros.cpp:27
pcl::PointCloud< pcl::PointXYZ > CloudOS1XYZ
Definition: os1_ros.h:24
uint16_t ring
laser ring number
Definition: point_os1.h:21
pcl::PointCloud< PointXYZIFN > CloudOS1XYZIFN
Definition: os1_ros.h:29
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
static Time now()
float imu_la_z(const uint8_t *imu_buf)
Definition: os1_packet.h:164
void add_packet_to_cloud(ns scan_start_ts, ns scan_duration, const PacketMsg &pm, CloudOS1 &cloud)
Definition: os1_ros.cpp:137
uint32_t px_range(const uint8_t *px_buf)
Definition: os1_packet.h:107
ROSCPP_DECL void spinOnce()
void convert2XYZIRFN(const CloudOS1 &in, CloudOS1XYZIRFN &out)
Definition: os1_ros.cpp:310
#define ROS_ERROR(...)
float imu_av_z(const uint8_t *imu_buf)
Definition: os1_packet.h:183
pcl::PointCloud< PointXYZIRF > CloudOS1XYZIRF
Definition: os1_ros.h:28
sensor_msgs::PointCloud2 cloud_to_cloud_msg(const CloudOS1 &cloud, ns timestamp, const std::string &frame="os1")
Definition: os1_ros.cpp:70
uint16_t px_signal_photons(const uint8_t *px_buf)
Definition: os1_packet.h:120
static PointOS1 nth_point(int ind, const uint8_t *col_buf)
Definition: os1_ros.cpp:119


ouster
Author(s): ouster developers
autogenerated on Mon Jun 10 2019 14:16:21