メインコンテンツへスキップ
ブログ記事一覧

Yagi のご紹介:無線のためのプログラミング言語

信号を一度記述するだけで、Yagi が受信機、テスト信号、検出器を構築します。私たちがこれを開発する理由をご紹介します。

Yagi は、291 Group が開発した無線周波数システム向けのプログラミング言語です。その名は、1926 年に Hidetsugu Yagi と Shintaro Uda が発明した Yagi-Uda アンテナに由来します。基本となる考え方は一言で表せます。信号は一度だけ記述する、ということです。

無線ソフトウェアは三度書かれている

現在、新しい無線機能は通常三度書かれます。アイデアを実証するために Python で一度、高速化のために C++ で一度、さらに専用ハードウェアに載せるためにハードウェア言語でもう一度です。サンプルレートや単位はコメントやエンジニアの頭の中にしか存在しないため、不一致があってもエラーにはならず、気づかないうちに無意味なデータが生まれます。新しい信号を扱うたびに、手作りの復調器、個別のテスト信号生成器、個別の検出ロジックが必要になります。

信号は一度だけ記述する

Yagi では、信号を一度だけ記述します。どのように変調されるか、シンボルがどれだけの速さで届くか、フレームがどのように構成され検査されるかを記述するのです。その一つの記述から、Yagi は受信機、テスト信号、検出器を生成し、同じプログラムをノートパソコンでもフィールドセンサーでも、無線機からのライブ入力でも録音データからでも実行します。

以下は、無線機を 433.92 MHz に同調させ、気象センサーをデコードする短いプログラムです。

radio sdr = hackrf("one") {
  rx.freq = 433.92 MHz
  rx.rate = 2 Msps
}

signal WeatherSensor {
  modulation:  ook
  symbol_rate: 2.4 kbaud
  coding:      nrz
  frame:       preamble(0xAAAA) ++ sync(0x2DD4)
            ++ payload(bytes[8]) ++ crc16(poly: 0x1021)
}

sdr.rx
  |> lowpass(cutoff: 100 kHz)
  |> decimate(10)
  |> WeatherSensor.demod()
  |> each(frame => log(frame.payload))

周波数とは何かを理解している言語

無線は言語そのものに組み込まれています。周波数、サンプルレート、物理単位は型であり、実際の無線機の限界も型として扱われます。受信機が同調できない周波数を指定したり、異なるサンプルレートで動作する二つのブロックを接続したりすると、Yagi は現場ではなく、プログラムのコンパイル時にそれを止めます。

短い記述で、確かな成果

  • 28 行の LoRa の記述で、公開されている 205 件の録音のうち 196 件をデコードできます。これは C++ で書かれた 2,100 行のリファレンスデコーダーがデコードした 187 件を上回ります。
  • デバイスライブラリには 95 種類のデバイスが記述されており、それぞれが実際の録音からなる公開テストコレクションで検証されています。
  • すでに 433 MHz センサー、航空機トランスポンダー(ADS-B)、Bluetooth Low Energy のアドバタイジング、プッシュツートーク音声無線をデコードできます。

HackRF や RTL-SDR など、一般的なソフトウェア無線機で動作します。

Yagi をフォロー

Yagi の拠点は GitHub の github.com/yagi-lang です。こちらでフォローして、いち早くご覧ください。