lidar_utils/velodyne/frame_converter/
converter.rs

1use super::impls;
2use crate::{
3    common::*,
4    velodyne::{
5        config::{
6            Config, Dynamic_Config, Vlp16_Dual_Config, Vlp16_Dynamic_Config, Vlp16_Last_Config,
7            Vlp16_Strongest_Config, Vlp32_Dual_Config, Vlp32_Dynamic_Config, Vlp32_Last_Config,
8            Vlp32_Strongest_Config,
9        },
10        marker::{
11            DualReturn, DynamicModel, DynamicReturn, LastReturn, ModelMarker, ReturnTypeMarker,
12            StrongestReturn, Vlp16, Vlp32,
13        },
14        packet::DataPacket,
15        pcd_converter::{
16            Dynamic_PcdConverter, PointCloudConverter, Vlp16_Dual_PcdConverter,
17            Vlp16_Dynamic_PcdConverter, Vlp16_Last_PcdConverter, Vlp16_Strongest_PcdConverter,
18            Vlp32_Dual_PcdConverter, Vlp32_Dynamic_PcdConverter, Vlp32_Last_PcdConverter,
19            Vlp32_Strongest_PcdConverter,
20        },
21        point::{DualReturnPoint, DynamicReturnPoints, SingleReturnPoint},
22    },
23};
24
25pub use converter_impls::*;
26pub use definitions::*;
27
28mod definitions {
29    use super::*;
30
31    /// The trait is implemented by all variants of frame converters.
32    pub trait FrameConverter<Model, ReturnType>
33    where
34        Model: ModelMarker,
35        ReturnType: ReturnTypeMarker,
36    {
37        type Frame;
38
39        /// Construct a frame converter from a config type.
40        fn from_config(config: Config<Model, ReturnType>) -> Self;
41
42        /// Converts a packet into a collection of frames of points.
43        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
44        where
45            P: Borrow<DataPacket>;
46
47        fn pop_remaining(&mut self) -> Option<Self::Frame>;
48    }
49
50    #[derive(Debug)]
51    pub(crate) struct RemainingPoints(pub(crate) DynamicReturnPoints);
52
53    impl RemainingPoints {
54        pub fn new(return_type: DynamicReturn) -> Self {
55            Self(match return_type {
56                DynamicReturn::LastReturn | DynamicReturn::StrongestReturn => {
57                    DynamicReturnPoints::Single(vec![])
58                }
59                DynamicReturn::DualReturn => DynamicReturnPoints::Dual(vec![]),
60            })
61        }
62
63        pub fn take(&mut self) -> DynamicReturnPoints {
64            let empty = self.0.empty_like();
65            mem::replace(&mut self.0, empty)
66        }
67    }
68
69    #[derive(Debug)]
70    #[allow(non_camel_case_types)]
71    pub struct Dynamic_FrameConverter {
72        pub(crate) pcd_converter: Dynamic_PcdConverter,
73        pub(crate) remaining_points: RemainingPoints,
74    }
75
76    #[derive(Debug)]
77    #[allow(non_camel_case_types)]
78    pub struct Vlp16_Last_FrameConverter {
79        pub(crate) pcd_converter: Vlp16_Last_PcdConverter,
80        pub(crate) remaining_points: Vec<SingleReturnPoint>,
81    }
82
83    #[derive(Debug)]
84    #[allow(non_camel_case_types)]
85    pub struct Vlp16_Strongest_FrameConverter {
86        pub(crate) pcd_converter: Vlp16_Strongest_PcdConverter,
87        pub(crate) remaining_points: Vec<SingleReturnPoint>,
88    }
89
90    #[derive(Debug)]
91    #[allow(non_camel_case_types)]
92    pub struct Vlp16_Dual_FrameConverter {
93        pub(crate) pcd_converter: Vlp16_Dual_PcdConverter,
94        pub(crate) remaining_points: Vec<DualReturnPoint>,
95    }
96
97    #[derive(Debug)]
98    #[allow(non_camel_case_types)]
99    pub struct Vlp16_Dynamic_FrameConverter {
100        pub(crate) pcd_converter: Vlp16_Dynamic_PcdConverter,
101        pub(crate) remaining_points: RemainingPoints,
102    }
103
104    #[derive(Debug)]
105    #[allow(non_camel_case_types)]
106    pub struct Vlp32_Last_FrameConverter {
107        pub(crate) pcd_converter: Vlp32_Last_PcdConverter,
108        pub(crate) remaining_points: Vec<SingleReturnPoint>,
109    }
110
111    #[derive(Debug)]
112    #[allow(non_camel_case_types)]
113    pub struct Vlp32_Strongest_FrameConverter {
114        pub(crate) pcd_converter: Vlp32_Strongest_PcdConverter,
115        pub(crate) remaining_points: Vec<SingleReturnPoint>,
116    }
117
118    #[derive(Debug)]
119    #[allow(non_camel_case_types)]
120    pub struct Vlp32_Dual_FrameConverter {
121        pub(crate) pcd_converter: Vlp32_Dual_PcdConverter,
122        pub(crate) remaining_points: Vec<DualReturnPoint>,
123    }
124
125    #[derive(Debug)]
126    #[allow(non_camel_case_types)]
127    pub struct Vlp32_Dynamic_FrameConverter {
128        pub(crate) pcd_converter: Vlp32_Dynamic_PcdConverter,
129        pub(crate) remaining_points: RemainingPoints,
130    }
131}
132
133mod converter_impls {
134    use super::*;
135
136    impl FrameConverter<DynamicModel, DynamicReturn> for Dynamic_FrameConverter {
137        type Frame = DynamicReturnPoints;
138
139        fn from_config(config: Dynamic_Config) -> Self {
140            let remaining_points = RemainingPoints::new(config.return_type);
141            Self {
142                pcd_converter: Dynamic_PcdConverter::from_config(config),
143                remaining_points,
144            }
145        }
146
147        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
148        where
149            P: Borrow<DataPacket>,
150        {
151            let Self {
152                pcd_converter,
153                remaining_points,
154            } = self;
155
156            impls::convert_dynamic_return(pcd_converter, remaining_points, packet.borrow())
157        }
158
159        fn pop_remaining(&mut self) -> Option<Self::Frame> {
160            let remaining = self.remaining_points.take();
161            if remaining.is_empty() {
162                None
163            } else {
164                Some(remaining)
165            }
166        }
167    }
168
169    impl FrameConverter<Vlp16, LastReturn> for Vlp16_Last_FrameConverter {
170        type Frame = Vec<SingleReturnPoint>;
171
172        fn from_config(config: Vlp16_Last_Config) -> Self {
173            Self {
174                pcd_converter: Vlp16_Last_PcdConverter::from_config(config),
175                remaining_points: vec![],
176            }
177        }
178
179        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
180        where
181            P: Borrow<DataPacket>,
182        {
183            let Self {
184                pcd_converter,
185                remaining_points,
186            } = self;
187
188            impls::convert_single_return(pcd_converter, remaining_points, packet.borrow())
189        }
190
191        fn pop_remaining(&mut self) -> Option<Self::Frame> {
192            if self.remaining_points.is_empty() {
193                None
194            } else {
195                Some(mem::take(&mut self.remaining_points))
196            }
197        }
198    }
199
200    impl FrameConverter<Vlp16, StrongestReturn> for Vlp16_Strongest_FrameConverter {
201        type Frame = Vec<SingleReturnPoint>;
202
203        fn from_config(config: Vlp16_Strongest_Config) -> Self {
204            Self {
205                pcd_converter: Vlp16_Strongest_PcdConverter::from_config(config),
206                remaining_points: vec![],
207            }
208        }
209
210        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
211        where
212            P: Borrow<DataPacket>,
213        {
214            let Self {
215                pcd_converter,
216                remaining_points,
217            } = self;
218
219            impls::convert_single_return(pcd_converter, remaining_points, packet.borrow())
220        }
221
222        fn pop_remaining(&mut self) -> Option<Self::Frame> {
223            if self.remaining_points.is_empty() {
224                None
225            } else {
226                Some(mem::take(&mut self.remaining_points))
227            }
228        }
229    }
230
231    impl FrameConverter<Vlp16, DualReturn> for Vlp16_Dual_FrameConverter {
232        type Frame = Vec<DualReturnPoint>;
233
234        fn from_config(config: Vlp16_Dual_Config) -> Self {
235            Self {
236                pcd_converter: Vlp16_Dual_PcdConverter::from_config(config),
237                remaining_points: vec![],
238            }
239        }
240
241        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
242        where
243            P: Borrow<DataPacket>,
244        {
245            let Self {
246                pcd_converter,
247                remaining_points,
248            } = self;
249
250            impls::convert_dual_return(pcd_converter, remaining_points, packet.borrow())
251        }
252
253        fn pop_remaining(&mut self) -> Option<Self::Frame> {
254            if self.remaining_points.is_empty() {
255                None
256            } else {
257                Some(mem::take(&mut self.remaining_points))
258            }
259        }
260    }
261
262    impl FrameConverter<Vlp16, DynamicReturn> for Vlp16_Dynamic_FrameConverter {
263        type Frame = DynamicReturnPoints;
264
265        fn from_config(config: Vlp16_Dynamic_Config) -> Self {
266            let remaining_points = RemainingPoints::new(config.return_type);
267            Self {
268                pcd_converter: Vlp16_Dynamic_PcdConverter::from_config(config),
269                remaining_points,
270            }
271        }
272
273        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
274        where
275            P: Borrow<DataPacket>,
276        {
277            let Self {
278                pcd_converter,
279                remaining_points,
280            } = self;
281
282            impls::convert_dynamic_return(pcd_converter, remaining_points, packet.borrow())
283        }
284
285        fn pop_remaining(&mut self) -> Option<Self::Frame> {
286            let remaining = self.remaining_points.take();
287            if remaining.is_empty() {
288                None
289            } else {
290                Some(remaining)
291            }
292        }
293    }
294
295    impl FrameConverter<Vlp32, LastReturn> for Vlp32_Last_FrameConverter {
296        type Frame = Vec<SingleReturnPoint>;
297
298        fn from_config(config: Vlp32_Last_Config) -> Self {
299            Self {
300                pcd_converter: Vlp32_Last_PcdConverter::from_config(config),
301                remaining_points: vec![],
302            }
303        }
304
305        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
306        where
307            P: Borrow<DataPacket>,
308        {
309            let Self {
310                pcd_converter,
311                remaining_points,
312            } = self;
313
314            impls::convert_single_return(pcd_converter, remaining_points, packet.borrow())
315        }
316
317        fn pop_remaining(&mut self) -> Option<Self::Frame> {
318            if self.remaining_points.is_empty() {
319                None
320            } else {
321                Some(mem::take(&mut self.remaining_points))
322            }
323        }
324    }
325
326    impl FrameConverter<Vlp32, StrongestReturn> for Vlp32_Strongest_FrameConverter {
327        type Frame = Vec<SingleReturnPoint>;
328
329        fn from_config(config: Vlp32_Strongest_Config) -> Self {
330            Self {
331                pcd_converter: Vlp32_Strongest_PcdConverter::from_config(config),
332                remaining_points: vec![],
333            }
334        }
335
336        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
337        where
338            P: Borrow<DataPacket>,
339        {
340            let Self {
341                pcd_converter,
342                remaining_points,
343            } = self;
344
345            impls::convert_single_return(pcd_converter, remaining_points, packet.borrow())
346        }
347
348        fn pop_remaining(&mut self) -> Option<Self::Frame> {
349            if self.remaining_points.is_empty() {
350                None
351            } else {
352                Some(mem::take(&mut self.remaining_points))
353            }
354        }
355    }
356
357    impl FrameConverter<Vlp32, DualReturn> for Vlp32_Dual_FrameConverter {
358        type Frame = Vec<DualReturnPoint>;
359
360        fn from_config(config: Vlp32_Dual_Config) -> Self {
361            Self {
362                pcd_converter: Vlp32_Dual_PcdConverter::from_config(config),
363                remaining_points: vec![],
364            }
365        }
366
367        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
368        where
369            P: Borrow<DataPacket>,
370        {
371            let Self {
372                pcd_converter,
373                remaining_points,
374            } = self;
375
376            impls::convert_dual_return(pcd_converter, remaining_points, packet.borrow())
377        }
378
379        fn pop_remaining(&mut self) -> Option<Self::Frame> {
380            if self.remaining_points.is_empty() {
381                None
382            } else {
383                Some(mem::take(&mut self.remaining_points))
384            }
385        }
386    }
387
388    impl FrameConverter<Vlp32, DynamicReturn> for Vlp32_Dynamic_FrameConverter {
389        type Frame = DynamicReturnPoints;
390
391        fn from_config(config: Vlp32_Dynamic_Config) -> Self {
392            let remaining_points = RemainingPoints::new(config.return_type);
393            Self {
394                pcd_converter: Vlp32_Dynamic_PcdConverter::from_config(config),
395                remaining_points,
396            }
397        }
398
399        fn convert<P>(&mut self, packet: P) -> Result<Vec<Self::Frame>>
400        where
401            P: Borrow<DataPacket>,
402        {
403            let Self {
404                pcd_converter,
405                remaining_points,
406            } = self;
407
408            impls::convert_dynamic_return(pcd_converter, remaining_points, packet.borrow())
409        }
410
411        fn pop_remaining(&mut self) -> Option<Self::Frame> {
412            let remaining = self.remaining_points.take();
413            if remaining.is_empty() {
414                None
415            } else {
416                Some(remaining)
417            }
418        }
419    }
420}