スタックチャン

TypeScriptで作る
オープンソースロボット

ゴール

  • スタックチャンとオープンソースハードウェアについて知ってもらう
  • 「TypeScriptで組み込み開発」の世界を身近に感じてもらう

自己紹介

  • ししかわ @meganetaaan
    • Twitterのアカウントを永久凍結されている
    • スタックチャンを作っている

【前編】スタックチャンって何?

スタックチャン

スタックチャンの機能

  • 表情
  • 首振り
  • 対話
  • 音声合成
  • 音声認識(開発中)
  • 顔認識 (開発中)

基本機能の上にユーザアプリケーション(mod)をインストール。
ユーザが自由にふるまいをプログラミングできる。

DEMO

AIスタックチャン

VOICEVOX: ずんだもん

AIスタックチャン ... 😮‍💨

Motivation

クローズドなロボット...内部のプログラムやバックエンドが非公開

Motivation

クローズドなロボットは、サービス終了とともにコミュニケーション能力を失う

Motivation

自分のロボットと永く暮らすには?
▷自分でメンテできるように全て公開してしまえばいい!

Motivation

「誰もがユーザであり、同時に開発者でもある」

👉

スタックチャンの特徴「すべてがオープン」

  • オープンな仕様
  • オープンなプロセス
  • オープンなコミュニティ

オープンな仕様

  • 全てのリソースを Apache v2.0 で公開
    • ケース、基板、ソフトすべて
    • 商用、非商用問わず利用可能
    • 改造&キット化して販売する人も
  • オープンソースハードウェア協会(OSHWA)の認定を取得

オープンなプロセス

  • 製作のようすを細かく発信
    • Twitter #スタックチャン
    • Hackaday.io
  • 悩みや失敗もオープンにして敷居を下げる
    • モジャった
    • バグった
    • 基板燃えた

オープンなコミュニティ

  • 様々な界隈から「オープン」と「カワイイ」を共通項に大集合
    • Maker
    • ホビーロボット
    • 生成AI
    • ぬいの者
  • 「AIスタックチャン」の登場でさらに拡大
  • DiscordやTwitterで活発に活動中

コミュニティの活動: 製作

  • 作る
    • キットを購入して組み立てる
    • 公開されているデータから自作する
    • 完全自作する
  • 愛でる
    • お外に連れ出す
    • イベントに出展する
  • 🔍#スタックチャン

コミュニティの活動: お誕生日会

  • スタックチャンの誕生日は7月2日
  • 毎年やっているスタックチャンオンリーイベント
  • 「お誕生日会」のコンセプトに従って楽しくお祝い
  • LT大会、お祝いのビデオメッセージ、交流会、抽選会など
  • 1歳の誕生日
  • 参加者20人
  • スタックチャンケーキでお祝い!
  • 2歳の誕生日
  • ⏫参加者50人
  • スタックチャンピニャータを割ってお祝い!




今年は 7/14(日)
開催予定🎂

コミュニティの活動: メイカー系イベント

  • メイカーフェアやNT等、各種ものつくり系イベントへの出展
    • 多くのイベントはコミュニティメンバー主導
    • 計画的 < ゲリラ的
  • メイカーフェア東京
  • 展示+キット販売
  • メイカーフェア深セン
  • ししかわが皆さんの作品を預かり✈
  • M5StackとNT深センのブースを間借り

【後編】スタックチャンとTypeScript

スタックチャンはTypeScriptで動く

  • スタックチャン本体で動くソースコードはほぼすべてTypeScript
    • 顔の描画
    • 音声合成
    • 対話管理(ChatGPT4やClaude3との通信)
    • モータードライバ
    • 上記機能の初期化や設定処理
  • Disclaimer: TypeScript版スタックチャンは開発途上
    • 世に出ているスタックチャンの8割はArduino(C/C++)、2割がその他(TypeScriptやUIFlow)

背景:こんなロボットを作りたい

  • 手のひらサイズにしたい!
  • シンプルな構成で誰でも作れるようにしたい
  • 色々な場所に連れ出したり、展示したりしたい
  • M5Stack はロボットのお顔としても最適では?

