逆振り子二足歩行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

逆振り子型二足歩行

ネタロボット試作機足郎1に、以前二足歩行させてみた。
http://robo.genv.sophia.ac.jp/wp_robot/?p=1330
が、これは、もともと考えていた歩行とは違っていた。しかも、この方法では、このような足だけのロボットは早い動きができない。
そこで、最初からの計画に従って、逆振り子の中で歩行する方法を地道に追求しようと思っている。
ロボットの体を左右に揺らせる、これは結構早くできる。

この揺れの中に、前後の足の動作を組み込んでみた。

動かすサーボが倍になったので、揺れが遅くなって足が上がっていない。
しかし、早く歩行ができそうな気がしている。

リモートコントローラー JAico

基本、ロボット足郎のRaspberryPIにsshでログインして、ロボットを制御していたが、cosmで書かれた制御プログラムを、パソコンで編集して、それを足郎に転送して、とかいう作業が面倒になった。
そこで、パソコンから足郎のRaspberryPIで動かしている制御ソフトAicoを制御した方が楽だと思って、Aicoにサーバー機能を持たせ、それに接続するパソコン上のクライアントJAicoをJAVAで作成した。面倒なことを言ったようだが、ロボットにsshしても制御できるし、パソコンからも直接制御できるようにしたということだ。
Aicoの主要な機能をJAicoからもできるようになった。
さらに、パソコンからの制御の大きなメリットは、JAVAのグラフィックインターフェイスを使えることだ。そのうち、センサーの動きもパソコン側にグラフィカルに表示させることができるようになるだろう。
この過程で、JAVAのソケット機能でサーバー、クライアントをプログラミングしたが、もう、なんどもなんども、この辺りのプログラムは書いてきたのに、色々、詰まった。例えば、サーバーがデータを送ったのか、まだバッファリングしているのかがわからずに、tcpdumpでパケットの送付状況を確認するようなことも、久しぶりにやった。しかし、まあ、無事動いてよかった。

片足立ちさせてみる

ディープラーニングだとかセンサーのことばっかりやっていたが、久しぶりにサーボを制御しようとした。
すると、コントロールソフトAicoをJAVAにしてから、まともにサーボの制御をしていなかったのに気づいた。そのために、制御プログラムのCOSM言語がJAVAのAicoでうまく動かないのに気づいた。いろいろ直した。
それに伴ってAicoもCosmも相当改訂した。
さしあたって、ロボットに片足立ちさせて見た。

どうってことでもない。一応、ちゃんと片足で立っている(左足の隙間!!、笑)。
この動きの間、センサーとサーボ角度を全て記録するようにモニターさせた。Cosmのプログラムで制御できる。モニターは、サーボの制御とは別スレッドで動かしている。それを実現するために、I2Cの1チャンネルはサーボだけに割り当てた。センサーは、全てSPIにぶら下げている。

よくみると、正常に動いていないセンサーがある。おい、どうなっているの。
モニターの結果として、うまくいった場合の評点を与えるようにしている。それを通して、倒れてしまうようなまずい状態と、そうでない状態の識別、サーボのコントロールの仕方を強化学習、深層学習をさせようと思っているのに!!
それと、倒れても壊れないように、部屋に太めの鉄線を渡して、そこにぶら下がるようにした。
Cosmのプログラムは以下の通りだが、使っていないスピードやサーボ角度の定義も入っている。
#######################################
# ashiro1-9.cosm
# 2017年6月29日
# 再び1から作り直す
#######################################
%param foot_rest 25 # 足関節の緩和角度
%param null_angle 0 # ゼロ角度
%defspeed slow {
interval:10
steps:40
}
%defspeed normal {
interval:5
steps:40
}
%defspeed fast {
interval:3
steps:10
}
# 右へ
%defangles leg_stand {
RightUpperRight:$null_angle
RightUpperLeft:$null_angle
LeftUpperRight:$null_angle
LeftUpperLeft:$null_angle
}
%defangles foot_rest {
RightLowerRight:-$foot_rest
RightLowerLeft:-$foot_rest
LeftLowerRight:-$foot_rest
LeftLowerLeft:-$foot_rest
# 前後はさしあたってゼロにしておく
RightLowerFront:$null_angle
RightLowerBack:$null_angle
LeftLowerFront:$null_angle
LeftLowerBack:$null_angle
}
%defangles right_leg_phase_1 {
# これだけ完全休息から少し戻しておく
RightLowerRight:28
RightLowerLeft:-28
#
RightUpperRight:28
RightUpperLeft:-28
LeftUpperRight:20
LeftUpperLeft:-20
}
%defangles right_leg_phase_2 {
RightLowerRight:45
RightLowerLeft:-45
RightUpperRight:-5
RightUpperLeft:5
LeftUpperRight:23
LeftUpperLeft:-23
}
%defexec walk1 {
monitor:start
##
stand:all
speed:normal
# ゆっくり右に倒す
setAngle:right_leg_phase_1
delay:500
# ゆっくりと重心のない足を上げる
speed:slow
setAngle:right_leg_phase_2
##
monitor:stop
# この行動に評価を与える
rating:set
}
#以上は全て定義
#以下が、定義以外の実行コマンド
%exec walk1 1

Aicoの使い方(備忘録)

