ラベル servoblaster の投稿を表示しています。 すべての投稿を表示
ラベル servoblaster の投稿を表示しています。 すべての投稿を表示

2018年5月3日木曜日

ServoBlaster が更新されました

去年こちらに書いたServoBlasterの問題が修正されていました。

 https://github.com/richardghirst/PiBits/tree/master/ServoBlaster

kernel 4.9以降に"/proc/cpuinfo"の"Hardware"情報を元に"board_model"を判定する方法
(実際は、"board_model"からgpioのベースになるアドレスを設定する方法)に不具合が
出ていましたが、こちらの"bcm_host_get_peripheral_address()" を使う方法になっています。

手持ちのRespberry Pi 2 Model Bでの動作確認ができました。

2017年5月5日金曜日

「簡易ポーズエディタ」 遂に、ボタンを使う


Raspberry Pi 2 Model B + ServoBlaster + シェルスクリプト(GtkDialog)で4足歩行ロボットを操作。
「簡易ポーズエディタ」の、今まで飾りになっていた上部のボタンに、機能を持たせた。
「左回転」「前進」「後退」「右回転」のボタンでそれぞれの動作を起動する。
(GtkDialogから、別のシェルスクリプトに書かれたfunction呼んでいるだけ)
ただし、「停止」ボタンを押さない限り、繰り返し回数上限まで動作を続行する。

ヘボいのは、上限に達して終了しても、操作ボタンがグレイアウトから復帰しない点。
「停止」ボタンを押さないと、復帰しない。

2017年3月26日日曜日

Raspberry Pi kernel 4.9でServoBlaster(その2 非推奨)

前回の暫定的な処置を少し変更。
"/proc/cpuinfo"の"Hardware"情報を元にする方法はkernel 4.9では通用しないので、
"/proc/device-tree/soc/ranges"を読み込んで、"board_model"を判定するように変更してみた。

参考:下のリンク、pelwellさんのコメントを参考にしました。
https://github.com/raspberrypi/linux/issues/1902#issuecomment-287365600

 ※以下は非推奨です!! Raspberry Pi 2 Model Bでしか確認していません!※

"servod.c"をエディタで開き、958行目からの
if (strstr(modelstr, "BCM2708"))
            board_model = 1;
else if (strstr(modelstr, "BCM2709"))
            board_model = 2;
else
            fatal("servod: Cannot parse the hardware name string\n");
ここを下のように書き換える。
char buffer[5];
  FILE *file;
        
  file = fopen("/proc/device-tree/soc/ranges", "rb");
  fread(buffer, 1, sizeof(buffer), file);
  fclose(file);

  if (buffer[4] == 0x20)
        board_model = 1;
  else if (buffer[4] == 0x3f)
        board_model = 2;
  else
        fatal("servod: Cannot parse the board model\n");
※追記1(2017/04/22 20:20)※
本当は"hardware name"を読んでいる訳ではないので、最後のメーッセージは
"servod: Cannot parse the board model\n"
 とでもすれば良いですかね

※追記2(2017/04/27 20:25)※
"char buffer[8]"から"char buffer[5] "へ変更

以前の"servod"を削除して、改めて"make"し、"servod"を起動する。



※追記3(2017/05/03 21:40)※
下記にて、"/proc/device-tree/soc/ranges"を開けなかった場合の処理を追加。
fseekでファイル読込開始位置を指定し、配列への読み込みを限定してみた。
(特に意味は無い)

char buffer[1];
  FILE *file;
 
  file = fopen("/proc/device-tree/soc/ranges", "rb");
 
  if (!file)
        fatal("Unable to open /proc/device-tree/soc/ranges: %m\n");
 
  fseek(file, 4, SEEK_SET);
  fread(buffer, 1, sizeof(buffer), file);
  fclose(file);

  if (buffer[0] == 0x20)
        board_model = 1;
  else if (buffer[0] == 0x3f)
        board_model = 2;
  else
        fatal("servod: Cannot parse the board model\n");

2017年3月13日月曜日

ラズパイ kernel 4.9でServoBlaster(非推奨)

Raspberry Pi 2 Model Bで使っているArch Linux ARMのkernelが、4.9系に上がりましたが、、、。
ServoBlasterは4.9系に対応しておらず、
"servod: Cannot parse the hardware name string"
エラーを吐いて起動しません。


ServoBlasterは、"/proc/cpuinfo"から情報を取ってRaspberry Piの機種ボードモデルを判別しているらしいのですが、
kernel 4.9になってから、"/proc/cpuinfo"での情報が変わったようです。
これに対応させるように、応急処置をしてみました。

※追記1(2017/03/26 16:55)※
Raspberry Piのボードモデル判別の方法を修正したものが、次にあります。
 http://aoo10yan.blogspot.jp/2017/03/raspberry-pi-kernel-49servoblaster.html


※以下は非推奨です!! Raspberry Pi 2 Model Bでしか確認していません!※

