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
use super::{FullPoint, ConversionError, Convertor};
use crate::packet::{RawPacket, PacketMeta, parse_packet};
const HDL_32_TABLE: [f32; 32] = [
-30.67, -9.33, -29.33, -8.00, -28.00, -6.67, -26.67, -5.33,
-25.33, -4.00, -24.00, -2.67, -22.67, -1.33, -21.33, 0.00,
-20.00, 1.33, -18.67, 2.67, -17.33, 4.00, -16.00, 5.33,
-14.67, 6.67, -13.33, 8.00, -12.00, 9.33, -10.67, 10.67,
];
#[derive(Copy, Clone, Debug, Default)]
pub struct Hdl32Convertor;
impl Convertor for Hdl32Convertor {
fn convert<F, P>(&self, raw_packet: &RawPacket, mut f: F)
-> Result<PacketMeta, ConversionError>
where F: FnMut(P), P: From<FullPoint>
{
let (meta, iter) = parse_packet(raw_packet);
let timestamp = meta.timestamp;
let mut cache = [0u16; 32];
let mut prev_azimuth = std::u16::MAX;
for (header, azimuth, block_iter) in iter {
let azim_sin_cos = (azimuth as f32/100.).to_radians().sin_cos();
if &header != b"\xFF\xEE" { Err(ConversionError)? }
for raw_point in block_iter {
let laser_id = raw_point.laser;
let cached = &mut cache[laser_id as usize];
if azimuth == prev_azimuth && *cached == raw_point.distance {
*cached = 0;
continue
}
*cached = raw_point.distance;
let distance = (raw_point.distance as f32)/500.;
let hor_angle = HDL_32_TABLE[laser_id as usize].to_radians();
let xyz = compute_xyz(distance, azim_sin_cos, hor_angle);
let intensity = raw_point.intensity;
let point = FullPoint { xyz, intensity, laser_id, timestamp };
f(point.into());
}
prev_azimuth = azimuth;
}
Ok(meta)
}
}
fn compute_xyz(dist: f32, (a_sin, a_cos): (f32, f32), w: f32) -> [f32; 3] {
let (w_sin, w_cos) = w.sin_cos();
let t = dist*w_cos;
[
t*a_sin,
t*a_cos,
dist*w_sin,
]
}