色々回り道をしていると、記録していないことは忘れてしまう。足郎のコントロールシステムであるAicoの基本的な使い方を忘れないように記録しておこう。現時点のバージョン(ver.3)のものである。使ってない人には、訳がわからないと思うが、備忘録なので無視願います。
1。起動
java -jar Aico.jar
2。起動オプション
(1)ハイフンなしで 二つの数字を空白を挟んで並べると、サーボ番号とその角度とみなされ、即実行される。
(2)-com の後に  XXXX.cosmというファイルを指定すると、そのファイルは、制御言語cosmで書かれているとみなされて、記載されているプログラムを即実行する
(3)-stand | -relax | -rest のいずれかの後に、サーボグループを指定すると、それらのグループのサーボを起立:緩和:休息の状態にする。グループとしては、all, left, right, leftUpper, leftLower, rightUpper, rightLower が、指定できる。
(4)-help は使い方の表示
3。コマンドモード
起動オプションを何も指定しない場合、および、起動オプションで指定した動作を終了すると自動的にコマンド解釈モードに入る。
aico >>
というプロンプトが表示され、コマンドを受け付ける。
(1)quit, exit, bye のいずれかが入力されるとAicoを終了する
(2)readの後にcosmのプログラムファイル名(パス)を記載するとそれを読み込む。実行はしない。指定されたプログラムがないと、src/resourcesのフォルダいかにあるかどうかもチェックする。
(3)exec コマンド(単に'e' 一文字でもいい)で、読み込まれたプログラムを実行する。その際、exec allで全てを実行し、 exec xxx:yyy&sss:ttt ・・・で、読み込まれたプログラムの個々のコマンドを実行する。引数部分は、%defexec 内に記載する個別コマンドのフォーマットで記載し、複数のコマンドを実行する場合は'&'でつなげる
(4)chparam(cpでも良い)で、読み込まれたプログラムのパラメータの値を変更できる。
chparam expara1:30&expara2:35 のような感じで指定する。expara1,expara2はパラメータ名の例。
(5)chspeed (csでも良い)で、読み込まれたプログラムの実行速度の定義を変更できる。chspeed interval:2&steps:30 のような感じで指定する。必ず、intervalかsteps、あるいは両方指定される必要がある。
(6)angle (aのみでも良い)個別サーボの角度を与える。angle 4 30 のような感じで指定する。この場合、サーボ番号4を角度30に設定する。
(7)inertia 左右、または、前後に関わるサーボだけを弛緩させる inertia rightleft,30 左右の動きに関わるサーボ群の30度弛緩、rightleft の代わりにfrontbackで、前後のサーボの弛緩。
(8)起動オプション(3)と同じことができる。ただし、'-'はいらない。
(9)各種テストの実行。pres:圧力センサーのテスト、accel:加速度センサーのテスト、memtest:メモリーのテスト、monitest:モニターテスト

左右の足のサーボをスレッド化したかった

左右の足のサーボを、それぞれ別スレッドで動かそうと思った。
RaspberryPIはデフォルトでは1個のI2Cチャンネルだが、簡単に二つのチャンネルを有効化できる。/boot/config.txt に、
dtparam=i2c_vc=on
の一行を加え、/boot/cmdline.txtni に、
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=27ca714e-02 rootfstype=ext4 elevator=deadline fsck.repair=yes bcm2708.vc_i2c_override=1 rootwait quiet splash plymouth.ignore-serial-consoles
のように、
bcm2708.vc_i2c_override=1
を加えて、リブートする。
そうすると、
pi@ashiro:~ $ ls -l /dev/i2c-*
crw-rw---- 1 root i2c 89, 0 6月 27 17:17 /dev/i2c-0
crw-rw---- 1 root i2c 89, 1 6月 27 17:17 /dev/i2c-1
の二つのデバイスが現れる。すると、ID_SDとID_SCに割り当てられている27,28番ピンをSDA0とSCL0ピンとして使える。0チャンネルが新しく加わる。(プルアップする必要がある)
$ i2cdetect -y 0
とすれば、0チャンネルにぶら下がっているデバイスが認識できる。
この二つのデバイスに、左足と右足のサーボ群をそれぞれスレッドで動かすようにぶら下げたいのだが、足郎1の上版ボードにPCA9685のボードを乗せる余裕がない。諦めた。
足郎2では、最初から乗せるような設計にしたいと思っている。
http://robo.genv.sophia.ac.jp/wp_robot/?p=1844 参照)

記憶のフォーマット

センサーとサーボの状態を脳に記憶させるのだが、フフォーマットを少し考えた。
記憶から、自己学習させる。
一連のサーボの動態、結果としてのセンサーデータから、その動きが、いい結果をもたらすのか、否か、その評価ができるようにする。
センサーが、ひどい動きをすれば、それは忌むべき状態だ。その、嫌な感覚をロボットに教え込む。
ほんとうは立つところから教えたい。

脳の状態表示のためのLedをつけた

人工知能を組み込んだ小脳の学習データの記録や、成功、失敗の判断状況がすぐわかるようにするために、Ledを取り付けた。

300オームの抵抗をかましたが、大きすぎたかもしれない。Ledなんて、切れるほどに光らせたらいいと思っているのに以外と暗くなってしまった。

ロボット上で、圧力センサー8個と加速度センサー5個を制御する

全てのセンサー(足裏に片足4個両足8個の圧力センサー、上版とスネ2個及び足2個の計5個の加速度センサー)をロボットに装着、2つのSpiチャンネルをフル稼働してデータが取れるようになった。
加速度センサの膝下に設置した2個は、X軸が縦になっているので1gのあたりでうろついている。異常値が1つあるが、電源がショートしたか飛んだのではないかと思っている。
圧力センサーの不器用な動きがきになるが、ADコンバータの仕様ではないかと思っている。
ロボットは、配線のお化けのようになった。
次は、これらのセンサーとサーボモーター群をロボットの脳である、ニューラルネットワークシステムにつなげる。