"servod.c"をエディタで開き、
else if (strstr(modelstr, "BCM2709"))
この行を下のように書き換える。
else if (strstr(modelstr, "BCM2709") || strstr(modelstr, "BCM2835"))
以前の"servod"を削除して、改めて"make"し、"servod"を起動する。


自分の環境では、これで動きました。

2017年3月3日金曜日

Scratch 1.4からServoBlasterを使う

Arch Linux ARMに入っているScratch 1.4のブロックを使ってServoBlasterを動かそうという試み。

※言うまでもないですが、Scratchの改造・シェルスクリプトの実行は自己責任で!※

通常は、直接ServoBlasterを動かすためのブロックは用意されていないので、
ScratchをSmalltalkのレベルで改造する必要があり、以下を参考にして、
ブロックの追加を行った。情報を公開してくださった方々に感謝。
参考
http://itpro.nikkeibp.co.jp/article/COLUMN/20111019/371085/
http://oohito.com/nqthm/archives/2243
http://d.hatena.ne.jp/minekoa/20080314/1205484707

概要
ServoBlasterは、"echo 0=50% > /dev/servoblaster"と言った形式のコマンドで、
"/dev/servoblaster"に値を送る事でサーボモータを動かす。
 なので、Scratch側から上記のコマンド相当(ファイルへの書き込み)を実行できれば、
ServoBlasterが動くはず。

だったが、、、。

やってみたところ、Scratchで直接ファイル(/dev/servoblaster)への書き込みを
実行しても、ServoBlasterで拾わなかった。
そこで、Scratch外部のシェルスクリプトから"echo 0=50% > /dev/servoblaster"を送ってみた。
動作確認ができたので、この方法を使うことにした。

手順
①・ScratchからSmalltalkへ降りて、ブロックの追加をする。
②・追加したブロックに任意のファイルへの書き込みのメソッド(?)を設定する。
③・任意のファイルの更新を監視し、変更があった場合にファイル内容(文字列)を読み込んで、
"echo"コマンドで"/dev/servoblaster"へ送る為のシェルスクリプトを作成する。


手順①は上述の参考サイトを見て、適当なブロックのカテゴリに追加。


