膝の役割

足郎2には膝ができる。
全体背が高くなることによって、傾き角度はそれほど大きくできなくて、また、大きくする必要もない。膝があるので、後ろに曲げることによって傾かずとも前後のための足上げが実現する。
逆振り子の揺れも小さく済む。
それによって、左右の逆振り子を早く動かしても、勢いがつかない。足郎1では、大きく左右に揺らさなければならないので、早く動かすと勢いのために左右に倒れやすかった。それが少なくなるのが大きい。
すなわち、足郎2は素早い歩行が可能になるのである。ただ実際には、サーボの性能があるので、それほど早くは動かせない。何しろ1個600円のキワモノサーボであるから(笑)ただ、そのサーボで十分満足しているのだが。
そう見ると、固有振動という考え方は正しくないのかもしれないと思う。高くなると、固有振動はゆっくりになるからである。
基本、一方の側に揺れたとき、逆足の膝を曲げる動作を加える。さらに逆に揺れるときにその足を元に戻して伸ばす。これ以外の動作は、すべて足郎1と同じで良いはずだ。それで二足歩行ができる。
足郎1の二足歩行の最終版は、極めて単純な制御で実現できている。したがって、この足郎2もそれ以上の複雑な操作はいらないはずだ。
すでに足郎2の部品は業者の方でも設計が終わり、製作段階になっている。

足郎2シミュレーターの設計

足郎2のシミュレーターを作り始めている。

パーツについてのJAVAのクラスを作り、インスタンス化して、全体を制御して、描画関数の引数に与えるような感じで作ろうとしている。
位置を表すのに座標と角度が用いられる。座標があればある意味全て事足りるのだが、サーボは角度を作るだけなので、角度から座標への変換が必要になる。
座標は、絶対的な座標(初期状態で起立しているときの上板の中心位置を原点とする)と相対座標(上板の中心を座標の原点とした座標)の二つで表せば良い。
各パーツクラスは、それにつながっているバーツとの相対角度を持っている。その角度は、自己を水平として、他者の角度を図にあるような方向で測った角度とする。角度は、すべて座標面に対する傾きである。これらの角度は、全て、前後の角度と左右の角度のペアである。
絶対角度が難しいが、当面は、重心のある足は水平であることを前提にして導き出そう。現実には、重心は、微妙に両足に分散している可能性はあるが、相対的に強く重心が載っている側の足を基準としておく。

逆振り子の固有振動

足郎1の二足歩行動画の最終バージョンにおける逆振り子は、倒れるギリギリまで早くしたものだ。つまり、それ以上早い揺れは、転倒を招く。
逆にそれよりゆっくりとした振り子の動きにすればするほど、ぎこちない動きになり、逆足の吊り上げもうまくいかずに、歩行が面倒になる。
そのギリギリの揺れは、固有振動と考えて良いのではないかと思う。
足郎2は、高さがほぼ倍になる。すると、当然固有振動は遅くなる。早く動かすと倒れやすくなる。ゆっくりとした速さで、しっかりステップを前に出さなければならなくなるだろう。
当面、足郎2のシミュレーターの作成に集中しよう。

モアイ像の歩行と足郎1の逆振り子型の二足歩行

同僚の先生に、足郎1の逆振り子型の二足歩行の動画を見せたところ、これが、モアイ像を揺らして動かしたという説の映像とそっくりだという。

確かに。これだ!!!次の足郎1の歩行と、基本同じではないか!!!

足郎1の逆振り子型の二足歩行は、基本体を揺らして、前後の動きをプラスしているだけである。モアイ像の姿と同じである。左右にいる人々が揺らしている状況を、足郎1の上にあるサーボモータが代わりにやっているだけである。
人間の二足歩行も、極めてエネルギー節約的だが、これもまた、逆振り子型の二足歩行だからなのだ。
足郎2の設計図もほぼできた。部品の発注を二、三日中にはできるだろう。本格的な逆振り子型二足歩行ロボットが創り出されるはずである。

足郎2を構想する

足郎2は、逆振り子型の二足歩行とクラウドを利用した知的会話機能を持たせる。以下はイメージ図だが、サーボモーター類は、3Dプリンタでちゃんとカバーを作る予定だ。
膝がある方が、二足歩行の実現はよほど楽だ。その辺りは、足郎1で実感している。
「ハウルの動く城」の最後の姿に似ている(笑)