背景:こんなロボットを作りたい

背景:マイコンの世界へようこそ

  • 小型、軽量、低コスト
  • 計算リソースが限られている
  • リアルタイム処理が得意(FreeRTOSなど)
  • ハードウェアプロトコル(GPIO、I2C、SPI ...)を駆使する
製品特性 Raspberry Pi Zero 2 W M5Stack CoreS3
CPUクロック 1GHz (クアッドコア ARM Cortex-A53) 最大240MHz (デュアルコア Xtensa LX7)
メモリ 512MB RAM 512KB SRAM
(外部に8MB PSRAM可能)

背景: Web開発者が組み込みやるときのつらみ

  • 組み込み始めたてのししかわ(SIerのR&DでWeb開発->ロボットベンチャー)
  • C/C++のベストプラクティスと組み込み開発の知識を両方やらないといけなくて大変厳しい

C/C++ 組み込み わかんないよ!!!

  • 「使い慣れた言語で開発がしたい」 「もう環境が来い」
  • Node.jsのパッケージ管理やLint、テストなどのエコシステムを流用できると尚可

要求をおさらい

  • M5Stack(マイコン)に対応させたい
  • JavaScript(TypeScript)で開発したい
    • モーターやセンサを駆動したい
    • グラフィックスやサウンドもほしい
    • Webのエコシステムを活用できれば尚可
  • 外部サービスと連携したい
    • 一方オフラインでも動作させたい

そんな夢のようなプラットフォームが ...

あった

Moddable SDK

moddable

https://moddable.com/

  • 組み込み向けJavaScript開発プラットフォーム
    • JSエンジン「xs」
    • xsの上で動作するモジュール群
    • コンパイラやデバッガなどの開発ツール
  • OSS (混合ライセンス)

環境構築

npx xs-dev setup
npx xs-dev setup --device esp32
  • 関連ツールが$HOME/.local/share/にインストールされる
    • 合計2GBくらいあるので注意

Moddable SDKの特徴

  • マイコン上でJavaScriptエンジンが動作する「スタンドアロン型」
  • 最新のJavaScript(ECMAScript)に準拠
  • 標準化された組み込み向けJavaScript API「Ecma-419」
    • TypeScriptに対応
  • マルチデバイス対応
    • M5StackシリーズやRaspberry Pi Picoなどで動作

極小JavaScriptエンジン「XS」

  • ModdableのコアとなるJavaScriptエンジン
  • EcmaScriptの最新仕様に準拠
    • test262の言語機能セクションの 99.41% をパスしている

フル機能のJavaScript(TypeScript)がスタンドアロンで動作する

type CounterProps = {
  tick?: number;
}
class Counter {
  // プライベートフィールドと初期化子
  #tick: number;
  #count: number = 0;
  constructor(option: CounterProps = {}) {
    // オプショナルチェインとNull合体演算子
    this.#tick = option?.tick ?? 1
  }
  // getter/setter
  get count() {
    return this.#count
  }
  increment() {
    this.#count += this.#tick
  }
  decrement() {
    this.#count -= this.#tick
  }
}

Ecma-419

https://419.ecma-international.org/

  • 組み込みシステム向けAPIの仕様
    • ハードウェア
    • ネットワーク
  • ModdableでJS + 型定義の形で実装されている

Ecma-419: ハードウェア

  • ハードウェアプロトコル
    • Digital/Analog
    • PWM
    • SPI
    • I2C
    • Serial
  • ドライバ
    • Sensor
    • Display
    • RTC(Real Time Clock)

例(examples/io/digitalより)

const Digital = device.io.Digital;
const led = new Digital({
   pin: device.pin.led,
   mode: Digital.Output,
});
led.write(1);

let state = 0;
System.setInterval(() => {
	led.write(state);
	state ^= 1;
}, 200);

Ecma-419: ネットワーク

  • ネットワークインタフェース (WiFi & Ethernet)
  • TCP/UDP
  • DNS
  • HTTP
  • MQTT
  • WebSocket