('servo %s' #- #servo: '0=50%')

ブロックができたことを確認。


手順②では、今回は任意のファイルを"/home/o10yan/Scratch/servo"と決めうちする。
(ホームディレクトリは私の環境の場合なので、そこは御自分の環境に読み替えて下さい)
書き込む文字列は引数"t1"で渡されていると推測。

servo: t1 
    | file |
    file _ FileStream fileNamed: '/home/o10yan/Scratch/servo'.
    file nextPutAll: t1.
    file close.
    (Delay forMilliseconds: 10) wait

(注:上記"file _"は、Scratchでは"file ←"と表示される)


Scratch側の準備は以上で終了。
試しに動かしてみて、ファイルができているかを確認。



手順③で以下のように、ファイル監視のシェルスクリプトを作成。
ファイルの更新監視用に"inotifywait"を使うので、予め"inotify-tools"をインストールしておく。
先ずは、監視用のファイルが存在するかを確認して、無ければ作っておく。
"inotifywait"で指定のファイルに更新があるかを監視し、更新があった場合、
ファイルの内容を変数(text_line)に読み込んで、それを"/dev/servoblaster"へ送る。
ファイルに文字列が残ってしまうと気持ち悪いので、空白を書き込んでおく。

#!/bin/bash

if [ ! -e /home/o10yan/Scratch/servo ]; then
    touch /home/o10yan/Scratch/servo
fi

while inotifywait -e modify /home/o10yan/Scratch/servo; do
    text_line=$(cat /home/o10yan/Scratch/servo)

    if [ -n '$text_line' ]; then
         echo '' > /home//o10yan/Scratch/servo
         echo $text_line > /dev/servoblaster
    fi
done

出来上がったシェルスクリプトを実行し、監視状態になることを確認し、
Scratchのブロックを動かす。


今回は、ServoBlasterを動かすための改造を行ったが、次回はLinuxコマンドを
送るような改造を行う。

※お願い※
私は、Smalltalkについて全然分かっていないので、コピペ主体で改造してます。
Smalltalkに詳しい方で、「ここは間違っている」「こうした方が良い」と言う
指摘がありましたら、コメントを頂けると有難いです。
よろしくお願いします。

2016年9月18日日曜日

再修正「簡易ポーズエディタ」

修正「簡易ポーズエディタ」 で作ったスクリプトの再修正
例によって、上部のボタンは意味なし 。

原点に対する補正値を入れられるようにした。
起動時に、原点復帰を行う。

#!/bin/bash

export test00='
echo $USER
'
export SERVO0='50'
export SERVO1='50'
export SERVO2='50'
export SERVO3='50'
export SERVO4='50'
export SERVO5='50'
export SERVO6='50'
export SERVO7='50'

#原点に対する補正値の設定 
export ADJUST0='4'
export ADJUST1='3'
export ADJUST2='-3'
export ADJUST3='5'
export ADJUST4='-4'
export ADJUST5='-3'
export ADJUST6='1'
export ADJUST7='-3'

for((i = 0; i <= 7; i++)); do
    echo $i=$((SERVO$i + ADJUST$i))% > /dev/servoblaster
done

export MAIN_DIALOG='
  <window>
    <vbox>
      <hbox>
        <vbox>
          <hbox>
            <frame サーボ5(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO5</variable>
                <action>bash -c "echo 5="$((SERVO5 + ADJUST5))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT5</action>
              </vscale>
            </frame>
            <frame サーボ4(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO4</variable>
                <action>bash -c "echo 4="$((SERVO4 + ADJUST4))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT4</action>
              </vscale>
            </frame>
          </hbox>
          <hbox>
            <frame サーボ7(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO7</variable>
                <action>bash -c "echo 7="$((SERVO7 + ADJUST7))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT7</action>
              </vscale>
            </frame>
            <frame サーボ6(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO6</variable>
                <action>bash -c "echo 6="$((SERVO6 + ADJUST8))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT6</action>
              </vscale>
            </frame>
          </hbox>
        </vbox>

        <vbox>
          <hbox>
            <button>
              <label>ボタン 1</label>
              <action>echo $LANG</action>
            </button>
            <vbox>
              <button width-request="110">
                <label>前進</label>
                <action>bash -c "$test00"</action>
              </button>
              <button>
                <label>後退</label>
              </button>
            </vbox>
            <button>
              <label>ボタン 4</label>
            </button>
          </hbox>
          <vbox>
            <frame>
              <text>
                <variable>TEXT0</variable>
                <input>echo "echo 0="$SERVO0"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT1</variable>
                <input>echo "echo 1="$SERVO1"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT2</variable>
                <input>echo "echo 2="$SERVO2"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT3</variable>
                <input>echo "echo 3="$SERVO3"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT4</variable>
               <input>echo "echo 4="$SERVO4"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT5</variable>
                <input>echo "echo 5="$SERVO5"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT6</variable>
                <input>echo "echo 6="$SERVO6"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT7</variable>
                <input>echo "echo 7="$SERVO7"% > /dev/servoblaster"</input>
              </text>
            </frame>
          </vbox>
          <entry>
            <variable>FILE0</variable>
            <default>"./temp.txt"</default>
          </entry>
          <button>
            <label>新規作成</label>
            <action>echo "#!/bin/bash" > $FILE0</action>
            <action>echo "" >> $FILE0</action>
            <action>echo "echo 0="$((SERVO0 + ADJUST0))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 1="$((SERVO1 + ADJUST1))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 2="$((SERVO2 + ADJUST2))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 3="$((SERVO3 + ADJUST3))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 4="$((SERVO4 + ADJUST4))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 5="$((SERVO5 + ADJUST5))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 6="$((SERVO6 + ADJUST6))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 7="$((SERVO7 + ADJUST7))"% > /dev/servoblaster" >> $FILE0</action>
          </button>
          <button>
            <label>ポーズ追加</label>
            <action>echo "" >> $FILE0</action>
            <action>echo "sleep 1" >> $FILE0</action>
            <action>echo "" >> $FILE0</action>
            <action>echo "echo 0="$((SERVO0 + ADJUST0))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 1="$((SERVO1 + ADJUST1))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 2="$((SERVO2 + ADJUST2))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 3="$((SERVO3 + ADJUST3))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 4="$((SERVO4 + ADJUST4))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 5="$((SERVO5 + ADJUST5))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 6="$((SERVO6 + ADJUST6))"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 7="$((SERVO7 + ADJUST7))"% > /dev/servoblaster" >> $FILE0</action>
          </button>
        </vbox>

        <vbox>
          <hbox>
            <frame サーボ0(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO0</variable>
                <action>bash -c "echo 0="$((SERVO0 + ADJUST0))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT0</action>
              </vscale>
            </frame>
            <frame サーボ1(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO1</variable>
                <action>bash -c "echo 1="$((SERVO1 + ADJUST1))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT1</action>
              </vscale>
            </frame>
          </hbox>
          <hbox>
            <frame サーボ2(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO2</variable>
                <action>bash -c "echo 2="$((SERVO2 + ADJUST2))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT2</action>
              </vscale>
            </frame>
            <frame サーボ3(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO3</variable>
                <action>bash -c "echo 3="$((SERVO3 + ADJUST3))"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT3</action>
              </vscale>
            </frame>
          </hbox>
        </vbox>
      </hbox>
    </vbox>
  </window>
'

gtkdialog -p MAIN_DIALOG -c 

2016年6月5日日曜日

修正「簡易ポーズエディタ」

Raspberry Pi 2 4足歩行ロボット用「簡易ポーズエディタ」 で作ったスクリプトの修正。
例によって、上部のボタンは意味なし 。


レイアウト修正と、ファイル「新規作成」の修正及び、「ポーズ追加」ボタンの付加。

中央下の「新規作成」ボタンでスクリプトファイル(形式のテキストファイル)作成。

「ポーズ追加」ボタンで、次のポーズを追加。

テキストファイルなので、実行権限はなし。
動きの無いサーボモータに対しても同位置の指示が書き込みされている。
ポーズ間のスリープは1秒固定。

実際には、上の修正をしながらシェルスクリプトとして手作業で仕上げて行く。

#!/bin/bash

export test00='
echo $USER
'
export SERVO0='50'
export SERVO1='50'
export SERVO2='50'
export SERVO3='50'
export SERVO4='50'
export SERVO5='50'
export SERVO6='50'
export SERVO7='50'

export MAIN_DIALOG='
  <window>
    <vbox>
      <hbox>
        <vbox>
          <hbox>
            <frame サーボ5(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO5</variable>
                <action>bash -c "echo 5="$SERVO5"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT5</action>
              </vscale>
            </frame>
            <frame サーボ4(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO4</variable>
                <action>bash -c "echo 4="$SERVO4"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT4</action>
              </vscale>
            </frame>
          </hbox>
          <hbox>
            <frame サーボ7(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO7</variable>
                <action>bash -c "echo 7="$SERVO7"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT7</action>
              </vscale>
            </frame>
            <frame サーボ6(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO6</variable>
                <action>bash -c "echo 6="$SERVO6"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT6</action>
              </vscale>
            </frame>
          </hbox>
        </vbox>

        <vbox>
          <hbox>
            <button>
              <label>ボタン 1</label>
              <action>echo $LANG</action>
            </button>
            <vbox>
              <button width-request="110">
                <label>前進</label>
                <action>bash -c "$test00"</action>
              </button>
              <button>
                <label>後退</label>
              </button>
            </vbox>
            <button>
              <label>ボタン 4</label>
            </button>
          </hbox>
          <vbox>
            <frame>
              <text>
                <variable>TEXT0</variable>
                <input>echo "echo 0="$SERVO0"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT1</variable>
                <input>echo "echo 1="$SERVO1"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT2</variable>
                <input>echo "echo 2="$SERVO2"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT3</variable>
                <input>echo "echo 3="$SERVO3"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT4</variable>
               <input>echo "echo 4="$SERVO4"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT5</variable>
                <input>echo "echo 5="$SERVO5"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT6</variable>
                <input>echo "echo 6="$SERVO6"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT7</variable>
                <input>echo "echo 7="$SERVO7"% > /dev/servoblaster"</input>
              </text>
            </frame>
          </vbox>
          <entry>
            <variable>FILE0</variable>
            <default>"./temp.txt"</default>
          </entry>
          <button>
            <label>新規作成</label>
            <action>echo "#!/bin/bash" > $FILE0</action>
            <action>echo "" >> $FILE0</action>
            <action>echo "echo 0="$SERVO0"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 1="$SERVO1"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 2="$SERVO2"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 3="$SERVO3"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 4="$SERVO4"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 5="$SERVO5"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 6="$SERVO6"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 7="$SERVO7"% > /dev/servoblaster" >> $FILE0</action>
          </button>
          <button>
            <label>ポーズ追加</label>
            <action>echo "" >> $FILE0</action>
            <action>echo "sleep 1" >> $FILE0</action>
            <action>echo "" >> $FILE0</action>
            <action>echo "echo 0="$SERVO0"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 1="$SERVO1"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 2="$SERVO2"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 3="$SERVO3"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 4="$SERVO4"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 5="$SERVO5"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 6="$SERVO6"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 7="$SERVO7"% > /dev/servoblaster" >> $FILE0</action>
          </button>
        </vbox>

        <vbox>
          <hbox>
            <frame サーボ0(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO0</variable>
                <action>bash -c "echo 0="$SERVO0"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT0</action>
              </vscale>
            </frame>
            <frame サーボ1(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO1</variable>
                <action>bash -c "echo 1="$SERVO1"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT1</action>
              </vscale>
            </frame>
          </hbox>
          <hbox>
            <frame サーボ2(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO2</variable>
                <action>bash -c "echo 2="$SERVO2"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT2</action>
              </vscale>
            </frame>
            <frame サーボ3(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO3</variable>
                <action>bash -c "echo 3="$SERVO3"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT3</action>
              </vscale>
            </frame>
          </hbox>
        </vbox>
      </hbox>
    </vbox>
  </window>
'

gtkdialog -p MAIN_DIALOG -c 

2015年12月11日金曜日

Raspberry Pi 2 より少ないサーボ制御を

前回は「Raspberry Pi 2 より多くのサーボ制御を」やったが、
今回はデフォルトの8個を減らして、他の用途に使えるGPIOを増やしたい場合。
これも簡単。前回と同様ServoBlasterのオプションを使う。

--p1pins=<list>
 
 これで、サーボモータのID0にGPIO-17、ID1にGPIO-22がセットされた。 
 
 もし、デフォルトの設定からIDを変更したくない場合は、ダミーの"0"を噛ませれば良い。

2015年11月15日日曜日

Raspberry Pi 2 より多くのサーボ制御を

ServoBlasterでは、デフォルトで8個のサーボモータを制御できる。
8個の制御で事足りるんだが、もっと多くのサーボモータを使いたくなったらどうする?

安心してください。拡張できますよ。

ServoBlasterのオプションでどのピンを使うか指定することが出来る。

--p1pins=<list>
 
 このオプションの<list>に使うピンのボード上の番号をカンマ区切りで書いていくだけ。
 
 
上の画像では17本のピンを指定している。
個々のピンにサーボモータを繋いでの動作確認はしているが、そんなに沢山のサーボモータを
持っていないので、同時接続での確認は出来ていない。

(2015/10/3の更新で、Raspberry Pi 2用のマップが追加されたので、フルで指定すれば
26個のサーボモータが使えるんじゃないかと思う。)

Raspberry Piで多数のサーボモータを制御する場合、サーボモータードライバ等を
別途用意しなければならないと思いがちだが、ソフトだけでもある程度の対応が
可能だというお話し。

2015年11月7日土曜日

Raspberry Pi 2 4足歩行ロボットの追加モーション

4足歩行ロボットの別モーションを作ってみた。
と言っても、ポーズを決めて順番に並べて行くだけの簡単な作業です。


予め、(移動の為に)浮かせる脚の対角線上の脚に重心が掛かるようにしておき、
その後目的の脚を浮かせるようになるので、3点支持での歩行になる筈だったが、、、。

一応、移動する脚は摺ることなく、浮いた状態で移動してるのが見えると思う。
でも、何か違うよね?!

2015年10月17日土曜日

Raspberry Pi 2 4足歩行ロボット用「簡易ポーズエディタ」

前回「Raspberry Pi 2 やっぱりシェルスクリプトでやる」で作ったServoBlaster用シェルスクリプトの発展形。


 4足歩行ロボットの脚に対応したスライダーを操作してポーズを決め、
その時点のコマンドを任意のファイルに書き出すgtkdialog使用のシェルスクリプト。

#!/bin/bash

export test00='
echo $USER
'
export SERVO0='50'
export SERVO1='50'
export SERVO2='50'
export SERVO3='50'
export SERVO4='50'
export SERVO5='50'
export SERVO6='50'
export SERVO7='50'

export MAIN_DIALOG='
  <window>
    <vbox>
      <hbox>
        <vbox>
          <hbox>
            <frame サーボ5(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO5</variable>
                <action>bash -c "echo 5="$SERVO5"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT5</action>
              </vscale>
            </frame>
            <frame サーボ4(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO4</variable>
                <action>bash -c "echo 4="$SERVO4"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT4</action>
              </vscale>
            </frame>
          </hbox>
          <hbox>
            <frame サーボ7(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO7</variable>
                <action>bash -c "echo 7="$SERVO7"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT7</action>
              </vscale>
            </frame>
            <frame サーボ6(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO6</variable>
                <action>bash -c "echo 6="$SERVO6"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT6</action>
              </vscale>
            </frame>
          </hbox>
        </vbox>

        <vbox>
          <hbox>
            <button>
              <label>ボタン 1</label>
              <action>echo $LANG</action>
            </button>
            <vbox>
              <button>
                <label>前進</label>
                <action>bash -c "$test00"</action>
              </button>
              <button>
                <label>後退</label>
              </button>
            </vbox>
            <button>
              <label>ボタン4</label>
            </button>
          </hbox>
          <vbox>
            <frame>
              <text>
                <variable>TEXT0</variable>
                <input>echo "echo 0="$SERVO0"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT1</variable>
                <input>echo "echo 1="$SERVO1"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT2</variable>
                <input>echo "echo 2="$SERVO2"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT3</variable>
                <input>echo "echo 3="$SERVO3"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT4</variable>
               <input>echo "echo 4="$SERVO4"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT5</variable>
                <input>echo "echo 5="$SERVO5"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT6</variable>
                <input>echo "echo 6="$SERVO6"% > /dev/servoblaster"</input>
              </text>
              <text>
                <variable>TEXT7</variable>
                <input>echo "echo 7="$SERVO7"% > /dev/servoblaster"</input>
              </text>
            </frame>
          </vbox>
          <entry>
            <variable>FILE0</variable>
            <default>"./temp.txt"</default>
          </entry>
          <button>
            <label>Write</label>
            <action>echo "echo 0="$SERVO0"% > /dev/servoblaster" > $FILE0</action>
            <action>echo "echo 1="$SERVO1"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 2="$SERVO2"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 3="$SERVO3"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 4="$SERVO4"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 5="$SERVO5"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 6="$SERVO6"% > /dev/servoblaster" >> $FILE0</action>
            <action>echo "echo 7="$SERVO7"% > /dev/servoblaster" >> $FILE0</action>
          </button>
        </vbox>

        <vbox>
          <hbox>
            <frame サーボ0(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO0</variable>
                <action>bash -c "echo 0="$SERVO0"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT0</action>
              </vscale>
            </frame>
            <frame サーボ1(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO1</variable>
                <action>bash -c "echo 1="$SERVO1"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT1</action>
              </vscale>
            </frame>
          </hbox>
          <hbox>
            <frame サーボ2(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1" inverted="true">
                <default>50</default>
                <variable>SERVO2</variable>
                <action>bash -c "echo 2="$SERVO2"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT2</action>
              </vscale>
            </frame>
            <frame サーボ3(%)>
              <vscale height-request="200" range-min="10" range-max="90" range-step="1">
                <default>50</default>
                <variable>SERVO3</variable>
                <action>bash -c "echo 3="$SERVO3"% > /dev/servoblaster"</action>
                <action type="refresh">TEXT3</action>
              </vscale>
            </frame>
          </hbox>
        </vbox>
      </hbox>
    </vbox>
  </window>
'

gtkdialog -p MAIN_DIALOG -c 

というわけで、中央上部のボタンは前回同様飾り。
 使い道の無かったシェルスクリプトに、多少は意味を持たせてみた。

2015年10月12日月曜日

Raspberry Pi 2 やっぱりシェルスクリプトでやる

シェルスクリプトでもgtkdialogを使うことで、GUI操作が可能なので、
gtkdialogのスライダーを使って、サーボモータを動かしてみようと思った。
(サーボモータの制御にはServoBlasterを使用するので、そのインターフェースって感じ。)

Arch Linux ARMではリポジトリにgtkdialogがパッケージとしてあるので、
pacmanでインストールする。

例によって体裁は考えずに、兎に角動くものを作る。

#!/bin/bash

export test00='
echo $USER
'

export MAIN_DIALOG='
  <window>
    <vbox>
      <hbox>
        <button>
          <label>ボタン1</label>
          <action>echo $LANG</action>
        </button>
        <vbox>
          <button>
            <label>前進</label>
            <action>bash -c "$test00"</action>
          </button>
          <button>
            <label>後退</label>
          </button>
        </vbox>
        <button>
          <label>ボタン4</label>
        </button>
      </hbox>
      <frame サーボ0(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO0</variable>
          <action>bash -c "echo 0="$SERVO0"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
      <frame サーボ1(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO1</variable>
          <action>bash -c "echo 1="$SERVO1"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
      <frame サーボ2(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO2</variable>
          <action>bash -c "echo 2="$SERVO2"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
      <frame サーボ3(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO3</variable>
          <action>bash -c "echo 3="$SERVO3"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
      <frame サーボ4(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO4</variable>
          <action>bash -c "echo 4="$SERVO4"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
      <frame サーボ5(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO5</variable>
          <action>bash -c "echo 5="$SERVO5"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
      <frame サーボ6(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO6</variable>
          <action>bash -c "echo 6="$SERVO6"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
      <frame サーボ7(%)>
        <hscale range-min="10" range-max="90" range-step="1">
          <default>50</default>
          <variable>SERVO7</variable>
          <action>bash -c "echo 7="$SERVO7"% > /dev/servoblaster"</action>
        </hscale>
      </frame>
    </vbox>
 </window>
'

gtkdialog -p MAIN_DIALOG -c 


今のところボタンは飾りなので、気にしない。

一応、できたってだけで、使い道は無い

2015年10月4日日曜日

Raspberry Pi 2 4足歩行ロボットを作ってみよう(その4)

「先ずは、設計図を描け」ってのは言わずに 、
反省回。

1・素材選び
 加工がし易いだろうという安易な考えで、1mm厚の塩ビ板を選んだこと。
 又、部位による素材の使い分けをしなかったこと。強度を要する部位には
 それなりの素材を使用しなければならない。

2・サイズ及び重量
 Raspberry Pi 2 Model Bとブレッドボードをそのまま並列で置けるような
 大きさの本体を作ったこと。
 そもそも大きすぎ、重すぎてサーボモータSG90に負荷が掛かりすぎ。

3・ブラケット形状
 脚を水平方向に動かすサーボモータを収めるべきブラケットをL(エル)字型に
 したこと。
 脚を支える部分に当たるため、L字型ではなく、コの字型にすべき。
 (下の画像の赤線の形状)

 垂直方向に動かすサーボモータのを、水平方向サーボモータ及び本体から
 離して取り付けたこと。
 (下の画像の水色線のように取り付ける)

ブラケットを作り直したいけど、気力が無い

『次号機は無い』

2015年10月3日土曜日

Raspberry Pi 2 4足歩行ロボットを作ってみよう(その3)

さて、ロボットにRaspberry Pi 2 Model Bとブレッドボードを載せ、
サーボモータとの配線を完了する。

Raspberry Pi用の電源はスマートフォンの充電器(5V 2A)からとり、
サーボモータ用には別途用意する。
(本当は、ラズパイの電源もモバイルバッテリー等からとりたいけど、それまで
載せたら、脚が崩壊する)
当初単3電池4本でやってみたが、重過ぎで、ブラケット部の歪みが激しい。
そこで、単4電池にしてみたところ、何とか姿勢を維持できるようになった。



サーボモータを制御する為のシェルスクリプトを適当に作る。
兎にも角にも、動かしたいので、スクリプトの体裁は考えない。

#!/bin/bash

hservo=(0 2 4 6)
vservo=(1 3 5 7)

function home(){
    for i in ${hservo[@]};do
        echo $i=50% > /dev/servoblaster
    done
    
    echo 0=55% > /dev/servoblaster
    echo 4=45% > /dev/servoblaster
    
    for i in ${vservo[@]};do
        echo $i=50% > /dev/servoblaster
    done

    echo 7=45% > /dev/servoblaster
}

function star(){
    echo 0=65% > /dev/servoblaster
    echo 2=40% > /dev/servoblaster
    echo 4=35% > /dev/servoblaster
    echo 6=60% > /dev/servoblaster
    
    sleep 0.1

    echo 1=30% > /dev/servoblaster
    echo 3=70% > /dev/servoblaster
    echo 5=70% > /dev/servoblaster
    echo 7=30% > /dev/servoblaster

    sleep 0.5

    echo 1=70% > /dev/servoblaster
    echo 3=30% > /dev/servoblaster
    echo 5=30% > /dev/servoblaster
    echo 7=70% > /dev/servoblaster

    sleep 0.5

    echo 1=30% > /dev/servoblaster
    echo 3=70% > /dev/servoblaster
    echo 5=70% > /dev/servoblaster
    echo 7=30% > /dev/servoblaster
}

function first(){
    echo 1=70% > /dev/servoblaster
    echo 7=60% > /dev/servoblaster

    sleep 0.2

    echo 0=65% > /dev/servoblaster
    echo 6=40% > /dev/servoblaster
    
    echo 2=40% > /dev/servoblaster
    echo 4=55% > /dev/servoblaster

    sleep 0.1

    echo 1=30% > /dev/servoblaster
    echo 7=30% > /dev/servoblaster
} 

function second(){
    echo 5=30% > /dev/servoblaster
    echo 3=30% > /dev/servoblaster

    sleep 0.2

    echo 2=60% > /dev/servoblaster
    echo 4=35% > /dev/servoblaster
    
    echo 0=45% > /dev/servoblaster
    echo 6=60% > /dev/servoblaster

    sleep 0.1

    echo 5=70% > /dev/servoblaster
    echo 3=70% > /dev/servoblaster
} 

home
sleep 0.5
star
sleep 0.5

for((i = 0; i < 5; i++));do
    first
    sleep 0.5
    second
    sleep 0.5
done

sleep 1
star

じゃあ、動かしてみよう。
デスクトップPCからSSHでRaspberry Piへログインし、先ずはsudoでServoBlasterを起動。
シェルスクリプトを動かす。


まあ、真っ直ぐ進まないのはご愛嬌。
何せ手作り故、脚部の加工精度なんて出てない。多少は補正を入れてあるけど、適当なので。

それでも、初めて自作したロボットが前進したので大満足!!

今後は、それっぽいモーションを少しずつ作って行きたい。

2015年9月26日土曜日

Raspberry Pi 2 4足歩行ロボットを作ってみよう(その2)

ロボット製作は疎か、電子工作すらやったことのない文系なので、
ゼロからの出発は無理。
参考になるサイトを探し回った結果、以下のページを参考にした。

http://www.robotshop.com/letsmakerobots/project-sc-qr-1-with-more-videos
http://robotshop.com/letsmakerobots/arduino-quadruped-walking-robot
http://www.robotshop.com/letsmakerobots/chopstick-junior-10
(『参考にした』と言ったら、先方に失礼なんですが、、、。)

動画を何度も見て、頭の中でイメージを固めていく。
で、図面など描ける筈もないので、簡単なスケッチを書く。

上のスケッチから、ダンボールや厚紙で、具体的な形にしてみる。
右の白いのは、平行リンクっぽい足の動きを確かめるための物で、大きく作ってある。

SG90をブラケットにはめ込んでみた。

何となく、具体的なイメージが掴めたら、用意した『硬質塩ビ板』で作る。
用意した塩ビ板が(事もあろうに)1mm厚だったため、実際にサーボモータや
脚を取り付けてみると、胴体がペランペランで歪んでしまった。
今更、素材を変更して作り直す気力はなかったので、、、。
補強用の桟を取り付け、ブラケットも強度が必要な部分は2枚重ねにした。
これで、Raspberry Pi 2とブレッドボードを載せても、何とか支えることができる
ようにになった。

後は、いよいよ配線してServoBlasterでマイクロサーボSG90を制御するための
シェルスクリプトを動かすことになる。

果たして、この自作4足歩行ロボット(もどき)は動くのだろうか?

2015年9月23日水曜日

Raspberry Pi 2 4足歩行ロボットを作ってみよう(その1)

ロボットと言えば多脚。

(いろんな意味で)入手できるサーボモータは、
デジタル・マイクロサーボ SG90の10個セットなので、
これで、できそうな範囲を考える。

サーボモータ10個以内だと、2自由度の4脚(Quadruped Robot)って選択肢になる。
ネットで4足歩行ロボットの情報を漁りつつ、Raspberry PiのGPIOでサーボモータを
制御する方法を調べる。

サーボモータの制御は、GPIOからPWM(パルス幅変調)信号をモータ側へ
与えることで回転角度を調節する仕組みらしい。
信号のパルス幅を変える(変調する)ことで、角度も変わる。
Raspberry Pi 2 Model Bの場合、ハード的に精度の高いPWMを扱えるのは、GPIOの
18番と19番(あるいは12番と13番)の二つになるので、これでは最低8個の
サーボモータを動かすには足りない。

ハード(PCA9685搭載のサーボドライバー) を追加する手もあるが、そこまで
したくはない。
ソフトで擬似的にPWM制御が出きるようなのでそれを試す。

すぐ見つかったのは、WiringPiと言う、C言語でGPIOを制御する為のライブラリと、
デバイスファイルに値を書き込むことでサーボモータを制御するServoBlaster。

WiringPi
WiringPiはC/C++以外にもPythonやPHP用のラッパーを使えば、それらでの使用が可能。
WiringPiはpacmanでArch Linux ARM のリポジトリからインストール可能。
コンパイルとか面倒なことはしたくないので、Pythonで試してみる。

Arch Linux ARMではPython3が標準なので WiringPi2-Python(ラッパー)を
インストールして、 import wiringpi2として呼び出す。
※追記2(2016/05/15 13:35)※
ラッパーのインストール事情が変わったようなので、こちらを参照

インストールはgitで
git clone https://github.com/Gadgetoid/WiringPi2-Python.git
cd WiringPi2-Python
sudo python setup.py install
sudo python3 setup.py install
サンプル:
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import wiringpi2 as wiringpi
from time import sleep

wiringpi.wiringPiSetupGpio()

def movleft(pin):
    wiringpi.softPwmCreate(pin,0,200)
    sleep(0.5)
    wiringpi.softPwmWrite(pin,20)

def movright(pin):
    wiringpi.softPwmCreate(pin,0,200)
    sleep(0.5)
    wiringpi.softPwmWrite(pin,10)

def movmiddle(pin):
    wiringpi.softPwmCreate(pin,0,200)
    sleep(0.5)
    wiringpi.softPwmWrite(pin,15)

movleft(17)
movright(17)
movleft(17)
movmiddle(17)

wiringpi.softPwmCreate(pin,0,200)
softPwmCreateの第1引数でGPIO番号を指定し、第2引数でPWM初期値(取り敢えず"0"にしとく)、
第3引数で200を指定して、サーボモータの周期に合わせて20msにする。
wiringpi.softPwmWrite(pin,20)
後は、softPwmWriteで指定したGPIO番号にいくつのカウンタを送るかを指定する。
1カウンタは0.1msに固定されているので、20を引数にすれば2.0ms幅の信号が送られる。
(※上のサンプルは、都度softPwmCreateを実行してますが、1回設定すれば良いので、
 これは悪い例です。マネしないでください※)

あのー、Pythonってインデントで構文ブロックを判断するんですか?
慣れないと変な間違いをしそう。
一応、動きましたけどね。

ServoBlaster
 さてServoBlaster、これはちと古いのでそのままではRaspberry Pi 2 Model B
に対応していない。
対応版のこちら ServoBlaster-20150219.tgz を使う。
ただし、kernelのバージョンが4.1以上の場合は、コードの修正が必要。
ServoBlaster-20150219.tgzを解凍した中の、servod.c をエディタで開き、
1281行目

if (mknod(MBFILE, S_IFCHR|0600, makedev(100, 0)) < 0)

makedev(100,0) を makedev(249,0) に書き換えたうえで、
"cd ServoBlaster", "make", "sudo ./servod"を実行。

こんな表示が出ればOK。

使い方は簡単で、

echo 0=50% > /dev/servoblaster

のように、ServoBlasterでの番号にどの程度動かすかを指定して、
/dev/servoblasterに書き込むだけ。
パーセンテージ指定の他に、パルス幅の指定や、相対的な増減量指定もできる。
(自分は%指定しか使わないので、他の方法を詳しく知りたい場合は検索してくださ い)
これなら、シェルスクリプトで手軽に使えるね!

さあ、基幹となるサーボモータの制御ができたら、いよいよロボットの作成に移る。

※追記1(2015/11/15 10:45)※
 文中では、ServoBlaster-20150219.tgzを使用していましたが、
 2015/10/3にServoBlasterが更新され、Raspberry Pi 2 、kernel4.1(以降)に対応しています。
https://github.com/richardghirst/PiBits/tree/master/ServoBlaster
更新版を使っての動作確認が出来ました。

 ※追記3(2017/04/29 21:30)※
"servod: Cannot parse the hardware name string"
kernel4.9系で、上のエラーが出る場合、こちらに対処方法があります