エミュレータ

Emulatorを使用すると, Simulatorよりも詳細な出力位相/パルス幅, 出力電圧, 出力音波, および, 音場の計算が行える.

NOTE: 現在, EmulatorはRust, 及び, Pythonからのみ使用可能である. C++, C#へ移植する予定はない.

Install

cargo add autd3-emulator
pip install pyautd3_emulator

APIs

Emulatorが出力するデータはPolarsのDataFrameである. 詳しくは, Polarsのドキュメントを参照されたい.

振動子テーブル

振動子の一覧を表示する.

各列には, デバイスインデックス, 振動子の(ローカル)インデックス, 位置, 極方向が格納される.

use autd3::prelude::*;
use autd3_emulator::*;

fn main() {
let emulator = Emulator::new([AUTD3::default()]);
let df = emulator.transducer_table();
dbg!(df);
}
from pyautd3 import AUTD3
from pyautd3_emulator import Emulator

with Emulator([AUTD3()]) as emulator:
    df = emulator.transducer_table()
    print(df)
┌─────────┬────────┬────────────┬────────────┬───────┬─────┬─────┬─────┐
│ dev_idx ┆ tr_idx ┆ x[mm]      ┆ y[mm]      ┆ z[mm] ┆ nx  ┆ ny  ┆ nz  │
│ ---     ┆ ---    ┆ ---        ┆ ---        ┆ ---   ┆ --- ┆ --- ┆ --- │
│ u16     ┆ u8     ┆ f32        ┆ f32        ┆ f32   ┆ f32 ┆ f32 ┆ f32 │
╞═════════╪════════╪════════════╪════════════╪═══════╪═════╪═════╪═════╡
│ 0       ┆ 0      ┆ 0.0        ┆ 0.0        ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 1      ┆ 10.16      ┆ 0.0        ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 2      ┆ 20.32      ┆ 0.0        ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 3      ┆ 30.48      ┆ 0.0        ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 4      ┆ 40.639999  ┆ 0.0        ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ …       ┆ …      ┆ …          ┆ …          ┆ …     ┆ …   ┆ …   ┆ …   │
│ 0       ┆ 244    ┆ 132.080002 ┆ 132.080002 ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 245    ┆ 142.23999  ┆ 132.080002 ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 246    ┆ 152.399994 ┆ 132.080002 ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 247    ┆ 162.559998 ┆ 132.080002 ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
│ 0       ┆ 248    ┆ 172.720001 ┆ 132.080002 ┆ 0.0   ┆ 0.0 ┆ 0.0 ┆ 1.0 │
└─────────┴────────┴────────────┴────────────┴───────┴─────┴─────┴─────┘

出力位相/パルス幅の計算

use autd3::prelude::*;
use autd3_emulator::*;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let emulator = Emulator::new([AUTD3::default()]);

let record = emulator.record(|autd| {
    autd.send(Silencer::default())?;
    autd.send((
        Sine {
            freq: 200 * Hz,
            option: Default::default(),
        },
        Uniform {
            intensity: EmitIntensity::MAX,
            phase: Phase::ZERO,
        },
    ))?;
    autd.tick(Duration::from_millis(10))?;
    Ok(())
})?;
let df = record.phase();
dbg!(df);

let df = record.pulse_width();
dbg!(df);
Ok(())
}
from pyautd3 import (
    AUTD3,
    Duration,
    EmitIntensity,
    Hz,
    Phase,
    Silencer,
    Sine,
    SineOption,
    Uniform,
)
from pyautd3_emulator import Emulator, Recorder

with Emulator([AUTD3()]) as emulator:

    def f(autd: Recorder) -> None:
        autd.send(Silencer())
        autd.send(
            (
                Sine(freq=200.0 * Hz, option=SineOption()),
                Uniform(intensity=EmitIntensity.MAX, phase=Phase.ZERO),
            ),
        )
        autd.tick(Duration.from_millis(10))

    record = emulator.record(f)

    df = record.phase()
    print(df)

    df = record.pulse_width()
    print(df)

NOTE: tickで指定する時間間隔は, の倍数である必要がある.

各時刻 (単位) における, 位相/パルス幅が各列に格納される. 各列の名前は<phase/pulse_width>@<時刻>[ns]である.

