autd3/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![warn(missing_docs)]
3#![warn(rustdoc::missing_crate_level_docs)]
4#![warn(rustdoc::unescaped_backticks)]
5
6//! # AUTD3: Airborne Ultrasound Tactile Display 3
7//!
8//! Airborne Ultrasound Tactile Display (AUTD) is a midair haptic device that can remotely produce tactile sensation on a human skin surface without wearing devices.
9//! Please see [our laboratory homepage](https://hapislab.org/en/airborne-ultrasound-tactile-display) for more details on AUTD.
10//! This crate is a client library to drive AUTD version 3 devices. This cross-platform library supports Windows, macOS, and Linux (including Single Board Computer such as Raspberry Pi).
11
12/// [`Controller`] module.
13pub mod controller;
14/// Primitive [`Gain`], [`Modulation`] and utilities for [`GainSTM`] and [`FociSTM`].
15///
16/// [`Gain`]: autd3_core::gain::Gain
17/// [`Modulation`]: autd3_core::modulation::Modulation
18/// [`GainSTM`]: autd3_driver::datagram::GainSTM
19/// [`FociSTM`]: autd3_driver::datagram::FociSTM
20pub mod datagram;
21#[doc(hidden)]
22pub mod link;
23/// Prelude module.
24pub mod prelude;
25
26pub use autd3_core as core;
27pub use autd3_driver as driver;
28#[cfg(feature = "gain")]
29pub use datagram::gain;
30#[cfg(feature = "modulation")]
31pub use datagram::modulation;
32
33pub use controller::Controller;
34
35#[cfg(test)]
36mod tests {
37    use autd3_core::{devices::AUTD3, geometry::UnitQuaternion};
38    use autd3_driver::geometry::{Geometry, Point3, Vector3};
39
40    #[macro_export]
41    #[doc(hidden)]
42    macro_rules! assert_near_vector3 {
43        ($a:expr, $b:expr) => {
44            let aa = $a;
45            let bb = $b;
46            let x = (aa.x - bb.x).abs() > 1e-3;
47            let y = (aa.y - bb.y).abs() > 1e-3;
48            let z = (aa.z - bb.z).abs() > 1e-3;
49            if x || y || z {
50                panic!(
51                    "assertion failed: `(left ≈ right)`\n  left: `{:?}`,\n right: `{:?}`",
52                    aa, bb
53                );
54            }
55        };
56    }
57
58    #[must_use]
59    pub fn random_vector3(
60        range_x: std::ops::Range<f32>,
61        range_y: std::ops::Range<f32>,
62        range_z: std::ops::Range<f32>,
63    ) -> Vector3 {
64        use rand::Rng;
65        let mut rng = rand::rng();
66        Vector3::new(
67            rng.random_range(range_x),
68            rng.random_range(range_y),
69            rng.random_range(range_z),
70        )
71    }
72
73    #[must_use]
74    pub fn random_point3(
75        range_x: std::ops::Range<f32>,
76        range_y: std::ops::Range<f32>,
77        range_z: std::ops::Range<f32>,
78    ) -> Point3 {
79        use rand::Rng;
80        let mut rng = rand::rng();
81        Point3::new(
82            rng.random_range(range_x),
83            rng.random_range(range_y),
84            rng.random_range(range_z),
85        )
86    }
87
88    #[must_use]
89    pub fn create_geometry(n: usize) -> Geometry {
90        Geometry::new(
91            (0..n)
92                .map(|_| AUTD3::new(Point3::origin(), UnitQuaternion::identity()).into())
93                .collect(),
94        )
95    }
96}