焦点の移動
autd3において, Gain
は送信するたびに上書きされる.
したがって, 次のようなコードを実行すると, 約1秒ごとに焦点の位置が移動する.
use autd3::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut autd = Controller::open([AUTD3::default()], Nop::new())?;
autd.send(Sine {
freq: 150 * Hz,
option: SineOption::default(),
})?;
let center = autd.center() + Vector3::new(0.0, 0.0, 150. * mm);
loop {
autd.send(Focus {
pos: center + Vector3::new(20. * mm, 0.0, 0.0),
option: FocusOption::default(),
})?;
std::thread::sleep(std::time::Duration::from_secs(1));
autd.send(Focus {
pos: center - Vector3::new(20. * mm, 0.0, 0.0),
option: FocusOption::default(),
})?;
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
#include <chrono>
#include <thread>
#include "autd3.hpp"
#include "autd3/link/nop.hpp"
int main() {
auto autd = autd3::Controller::open({autd3::AUTD3{.pos =
autd3::Point3::origin(), .rot = autd3::Quaternion::Identity(),}},
autd3::link::Nop{});
autd.send(autd3::Sine(150 * autd3::Hz, autd3::SineOption{}));
const autd3::Point3 center = autd.center() + autd3::Vector3(0., 0., 150.);
while (true) {
autd.send(
autd3::Focus{center + autd3::Vector3(20., 0., 0.), autd3::FocusOption{}});
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
autd.send(
autd3::Focus{center - autd3::Vector3(20., 0., 0.), autd3::FocusOption{}});
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
using AUTD3Sharp;
using AUTD3Sharp.Utils;
using AUTD3Sharp.Link;
using AUTD3Sharp.Gain;
using AUTD3Sharp.Modulation;
using static AUTD3Sharp.Units;
using var autd = Controller.Open([new AUTD3(pos: Point3.Origin, rot: Quaternion.Identity)], new Nop());
autd.Send(new Sine(
freq: 150u * Hz,
option: new SineOption()
));
var center = autd.Center() + new Vector3(0.0f, 0.0f, 150.0f);
while (true)
{
autd.Send(new Focus(
pos: center + new Vector3(20.0f, 0.0f, 0.0f),
option: new FocusOption()
));
Thread.Sleep(1000);
autd.Send(new Focus(
pos: center - new Vector3(20.0f, 0.0f, 0.0f),
option: new FocusOption()
));
Thread.Sleep(1000);
}
import time
import numpy as np
from pyautd3 import AUTD3, Controller, Focus, FocusOption, Hz, Sine, SineOption
from pyautd3.link.nop import Nop
autd = Controller.open([AUTD3(pos=[0.0, 0.0, 0.0], rot=[1, 0, 0, 0])], Nop())
autd.send(
Sine(
freq=150 * Hz,
option=SineOption(),
)
)
center = autd.center() + np.array([0.0, 0.0, 150.0])
while True:
autd.send(
Focus(
pos=center + np.array([20.0, 0.0, 0.0]),
option=FocusOption(),
),
)
time.sleep(1)
autd.send(
Focus(
pos=center - np.array([20.0, 0.0, 0.0]),
option=FocusOption(),
),
)
time.sleep(1)
なお, Gain
とModulation
は独立しているので, どちらの焦点にもの正弦波AM変調がかかる.
上記のコードだとソフトウェア的にタイミングを制御している.
これの精度はOSや実行環境に依存するため, より精度の高い制御が必要な場合は, FociSTM/GainSTM
を使用することをおすすめする.
FociSTM
を使用して上記と同等の動作を実現するコードは以下の通りである.
use autd3::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut autd = Controller::open([AUTD3::default()], Nop::new())?;
autd.send(Sine {
freq: 150 * Hz,
option: SineOption::default(),
})?;
let center = autd.center() + Vector3::new(0.0, 0.0, 150. * mm);
autd.send(FociSTM {
foci: vec![
center + Vector3::new(20. * mm, 0.0, 0.0),
center - Vector3::new(20. * mm, 0.0, 0.0),
],
config: 0.5 * Hz,
// config: std::time::Duration::from_secs(2),
// config: SamplingConfig::new(1.0 * Hz),
// config: SamplingConfig::new(std::time::Duration::from_secs(1)),
})?;
Ok(())
}
#include <chrono>
#include <vector>
#include "autd3.hpp"
#include "autd3/link/nop.hpp"
int main() {
auto autd = autd3::Controller::open({autd3::AUTD3{.pos =
autd3::Point3::origin(), .rot = autd3::Quaternion::Identity(),}},
autd3::link::Nop{});
autd.send(autd3::Sine(150 * autd3::Hz, autd3::SineOption{}));
const autd3::Point3 center = autd.center() + autd3::Vector3(0., 0., 150.);
autd.send(autd3::FociSTM(
std::vector{
center + autd3::Vector3(20., 0., 0.),
center - autd3::Vector3(20., 0., 0.),
},
0.5f * autd3::Hz
// std::chrono::seconds(2)
// autd3::SamplingConfig{1.0f * autd3::Hz}
// autd3::SamplingConfig{std::chrono::seconds(1)}
));
return 0;
}
using AUTD3Sharp;
using AUTD3Sharp.Utils;
using AUTD3Sharp.Link;
using AUTD3Sharp.Gain;
using AUTD3Sharp.Modulation;
using static AUTD3Sharp.Units;
using var autd = Controller.Open([new AUTD3(pos: Point3.Origin, rot: Quaternion.Identity)], new Nop());
autd.Send(new Sine(
freq: 150u * Hz,
option: new SineOption()
));
var center = autd.Center() + new Vector3(0.0f, 0.0f, 150.0f);
autd.Send(new FociSTM(
foci: [
center + new Vector3(20.0f, 0.0f, 0.0f),
center - new Vector3(20.0f, 0.0f, 0.0f),
],
config: 0.5f * Hz
// config: Duration.FromSecs(2)
// config: new SamplingConfig(1.0f * Hz)
// config: new SamplingConfig(Duration.FromSecs(1))
));
import numpy as np
from pyautd3 import AUTD3, Controller, Hz, Sine, SineOption, FociSTM
from pyautd3.link.nop import Nop
autd = Controller.open([AUTD3(pos=[0.0, 0.0, 0.0], rot=[1, 0, 0, 0])], Nop())
autd.send(
Sine(
freq=150 * Hz,
option=SineOption(),
)
)
center = autd.center() + np.array([0.0, 0.0, 150.0])
autd.send(
FociSTM(
foci=[
center + np.array([20.0, 0.0, 0.0]),
center - np.array([20.0, 0.0, 0.0]),
],
config=0.5 * Hz,
# config=Duration.from_secs(2),
# config=SamplingConfig(1.0 * Hz),
# config=SamplingConfig(Duration.from_secs(1)),
)
)
FociSTM/GainSTM
はAUTD3デバイス内部でループされるため, ソフトウェアループは必要なく, FociSTM/GainSTM
の送信以降自動的に無限ループする.
また, タイミングはAUTD3デバイス内蔵のタイマーで制御されるため, 精度が高く, 解像度も最高で単位で指定できる
ただし, このタイマーの制約上, 出力不可能な周波数が存在する.
FociSTM/GainSTM
の切り替えタイミングは, 1ループの周波数, または周期で指定する.
すなわち, この場合は2つの焦点でとなるので, 各焦点は出力される.
なお, SamplingConfig
を使用することで, 1ループあたりではなく, サンプリング周波数, すなわち1焦点あたりの周波数や周期を指定することもできる.
したがって, 上記のコードのコメントアウト部分はすべて等価である.