以前にRaspberry piで2足歩行ロボットを作成しました。↓
上記の過去記事ではとりあえず完成を目指していたので、まともなモーションやサーボモーターの速度制御は行っていませんでした。
今回はその辺を修正する時間が出来たので、ここでまとめておこうかと思います。
足周りの修正
過去記事ではとりあえず足の部分も段ボールで組み立てていたのですが、やはり本体を支える力に乏しく、また耐久性も弱かったので、まともなモーションで動作させる事が困難でした。
そこで、サムネイルにある通り、M5stackを使った2足歩行ロボ作成時に採用した「適当な金属」で足回りを組むことにしました。↓
見栄えは決して良いとは言えませんが、とりあえず良しとします。
モーションの修正
足回りが頑丈になったので、よくあるオーソドックスなモーション?が可能になりました。
①片足上げる⇒②腰を回転⇒③足をおろす
の繰り返しのやつです。
プログラムは後述します。
しかし、これだけではサーボ―モータの速度制御を行っていない為、荒々しいモーションになってしまいます。
それはそれで躍動感があってよかったのですが、一応サーボモーターの速度制御を追加する事にしました。
サーボモーターの速度制御
恐らく、大抵の場合は速度制御のライブラリを使って簡単に制御できるのだと思いますが、今回の仕様上「webiopi」を使用していて、速度制御のライブラリが存在しません。
従って、サーボモーターの速度を制御するプログラムを自力で作成するしかありませんでした。
サーボモーターはPWMで角度を決めているので、速度の制御はどうやるんだろう?と素朴な疑問がありましたが、どうやらループ処理で少しずつ角度を変えていき、そこに待機時間を含ませることで比較的滑らかな動作が再現できるようです。(違ったらスイマセン)
ライブラリがあればもっとスマートなんでしょうけども、一応ループ処理で速度制御が出来たので、以下にモーションを含めたPython scriptプログラムを記載しておきます。
python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
import webiopi import time from webiopi import deviceInstance pwm0 = deviceInstance("pwm0") i = 0 n = 0 p = 0 t = 0 @webiopi.macro def SET(): global p global i global n global t pwm0.pwmWriteAngle(0, 10) time.sleep(1) pwm0.pwmWriteAngle(1, 0) time.sleep(1) pwm0.pwmWriteAngle(2, 8) time.sleep(1) pwm0.pwmWriteAngle(3, -5) time.sleep(1) p = 10 i = 8 n = 0 t = -5 @webiopi.macro def FW(): global p global i global n global t while(n <= 50): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) n = n + 1 if t <= 30: t = t + 1 while(i <= 48): pwm0.pwmWriteAngle(2, i) time.sleep(0.005) i = i + 1 while(n >= 0): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) n = n - 1 if t >= -5: t = t - 1 while(i >= 8): pwm0.pwmWriteAngle(2, i) time.sleep(0.005) i = i - 1 while(t >= -50): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) t = t - 1 if n >= -30: n = n - 1 while(p >= -30): pwm0.pwmWriteAngle(0, p) time.sleep(0.005) p = p - 1 while(t <= -5): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) t = t + 1 if n <= 0: n = n + 1 while(p <= 10): pwm0.pwmWriteAngle(0, p) time.sleep(0.005) p = p + 1 @webiopi.macro def BK(): global p global i global n global t while(n <= 50): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) n = n + 1 if t <= 30: t = t + 1 while(i >= -32): pwm0.pwmWriteAngle(2, i) time.sleep(0.005) i = i - 1 while(n >= 0): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) n = n - 1 if t >= -5: t = t - 1 while(i <= 8): pwm0.pwmWriteAngle(2, i) time.sleep(0.005) i = i + 1 while(t >= -50): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) t = t - 1 if n >= -30: n = n - 1 while(p <= 50): pwm0.pwmWriteAngle(0, p) time.sleep(0.005) p = p + 1 while(t <= -5): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) t = t + 1 if n <= 0: n = n + 1 while(p >= 10): pwm0.pwmWriteAngle(0, p) time.sleep(0.005) p = p - 1 @webiopi.macro def LT(): global p global i global n global t while(t >= -50): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) t = t - 1 if n >= -30: n = n - 1 while(p <= 50): pwm0.pwmWriteAngle(0, p) time.sleep(0.005) p = p + 1 while(t <= -5): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) t = t + 1 if n <= 0: n = n + 1 while(p >= 10): pwm0.pwmWriteAngle(0, p) time.sleep(0.005) p = p - 1 @webiopi.macro def RT(): global p global i global n global t while(n <= 50): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) n = n + 1 if t <= 30: t = t + 1 while(i >= -32): pwm0.pwmWriteAngle(2, i) time.sleep(0.005) i = i - 1 while(n >= 0): pwm0.pwmWriteAngle(3, t) pwm0.pwmWriteAngle(1, n) time.sleep(0.005) n = n - 1 if t >= -5: t = t - 1 while(i <= 8): pwm0.pwmWriteAngle(2, i) time.sleep(0.005) i = i + 1 |
グローバル変数を関数内で使用する為、各関数内でグローバル変数を宣言しています。
この変数を利用して、ループ処理で角度を1ずつ変化させ、その都度time sleepをかませています。
正直いってこの方法が合っているのかはわかりませんが、一応速度制御は出来ています。
ファイル名はmacro-pwm.pyとし、ラズパイのwebiopi/test/配下に上書きすればOKです。
完成
webiopiを起動させて、ブラウザからアクセスすれば下のような感じで操作できます。