呼吸したり、暴れたりする評価人形たち
1. まずは構想
ロボット幼児人形の要件概要としては
「頭手足が動いて、疑似呼吸し、その動きの設定できてネットワークで経由で操作できること。」
ということなので、まずは構想から考えてみる。
「幼児人形」なので駆動系をふんだんに用いるスペースもないが、ある程度トルクのあるサーボモータが必要。(できたあとから考えるとちょっとトルクが大きすぎた感はありました。)
その人形の中にネットワーク接続できる制御ボートというこなので、「ラズパイ系」がよさそうです。ラズパイといってもラズパイ3などは基板が大きすぎて入らないので「ラズパイゼロ」を選定。バッテリはラジコン系のものを使用しました。
ベースとなる人形なのですが、実際に幼児サイズになべくサイズを合わせる必要があります。
世の中には「おもちゃ」としてこのような人形はいっぱいありますが、もともと子供向けということもあり、リアルな幼児より一回り小さいものもあります。
また、今回ロボット化するにあたり、どのように駆動部を中に設置するかということ課題になりそうです。
そのような理由からなるべく柔らか素材のものでサイズがリアル幼児に近いものを探し☜にあるものがよさそうでした。
2. 機構部案
①人形の真正面と真横の写真と撮って、それを3D CADに読み込ませて大まかに内容物のサイズをつかみ、フレームの設置します。
②そのフレームに沿って駆動する軸を中心にサーボモータの配置を行います。
③ここで呼吸動作は回転ではなく上下運動する必要があるので、ピストンリンク機構を用いて回転運動から上下方向への動作に変換します。ただ、この上下運動への変換がうまくいくのかどうかということは最初この時点ではまったくわからないのです、これまでの経験と勘を生かしてうまくいくはずだと信じて邁進するしかありませんでした。
ラズパイゼロ(ver2ではない初期型)ではコアプロセッサがBCM2835(single core ARM1176JZF-S(ARMv6)SoC)であるためそれほどパフォーマンスは高くなく、OSが起動するまでに1分くらいかかってしまう。
そうなるといつ起動したのかもわからないので不安になる。そこで制御基板内部の状態がわかるようにLEDを2個設置することにしたのだが、体につけると衣服で見えなくなりるので違和感なくわかるところという意味で人形の目にLEDを忍ばせた。なんか一部の人には怖がられたけど、いたって自然に見えませんか!?
3. 制御部
3.1 システム構成
ラズパイは直接サーボモータをドライブすることができないので、LEDドライブようのPWMコントローラ(PCA9685PW)を使用することにする。これであればI2C IF経由で制御でき、12chまでのPWM出力することができる。
3.2 制御基板
PWMデバイス(PCA9685PW)や外部からの電源を供給したり動作モードを設定したるするIF基板が必要なので、以下のような回路で、基板サイズとしてはライズパイゼロとほぼ同じにして省スペース化をする。実はこの基板はいろいろあって3回ほど設計し直している。これは基本的な回路。
3.2 S/W構成
テキストスクリプトファイルを用意して置き10msec周期で各モーターの角度を制御できるようにするのが基本的な考え方。
3.3 PCA9685制御
これはサーボモータに制御するための信号PPM(Puls Position Moduration)を生成するデバイス。本来はLEDの調光に用いられるもので12chのPWMの信号が出力できるというなかなか便利なもの。12bitのタイミグ分解能があるので細かい制御もできそうです。
I2Cのデバイスアドレスは0x40(7bit表記)
実際に使用するServoMotor:S9470SVでは上記のPWM時間で制御できる限界値は下限値で0.85msec、上限値は2.15msecだった。
これを1.5msecを中央値角度(0°)とした場合、0.85msecは-65°、2.15msecは65°の角度が制御範囲となる。回転方向はプラス時間が時計回り方向となる。
分解能(1LSBあたり)= 0.00244141msec
角度(度) | PCA9685設定データ | パルス幅(msec) |
---|---|---|
0 | 350 | 0.85 |
65 | 618 | 1.5 (※中央位置) |
130 | 885 | 2.15 |
/* PCA9685の初期化は内容 */ void servo_init(void) { int16_t i; uint8_t w_buffer[4] = { 0x40, 0x00, 0x00, 0x00 }; uint8_t r_buffer[4] = { 0x00, 0x00, 0x00, 0x00 }; // いったんスタンバイにする(プリスケーラ設定のため) w_buffer[1] = 0x00; // MODE1 register w_buffer[2] = 0x31; // stanby mode exp_write_ex(EXP_DID_I2C0, w_buffer, 3, r_buffer, 0, 0); // プリスケーラ設定。分解能2.4us、周期10ms(周波数100Hz)!!デバイスごとに調整!! w_buffer[1] = 0xfe; // Pre scaler register w_buffer[2] = 60; // period = 10msec(frequency:100Hz) time resolution = 2.4usec exp_write_ex(EXP_DID_I2C0, w_buffer, 3, r_buffer, 0, 0); // MODE1設定 レジスタインクリメント、All-Call有効、アクティブ w_buffer[1] = 0x00; // MODE1 register w_buffer[2] = 0x21; // auto register increment, AEnable All-Call exp_write_ex(EXP_DID_I2C0, w_buffer, 3, r_buffer, 0, 0); // MODE2設定 トーテムポール出力設定 w_buffer[1] = 0x01; // MODE2 register w_buffer[2] = 0x04; // out drive is a totem pole structure. exp_write_ex(EXP_DID_I2C0, w_buffer, 3, r_buffer, 0, 0); // パルス初期値書き込み(1500us) w_buffer[1] = 0x06; // set PWM width start address for (i = 0; i < 6; i++) { w_buffer[2] = 0x00; w_buffer[3] = 0x00; exp_write_ex(EXP_DID_I2C0, w_buffer, 4, r_buffer, 0, 0); w_buffer[1] += 2; w_buffer[2] = 625 & 0xff; w_buffer[3] = 625 >> 8; exp_write_ex(EXP_DID_I2C0, w_buffer, 4, r_buffer, 0, 0); w_buffer[1] += 2; } }
4. 機構設計
5. 課題と対策
運用しているといろいろ課題も出てくる。そのうち大きな課題を2つあったので紹介。
5.1 サーボモータが固定されてしまう問題
当初使用したサーボモータはServoMotor:S9470SVでこれは制御パルス(PPM)を入力しないとモーターがフリー、つまり、電源OFFの状態となりそこから力が加わると多少回転は重いものの、制御が働いて固着することはなかった。
一方、人形を少し増産することになり、サーボモータに別のものを使うとPPMが入力されなくても電源がはいっている状態では最終制御したポジションで固まってしまう動作になった。
この辺の動作仕様はおそらく規定されていないものだと思う。使用する側としたら制御信号(PPM)が入力されないのであればモーターはフリーになるのが評価上望ましい。これに対しては周辺回路で対策することにした。
5.2 回路が昇天したり、ギアが壊れる問題
サーボモータのトルクを上げて壊れにくくしたき、通常動作運転には支障はなかったのだが、人形の手足が運用時時々何かに引っかかってサーボモータの負荷が大きくなこともあった。「負荷が大きくなる」=「回路に流れる電流が大きくなる」という関係から制御基板上おヒューズが切れたり、モータ内部のスイッチFETやギアBOXが破損(破壊)してしまう現象も発生した。
何か引っかかったときにある程度サーボモータのトルクがあれば解決すると思ったら大間違い!
何か外部の機械的負荷が高くなるとそれを支持された位置ポジションにFB(フィードバック)すらうため過大電流が流れることがあり。その時、何かが壊れます!(人形の過労死問題)
上記に示す回路は手足など回転負荷がかかりそうな部位に対してあらかじめ電流制限をかけて、無理に回転させないようする。電流リミット設定はDC値であるため、本来であればマイコンのDACが必要だがラズパイゼロでそんな気の利いたものはない。したがって、今回はPCA9685のPWM信号を平滑化してDC電位にすることでDACとして使用する。そのため一部F/Wの変更も必要。なんだかんだと言いながら回路規模が大きくなってきたため、今回から4層基板となった。
6. 三歳児製作編
次に幼児が成長して、三歳児を作ってみることにする。
素晴らしいですね。でも、怖いです。
いろいろ今後も書き溜めたネタをボチボチアップしていきます!