例(examples/io/tcp/fetchより)

import { fetch, Headers } from "fetch";
import { URLSearchParams } from "url";

const headers = new Headers([
	['Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8'],
	["Date", Date()],
	["User-Agent", "ecma-419 test"]
]);
const body = new URLSearchParams([
	["Date", Date()],
	["Input", "This is no input!"]
]);

fetch("http://httpbin.org/post", { method:"POST", headers, body })
.then(response => {
	trace(`\n${response.url} ${response.status} ${response.statusText}\n\n`);
	response.headers.forEach((value, key) => trace(`${key}: ${value}\n`));
	trace("\n");
	return response.json();
})
.then(json => {
	trace(JSON.stringify(json, null, "\t"));
	trace("\n");
});

標準化していると何が嬉しいの?

  • オープンな場所(TC53)で議論された、安定したAPI
  • Moddable以外の「組み込み向けJavaScriptプラットフォーム」との相互運用性(が生まれるといいな〜〜チラッチラッ)

マルチデバイス対応

  • M5Stackの様々なデバイスに対応
    • M5Atom
    • M5StickC
    • M5Stack
    • M5Stack Core2
    • M5Stack CoreS3

スタックチャン ♡ Moddable SDK

スタックチャン ♡ Moddable SDK

  • TypeScript
  • Moddableの組み込み機能
    • グラフィックス
    • サウンド
  • 性能とのトレードオフ
  • Webのエコシステム

各機能モジュールの型定義を用意

/**
 * The Driver for the actuator
 */
export type Driver = {
  applyRotation: (ori: Rotation, time?: number) => Promise<void>
  getRotation: () => Promise<Maybe<Rotation>>
  setTorque: (torque: boolean) => Promise<void>
  onAttached?: () => void
  onDetached?: () => void
}

/**
 * The text-to-speech engine
 */
export type TTS = {
  stream: (text: string) => Promise<void>
  onPlayed: (volume: number) => void
  onDone: () => void
}

/**
 * The display renderer
 */
export type Renderer = {
  update: (interval: number, faceContext: Readonly<FaceContext>) => void
  addDecorator(decorator: FaceDecorator): void
  removeDecorator(decorator: FaceDecorator): void
}

効用①:複数の実装が型安全に書ける

{
    "config": {
        "tts": {
            "type": "voicevox"
        },
        "driver": {
            "type": "dynamixel"
        }
    }
}

設定で実装を切り替え

効用②:mod(ユーザアプリケーション)が型安全に書ける

さらに:Pull Requestももらえた🚀



スタックチャン ♡ Moddable SDK

  • TypeScript
  • Moddableの組み込み機能
    • グラフィックス
    • サウンド
  • 性能とのトレードオフ
  • Webのエコシステム

グラフィックス

  • UIフレームワーク「piu」「commodetto」が同梱
  • モダンなUI構築のための機能が全部入り
    • 文字/画像
    • アウトライン描画
    • タッチ入力
    • アニメーション/トランジション
    • レスポンシブ
    • コンポーネント指向
ドラッグ&ドロップ
トランジション
スクロール
国際化

アウトライン描画!

サウンド

  • 音声も機能が充実
    • オーディオ入力/出力
    • ストリーミング再生
    • 音声合成クライアント

スタックチャン ♡ Moddable SDK

  • TypeScript
  • Moddableの組み込み機能
    • グラフィックス
    • サウンド
  • 性能とのトレードオフ
  • Webのエコシステム

性能とのトレードオフ

  • Moddableは省メモリ指向
    • xsエンジンのペナルティ
    • Moddableのモジュールは実行速度よりメモリ効率を重視
      • 細かい話だとMapの内部実装がHashMapじゃなくてListなのでランダムアクセスがO(n)
  • デバッガでプロファイリングが可能
  • 性能が求められる箇所は Cで実装し、JavaScriptのコードから利用できる
    • もちろんこのような関数に対しても型定義が用意されているし、自作も可能

