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

2018年1月4日木曜日

OpenCVのテンプレートマッチングを試す

以前にOpenCVを使って顔検出をやってみたが、今回はテンプレートマッチングで、
簡易的に数字を検出してみる。
  
下のページを参考にさせてもらいました。有り難うございました。
http://www.tech-tech.xyz/archives/3065942.html

本当は画像の中から文字を検出したかったのだが、意外と面倒そうだった。
手書きの文字やフォント不明の文字を認識したいわけではなく、予め用意した数字と
同じものさえ検出できればよかったので、テンプレート画像との一致を見つけることで
良しとした。

先ず、テンプレート画像を用意する。

上の画像から、検出したい数字の部分を切り取ってテンプレート画像を作る。
これら「1」「2」「3」のテンプレートを使って検出を行う。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import cv2
import shutil

shutil.copyfile("test.jpg","result.jpg")

img = cv2.imread("result.jpg", 0)

for temp_num in [1, 2, 3]:
    temp = cv2.imread("temp" + str(temp_num) + ".png", 0)

    result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)

    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

    if max_val > 0.8:
        top_left = max_loc
        w, h = temp.shape[::-1]
        bottom_right = (top_left[0] + w, top_left[1] + h)

        result = cv2.imread("result.jpg")
        cv2.rectangle(result,top_left, bottom_right, (255, 0, 0), 2)
        cv2.imwrite("result.jpg", result)

※追記1(2018/01/04 20:20)※
  誤検出を減らすように、テンプレートマッチングの結果から
"max_val"(グレースケールで最も高い輝度の値)が0.8より大きい時だけ 
枠表示をするように変更しました。
何回か試したところ、正常に検出できた場合の"max_val"は、ほぼ0.9以上。
誤検出の場合は、0.7以下でした。
そこで「エイヤッ」と、0.8を設定しました。


今回は検出する画像がjpg、テンプレート画像がpngという変則コードになってしまったが
実行できれば問題ない(本当かよ?)

実際のカードを作って、それらを並べ替えてやってみた。
元画像を印刷した後、切り取って数字カードを作る。

それらのカードを適当に並べ替えて検出してみた。

更に、枠を外してやってみた。

<結果>
・影があったり、余分な物が写っている画像でも、正常に検出ができた。

<問題点>
・検出する画像の数字部分とテンプレート画像のサイズが(大体)合っていないと、
以下のようになる。
間違った検出。画像の数字に対してテンプレートが小さい
 ・検出する画像が大きいと時間が掛かる。



2017年5月14日日曜日

Raspberry Pi Arch Linux ARMにOpenCV入れてみた

Arch Linux ARMにOpenCVとやらを入れてみた。
インストール自体は至極簡単。pacman(yaourt)任せでOK。
sudo pacman -S opencv
Pythonで使いたいので、"numpy"もインストールする。
sudo pacman -S python-numpy
"numpy"は、Pythonで数値計算を効率良く(高速に?)行う為のライブラリらしい。
これだけで、OpenCVが使えるようになる。
このようなBGR値を、操作することで画像処理を行っていく(らしい)。

ついでなので、画像での顔検出をやってみる。
下のページを参考にさせてもらいました。有り難うございます。
http://peaceandhilightandpython.hatenablog.com/entry/2016/02/18/194303
(自分の環境で動くように、パスの指定等は変更しています。)
検出用には、OpenCVをインストールすると標準で入っている、
"/usr/share/opencv/haarcascades/haarcascade_frontface_default.xml"
を使用する。
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import cv2
import numpy as np

faceCascade = cv2.CascadeClassifier('/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml')

img = cv2.imread('./face.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face = faceCascade.detectMultiScale(gray, 1.1, 3)

if len(face) > 0:
    for rect in face:
    cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (255, 255,255), thickness=2)
else:
    print("no face")

cv2.imwrite('detected.jpg', img)

元の画像(お馴染みの)

検出結果

試しに、180度回転して上下逆にした画像で実行してみた。
これは、"no face"となり、検出できなかった。

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月10日金曜日

Scratch 1.4へテキストファイルを読み込む

前回、Scratchのブロックを追加して、Linuxコマンドを送るようにしたので、
コマンドの出力結果をScratchへ読み込むブロックも作ってみる。

※言うまでもないですが、Scratchの改造は自己責任で!※
通常は、直接外部ファイルを読み込むためのブロックは用意されていないので、
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