各行は振動子テーブルの行と対応している.

┌─────────────┬────────────────┬────────────────┬────────────────┬───┬────────────────┬───────────────┬───────────────┬───────────────┐
│ phase@0[ns] ┆ phase@25000[ns ┆ phase@50000[ns ┆ phase@75000[ns ┆ … ┆ phase@9900000[ ┆ phase@9925000 ┆ phase@9950000 ┆ phase@9975000 │
│ ---         ┆ ]              ┆ ]              ┆ ]              ┆   ┆ ns]            ┆ [ns]          ┆ [ns]          ┆ [ns]          │
│ u8          ┆ ---            ┆ ---            ┆ ---            ┆   ┆ ---            ┆ ---           ┆ ---           ┆ ---           │
│             ┆ u8             ┆ u8             ┆ u8             ┆   ┆ u8             ┆ u8            ┆ u8            ┆ u8            │
╞═════════════╪════════════════╪════════════════╪════════════════╪═══╪════════════════╪═══════════════╪═══════════════╪═══════════════╡
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ …           ┆ …              ┆ …              ┆ …              ┆ … ┆ …              ┆ …             ┆ …             ┆ …             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
│ 0           ┆ 0              ┆ 0              ┆ 0              ┆ … ┆ 0              ┆ 0             ┆ 0             ┆ 0             │
└─────────────┴────────────────┴────────────────┴────────────────┴───┴────────────────┴───────────────┴───────────────┴───────────────┘
┌───────────────────┬───────────────────────┬───────────────────────┬───────────────────────┬───┬─────────────────────────┬─────────────────────────┬────────────────────────┬────────────────────────┐
│ pulse_width@0[ns] ┆ pulse_width@25000[ns] ┆ pulse_width@50000[ns] ┆ pulse_width@75000[ns] ┆ … ┆ pulse_width@9900000[ns] ┆ pulse_width@9925000[ns] ┆ pulse_width@9950000[ns ┆ pulse_width@9975000[ns │
│ ---               ┆ ---                   ┆ ---                   ┆ ---                   ┆   ┆ ---                     ┆ ---                     ┆ ]                      ┆ ]                      │
│ u16               ┆ u16                   ┆ u16                   ┆ u16                   ┆   ┆ u16                     ┆ u16                     ┆ ---                    ┆ ---                    │
│                   ┆                       ┆                       ┆                       ┆   ┆                         ┆                         ┆ u16                    ┆ u16                    │
╞═══════════════════╪═══════════════════════╪═══════════════════════╪═══════════════════════╪═══╪═════════════════════════╪═════════════════════════╪════════════════════════╪════════════════════════╡
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ …                 ┆ …                     ┆ …                     ┆ …                     ┆ … ┆ …                       ┆ …                       ┆ …                      ┆ …                      │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
│ 8                 ┆ 16                    ┆ 24                    ┆ 33                    ┆ … ┆ 50                      ┆ 53                      ┆ 55                     ┆ 57                     │
└───────────────────┴───────────────────────┴───────────────────────┴───────────────────────┴───┴─────────────────────────┴─────────────────────────┴────────────────────────┴────────────────────────┘

出力電圧

use autd3::prelude::*;
use autd3_emulator::*;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let emulator = Emulator::new([AUTD3::default()]);

let record = emulator.record(|autd| {
    autd.send(Silencer::disable())?;
    autd.send((
        Static { intensity: 0xFF },
        Uniform {
            intensity: EmitIntensity::MAX,
            phase: Phase(0x40),
        },
    ))?;
    autd.tick(Duration::from_millis(1))?;
    Ok(())
})?;

let df = record.output_voltage();
dbg!(df);
    Ok(())
}
from pyautd3 import AUTD3, Duration, EmitIntensity, Phase, Silencer, Static, Uniform
from pyautd3_emulator import Emulator, Recorder

with Emulator([AUTD3()]) as emulator:

    def f(autd: Recorder) -> None:
        autd.send(Silencer.disable())
        autd.send((Static(), Uniform(phase=Phase(0x40), intensity=EmitIntensity.MAX)))
        autd.tick(Duration.from_millis(1))

    record = emulator.record(f)

    df = record.output_voltage()
    print(df)