スタックチャン ♡ Moddable SDK

  • TypeScript
  • Moddableの組み込み機能
    • グラフィックス
    • サウンド
  • 性能とのトレードオフ
  • Webのエコシステム

Webのエコシステムとの親和性

  • ✅TypeScript
  • ✅Linter/Formatter
  • ⬜テスト: IOをモックした単体テストを導入予定
  • その他
    • ⬜npm
    • ✅Wasm
    • ⬜Node-RED

npm

  • Moddableのパッケージ管理ツール mcpack 経由で利用可能
  • ただし既存のパッケージは動作しないものが多い
    • ブラウザ/Node.jsの機能を使っている
    • 性能的な制約

Wasm

  • Wasmビルド -> ブラウザ上で画面をプレビュー

Node-RED

  • スタックチャン × ビジュアルプログラミングの可能性
  • Blockyも使える

まとめ:スタックチャンとModdable(TypeScript)が出会ったら

  • 操作性/学習性(Usability)↑↑↑
    • Web開発者がマイコンで動くアプリを開発できる
    • TypeScriptの恩恵でチーム開発も捗る
  • 相互運用性↑↑
    • 標準化されたAPI
    • M5Stackなど様々なマイコンに対応
    • PCでデバッグ
  • 性能効率(Performance Efficiency)↓
    • C APIで補う
  • ワクワク感↑↑↑
    • Webのエコシステムと接続して広がる可能性!

📣宣伝

🇯🇵Moddable日本語訳プロジェクト

  • Moddableの130以上あるマークダウン文書を日本語訳しよう!
  • OSSコントリビュートのチャンス!
  • Moddableの機能群や内部実装に詳しくなれる!

https://github.com/Moddable-OpenSource/moddable-jp

コミュニティに参加しよう!

参考

はじめまして!これはスタックチャンです。 スタックチャンはオープンソースで手乗りサイズのカワイイロボットです。 キャッチフレーズは「コミュニケーションロボットを、あなたの手に。 Stack-chanの名前の由来は、IoT開発モジュールのM5Stackに、日本語で小さい子供を呼ぶときの敬称である「ちゃん」を足したものです。 親しみをこめて半角カナで表現しています。

スタックチャンはコミュニケーションロボットの基本的な機能を提供していて、 これらの機能をベースにユーザ自身が自分でアプリケーションを構築していけます。

※厳密にいうと回路や外装のデザインには著作権無いらしいが、製作者のオープンなスタンスを示すために付けている

ラズパイなどのシングルボードコンピュータに比べて非常に小型で、その分計算リソースが限られています。 LinuxのようなOSを搭載せずFreeRTOSなどのリアルタイムOSを搭載します。

最新のJavaScript(ECMAScript)に対応している:ModdableのJavaScriptエンジン「xs」は最新のECMAScriptに対応しています。つまりM5Stackの中でフル機能のJavaScriptが使えます。const、letやオブジェクトの分割代入、async、awaitまで揃っています。もしWebと連携する何かをM5Stackで作りたいなら、サーバ側のコードも、M5StackのコードもすべてJavaScriptで統一することだって可能です。

ちなみに、家電の操作画面に採用された(洗濯機、マッサージガン、カメラ)

余談だがC言語による小さいJavaScriptエンジンの実装として参考になる。内部実装に関するドキュメントも充実している。

ここで会場どよめく

- 基本機能の「ホスト」の上にユーザアプリケーションの「mod」を使ってもらう - マイクラとかPCゲームをする人には馴染み深い単語。ユーザが定義できる拡張機能。 - 音声合成、対話管理などの機能モジュールごとにインタフェースを定義して実装。設定ファイルで置き換え可能にしてある

趣味のものつくり界隈だとそもそもgitでのコード管理も根付いていない場合が多く、コードの寄贈を受けるのが難しかった。 GitHubの使い方やOSSの振る舞いを心得ているWeb開発者を開発に引き込める点で効果を実感している。

その他 - アップデート容易性↑ - セキュリティ↑