エミュレータ
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)を参照されたい.