あ…ありのまま今起こった事を話すぜ!
「時間ベースで処理するタイプの台形制御ができたぞー」
「さあ、実行しよう!」
「い、1秒ごとにしか速度が変わらないぞ???」
「これ整数で返されとるやんけー」
問題点
SPIKE PrimeにはMicropythonで用意されたtime
モジュールとLegacyバージョンに限りTimer
クラスがサポートされています。
しかし、Timer
クラスのドキュメントを見るととんでもないことが書いてあります。
秒数が整数型で返されます。
これってどこに需要があるタイマーなんでしょうか。
では先ほど紹介したtime
モジュールを使えばいいじゃないかということですが、こちらもどちらのバージョンともに整数が返されます。
# SPIKE Legacyのみ可
from spike.control import Timer
timer = Timer()
print(timer.now()) # int型
# SPIKE Legacy、SPIKE 3 どちらとも可
import time
print(time.time()) # int型
検証
待機関数
# SPIKE Legacyのみ可
from spike.control import wait_for_seconds
wait_for_seconds(1.5) # 正しく1.5秒待つ
# SPIKE 3のみ可
import runloop
await runloop.sleep_ms(1500) # 正しく1.5秒待つ
# SPIKE Legacy、SPIKE 3 どちらとも可
import time
time.sleep(1.5) # 正しく1.5秒待つ
Pythonにはwait_for_seconds
関数があるのでそちらで
少数型を正しく処理してくれるか試すと、こちらも問題なく少数秒で待ってくれました。
time_ms
とtime_ns
import time
print(time.time_ms / (10**3)) # 整数部分しか変化しない
print(time.time_ns / (10**9)) # 整数部分しか変化しない
それぞれ細かい数値を取得できるtime_ms
とtime_ns
ですが、SPIKEの同じプログラム内で何度呼び出しても秒数が1秒ごとにしか更新されません。残念ですが使い物にならなさそうです。
perf_counter
import time
print(time.perf_counter()) # NameError: name 'perf_counter' is not defined
精度が高い時間を呼び出したい時に定評のあるperf_counter
ですが、残念ながらSPIKE Primeには存在しないようです。
ブロック言語
Pythonなのが悪いのかと思い、ブロック言語環境で時間を取得してみると、何の問題もなく少数まで取得できました。
解決策
上の検証結果から、内部では少数秒で処理されているがtime
系の関数では取得できないことがわかります。
じゃあどうするんだというとtick
を使います。これはCPU時間をベースにtime
関数と同じような動作が期待できます。
import time
print(time.tick_ms() / (10**3)) # float型
print(time.tick_ns() / (10**9)) # float型
ただ肝心の少数型で返してくれるtick
関数というものは存在しないので割り算で少数型にします。
tick
関数はtime
関数に比べてなにか信頼性がないというか、私は少し不安ですが今はこれしか思いつかないので、tick
を使っていきます。
参考文献