ブロックの追加。

('addFile %s to %L' #- #addfile:toList: 'filename')

外部ファイルを読み込んで、Scratch側のリストに追加するメソッドを設定する。
読み込むファイルまでのパスを抽出し 、空ならデフォルトのパスにする。
空でなければ、抽出したパスを使う。その上でファイルの有無を確認して処理を進める。
一行ごとに指定したリストに追加して行く。
この、リストに追加して行く処理は、まるごとScratchの「(なにか)を(リスト)に追加する」
利用する。

リストに追加して行く処理を考えている最中に、内容をTwitterにつぶやいたところ、
Smalltalkに詳しいsumimさんからスマートな方法をご教示頂きました。 有難うございました。

addfile: t1 toList: t2 
    | path file |
    path _ FileDirectory dirPathFor: t1.
    path = '' ifTrue: [path _ FileDirectory default pathName].
    ((FileDirectory on: path)
        fileExists: t1)
        ifTrue: 
            [file _ FileStream readOnlyFileNamed: t1.
            file contentsOfEntireFile lines do: [:line | self append: line toList: t2]]


先に格納用のリストを作っておく。
前回追加したブロックで、コマンドの出力をファイルにリダイレクトする文字列を実行。
リダイレクトで指定したファイルを、格納用のリストに追加するように実行。

"ls > /home/o10yan/lstest.txt"で"ls"コマンドの結果をファイルにして、
それをScratchのリストに読み込む一連の流れをやってみた。

勿論、出力結果にこだわらなくても、平文テキストファイルの読み込み用としても使える。

2017年3月5日日曜日

Scratch 1.4からLinuxコマンドを使う

前回では、ServoBlasterと言う限られた条件化で動かしたが、
少しだけ書き換えて、Linuxコマンド全般を使えるようにしてみる。

※言うまでもないですが、Scratchの改造・シェルスクリプトの実行は自己責任で!※
通常は、直接Linuxコマンドを動かすためのブロックは用意されていないので、
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


ブロックの追加。

('shell %s' #- #shell: '')

メソッドで、保存するファイル名を変更。
(ホームディレクトリは私の環境の場合なので、そこは御自分の環境に読み替えて下さい)

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


シェルスクリプトの指定ファイルも変更。
読み込んだ文字列(コマンド)をそのまま"eval"で評価して実行。

#!/bin/bash

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

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

    if [ -n '$text_line' ]; then
         echo '' > /home//o10yan/Scratch/shell
         eval $text_line
    fi
done

Scratchから"gpio readall"を送って見たところ
SLを走らせてみた

まとめ
やってることは非常に単純。
Scratchから文字列をファイルに保存する。
シェルスクリプトで、文字列をコマンドとして実行する。

現実的には、「遠隔センサー接続」を利用したり、scratchClient と言うソフトで
できるようなので、そちらを使った方が楽だと思います。
が、実験としては、面白かったです。

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年8月16日火曜日

ワークスペース毎に動くタイリング・シェルスクリプト

前回作成したシェルスクリプトを、ワークスペース毎に操作できるようにする実験


WmCtrlGtk(0)とWmCtrlGtk(1)で、それぞれワークスペース0とワークスペース1を別個に操作する。
(その分、シェルスクリプトから保存するファイルが増えてます。)

#!/bin/bash

PRE_IFS=$IFS
IFS=$'\n'

top_panel_h=0
bottom_panel_h=26
title_h=30
disp_width=$(xwininfo -root | grep 'Width' | cut -f2 -d ':')
disp_height=$(xwininfo -root | grep 'Height' | cut -f2 -d ':')
export current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)

if [ ! $(wmctrl -l | grep "WmCtrlGtk("$current_ws")") ]; then
    export MAIN_DIALOG$current_ws='
    <window title="WmCtrlGtk('$current_ws')">
        <hbox>
            <button>
                <label>h</label>
                <action>'$0' h 200</action>
            </button>
            <button>
                <label>v</label>
                <action>'$0' v 200</action>
            </button>
            <button>
                <label>r</label>
                <action>'$0' r</action>
            </button>
            <button>
                <label>+100</label>
                <action>'$0' 100</action>
            </button>
            <button>
                <label>-100</label>
                <action>'$0' -100</action>
            </button>
        </hbox>
    </window>
    '

    gtkdialog -p MAIN_DIALOG$current_ws -c
fi

rotate_flag=0
if [ $# -eq 1 ]; then
    if [ $1 = 'h' -o $1 = 'v' ]; then
        hv_flag=$1
        main_add=0
    elif [ $1 = 'r' ]; then
        rotate_flag=1
    elif [ $1 -gt 0 -o $1 -lt 0 ]; then
        rotate_flag=2
    else
        hv_flag='h'
    fi
elif [ $# -eq 2 ]; then
    hv_flag=$1
    main_add=$2
else
    exit 0
fi

temp_file='./wm-ctrl'$current_ws'.txt'
if [ $rotate_flag -gt 0 ]; then
    hv_flag=$(sed -n 1p ./wm-ctrl${current_ws}.his | cut -f1 -d',')
    main_add=$(sed -n 1p ./wm-ctrl${current_ws}.his | cut -f2 -d',')
    if [ $rotate_flag -eq 1 ]; then
        temp_1=$(sed -n 2p ./wm-ctrl${current_ws}.his)
        sed -i '$a '$temp_1'' ./wm-ctrl${current_ws}.his
        sed -i 1,2d ./wm-ctrl${current_ws}.his
    else
        sed -i 1d ./wm-ctrl${current_ws}.his
        main_add=$((main_add + $1))
    fi
    sed -i 's/_/ /g' ./wm-ctrl${current_ws}.his
    temp_file='./wm-ctrl'$current_ws'.his'
fi

wmctrl -l > wm-ctrl${current_ws}.txt
sed -i '/WmCtrlGtk/d' ./wm-ctrl${current_ws}.txt
txt_lines=$(wc $temp_file | sed 's/^[ \t]*//' | cut -f1 -d " ")
if [ $txt_lines -gt 0 ]; then
#    current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)
    #active_win=$(xprop -root -notype _NET_ACTIVE_WINDOW | cut -b 33-43)

    ws_windows=0
    for((i = 1; i <= $txt_lines; i++)); do
        ws_flag=$(sed -n $i'p' $temp_file | cut -b 12-13)
        if [ $ws_flag -eq $current_ws ]; then
            let ws_windows++
        fi
    done

    disp_width2=$((disp_width / 2))
    disp_height2=$(($(((disp_height - top_panel_h - bottom_panel_h) / 2)) - title_h))
    disp_width_main=$((disp_width2 + main_add))
    disp_height_main=$((disp_height2 + main_add))
    disp_width_sub=$((disp_width2 - main_add))
    disp_height_sub=$((disp_height2 - main_add))

    pos_width=$((disp_width / 2))
    pos_height=$(((disp_height - top_panel_h - bottom_panel_h) / 2))

    if [ $hv_flag = 'v' ]; then
        x_pos=(0 0 $pos_width $pos_width)
        y_pos=($((0 + top_panel_h)) $((pos_height + top_panel_h + main_add)) \
              $((pos_height + top_panel_h+ main_add)) $((0 + top_panel_h)))
    else
        x_pos=(0 $((pos_width + main_add)) $((pos_width + main_add)) 0)
        y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
              $((pos_height + top_panel_h)))
    fi

    case $ws_windows in
        1)
            temp_width=$disp_width
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));; 
        [2-3])
            temp_width=$disp_width2
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));;
        *)
            temp_width=$disp_width2
            temp_height=$disp_height2;;
    esac

    window_array=()
    n=0
    for((i = 1; i <= $txt_lines; i++)); do
        if [ $n -gt 3 ]; then
            n=0
        fi
        ws_flag=$(sed -n $i'p' $temp_file | cut -b 11-13)
        if [ $ws_flag -eq $current_ws ]; then
            win_id=$(sed -n $i'p' $temp_file | cut -b 1-10)
            if [ $rotate_flag -eq 0 ]; then
                if [ $n -eq 0 ]; then
                    echo $hv_flag','$main_add',' > wm-ctrl${current_ws}.his
                    echo $win_id'__'$current_ws'_' >> wm-ctrl${current_ws}.his
                else
                    echo $win_id'__'$current_ws'_' >> wm-ctrl${current_ws}.his
                fi
            fi
            if [ $ws_windows -eq 2 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                else
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_sub 
                    else
                        temp_width=$disp_width_sub
                        temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h))
                    fi
                fi
            fi            
            if [ $ws_windows -eq 3 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                fi
            fi
            if [ $ws_windows -gt 2 -a $n -gt 0 ]; then
                if [ $hv_flag = 'v' ]; then
                    temp_width=$disp_width2
                    temp_height=$disp_height_sub 
                else
                    temp_width=$disp_width_sub
                    temp_height=$disp_height2
                fi
            fi
            if [ $ws_windows -gt 3 -a $n -gt 0 ]; then
                x_pos=(0 $pos_width $pos_width 0)
                y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
                      $((pos_height + top_panel_h)))
                temp_width=$disp_width2
                temp_height=$disp_height2
            fi
            window_array+=( $win_id','${x_pos[$n]}','${y_pos[$n]}','$temp_width','$temp_height )
            let n++
        fi
    done

    for par in ${window_array[@]}; do
        for((i = 1; i <= 5; i++)); do
            declare par$i=$(echo ${par} | cut -f$i -d ',')
        done
        wmctrl -i -r $par1 -e 0,$par2,$par3,$par4,$par5
    done