各時刻 (単位) における, 出力電圧が各列に格納される. 各列の名前はvoltage[V]@<時刻>[25us/512]である.

各行は振動子テーブルの行と対応している.

┌────────────────────────┬────────────────────────┬────────────────────────┬────────────────────────┬───┬────────────────────────────┬────────────────────────────┬────────────────────────────┬────────────────────────────┐
│ voltage[V]@0[25us/512] ┆ voltage[V]@1[25us/512] ┆ voltage[V]@2[25us/512] ┆ voltage[V]@3[25us/512] ┆ … ┆ voltage[V]@20476[25us/512] ┆ voltage[V]@20477[25us/512] ┆ voltage[V]@20478[25us/512] ┆ voltage[V]@20479[25us/512] │
│ ---                    ┆ ---                    ┆ ---                    ┆ ---                    ┆   ┆ ---                        ┆ ---                        ┆ ---                        ┆ ---                        │
│ f32                    ┆ f32                    ┆ f32                    ┆ f32                    ┆   ┆ f32                        ┆ f32                        ┆ f32                        ┆ f32                        │
╞════════════════════════╪════════════════════════╪════════════════════════╪════════════════════════╪═══╪════════════════════════════╪════════════════════════════╪════════════════════════════╪════════════════════════════╡
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ …                      ┆ …                      ┆ …                      ┆ …                      ┆ … ┆ …                          ┆ …                          ┆ …                          ┆ …                          │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
│ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ 12.0                   ┆ … ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      ┆ -12.0                      │
└────────────────────────┴────────────────────────┴────────────────────────┴────────────────────────┴───┴────────────────────────────┴────────────────────────────┴────────────────────────────┴────────────────────────────┘

出力音圧

use autd3::prelude::*;
use autd3_emulator::*;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let emulator = Emulator::new([AUTD3::default()]);

let record = emulator.record(|autd| {
    autd.send(Silencer::disable())?;
    autd.send((
        Static { intensity: 0xFF },
        Uniform {
            intensity: EmitIntensity::MAX,
            phase: Phase(0x40),
        },
    ))?;
    autd.tick(Duration::from_millis(1))?;
    Ok(())
})?;

let df = record.output_ultrasound();
dbg!(df);
    Ok(())
}
from pyautd3 import AUTD3, Duration, EmitIntensity, Phase, Silencer, Static, Uniform
from pyautd3_emulator import Emulator, Recorder

with Emulator([AUTD3()]) as emulator:

    def f(autd: Recorder) -> None:
        autd.send(Silencer.disable())
        autd.send((Static(), Uniform(phase=Phase(0x40), intensity=EmitIntensity.MAX)))
        autd.tick(Duration.from_millis(1))

    record = emulator.record(f)

    df = record.output_ultrasound()
    print(df)

各時刻 (単位) における, 規格化された出力音圧が各列に格納される. 各列の名前はp[a.u.]@<時刻>[25us/512]である.

各行は振動子テーブルの行と対応している.

┌─────────────────────┬─────────────────────┬─────────────────────┬─────────────────────┬───┬─────────────────────────┬─────────────────────────┬─────────────────────────┬─────────────────────────┐
│ p[a.u.]@0[25us/512] ┆ p[a.u.]@1[25us/512] ┆ p[a.u.]@2[25us/512] ┆ p[a.u.]@3[25us/512] ┆ … ┆ p[a.u.]@20476[25us/512] ┆ p[a.u.]@20477[25us/512] ┆ p[a.u.]@20478[25us/512] ┆ p[a.u.]@20479[25us/512] │
│ ---                 ┆ ---                 ┆ ---                 ┆ ---                 ┆   ┆ ---                     ┆ ---                     ┆ ---                     ┆ ---                     │
│ f32                 ┆ f32                 ┆ f32                 ┆ f32                 ┆   ┆ f32                     ┆ f32                     ┆ f32                     ┆ f32                     │
╞═════════════════════╪═════════════════════╪═════════════════════╪═════════════════════╪═══╪═════════════════════════╪═════════════════════════╪═════════════════════════╪═════════════════════════╡
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ …                   ┆ …                   ┆ …                   ┆ …                   ┆ … ┆ …                       ┆ …                       ┆ …                       ┆ …                       │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
│ 0.0                 ┆ -0.000272           ┆ -0.000481           ┆ -0.000618           ┆ … ┆ -0.36185                ┆ -0.350698               ┆ -0.339501               ┆ -0.328258               │
└─────────────────────┴─────────────────────┴─────────────────────┴─────────────────────┴───┴─────────────────────────┴─────────────────────────┴─────────────────────────┴─────────────────────────┘

