Controller
ここでは, Controller
に存在するAPIを紹介する.
fpga_state
FPGAの状態を取得する.
これを使用する前に, ReadsFPGAState
で状態取得を有効化しておく必要がある.
use autd3::prelude::*;
#[allow(unused_variables)]
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut autd = Controller::open([AUTD3::default()], autd3::link::Nop::new())?;
autd.send(ReadsFPGAState::new(|_dev| true))?;
let info = autd.fpga_state()?;
Ok(())
}
#include<autd3.hpp>
#include<autd3/link/nop.hpp>
int main() {
using namespace autd3;
auto autd =
Controller::open({AUTD3{}}, link::Nop{});
autd.send(ReadsFPGAState([](const auto&) { return true; }));
const auto info = autd.fpga_state();
return 0; }
using AUTD3Sharp;
using AUTD3Sharp.Link;
using AUTD3Sharp.Utils;
using var autd = Controller.Open([new AUTD3()], new Nop());
autd.Send(new ReadsFPGAState(_ => true));
var info = autd.FPGAState();
from pyautd3 import Controller, AUTD3, ReadsFPGAState
from pyautd3.link.nop import Nop
autd = Controller.open([AUTD3()], Nop())
autd.send(ReadsFPGAState(lambda _: True))
info = autd.fpga_state()
ReadsFPGAState
コンストラクタの引数はFn(&Device) -> bool
で, デバイス毎に状態取得を有効化するかどうかを指定する.
有効化していないデバイスに対してfpga_state
はNone
を返す.
FPGAの状態としては, 現在以下の情報が取得できる.
is_thermal_assert
: ファン制御用の温度センサがアサートされているかどうかcurrent_mod_segment
: 現在のModulation Segmentcurrent_stm_segment
: 現在のFociSTM/GainSTM Segmentcurrent_gain_segment
: 現在のGain Segmentis_gain_mode
: 現在Gainが使用されているかどうかis_stm_mode
: 現在FociSTM/GainSTMが使用されているかどうか
send
デバイスにデータを送信する.
データは単体か2つのみ同時に送信することができる.
sender
送信時の設定をsender
経由で指定できる.
use autd3::prelude::*;
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut autd = Controller::open([AUTD3::default()], autd3::link::Nop::new())?;
let mut sender = autd.sender(
SenderOption {
send_interval: Duration::from_millis(1),
receive_interval: Duration::from_millis(1),
timeout: None,
parallel: ParallelMode::Auto,
strict: true
},
FixedSchedule::default(),
);
let d = Null {};
sender.send(d)?;
Ok(())
}
#include<chrono>
#include<autd3.hpp>
#include<autd3/link/nop.hpp>
int main() {
using namespace autd3;
auto autd = Controller::open({AUTD3{}}, link::Nop{});
auto sender =
autd.sender(SenderOption{.send_interval = std::chrono::milliseconds(1),
.receive_interval = std::chrono::milliseconds(1),
.timeout = std::nullopt,
.parallel = ParallelMode::Auto,
.strict = true},
FixedSchedule{});
const Null d;
sender.send(d);
return 0; }
using AUTD3Sharp;
using AUTD3Sharp.Link;
using AUTD3Sharp.Gain;
using AUTD3Sharp.Utils;
using var autd = Controller.Open([new AUTD3()], new Nop());
var sender = autd.Sender(
new SenderOption
{
SendInterval = Duration.FromMillis(1),
ReceiveInterval = Duration.FromMillis(1),
Timeout = null,
Parallel = ParallelMode.Auto,
Strict = true,
},
new FixedSchedule()
);
var d = new Null();
sender.Send(d);
from pyautd3 import AUTD3, Controller, Duration, Null, SenderOption, FixedSchedule, ParallelMode
from pyautd3.link.nop import Nop
autd = Controller.open([AUTD3()], Nop())
sender = autd.sender(
SenderOption(
send_interval=Duration.from_millis(1),
receive_interval=Duration.from_millis(1),
timeout=None,
parallel=ParallelMode.Auto,
strict=True
),
FixedSchedule(),
)
d = Null()
sender.send(d)
ここで,
send_interval
: 送信間隔receive_interval
: 受信間隔timeout
: タイムアウト時間. 詳細は送信データのチェックについてを参照parallel
: 並列計算モード. 詳細は並列計算についてを参照strict
: 送信データのチェックを厳密に行うかどうか. 詳細は送信データのチェックについてを参照 であり, デフォルト値は上記の通り.
第2引数は送受信間隔を調整する構造体であり, 以下から選択する.
FixedSchedule
: 送信処理にかかった時間にかかわらず, 前回の送信開始時刻から指定した間隔で次の送信を開始する.FixedDelay
: 送信処理が完了してから指定した間隔で次の送信を開始する.
これらの構造体は, どのようにスレッドをスリープさせるかを指定する以下の構造体を持つ.
SpinSleeper
:spin_sleep
を使用StdSleeper
:std::thread::sleep
を使用SpinWait
: ビジーウェイトを使用
なお, Controller::send
はController::default_sender_option
(変更可能) とデフォルトのFixedSchedule(SpinSleeper)
を使用した場合と等価である.
送信データのチェックについて
タイムアウトの値が
- 0より大きい場合, 送信データがデバイスで処理されるか, 指定したタイムアウト時間が経過するまで待機する. 送信データがデバイスで処理されたのが確認できなかった場合にエラーを返す.
- 0, かつ,
strict=false
の場合,send
関数は送信データがデバイスで処理されたか確認できなくてもエラーを返さない.
確実にデータを送信したい場合はこれを適当な値に設定しておくことをおすすめする.
SenderOption
で指定しない場合, デフォルト値 () が使用される.
複数をまとめて送信する場合は, それぞれのデータのタイムアウト値の最大値が使用される.
並列計算について
各データの内部での計算は, デバイス単位で並列に実行することができる.
ParallelMode::On
を指定すると並列計算を有効化, ParallelMode::Off
を指定すると無効化する.
ParallelMode::Auto
の場合, デバイスの数が以下に示す各データの並列計算スレッショルド値を超える場合に並列計算が有効化される.
並列計算スレッショルド値 | |
---|---|
Clear /GPIOOutputs /ForceFan /PhaseCorrection /ReadsFPGAState /SwapSegment /Silencer /Synchronize /FociSTM (焦点数が4000未満)/Modulation | 18446744073709551615 |
PulseWidthEncoder /FociSTM (焦点数が4000以上)// GainSTM /Gain | CPUのコア数 |
inspect
(Rustのみ)
Gain
やModulation
, GainSTM
, FociSTM
の計算は並列化やメモリアロケーションを最小にするために遅延されており, 計算結果は送信フレーム内に直接構成される.
そのため, これらの計算結果を送信前に直接確認することはできない.
Controller::inspect
を使用することで, 送信することなく, これらの計算結果を確認することができる.
use autd3::prelude::*;
#[allow(unused_variables)]
fn main() -> Result<(), Box<dyn std::error::Error>> {
let autd = Controller::open([AUTD3::default()], autd3::link::Nop::new())?;
let r = autd.inspect(Null {})?;
dbg!(&r[0]); // result of device 0
// &r[0] = Some(
// GainInspectionResult {
// name: "Null",
// data: [
// Drive {
// phase: 0x00,
// intensity: 0x00,
// },
// ︙
// Drive {
// phase: 0x00,
// intensity: 0x00,
// },
// ],
// segment: S0,
// transition_mode: None,
// },
// )
Ok(())
}