サーボモーターを支える板が最も細かい部品なので、それから設計にかかる。
空いた時間に、ロボットのシミュレータを作るつもりだ。サーボモータ類の動きとロボットの動きが視覚的に確認できるものにしたい。

足郎1の開発を終える

足郎1で調べたいことは、ほとんどやり終えたと思う。
これ以上調べても、それは、膝のない、足郎1の特殊な状況での問題だけなような気がするからだ。
膝があり、高さが足郎1のほぼ倍になるはずの、足郎2の設計を始めよう。足郎1で問題だったところを全て解決するような設計にしたい。
アルミの部品は、ほぼ、外注にしようと思う。パーツはそんなに多くない。倍にはならないだろうと思う。
足郎1は、分解して、RaspberryPIや、16個のサーボモーターを再利用する予定だったが、愛着があるので、これはこれで、そのまま残しておこうと思う。ちゃんと動く状態にしておこう。

逆振り子二足歩行3

逆振り子から出発して、歩行を組み込もうとして、ぎこちなくなってまた逆振り子から出発し直すを何度か繰り返して、やはり逆振り子そのものをきちんとやりきることが大切だと思うようになった。

これは、ただ、逆振り子をきちんとしているだけだが、一見二足歩行になってしまっている。しかも、前回の、二足歩行を無理無理入れた感じもない。
これだ!これこそやりたい二足歩行の原型だ!
この間、制御システムAicoをいじった。うえ向きのサーボと下向きのサーボで、引きと緩めるの方向が逆だったのを統一して、常にプラスの値をあたえると引きになるようにしたり、クライアントのJAicoで、エディターのマルチウィンドウを実現したりの改良もやった。

逆振り子型二足歩行2

歩行の形を少し整えた。
足が上がっていないにもかかわらず、歩いているかのような感じになってきている(笑)
これで、折りたためる膝があれば、普通に歩けると思うのだが。
まあ、もう少し、この膝なし足ロボットで試験しよう。

cosmで書いた制御プログラムは次のようなものだ。何か、それらしい感じを読み取ることができるのかもしれない。