音場の計算 (瞬時値)

use autd3::prelude::*;
use autd3_emulator::*;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let emulator = Emulator::new([AUTD3::default()]);

let focus = emulator.center() + Vector3::new(0., 0., 150. * mm);

let record = emulator.record(|autd| {
    autd.send(Silencer::disable())?;
    autd.send((
        Static { intensity: 0xFF },
        Focus {
            pos: focus,
            option: Default::default(),
        },
    ))?;
    autd.tick(Duration::from_millis(1))?;
    Ok(())
})?;

let mut sound_field = record.sound_field(
    RangeXY {
        x: focus.x - 20.0..=focus.x + 20.0,
        y: focus.y - 20.0..=focus.y + 20.0,
        z: focus.z,
        resolution: 1.,
    },
    InstantRecordOption {
        sound_speed: 340e3 * mm,
        time_step: Duration::from_micros(1),
        print_progress: true,
        memory_limits_hint_mb: 128,
        gpu: true,
    },
)?;

let df = sound_field.observe_points();
dbg!(df);

let df = sound_field
    .skip(Duration::from_micros(500))?
    .next(Duration::from_micros(500))?;
dbg!(df);
    Ok(())
}

NOTE: gpuオプションは, gpu featureを有効にしている場合のみ使用可能である.

import numpy as np
from pyautd3 import AUTD3, Focus, FocusOption, Silencer, Static, Duration
from pyautd3_emulator import Emulator, RangeXYZ, Recorder, InstantRecordOption

with Emulator([AUTD3()]) as emulator:
    focus = emulator.center() + np.array([0.0, 0.0, 150.0])

    def f(autd: Recorder) -> None:
        autd.send(Silencer.disable())
        autd.send((Static(), Focus(pos=focus, option=FocusOption())))
        autd.tick(Duration.from_millis(1))

    record = emulator.record(f)

    sound_field = record.sound_field(
        RangeXYZ(
            x=(focus[0] - 20.0, focus[0] + 20.0),
            y=(focus[1] - 20.0, focus[1] + 20.0),
            z=(focus[2], focus[2]),
            resolution=1.0,
        ),
        InstantRecordOption(
            sound_speed=340e3,
            time_step=Duration.from_micros(1),
            print_progress=True,
            memory_limits_hint_mb=128,
            gpu=True,
        ),
    )

    df = sound_field.observe_points()
    print(df)

    df = sound_field.skip(Duration.from_micros(500)).next(
        Duration.from_micros(500),
    )
    print(df)

NOTE: 計測点を指定する方法として, Rust版は, RangeXYZ以外に, 列挙順の異なるRangeZXY等や, 2次元専用のRangeXY等, 1次元専用のRangeX等が使用できる. あるいは, 任意の点を指定するために, Vec<Vector3>が使用できる. Python版は, RangeXYZのみが使用できる.

print_progressオプションを有効にすると計算の進捗が表示される. また, gpuオプションを有効にすると, 計算がGPU上で実行される.

膨大なメモリが消費される可能性があるため, next関数によって, 一部時刻のみを取得するようになっている. なお, skip関数を使用することで, 指定した時間だけスキップすることができる.

各観測点における, 出力音圧が時系列順 (単位はtime_stepで指定) に各列に格納される. 各列の名前は, p[Pa]@<時刻>[ns]である. 各行は, observe_pointsで取得できる観測点と対応している.