fi

if [ $rotate_flag -gt 0 ]; then
    sed -i 's/ /_/g' ./wm-ctrl${current_ws}.his
    temp=$hv_flag','$main_add','
    sed -i '1i '$temp'' ./wm-ctrl${current_ws}.his
fi

2016年7月3日日曜日

GtkDialogでOpenboxウィンドウのタイリング

前回、作成したシェルスクリプトをGtkDialogを使ってGUI操作できるようにする実験


※追記1(2016/07/09 21:00)※
一応、上部にパネルを表示している場合を想定。
top_panel_hで高さを指定する。

#!/bin/bash

PRE_IFS=$IFS
IFS=$'\n'

top_panel_h=0
bottom_panel_h=26
title_h=30
disp_width=$(xwininfo -root | grep 'Width' | cut -f2 -d ':')
disp_height=$(xwininfo -root | grep 'Height' | cut -f2 -d ':')

if [ ! $(wmctrl -l | grep "WmCtrlGtk") ]; then
    export MAIN_DIALOG='
    <window title="WmCtrlGtk">
        <hbox>
            <button>
                <label>h</label>
                <action>'$0' h</action>
            </button>
            <button>
                <label>v</label>
                <action>'$0' v</action>
            </button>
            <button>
                <label>r</label>
                <action>'$0' r</action>
            </button>
            <button>
                <label>+100</label>
                <action>'$0' 100</action>
            </button>
            <button>
                <label>-100</label>
                <action>'$0' -100</action>
            </button>
        </hbox>
    </window>
    '

    gtkdialog -p MAIN_DIALOG -c
