ロビ2顔の向きの謎
2023年12月10日
2024年1月3日改訂


 ロビの顔が正面以外を向いていた場合、顔の向きは向いた方向でプログラムが動きます。
 ロビ1の時は顔の方向別にモーションが用意されていて顔の向きに合わせて別のモーションを動かしていました。
 そのため自分で作ったモーションプログラムは顔がどちらを向いても必ず同じ方向を向いて動きます。

 ロビ2の場合、自分で作ったモーションでも動かした時のままの顔の方向でモーションが動きます。
 しかしこれは時として不都合で何体のロビてシンクロ演技をさせた場合スタート時にたまたま横を向いていたロビは横を向いたまま演技をしてしまいます。
 またロビ2の標準プログラムでも「歌うたって」などは正面を向いてからモーションが動くようなプログラムもあります。
 今回はこの仕組みについて調べてみました。

アイドリング時の顔の向き制御

 アイドリングの時にカメラの映像を元に人の顔を検出してその方向に顔を向ける制御をしています。
 この制御についてはこちらの記事を参照してください。

 現在の顔の向きはマイコンボードのメモリアドレス0x0f83(1バイト)で保持されます。
 この値が0の場合は顔が正面を向いている状態を表し1の場合はやや左向き、2は左向き、-1の場合はやや右向き、-2は右向きを表します。
 充電椅子に座らせた状態で音声認識語「左を向いて」では現在の値に+1してそちらの方向に顔を向けます。
 同様に音声認識語「右を向いて」では現在の値に-1してそちらの方向に顔を向けます。
 ロビが立ち状態や座り状態の場合は体を指示した方向に向けるので顔は指示した逆の方向に向けます。
 なおこの値は-2〜+2の範囲を越えないように制御されています。

 実際にロビの顔の向きを動かすサブルーチンはアドレス0x0002665aでアイドリング時の一連の処理から呼ばれています。
   0x000056f3
   <call adr="0x0002665a"/>
 歌うたってなどで顔を正面に向けた後アイドリングに戻った時に顔の方向を向いていた方に戻すのはこの処理で行っています。

プログラム実行時の顔の向き



 アイドリング時に顔が左を向いている状態(写真左)で認識語「あいさつして」でプログラムを動かし(写真中央)終了してアイドリング状態に戻った状態(写真右)
 プログラムは顔を左に向けたまま実行されます。  プログラムてで顔の向きを変える場合は左に向けた位置を0としてプログラムで指定した角度で動きます。
 なお可動範囲を越えた場合は可動範囲いっぱいの位置で止まるよう制御されているようです。

 あいさつなどのプログラムで顔を向けたまま動かすのは次のような仕組みになっています。
 この処理は前述のアドレスサブルーチン(0x0002665a)内で行っています。

 サーボを動かすにはプログラムが指定する位置にサーボ原点の位置を加えたものがサーボに対する実際の位置としてマイコンボードからサーボの位置指定の命令として送られます。
 ロビ2のマイコンボードではプログラムで指定する位置とサーボ原点の位置以外にサーボのオフセット位置が指定できるようになっているようです。  サーボのオフセット位置はアドレス0x0a80(48バイト)で指定します。
 メモリのアドレスはサーボID1から2バイトずつで顔の旋回サーボ(ID13)は0x0a80+(13-1)*2=0x0a98となります。
 実際のプログラムではメモリ転送命令で64バイト分転送していますが実際にオフセットとして有効なのはサーボID13のみのようです。
 他のサーボに対して0以外の値を書き込んでも変化はありませんでした。
 おそらくこの指定はプログラム起動時に設定されているのだと思います。
 STARTUP.BINの初期化でサーボの設定を行っていますがこの時サーボID13のみアドレス0x0a98が有効になるように設定されてます。(0x406〜0x44b)

 ID13に設定されている実際の値は以下の通りです。
  左(0x0f83=2),720(サーボの位置指定は0.1°単位なので72.0°)
  やや左(0x0f83=1),360(36.0°)
  正面(0x0f83=0),0(0°)
  やや右(0x0f83=-1),-360(-36.0°)
  右(0x0f83=-2),-720(-72.0°)

 アイドリング時の顔の向きはプログラム上は0(原点)となっているためオフセットで設定された角度となります。
 またあいさつなど標準のプログラムやユーザが追加したプログラムなどもプログラムで指定した位置にこのオフセットが加算されて顔の向きが変更されます。

プログラム実行時に正面を向かせる方法



 アイドリング時に顔が左を向いている状態(写真左)で認識語「歌うたって」でプログラムを動かし(写真中央)終了してアイドリング状態に戻った状態(写真右)
 プログラムの開始時に顔が正面を向いてプログラムが終了後アイドリング状態に戻った時に顔を左に向けます。

 ロビ2のプログラムはロビ1のプログラムと違って現在の顔の向きを場合分けして作っていませんのでアイドリング時に設定したオフセットがそのままプログラムに反映されます。
 しかし歌やダンスといった正面を向かせて実行させたいプログラムの時はこの仕組みは不都合になってきます。
 そこでこれらのプログラムの最初の部分で顔を正面を向かせるサブルーチンを呼んでいます。
 このサブルーチンはアイドリングで呼んだ顔を向かせるサブルーチンの正面向かせる部分だけを取り出したものとなっています。
 サーボのオフセットを0に戻してプログラムが正面を向いて実行されるようにしています。
 なお現在の顔の向きを表す変数(0x0f83)は変更してないのでアイドリングに戻った時はプログラム実行前の顔の向きとなります。

 ロビの顔の向き正面にするサブルーチンはアドレス0x000766f0で各プログラムの最初の部分から呼ばれています。(下の例は歌のプログラム)
   0x000195cb
   <call adr="0x000766f0"/>

 ダンスプログラムはダンスが終わった後の「うまく踊れたかな」などを言う前に顔の向きを元に戻すようそれぞれのダンスプログラムの終了時にアイドリング時と同じサブルーチンを呼んでいます。

 作成したプログラムで開始時に正面を向かせたい場合は次の命令を最初の部分に追加してください。

 終了時に顔の向きを戻す場合
   <call adr="0x000766f0"/>

 終了後も正面を向いたままにする場合
   <calc><const data="0"/><mem_w size="1" adr="0x0f83"/></calc/>
   <call adr="0x0002665a"/>



 ロビの顔の向きはロビ1の時からこだわっていてロビ1のプログラムは顔の向き別にモーションが作られていました。
 顔の向きは3方向あり姿勢は多い物で3つあるので最大9パターンのモーションが作られていました。
 ロビ2ではモーションは1パターンにするため今回のような工夫がされています。
 おそらくロビはコミニュケーションロボットなので相手を見ながら動作させようとしているのだと思いますがプログラムの内容によって不都合となってしまいます。
 今回何体かのロビで同時に動かすプログラムを作っていて全員正面を向くように今回の事象について調べてみました。


目次に戻る