┌────────────┬───────────┬───────┐
│ x[mm]      ┆ y[mm]     ┆ z[mm] │
│ ---        ┆ ---       ┆ ---   │
│ f32        ┆ f32       ┆ f32   │
╞════════════╪═══════════╪═══════╡
│ 66.625267  ┆ 46.713196 ┆ 150.0 │
│ 67.625267  ┆ 46.713196 ┆ 150.0 │
│ 68.625267  ┆ 46.713196 ┆ 150.0 │
│ 69.625267  ┆ 46.713196 ┆ 150.0 │
│ 70.625267  ┆ 46.713196 ┆ 150.0 │
│ …          ┆ …         ┆ …     │
│ 102.625267 ┆ 86.713196 ┆ 150.0 │
│ 103.625267 ┆ 86.713196 ┆ 150.0 │
│ 104.625267 ┆ 86.713196 ┆ 150.0 │
│ 105.625267 ┆ 86.713196 ┆ 150.0 │
│ 106.625267 ┆ 86.713196 ┆ 150.0 │
└────────────┴───────────┴───────┘
┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───┬──────────────────┬──────────────────┬──────────────────┬──────────────────┐
│ p[Pa]@500000[ns] ┆ p[Pa]@501000[ns] ┆ p[Pa]@502000[ns] ┆ p[Pa]@503000[ns] ┆ … ┆ p[Pa]@996000[ns] ┆ p[Pa]@997000[ns] ┆ p[Pa]@998000[ns] ┆ p[Pa]@999000[ns] │
│ ---              ┆ ---              ┆ ---              ┆ ---              ┆   ┆ ---              ┆ ---              ┆ ---              ┆ ---              │
│ f32              ┆ f32              ┆ f32              ┆ f32              ┆   ┆ f32              ┆ f32              ┆ f32              ┆ f32              │
╞══════════════════╪══════════════════╪══════════════════╪══════════════════╪═══╪══════════════════╪══════════════════╪══════════════════╪══════════════════╡
│ 22.249609        ┆ 14.994699        ┆ 11.20509         ┆ 3.416157         ┆ … ┆ 167.468948       ┆ 143.434677       ┆ 115.029839       ┆ 78.702179        │
│ 22.973528        ┆ 17.704706        ┆ 14.598668        ┆ 6.462077         ┆ … ┆ 128.688828       ┆ 102.245392       ┆ 73.068733        ┆ 39.29715         │
│ 23.043713        ┆ 20.534163        ┆ 15.762163        ┆ 9.015405         ┆ … ┆ 72.13736         ┆ 50.06559         ┆ 25.516897        ┆ -1.414132        │
│ 21.61729         ┆ 19.986338        ┆ 16.669203        ┆ 11.957072        ┆ … ┆ 6.599095         ┆ -8.152014        ┆ -22.183277       ┆ -34.678905       │
│ 17.479811        ┆ 18.30769         ┆ 16.697689        ┆ 12.929367        ┆ … ┆ -61.525105       ┆ -64.023788       ┆ -62.711498       ┆ -56.925694       │
│ …                ┆ …                ┆ …                ┆ …                ┆ … ┆ …                ┆ …                ┆ …                ┆ …                │
│ 14.888723        ┆ 14.758762        ┆ 13.289121        ┆ 9.737269         ┆ … ┆ -73.181961       ┆ -85.114655       ┆ -92.114983       ┆ -93.623962       │
│ 17.559294        ┆ 15.889968        ┆ 12.346513        ┆ 7.979947         ┆ … ┆ -28.419638       ┆ -61.184322       ┆ -90.326851       ┆ -113.895905      │
│ 18.171673        ┆ 15.26449         ┆ 10.946121        ┆ 5.410897         ┆ … ┆ 19.804182        ┆ -28.594215       ┆ -73.595749       ┆ -115.230705      │
│ 18.815191        ┆ 12.321008        ┆ 7.800498         ┆ 3.680776         ┆ … ┆ 65.869225        ┆ 9.351333         ┆ -48.561874       ┆ -98.87677        │
│ 16.717573        ┆ 10.482997        ┆ 4.044011         ┆ 0.89806          ┆ … ┆ 102.099556       ┆ 44.310383        ┆ -16.616224       ┆ -70.65287        │
└──────────────────┴──────────────────┴──────────────────┴──────────────────┴───┴──────────────────┴──────────────────┴──────────────────┴──────────────────┘

音場の計算 (RMS)

