lidar_utils/ouster/
config.rs

1//! Configuration types for Ouster LiDARs.
2
3use super::{
4    consts::{OS_1_BEAM_ALTITUDE_DEGREES, OS_1_BEAM_AZIMUTH_DEGREE_CORRECTIONS, PIXELS_PER_COLUMN},
5    enums::LidarMode,
6};
7use crate::common::*;
8
9// TODO: This workaround handles large array for serde.
10//       We'll remove is it once the const generics is introduced.
11big_array! { BigArray; }
12
13/// A serializable struct that represents a Ouster sensor configuration.
14#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Derivative)]
15#[derivative(Debug)]
16pub struct Config {
17    #[serde(with = "BigArray")]
18    #[derivative(Debug(format_with = "self::large_array_fmt"))]
19    pub beam_altitude_angles: [R64; PIXELS_PER_COLUMN],
20    #[serde(with = "BigArray", rename = "beam_azimuth_angles")]
21    #[derivative(Debug(format_with = "self::large_array_fmt"))]
22    pub beam_azimuth_angle_corrections: [R64; PIXELS_PER_COLUMN],
23    pub lidar_mode: LidarMode,
24}
25
26impl Config {
27    /// Creates new config.
28    pub fn new(
29        beam_altitude_angles: [f64; PIXELS_PER_COLUMN],
30        beam_azimuth_angle_corrections: [f64; PIXELS_PER_COLUMN],
31        lidar_mode: LidarMode,
32    ) -> Config {
33        Config {
34            beam_altitude_angles: unsafe { mem::transmute(beam_altitude_angles) },
35            beam_azimuth_angle_corrections: unsafe {
36                mem::transmute(beam_azimuth_angle_corrections)
37            },
38            lidar_mode,
39        }
40    }
41
42    /// Loads config JSON file from path.
43    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Config> {
44        let file = File::open(path.as_ref())?;
45        let ret = Self::from_reader(file)?;
46        Ok(ret)
47    }
48
49    /// Loads config JSON data from reader with [Read](std::io::Read) trait.
50    pub fn from_reader<R: Read>(reader: R) -> Result<Config> {
51        let ret = serde_json::de::from_reader(reader)?;
52        Ok(ret)
53    }
54
55    /// Parses from JSON string.
56    pub fn from_json_str(data: &str) -> Result<Config> {
57        let ret = serde_json::from_str(data)?;
58        Ok(ret)
59    }
60
61    /// Sets `beam_azimuth_angle_corrections` field.
62    pub fn beam_azimuth_angle_corrections(
63        &mut self,
64        beam_azimuth_angle_corrections: [f64; PIXELS_PER_COLUMN],
65    ) {
66        self.beam_azimuth_angle_corrections =
67            unsafe { mem::transmute(beam_azimuth_angle_corrections) };
68    }
69
70    /// Sets `beam_altitude_angles` field.
71    pub fn beam_altitude_angles(&mut self, beam_altitude_angles: [f64; PIXELS_PER_COLUMN]) {
72        self.beam_altitude_angles = unsafe { mem::transmute(beam_altitude_angles) };
73    }
74
75    /// Sets `lidar_mode` field.
76    pub fn lidar_mode(&mut self, lidar_mode: LidarMode) {
77        self.lidar_mode = lidar_mode;
78    }
79
80    /// Create default configuration for Ouster OS-1.
81    pub fn os_1_config() -> Self {
82        // From firmware 1.12.0
83        let beam_altitude_angles = OS_1_BEAM_ALTITUDE_DEGREES;
84        let beam_azimuth_angle_corrections = OS_1_BEAM_AZIMUTH_DEGREE_CORRECTIONS;
85
86        Self {
87            beam_altitude_angles: unsafe { mem::transmute(beam_altitude_angles) },
88            beam_azimuth_angle_corrections: unsafe {
89                mem::transmute(beam_azimuth_angle_corrections)
90            },
91            lidar_mode: LidarMode::Mode1024x10,
92        }
93    }
94}
95
96pub(crate) fn large_array_fmt<T: Debug>(
97    array: &[T; PIXELS_PER_COLUMN],
98    formatter: &mut Formatter,
99) -> Result<(), fmt::Error> {
100    write!(formatter, "{:?}", &array[..])
101}