fi

rotate_flag=0
if [ $# -eq 1 ]; then
    if [ $1 = 'h' -o $1 = 'v' ]; then
        hv_flag=$1
        main_add=0
    elif [ $1 = 'r' ]; then
        rotate_flag=1
    elif [ $1 -gt 0 -o $1 -lt 0 ]; then
        rotate_flag=2
    else
        hv_flag='h'
    fi
elif [ $# -eq 2 ]; then
    hv_flag=$1
    main_add=$2
else
    exit 0
fi

temp_file='./wm-ctrl.txt'
if [ $rotate_flag -gt 0 ]; then
    hv_flag=$(sed -n 1p ./wm-ctrl.his | cut -f1 -d',')
    main_add=$(sed -n 1p ./wm-ctrl.his | cut -f2 -d',')
    if [ $rotate_flag -eq 1 ]; then
        temp_1=$(sed -n 2p ./wm-ctrl.his)
        sed -i '$a '$temp_1'' ./wm-ctrl.his
        sed -i 1,2d ./wm-ctrl.his
    else
        sed -i 1d ./wm-ctrl.his
        main_add=$((main_add + $1))
    fi
    sed -i 's/_/ /g' ./wm-ctrl.his
    temp_file='./wm-ctrl.his'
fi

wmctrl -l > wm-ctrl.txt
sed -i '/WmCtrlGtk/d' ./wm-ctrl.txt
txt_lines=$(wc $temp_file | sed 's/^[ \t]*//' | cut -f1 -d " ")
if [ $txt_lines -gt 0 ]; then
    current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)
    #active_win=$(xprop -root -notype _NET_ACTIVE_WINDOW | cut -b 33-43)

    ws_windows=0
    for((i = 1; i <= $txt_lines; i++)); do
        ws_flag=$(sed -n $i'p' $temp_file | cut -b 12-13)
        if [ $ws_flag -eq $current_ws ]; then
            let ws_windows++
        fi
    done

    disp_width2=$((disp_width / 2))
    disp_height2=$(($(((disp_height - top_panel_h - bottom_panel_h) / 2)) - title_h))
    disp_width_main=$((disp_width2 + main_add))
    disp_height_main=$((disp_height2 + main_add))
    disp_width_sub=$((disp_width2 - main_add))
    disp_height_sub=$((disp_height2 - main_add))

    pos_width=$((disp_width / 2))
    pos_height=$(((disp_height - top_panel_h - bottom_panel_h) / 2))

    if [ $hv_flag = 'v' ]; then
        x_pos=(0 0 $pos_width $pos_width)
        y_pos=($((0 + top_panel_h)) $((pos_height + top_panel_h + main_add)) \
              $((pos_height + top_panel_h+ main_add)) $((0 + top_panel_h)))
    else
        x_pos=(0 $((pos_width + main_add)) $((pos_width + main_add)) 0)
        y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
              $((pos_height + top_panel_h)))
    fi

    case $ws_windows in
        1)
            temp_width=$disp_width
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));; 
        [2-3])
            temp_width=$disp_width2
            temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h));;
        *)
            temp_width=$disp_width2
            temp_height=$disp_height2;;
    esac

    window_array=()
    n=0
    for((i = 1; i <= $txt_lines; i++)); do
        if [ $n -gt 3 ]; then
            n=0
        fi
        ws_flag=$(sed -n $i'p' $temp_file | cut -b 11-13)
        if [ $ws_flag -eq $current_ws ]; then
            win_id=$(sed -n $i'p' $temp_file | cut -b 1-10)
            if [ $rotate_flag -eq 0 ]; then
                if [ $n -eq 0 ]; then
                    echo $hv_flag','$main_add',' > wm-ctrl.his
                    echo $win_id'__'$current_ws'_' >> wm-ctrl.his
                else
                    echo $win_id'__'$current_ws'_' >> wm-ctrl.his
                fi
            fi
            if [ $ws_windows -eq 2 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                else
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_sub 
                    else
                        temp_width=$disp_width_sub
                        temp_height=$((disp_height - top_panel_h - bottom_panel_h - title_h))
                    fi
                fi
            fi            
            if [ $ws_windows -eq 3 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                fi
            fi
            if [ $ws_windows -gt 2 -a $n -gt 0 ]; then
                if [ $hv_flag = 'v' ]; then
                    temp_width=$disp_width2
                    temp_height=$disp_height_sub 
                else
                    temp_width=$disp_width_sub
                    temp_height=$disp_height2
                fi
            fi
            if [ $ws_windows -gt 3 -a $n -gt 0 ]; then
                x_pos=(0 $pos_width $pos_width 0)
                y_pos=($((0 + top_panel_h)) $((0 + top_panel_h)) $((pos_height + top_panel_h)) \
                      $((pos_height + top_panel_h)))
                temp_width=$disp_width2
                temp_height=$disp_height2
            fi
            window_array+=( $win_id','${x_pos[$n]}','${y_pos[$n]}','$temp_width','$temp_height )
            let n++
        fi
    done

    for par in ${window_array[@]}; do
        for((i = 1; i <= 5; i++)); do
            declare par$i=$(echo ${par} | cut -f$i -d ',')
        done
        wmctrl -i -r $par1 -e 0,$par2,$par3,$par4,$par5
    done
fi

if [ $rotate_flag -gt 0 ]; then
    sed -i 's/ /_/g' ./wm-ctrl.his
    temp=$hv_flag','$main_add','
    sed -i '1i '$temp'' ./wm-ctrl.his
fi

2016年6月19日日曜日

wmctrlでOpenboxウィンドウのタイリング

wmctrlを使ったシェルスクリプトでOpenboxのウィンドウを
タイリング操作してみる。


(録画にリソースをとられているので緩慢な動きですが、
実際は、、、。もう少しだけマシかな?)

※一応スクリプトを載せますが、ググればもっと素晴らしいスクリプトが出てくるので、
興味のある方はそちらを見てくださいね。
https://bbs.archlinux.org/viewtopic.php?id=119020
尚、スクリプトには別途、wmctrl とxorg-apps のインストールが必要です※

※追記1(2016/06/21 20:25)※
スクリプトの書式を変更。機能的な変化はなし。
※追記2(2016/06/27 21:50)※
余分な処理を削除。機能的な変化なし。
※追記3(2016/06/28 22:30)※
メインウィンドウのローテーションを保持したままサイズ変更出きるようにした。
第一引数に数値(ピクセル単位)だけを指定すると、メインウィンドウのサイズが変更される。
プラスの数値で広く、マイナスの数値で狭くなる。
<使い方>
第一引数には、h、v、r及び数値の指定ができる。
h  ウィンドウを横に並べる。第2引数に数値を指定すると、その数値の分だけメインウィンドウが広くなる。
v  ウィンドウを縦に並べる。第2引数に数値を指定すると、その数値の分だけメインウィンドウが広くなる。
r  メインウィンドウを入れ替える(ローテートする)。
数値  メインウィンドウのサイズ変更。
(ウィンドウが4つ以上だと、メインの意味はなくなるので注意)

#!/bin/bash

PRE_IFS=$IFS
IFS=$'\n'

panel_h=28
title_h=28
disp_width=$(xwininfo -root | grep 'Width' | cut -f2 -d ':' | sed 's/^[ \t]*//')
disp_height=$(xwininfo -root | grep 'Height' | cut -f2 -d ':' | sed 's/^[ \t]*//')

rotate_flag=0
if [ $# -eq 1 ]; then
    if [ $1 = 'h' -o $1 = 'v' ]; then
        hv_flag=$1
        main_add=0
    elif [ $1 = 'r' ]; then
        rotate_flag=1
    elif [ $1 -gt 0 -o $1 -lt 0 ]; then
        rotate_flag=2
    else
        hv_flag='h'
        #main_add=$1
    fi
elif [ $# -eq 2 ]; then
    hv_flag=$1
    main_add=$2
else
    hv_flag='h'
    main_add=0
fi

temp_file='./wm-ctrl.txt'
if [ $rotate_flag -gt 0 ]; then
    hv_flag=$(sed -n 1p ./wm-ctrl.his | cut -f1 -d',')
    main_add=$(sed -n 1p ./wm-ctrl.his | cut -f2 -d',' | sed 's/^[ \t]*//')
    if [ $rotate_flag -eq 1 ]; then
        temp_1=$(sed -n 2p ./wm-ctrl.his)
        sed -i '$a '$temp_1'' ./wm-ctrl.his
        sed -i 1,2d ./wm-ctrl.his
    else
        sed -i 1d ./wm-ctrl.his
        main_add=$((main_add + $1))
    fi
    sed -i 's/_/ /g' ./wm-ctrl.his
    temp_file='./wm-ctrl.his'
fi

wmctrl -l > wm-ctrl.txt
txt_lines=$(wc $temp_file | sed 's/^[ \t]*//' | cut -f1 -d " ")
if [ $txt_lines -gt 0 ]; then
    current_ws=$(xprop -root -notype _NET_CURRENT_DESKTOP | cut -b 24)
    #active_win=$(xprop -root -notype _NET_ACTIVE_WINDOW | cut -b 33-43)

    ws_windows=0
    for((i = 1; i <= $txt_lines; i++)); do
        ws_flag=$(sed -n $i'p' $temp_file | cut -b 12-13)
        if [ $ws_flag -eq $current_ws ]; then
            let ws_windows++
        fi
    done

    disp_width2=$((disp_width / 2))
    disp_height2=$(($(((disp_height - panel_h) / 2)) - title_h))
    disp_width_main=$((disp_width2 + main_add))
    disp_height_main=$((disp_height2 + main_add))
    disp_width_sub=$((disp_width2 - main_add))
    disp_height_sub=$((disp_height2 - main_add))

    pos_width=$((disp_width / 2))
    pos_height=$(((disp_height - panel_h) / 2))

    if [ $hv_flag = 'v' ]; then
        x_pos=(0 0 $pos_width $pos_width)
        y_pos=(0 $((pos_height + main_add)) $((pos_height + main_add)) 0)
    else
        x_pos=(0 $((pos_width + main_add)) $((pos_width + main_add)) 0)
        y_pos=(0 0 $pos_height $pos_height)
    fi

    case $ws_windows in
        1)
            temp_width=$disp_width
            temp_height=$((disp_height - panel_h - title_h));; 
        [2-3])
            temp_width=$disp_width2
            temp_height=$((disp_height - panel_h - title_h));;
        *)
            temp_width=$disp_width2
            temp_height=$disp_height2;;
    esac

    window_array=()
    n=0
    for((i = 1; i <= $txt_lines; i++)); do
        if [ $n -gt 3 ]; then
            n=0
        fi
        ws_flag=$(sed -n $i'p' $temp_file | cut -b 11-13 | sed 's/^[ \t]*//')
        if [ $ws_flag -eq $current_ws ]; then
            win_id=$(sed -n $i'p' $temp_file | cut -b 1-10)
            if [ $rotate_flag -eq 0 ]; then
                if [ $n -eq 0 ]; then
                    echo $hv_flag','$main_add',' > wm-ctrl.his
                    echo $win_id'__'$current_ws'_' >> wm-ctrl.his
                else
                    echo $win_id'__'$current_ws'_' >> wm-ctrl.his
                fi
            fi
            if [ $ws_windows -eq 2 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                else
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_sub
                    else
                        temp_width=$disp_width_sub
                        temp_height=$((disp_height - panel_h - title_h))
                    fi
                fi
            fi            
            if [ $ws_windows -eq 3 ]; then
                if [ $n -eq 0 ]; then
                    if [ $hv_flag = 'v' ]; then
                        temp_width=$disp_width
                        temp_height=$disp_height_main
                    else
                        temp_width=$disp_width_main
                    fi
                fi
            fi
            if [ $ws_windows -gt 2 -a $n -gt 0 ]; then
                if [ $hv_flag = 'v' ]; then
                    temp_width=$disp_width2
                    temp_height=$disp_height_sub
                else
                    temp_width=$disp_width_sub
                    temp_height=$disp_height2
                fi
            fi
            if [ $ws_windows -gt 3 -a $n -gt 0 ]; then
                x_pos=(0 $pos_width $pos_width 0)
                y_pos=(0 0 $pos_height $pos_height)
                temp_width=$disp_width2
                temp_height=$disp_height2
            fi
            window_array+=( $win_id','${x_pos[$n]}','${y_pos[$n]}','$temp_width','$temp_height )
            let n++
        fi
    done

    for par in ${window_array[@]}; do
        for((i = 1; i <= 5; i++)); do
            declare par$i=$(echo ${par} | cut -f$i -d ',')
        done
        wmctrl -i -r $par1 -e 0,$par2,$par3,$par4,$par5
    done
fi

if [ $rotate_flag -gt 0 ]; then
    sed -i 's/ /_/g' ./wm-ctrl.his
    temp=$hv_flag','$main_add','
    sed -i '1i '$temp'' ./wm-ctrl.his
fi

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 

2016年5月15日日曜日

Raspberry Pi Arch Linux ARMでのWiringPi事情

 The wiringpi2 module has been deprecated, please 'import wiringpi' instead.


以前「4足歩行ロボットを作ってみよう(その1)」でWiringPiを紹介したが、
その時と事情が変わった模様。

前回は、Python用のラッパーWiringPi2-Pythonを使ったが、2016/5/15現在
そのままでは動かない事が分かった。

改めて、WiringPiをインストールして動作確認したので、その方法を書く。

クリーンな状態からやり直すためWiringPiをアンインストールし前回"git clone"した
ディレクトリを削除しておく。

WiringPiをインストール
$ sudo pacman -S wiringpi

こちら https://github.com/WiringPi/WiringPi-PythonのREADME.mdを参照しつつ
ツール関係をインストール
$ sudo pacman -S python-setuptools swig

GITからWiringPi-Pythonをインストール
$ git clone --recursive https://github.com/WiringPi/WiringPi-Python.git
$ cd ./WiringPi-Python
$ swig -python wiringpi.i
$ sudo python3 setup.py install

※上記のswigを忘れない事!!※

これでラッパーが使えるようになるが、Python3でラッパーを呼び出す際に
"import wiringpi2"としていたのが、"import wiringpi"となるので、以前に書いた
コードがあれば修正しておく
Python3で"import wiringpi2"とすると"ImportError"になる。

 ※追記1(2016/05/15 16:50)※
上記の方法でなくとも、別途"python-pip"をインストールの上で、
$ sudo pip3 install wiringpi
することで、簡単にインストール出来ました。


 ※追記2(2017/04/10 20:10)※
kernelが4.9系の場合は、こちらのneuralassemblyさんの修正版をインストールしてください。
(pip3でインストールしていた場合は、予めアンインストールしておいてください)

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 

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