masimaro blog

menu

home > 電子工作:Raspberry pi > Raspberry piで2足歩行ロボットの作成⑦【完成改】「モーション修正、サーボモーターの速度制御」

Raspberry piで2足歩行ロボットの作成⑦【完成改】「モーション修正、サーボモーターの速度制御」


Raspberry pi
2021-07-23


足周りの修正

とりあえず足の部分も段ボールで組み立てていたのですが、やはり本体を支える力に乏しく、また耐久性も弱かったので、まともなモーションで動作させる事が困難でした。

そこで、サムネイルにある通り、「適当な金属」で足回りを組むことにしました。

見栄えは決して良いとは言えませんが、とりあえず良しとします。

モーションの修正

足回りが頑丈になったので、よくあるオーソドックスなモーション?が可能になりました。

①片足上げる⇒②腰を回転⇒③足をおろす

の繰り返しのやつです。

プログラムは後述します。

しかし、これだけではサーボ―モータの速度制御を行っていない為、荒々しいモーションになってしまいます。

それはそれで躍動感があってよかったのですが、一応サーボモーターの速度制御を追加する事にしました。

サーボモーターの速度制御

恐らく、大抵の場合は速度制御のライブラリを使って簡単に制御できるのだと思いますが、今回の仕様上「webiopi」を使用していて、速度制御のライブラリが存在しません。

従って、サーボモーターの速度を制御するプログラムを自力で作成するしかありませんでした。

サーボモーターはPWMで角度を決めているので、速度の制御はどうやるんだろう?と素朴な疑問がありましたが、どうやらループ処理で少しずつ角度を変えていき、そこに待機時間を含ませることで比較的滑らかな動作が再現できるようです。(違ったらスイマセン)

ライブラリがあればもっとスマートなんでしょうけども、一応ループ処理で速度制御が出来たので、以下にモーションを含めたPython scriptプログラムを記載しておきます。

python

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を起動させて、ブラウザからアクセスすれば下のような感じで操作できます。

コメントを残す

お名前

コメント



コメント一覧

コメントはまだありません
MENU