ｽﾀｯｸﾁｬﾝの顔色を変えてみる

# この記事は何?
Moddable版ｽﾀｯｸﾁｬﾝのサンプルアプリケーションでｽﾀｯｸﾁｬﾝの顔色を変更することができました。

https://x.com/juraruming/status/1844846007403913306

背景とソフトウェアの変更点について記録を残しておきます。

この記事の対応をしているGitHubリポジトリはこちらです。

https://github.com/grace2riku/stack-chan/tree/dev


# 私のｽﾀｯｸﾁｬﾝ
私が購入したｽﾀｯｸﾁｬﾝを紹介します。

https://x.com/juraruming/status/1837834735357513942

ｽﾀｯｸﾁｬﾝ アールティver.の組立キット：RT-Stackchan-DIY-V1を購入し、組み立てました。

https://rt-net.jp/products/rt-stackchan/


# ｽﾀｯｸﾁｬﾝ歴
ｽﾀｯｸﾁｬﾝ アールティver.を購入したのは今年の7月末です。
Moddableで開発をしています。

# 開発環境
私の開発環境です。

* MacBook Retina 12-inch, 2017
* macOS Ventura 13.7.1（22H221）
* プロセッサ: 1.2 GHz デュアルコア Intel Core m3
* SSD 250G
* メモリ: 8GB, LPDDR3

開発環境構築は苦労しました。
Discordコミュニティの方の知見のおかげで何とかｽﾀｯｸﾁｬﾝの顔を見れました。
ありがたや🙏

https://x.com/juraruming/status/1838792470030880817

# 背景
開発環境を構築した後はこちらの記事を試してみました。

https://rt-net.jp/humanoid/archives/5584

**M5StackのMACアドレスをもとにデバイス固有の色を生成する**というｽﾀｯｸﾁｬﾝのオリジナリティを表現できる素敵な取組みです。

私のｽﾀｯｸﾁｬﾝの固有の色は下の写真のような色になりました。

https://x.com/juraruming/status/1842929494971277803

固有の色を設定できただけでも嬉しかったですが、ｽﾀｯｸﾁｬﾝらしい可愛いアクションが欲しいところです。
そこでｽﾀｯｸﾁｬﾝらしい可愛いアクションは出来て、顔色は固有の色にすることにしました。

> ｽﾀｯｸﾁｬﾝ アールティver.のGitHub mainブランチでは左、中央、右ボタンでつぎのアクションを実行します。
> * 左: キョロキョロする
> * 中央: 左→右→下→上→元に戻る、という流れで動く
> * 右: 目・口の色と顔色を反転する

# ソフトウェア変更点
[参考記事](https://rt-net.jp/humanoid/archives/5584)の変更に加え、下記を変更しました。

## 変更点1. デバイス固有の色を顔色に設定する
stack-chan/firmware/stackchan/default-mods/on-robot-created.tsにデバイス固有の色を顔色に設定するコードを追加します。

:::note info
コードは省略しています。
:::

```diff_typescript:firmware/stackchan/default-mods/on-robot-created.ts
import type { StackchanMod } from 'default-mods/mod'
import Timer from 'timer'
import { randomBetween, asyncWait } from 'stackchan-util'
+import { getDeviceSpecificColor } from 'color'

export const onRobotCreated: StackchanMod['onRobotCreated'] = (robot) => {
+  const [r, g, b] = getDeviceSpecificColor()
+  robot.setColor('secondary', r, g, b)
+  trace(`getDeviceSpecificColor() [${r}, ${g}, ${b}]\n`)

  /**
   * Button A ... Look around
   */
  let isFollowing = false
  const targetLoop = () => {
    if (!isFollowing) {
      robot.lookAway()
      return
    }
    const x = randomBetween(0.4, 1.0)
    const y = randomBetween(-0.4, 0.4)
    const z = randomBetween(-0.02, 0.2)
    trace(`looking at: [${x}, ${y}, ${z}]\n`)
    robot.lookAt([x, y, z])
  }
  Timer.repeat(targetLoop, 5000)
  robot.button.a.onChanged = async function () {
    if (this.read()) {
      isFollowing = !isFollowing
      const text = isFollowing ? 'looking' : 'look away'
      robot.showBalloon(text)
      await asyncWait(1000)
      robot.hideBalloon()
    }
  }

  /**
   * Button B ... Test motion
   */
  const testMotion = async () => {
    robot.showBalloon('moving...')
    await robot.driver.setTorque(true)

    for (const rot of [LEFT, RIGHT, DOWN, UP, FORWARD]) {
      robot.driver.applyRotation(rot)
      await asyncWait(1000)
    }

    await robot.driver.setTorque(false)
    robot.hideBalloon()
  }
  let isMoving = false
  robot.button.b.onChanged = async function () {
    if (this.read() && !isMoving) {
      isFollowing = false
      robot.lookAway()
      isMoving = true
      await testMotion()
      isMoving = false
    }
  }

  /**
   * Button C ... Change color
   */
  let flag = false
  robot.button.c.onChanged = function () {
    if (this.read()) {
      trace('pressed B\n')
      if (flag) {
        robot.setColor('primary', 0xff, 0xff, 0xff)
-        robot.setColor('secondary', 0x00, 0x00, 0x00)
+        robot.setColor('secondary', r, g, b)
      } else {
-        robot.setColor('primary', 0x00, 0x00, 0x00)
+        robot.setColor('primary', r, g, b)
        robot.setColor('secondary', 0xff, 0xff, 0xff)
      }
      flag = !flag
    }
  }
}
```

## 変更点2. typingsディレクトリにcolor.d.tsファイルを作成する
javascriptは経験がないですが顔色を変更するくらいだからなんとかなるだろう・・・と思っていました。
ですが私の力では実現できず、コミュニティの方に教えていただきました。

typescriptからjavascriptへの型変換のファイルが必要とのことで追加しました。
firmware/typingsディレクトリ以下にcolor.d.tsを追加しました。

```typescript:firmware/typings/color.d.ts
declare module "color" {
    function getDeviceSpecificColor(): [number,number, number];
}
```

以上の変更でｽﾀｯｸﾁｬﾝらしい可愛いアクションが出来て、顔色は固有の色にすることができました。

https://x.com/juraruming/status/1844846007403913306

# まとめ
まとめです。

* ｽﾀｯｸﾁｬﾝらしい可愛いアクションが出来て、顔色は固有の色にすることができた
* コミュニティの方がいなければできなかった。
* 固有の色を顔色に設定することで自分だけのｽﾀｯｸﾁｬﾝという感じを出せた

私は今回の変更点を加えたコードをベースにｽﾀｯｸﾁｬﾝの開発、機能拡張をしていきたいと思いました。