use autd3::prelude::*;
use autd3_emulator::*;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let emulator = Emulator::new([AUTD3::default()]);

let focus = emulator.center() + Vector3::new(0., 0., 150. * mm);

let record = emulator.record(|autd| {
    autd.send(Silencer::disable())?;
    autd.send((
        Static { intensity: 0xFF },
        Focus {
            pos: focus,
            option: Default::default(),
        },
    ))?;
    autd.tick(Duration::from_micros(25))?;
    Ok(())
})?;

let mut sound_field = record.sound_field(
    RangeXY {
        x: focus.x - 20.0..=focus.x + 20.0,
        y: focus.y - 20.0..=focus.y + 20.0,
        z: focus.z,
        resolution: 1.,
    },
    RmsRecordOption {
        sound_speed: 340e3 * mm,
        print_progress: true,
        gpu: true,
    },
)?;

let df = sound_field.observe_points();
dbg!(df);

let df = sound_field.next(Duration::from_micros(25))?;
dbg!(df);
    Ok(())
}

NOTE: gpuオプションは, gpu featureを有効にしている場合のみ使用可能である.

import numpy as np
from pyautd3 import AUTD3, Duration, Focus, FocusOption, Silencer, Static
from pyautd3_emulator import Emulator, RangeXYZ, Recorder, RmsRecordOption

with Emulator([AUTD3()]) as emulator:
    focus = emulator.center() + np.array([0.0, 0.0, 150.0])

    def f(autd: Recorder) -> None:
        autd.send(Silencer.disable())
        autd.send((Static(), Focus(pos=focus, option=FocusOption())))
        autd.tick(Duration.from_micros(25))

    record = emulator.record(f)

    sound_field = record.sound_field(
        RangeXYZ(
            x=(focus[0] - 20.0, focus[0] + 20.0),
            y=(focus[1] - 20.0, focus[1] + 20.0),
            z=(focus[2], focus[2]),
            resolution=1.0,
        ),
        RmsRecordOption(
            sound_speed=340e3,
            print_progress=True,
            gpu=False,
        ),
    )

    df = sound_field.observe_points()
    print(df)

    df = sound_field.next(Duration.from_micros(25))
    print(df)

NOTE: 最低, は時刻を進める必要がある.

NOTE: RMSで計算される値は, 上記の瞬時音場のRMSではない. 伝搬遅延や振動子の応答を無視した線形重ね合わせである.

各観測点における, 出力音圧のRMSが時系列順 (単位は) で各列に格納される. 各列の名前は, rms[Pa]@<時刻>[ns]である. 各行は, observe_pointsで取得できる観測点と対応している.

┌────────────┬───────────┬───────┐
│ x[mm]      ┆ y[mm]     ┆ z[mm] │
│ ---        ┆ ---       ┆ ---   │
│ f32        ┆ f32       ┆ f32   │
╞════════════╪═══════════╪═══════╡
│ 66.625267  ┆ 46.713196 ┆ 150.0 │
│ 67.625267  ┆ 46.713196 ┆ 150.0 │
│ 68.625267  ┆ 46.713196 ┆ 150.0 │
│ 69.625267  ┆ 46.713196 ┆ 150.0 │
│ 70.625267  ┆ 46.713196 ┆ 150.0 │
│ …          ┆ …         ┆ …     │
│ 102.625267 ┆ 86.713196 ┆ 150.0 │
│ 103.625267 ┆ 86.713196 ┆ 150.0 │
│ 104.625267 ┆ 86.713196 ┆ 150.0 │
│ 105.625267 ┆ 86.713196 ┆ 150.0 │
│ 106.625267 ┆ 86.713196 ┆ 150.0 │
└────────────┴───────────┴───────┘
┌───────────────┐
│ rms[Pa]@0[ns] │
│ ---           │
│ f32           │
╞═══════════════╡
│ 97.675339     │
│ 83.525314     │
│ 60.54364      │
│ 34.229084     │
│ 33.827206     │
│ …             │
│ 51.324219     │
│ 75.84668      │
│ 102.852501    │
│ 120.575188    │
│ 125.698715    │
└───────────────┘

さらなる, Exampleはautd3-emulator (Rust), 及び, pyautd3 (Python)を参照されたい.