#######################################
# ashiro1-10.cosm
# 逆振り子二足歩行
# 2017年7月4日 作成
# 2017年7月6日 ver.2
# 傾けた時に、前後の足を戻す操作を入れる
#######################################
%defspeed normal {
    interval:3
    #steps:25
    steps:15
}
%defspeed fast {
    interval:3
    #steps:25
    steps:10
}
# 40にすると倒れる
%param invpen_angle 35
# 揺れの逆足の開き角度
# 揺れた時に、揺れる方向の逆足が少し開いていないと、
# 近づきすぎて倒れる:逆足の吊り上げ角度にもなっている
# %param open_inv 15
%param open_inv 20
# 釣り上げられた足の閉じる方向への角度
%param close_inv 10
######################################
# 0 バージョンは、前後の足の動きを意識しないもの
# 最初の揺らしに使うと思う
######################################
%defangles right_invpen_0 {
#右に傾ける動きをする
# 逆足は開きを少し大きくしないと縮まって倒れる
    RightUpperRight:$invpen_angle-$open_inv
    RightUpperLeft:-$invpen_angle+$open_inv
    LeftUpperRight:$invpen_angle-$close_inv
    LeftUpperLeft:-$invpen_angle+$close_inv
# 上の動きに合わせて、足も角度をつけて
# 床にぴったりさせようとしているが、ちょっとずれている
    RightLowerRight:$invpen_angle
    RightLowerLeft:-$invpen_angle
    # 逆足は開きを少し大きくしないと縮まって倒れる
    LeftLowerRight:$invpen_angle
    LeftLowerLeft:-$invpen_angle
}
%defangles left_invpen_0 {
#左に傾ける動きをする
# 逆足は開きを少し大きくしないと縮まって倒れる
    RightUpperRight:-$invpen_angle+$close_inv
    RightUpperLeft:$invpen_angle-$close_inv
    LeftUpperRight:-$invpen_angle+$open_inv
    LeftUpperLeft:$invpen_angle-$open_inv
#
    RightLowerRight:-$invpen_angle
    RightLowerLeft:$invpen_angle
    LeftLowerRight:-$invpen_angle
    LeftLowerLeft:$invpen_angle
}
######################################
# 1 バージョンは、前後の足の動きの中で使う
# 前のステップで開いた足を戻す、前後の操作が入る
# 後ろに残っている足は、前足が垂直になるまでに
# さらに追加的に開く
%param excess_open 10
######################################
%defangles right_invpen_1 {
#右に傾ける動きをする
# 逆足は開きを少し大きくしないと縮まって倒れる
    RightUpperRight:$invpen_angle-$open_inv
    RightUpperLeft:-$invpen_angle+$open_inv
    LeftUpperRight:$invpen_angle
    LeftUpperLeft:-$invpen_angle
# 上の動きに合わせて、足も角度をつけて
# 床にぴったりさせようとしているが、ちょっとずれている
    RightLowerRight:$invpen_angle
    RightLowerLeft:-$invpen_angle
    # 逆足は開きを少し大きくしないと縮まって倒れる
    LeftLowerRight:$invpen_angle
    LeftLowerLeft:-$invpen_angle
# 前後に開いた足の処理
# 右足が前、左足が後ろの状態で開いている
# 前になっている右足を、直立状態まで戻す
# 後ろ足は、床に設置したまま、傾きを加える
#
    RightUpperFront:0
    RightUpperBack:0
    LeftUpperFront:-$step_length-$excess_open
    LeftUpperBack:$step_length+$excess_open
#
    RightLowerFront:0
    RightLowerBack:0
    LeftLowerFront:-$step_length-$excess_open
    LeftLowerBack:$step_length+$excess_open
}
%defangles left_invpen_1 {
#左に傾ける動きをする
# 逆足は開きを少し大きくしないと縮まって倒れる
    RightUpperRight:-$invpen_angle
    RightUpperLeft:$invpen_angle
    LeftUpperRight:-$invpen_angle+$open_inv
    LeftUpperLeft:$invpen_angle-$open_inv
#
    RightLowerRight:-$invpen_angle
    RightLowerLeft:$invpen_angle
    LeftLowerRight:-$invpen_angle
    LeftLowerLeft:$invpen_angle
#
    RightUpperFront:$step_length+$excess_open
    RightUpperBack:-$step_length-$excess_open
    LeftUpperFront:0
    LeftUpperBack:0
#
    RightLowerFront:$step_length+$excess_open
    RightLowerBack:-$step_length-$excess_open
    LeftLowerFront:0
    LeftLowerBack:0
}
######################################
# 前後に開く(すでに重心が移ったのちの動作)
# 歩幅
%param  step_length 15
# 出した方の足が着地する時に、後ろに倒れないよう
# 少し前かがみ加減の角度で足先を出す
%param  slouch 10
######################################
%defangles right_forward_1 {
# 右に傾いた時に、左足を前に、右足を後ろにする動作
    RightUpperFront:$step_length
    RightUpperBack:-$step_length
    LeftUpperFront:-$step_length
    LeftUpperBack:$step_length
#
    RightLowerFront:$step_length
    RightLowerBack:-$step_length
    LeftLowerFront:-$step_length+$slouch
    LeftLowerBack:$step_length-$slouch
}
%defangles left_forward_1 {
# 左に傾いた時に、右足を前に、左足を後ろにする動作
    RightUpperFront:-$step_length
    RightUpperBack:$step_length
    LeftUpperFront:$step_length
    LeftUpperBack:-$step_length
#
    RightLowerFront:-$step_length+$slouch
    RightLowerBack:$step_length-$slouch
    LeftLowerFront:$step_length
    LeftLowerBack:-$step_length
}
%defexec walk {
    stand:all
    speed:normal
    # 右に倒す、前後の動作は何もしない
    # 半分の動きしかできず、揺れが小さいので
    setAngle:right_invpen_0
    # 揺れは早く動かす
    # 左に倒す
    speed:fast
    setAngle:left_invpen_0
    # 足を開く
    # 開くときは、normalにする
    speed:normal
    setAngle:left_forward_1
    # 普通の歩行に移る
    exec:walk_sub,3
}
%defexec walk_sub{
    # 逆の動きに対応するバージョン
    # 右に倒す
    speed:fast
    setAngle:right_invpen_1
    # 足を開く
    speed:normal
    setAngle:right_forward_1
    # 左に倒す
    speed:fast
    setAngle:left_invpen_1
    # 足を開く
    speed:normal
    setAngle:left_forward_1
}
%exec walk 1