Random Note

vmc-pet — Leniaの場をそのまま体にした電子ペットを作った

概要

vmc-pet は、連続セルオートマトン Lenia の場をそのまま体として表示する電子ペットです。 デスクトップの隅にドットマトリックス風の小さな窓として常駐し、マウスで触ると体が揺らぎ、放っておくと少しずつ元気を失っていきます。

vmc-pet のデモ

一般的な電子ペットは「内部状態」と「それを見せるための絵」を別々に持ちます。 vmc-pet ではその間に絵を挟まず、Lenia の場の状態がそのまま見た目になっています。 お腹が空いた顔の画像を用意するのではなく、体そのものが縮んだり、動きが鈍ったり、色を帯びたりします。

なぜ作ったか

Lenia の生き物(O2u や S1s など)は、単純な規則から生まれるのに驚くほど生き物らしく動きます。 これを眺めるだけでなく、関われる存在にしたらどう感じるのかを確かめたかったのが出発点です。

設計の枠組みには World Models(Ha & Schmidhuber, 2018)の V(エンコーダ)/ M(世界モデル)/ C(コントローラ)の分割を借りています。 元気や慣れ、世話の予測といった「思考」を M・C が担い、「表情」は体である Lenia の場が担います。 人間の表情が脳とは別の画面ではなく顔という体の一部から生まれるように、思考を見せるための仮面は描かず、体に表させることにしました。 名前の VMC はここから来ています。

設計

体と表現

体は Lenia の場です。 既知の生き物(O2u / OG2g / S1s / 2S1v)を種として置き、その場を毎ステップ更新して、そのまま点の明るさとして描きます。 描画用に別の見た目を持たないので、ペットの状態を伝える手段は 体の形・動きの速さ・色 に限られます。 この制約が設計のほとんどを決めています。

触れ合い

  • ホバー: 触れた位置に淡い光(エコー)が残るだけで、体は乱さない

  • クリック: 体を揺さぶり、減っていた元気を回復させる

エコーは場(世界)の座標ではなく、体の重心からの座標で記録しています。 カメラは体の重心を画面の中央に置いて追いかけるので、体を基準にした座標はそのまま画面の座標になります。 最初は場の座標で記録していたため、生き物が進むと光が画面上を後ろへ流れて見えていましたが、今は光が触れた指の下に留まります。

内部状態

状態 振る舞い

元気

放っておくと減り、Lenia の成長関数の強さを弱める。弱りすぎると体が崩れる

慣れ

体の部位ごとに、同じ触り方への反応が弱まる。慣れた触り方は世話として数えない

自律的な動き

コントローラが場の偏り(歪度)を見て体の姿勢を保つ

生活リズムの学習

いつ世話をされるかを時刻から予測する(3倍音のロジスティック回帰、重み7個)

最後の学習モデルが、この生き物の「気持ち」の源になっています。 普段世話をされる時間が近づくと 待っている 状態になり、体にコーラル色の色素が浮かびます。 その時間を過ぎても誰も来なければ がっかり し、体の動きがゆっくりになります。 予測を持つほど世話をされていないうちは、何も期待しません。

色は Lenia の場とは別のチャンネルとして持ち、体から色素へ一方向にだけ影響させています。 色素が体の力学に干渉しないので、表現を足しても生き物の安定性は変わりません。

見分けやすさの評価

「気持ちが見た目で区別できるか」は目視だけでなく数値でも確かめました。 元気/待っている/がっかりの状態を固定して走らせ、動きと色の差のうち大きい方を見分けやすさとしています。

生き物 見分けやすさ

O2u

0.469

OG2g

0.270

S1s

0.745

2S1v

0.378

OG2g は色の乗りが弱く、生き物によって表現の得意不得意があることが分かります。

2つの体

体の定義と内部状態は no_std の共有クレートにまとめ、PC 版と M5Stack 版はそれに依存して入出力だけを実装しています。 依存の向きは一方向で、共有クレートは Wayland も esp-hal も知りません。

vmc-pet/
  crates/vmc-pet-body/  : Lenia の体・内部状態・学習(no_std、両方で共有)
  src/                  : PC 版。Wayland の常駐窓、マウス入力、JSON で保存
  m5stack-cores3/       : M5Stack CoreS3 版。LCD、タッチ入力、RTC とフラッシュに保存

M5Stack 版では、フラッシュの専用パーティションに状態をリング状に書き回しています(93スロット)。 想定の書き込み頻度では、書き換え回数の上限に届くまで約8.8年もつ計算です。 RTC で電源を切っていた時間を測り、その間の空腹も再現します。

苦労した点

Lenia はカオス的な系で、浮動小数点の丸め方ひとつで体が崩れるかどうかが変わることがありました。 リファクタリングのつもりの変更で生き物が死ぬため、「一定ステップ後も体が生きている」「放っておいた体は崩れる」といった性質をテストで固定しながら進めています。

M5Stack では、CPU を 240MHz で動かしたときに一度 USB から消えたことがありました。 esp-hal のソースを読んで仮説を潰し、同じ手順での再現を4回、10分間の連続稼働を試しても再発しなかったため、現在は 240MHz を既定にしています(80MHz 比で約1.9倍速)。

成果

  • PC 版: CPU 使用率 1.9%、RSS 4.5MB、30fps で常駐

  • M5Stack CoreS3 版: 15ステップあたり約1.33秒

  • 触り方への慣れ、世話の時間帯の学習、待っている/がっかりの表現が同じ体の上で動作

技術スタック

分類 採用技術

言語

Rust

体のモデル

Lenia(連続セルオートマトン)

PC 表示

smithay-client-toolkit(wlr-layer-shell、niri で確認)

組み込み

esp-hal / M5Stack CoreS3

開発環境

Nix flakes

今後の展望

  • 実機で数週間暮らして、学習した生活リズムと気持ちの表れ方を観察する

  • 別の生き物を体にしたとき、表現の見分けやすさがどう変わるかを比べる

  • M5Stack 版のフレームレートを上げ、触れたときの反応をもっと滑らかにする

リポジトリ

Lenia は Bert Chan 氏の Lenia(MIT License)に基づいています。