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
/*
 * File: plane.rs
 * Project: gain
 * Created Date: 30/05/2021
 * Author: Shun Suzuki
 * -----
 * Last Modified: 02/10/2021
 * Modified By: Shun Suzuki (suzuki@hapis.k.u-tokyo.ac.jp)
 * -----
 * Copyright (c) 2021 Hapis Lab. All rights reserved.
 *
 */

use std::f64::consts::PI;

use anyhow::Result;
use autd3_core::{
    gain::Gain,
    geometry::{Geometry, Vector3},
    hardware_defined::{DataArray, NUM_TRANS_IN_UNIT},
};
use autd3_traits::Gain;

/// Gain to create plane wave
#[derive(Gain)]
pub struct Plane {
    data: Vec<DataArray>,
    built: bool,
    duty: u8,
    dir: Vector3,
}

impl Plane {
    /// constructor
    ///
    /// # Arguments
    ///
    /// * `dir` - direction
    ///
    pub fn new(dir: Vector3) -> Self {
        Self::with_duty(dir, 0xFF)
    }

    /// constructor with duty
    ///
    /// # Arguments
    ///
    /// * `dir` - direction
    /// * `duty` - duty ratio
    ///
    pub fn with_duty(dir: Vector3, duty: u8) -> Self {
        Self {
            data: vec![],
            built: false,
            duty,
            dir,
        }
    }

    #[allow(clippy::unnecessary_wraps)]
    fn calc(&mut self, geometry: &Geometry) -> Result<()> {
        let wavenum = 2.0 * PI / geometry.wavelength;
        let duty = self.duty;
        for dev in 0..geometry.num_devices() {
            for i in 0..NUM_TRANS_IN_UNIT {
                let trp = geometry.position_by_local_idx(dev, i);
                let dist = self.dir.dot(&trp);
                let phase = wavenum * dist;
                let phase = autd3_core::utils::to_phase(phase);
                self.data[dev][i] = autd3_core::utils::pack_to_u16(duty, phase);
            }
        }
        self.built = true;
        Ok(())
    }
}