Client
Client はコマンドの送信・状態の読み出しを行うオブジェクト.
let mut client = Client::open(&geometry, &option).await?;client.send(Clear).await?;client.send(Synchronize).await?;client = await Client.open(geometry, TransportOption())await client.send(Clear())await client.send(Synchronize())var client = await Client.OpenAsync(layout, new TransportOption());await client.SendAsync(new Clear());await client.SendAsync(new Synchronize());| 引数 | 型 | 説明 |
|---|---|---|
geometry |
&Geometry |
デバイスの物理配置 |
option |
&TransportOption |
接続の設定. TransportOption 参照 |
let num_devices = client.num_devices();let now = client.device_time_now()?;
let firmware = client.read_firmware_version().await?;
client.send(Nop).await?;client.send_streaming(Nop).await?;
let state = tokio::time::timeout(Duration::from_millis(200), client.read_state()).await??;let fpga_state = state.replies().iter().map(|r| r.fpga_state).collect::<Vec<_>>();num_devices = client.num_devices()now = client.device_time_now()
firmware = await client.read_firmware_version()
await client.send(Nop())await client.send_streaming(Nop())
state = await asyncio.wait_for(client.read_state(), timeout=0.2)fpga_state = [r.fpga_state for r in state.replies]var numDevices = client.NumDevices;var now = client.DeviceTimeNow();
var firmware = await client.ReadFirmwareVersionAsync();
await client.SendAsync(new Nop());await client.SendStreamingAsync(new Nop());
using var timeout = new CancellationTokenSource(TimeSpan.FromMilliseconds(200));var state = await client.ReadStateAsync(timeout.Token);var fpgaState = state.Replies.Select(r => r.FpgaState).ToArray();| メソッド | async | 返り値 | 説明 |
|---|---|---|---|
num_devices() |
— | usize |
接続中のデバイス台数 |
geometry() |
— | &Geometry |
接続時のデバイスの物理配置 |
read_firmware_version() |
✓ | Result<Vec<FirmwareVersion>, Error> |
各デバイスの CPU/FPGA ファームウェアバージョン |
device_time_now() |
— | Result<SysTime, Error> |
現在のデバイスの時刻 (SysTime 参照) |
send(cmd) |
✓ | Result<(), Error> |
コマンドを送信し, 1 フレームずつ応答確認まで行う |
send_streaming(cmd) |
✓ | Result<(), Error> |
コマンドを応答を待たずに詰めて送り, 全フレームの応答を確認する (streaming 参照) |
read_state() |
✓ | Result<Response, Error> |
全デバイスへ生存確認を 1 回送り, その返信を返す (状態監視 参照) |
TransportOption の heartbeat_interval を指定すると, Client はその周期で生存確認を送り続ける (フェイルセーフ 参照). 既定では送らない.
デバイスを止める関数はない.
Rust は Client を drop したとき, C# は Dispose(), Python は with を抜けたときにソケットを閉じ, 生存確認の送信も止めるが, デバイスへは何も送らない.
デバイスは閉じた後も直前の出力を続けるので, 出力を止めるのはユーザーの責任.
streaming
Section titled “streaming”send は 1 フレームずつ応答を待つ (stop-and-wait).
send_streaming は応答を待たずに続けて送り, 最も古いフレームから応答を確かめる.
Modulation や STM のように複数フレームになるコマンドを速く送るときに使う.
client .send_streaming(Modulation::new(SamplingConfig::FREQ_4K, &modulation)) .await?;await client.send_streaming(Modulation(SamplingConfig.FREQ_4K, data))await client.SendStreamingAsync(new Modulation(SamplingConfig.Freq4k, modulation));Response と DeviceReply
Section titled “Response と DeviceReply”read_state は全デバイスの返信を Response にまとめて返す.
Response |
説明 |
|---|---|
replies() |
デバイス番号順の DeviceReply の配列 |
device_status() |
返信の flags から作ったデバイスごとの状態 (状態監視 参照) |
check() |
最も番号の小さい, エラーを返したデバイスのエラーを返す |
DeviceReply のフィールド |
説明 |
|---|---|
device |
返信したデバイスの番号 |
msg_id |
どの生存確認への返信か |
status |
エラーコード (0 = 成功) |
flags |
デバイスの状態フラグ |
unit_id |
デバイスの ID |
sys_time |
デバイスの時刻 [ns] (0 = 載っていない) |
telemetry |
Telemetry |
fpga_state |
FpgaState |
data |
読み出し系コマンドの値 |
FpgaState
Section titled “FpgaState”FPGA の状態フラグ
| メソッド | 型 | 説明 |
|---|---|---|
is_thermal_asserted() |
bool |
温度センサが閾値を超えているか |
current_mod_bank() |
ModulationBank |
現在の Modulation bank |
current_pattern_bank() |
PatternBank |
現在の Pattern bank (Pattern と STM で共有) |
is_pattern_mode() |
bool |
Pattern を出力しているか |
is_pattern_stopped() |
bool |
Pattern / STM の再生が止まっているか |
is_mod_stopped() |
bool |
Modulation の再生が止まっているか |
is_transition_pending() |
bool |
bank の切り替えが発効待ちか |
Telemetry
Section titled “Telemetry”CPU の診断カウンタ
| フィールド | 型 | 説明 |
|---|---|---|
fifo_drop |
u32 |
受信 FIFO が満杯で捨てたフレーム数 (捨てたフレームには返信しない) |
exec_late |
u32 |
処理時刻を 1 µs 以上過ぎてから処理を始めたフレーム数 |
sync_resync |
u8 |
同期入力のハード再同期回数 (Synchronize で 0 に戻る) |
cpu_watchdog |
u8 |
CPU ウォッチドッグの発火回数 (FPGA の再構成まで消えない) |
boot_failure |
u8 |
起動時に失敗した手順の数 (Clear で消えない) |
each はデバイスを引数にするクロージャを受け取り, デバイスごとに異なるコマンドを割り当てる.
client .send(each(|device| { Some(if device.idx() % 2 == 0 { Pattern::new(&left, Intensity::MAX) } else { Pattern::new(&right, Intensity::MAX) }) })) .await?;await client.send(each(lambda device: Pattern(left if device.idx() % 2 == 0 else right, Intensity.MAX)))await client.SendAsync(Command.Each(device => device.Idx % 2 == 0 ? new Pattern(left, Intensity.Max) : new Pattern(right, Intensity.Max)));Rust ではクロージャの返り値はすべて同じ型でなければならない.
型の異なるコマンドを混在させたい場合は, .boxed() で BoxedCommand に揃える.
client .send(each(|device| { Some(if device.idx() % 2 == 0 { Box::new(Pattern::new(&left, Intensity::MAX)) as Box<dyn Operation> } else { Box::new(SetSilencer::default()) }) })) .await?;