forked from ouster-lidar/ouster-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
os1_ros.cpp
156 lines (128 loc) · 4.61 KB
/
os1_ros.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <pcl_conversions/pcl_conversions.h>
#include "ouster/os1.h"
#include "ouster/os1_packet.h"
#include "ouster_ros/os1_ros.h"
namespace ouster_ros {
namespace OS1 {
using namespace ouster::OS1;
ns timestamp_of_imu_packet(const PacketMsg& pm) {
return ns(imu_gyro_ts(pm.buf.data()));
}
ns timestamp_of_lidar_packet(const PacketMsg& pm) {
return ns(col_timestamp(nth_col(0, pm.buf.data())));
}
bool read_imu_packet(const client& cli, PacketMsg& m) {
m.buf.resize(imu_packet_bytes + 1);
return read_imu_packet(cli, m.buf.data());
}
bool read_lidar_packet(const client& cli, PacketMsg& m) {
m.buf.resize(lidar_packet_bytes + 1);
return read_lidar_packet(cli, m.buf.data());
}
sensor_msgs::Imu packet_to_imu_msg(const PacketMsg& p) {
sensor_msgs::Imu m;
const uint8_t* buf = p.buf.data();
m.header.stamp.fromNSec(imu_gyro_ts(buf));
m.header.frame_id = "os1_imu";
m.orientation.x = 0;
m.orientation.y = 0;
m.orientation.z = 0;
m.orientation.w = 0;
m.linear_acceleration.x = imu_la_x(buf);
m.linear_acceleration.y = imu_la_y(buf);
m.linear_acceleration.z = imu_la_z(buf);
m.angular_velocity.x = imu_av_x(buf) * M_PI / 180.0;
m.angular_velocity.y = imu_av_y(buf) * M_PI / 180.0;
m.angular_velocity.z = imu_av_z(buf) * M_PI / 180.0;
for (int i = 0; i < 9; i++) {
m.orientation_covariance[i] = -1;
m.angular_velocity_covariance[i] = 0;
m.linear_acceleration_covariance[i] = 0;
}
for (int i = 0; i < 9; i += 4) {
m.linear_acceleration_covariance[i] = 0.01;
m.angular_velocity_covariance[i] = 6e-4;
}
return m;
}
sensor_msgs::PointCloud2 cloud_to_cloud_msg(const CloudOS1& cloud, ns timestamp,
const std::string& frame) {
sensor_msgs::PointCloud2 msg;
pcl::toROSMsg(cloud, msg);
msg.header.frame_id = frame;
msg.header.stamp.fromNSec(timestamp.count());
return msg;
}
static PointOS1 nth_point(int ind, const uint8_t* col_buf) {
float h_angle_0 = col_h_angle(col_buf);
auto tte = trig_table[ind];
const uint8_t* px_buf = nth_px(ind, col_buf);
float r = px_range(px_buf) / 1000.0;
float h_angle = tte.h_offs + h_angle_0;
PointOS1 point;
point.reflectivity = px_reflectivity(px_buf);
point.intensity = px_signal_photons(px_buf);
point.x = -r * tte.cos_v_angle * cosf(h_angle);
point.y = r * tte.cos_v_angle * sinf(h_angle);
point.z = r * tte.sin_v_angle;
point.ring = ind;
return point;
}
void add_packet_to_cloud(ns scan_start_ts, ns scan_duration,
const PacketMsg& pm, CloudOS1& cloud) {
const uint8_t* buf = pm.buf.data();
for (int icol = 0; icol < columns_per_buffer; icol++) {
const uint8_t* col_buf = nth_col(icol, buf);
float ts = (col_timestamp(col_buf) - scan_start_ts.count()) /
(float)scan_duration.count();
for (int ipx = 0; ipx < pixels_per_column; ipx++) {
auto p = nth_point(ipx, col_buf);
p.t = ts;
cloud.push_back(p);
}
}
}
void spin(const client& cli,
const std::function<void(const PacketMsg& pm)>& lidar_handler,
const std::function<void(const PacketMsg& pm)>& imu_handler) {
PacketMsg lidar_packet, imu_packet;
lidar_packet.buf.resize(lidar_packet_bytes + 1);
imu_packet.buf.resize(imu_packet_bytes + 1);
while (ros::ok()) {
auto state = poll_client(cli);
if (state & ERROR) {
ROS_ERROR("spin: poll_client returned error");
return;
}
if (state & LIDAR_DATA) {
if (read_lidar_packet(cli, lidar_packet.buf.data()))
lidar_handler(lidar_packet);
}
if (state & IMU_DATA) {
if (read_imu_packet(cli, imu_packet.buf.data()))
imu_handler(imu_packet);
}
ros::spinOnce();
}
}
static ns nearest_scan_dur(ns scan_dur, ns ts) {
return ns((ts.count() / scan_dur.count()) * scan_dur.count());
};
std::function<void(const PacketMsg&)> batch_packets(
ns scan_dur, const std::function<void(ns, const CloudOS1&)>& f) {
auto cloud = std::make_shared<OS1::CloudOS1>();
auto scan_ts = ns(-1L);
return [=](const PacketMsg& pm) mutable {
ns packet_ts = OS1::timestamp_of_lidar_packet(pm);
if (scan_ts.count() == -1L)
scan_ts = nearest_scan_dur(scan_dur, packet_ts);
OS1::add_packet_to_cloud(scan_ts, scan_dur, pm, *cloud);
if (packet_ts - scan_ts >= scan_dur) {
f(scan_ts, *cloud);
cloud->clear();
scan_ts = ns(-1L);
}
};
}
}
}