2023年4月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            

カテゴリー

ブログパーツ

無料ブログはココログ

« 2016年3月 | トップページ | 2016年5月 »

2016年4月

2016年4月30日 (土)

Arduinoで動かすアームロボットBraccio

久しぶりの「ウィークエンド」です。今回は入門者向けのアームロボットキットを組み立てます。Arduino.orgで開発したBraccioという6軸ロボットです。

購入はいつものスイッチサイエンスです。こちらのページです。Arduino同様、かなりオシャレなパッケージングです。

Dscn3418  Dscn3420

組み立てはラジコンカー程度ですから、あまりキット慣れしてない人でも大丈夫だと思います。とはいえ幾つか注意すべきことがあります。ほとんどの部分を止めるタッピングビスが短いので、あまり力を入れるとポストを舐めて効かなくなる恐れがあります。マニュアルにも「あまり力を入れて締めるな」とあるくらいです。精密ドライバーのような柄の細いものを使えば、力が入らず安心して作業できます。

もう一つ、写真を撮りそこないましたが、ベース部分にアーム全体にテンションをかける引きバネが入っています。これを2mmのタッピングで取り付けるようになっているのですが、引きバネのあなが大きいので、タッピングの頭に引っかからないため、外れやすくなっています。引きバネのあなをラジオペンチで少しつぶして、タッピングの頭から外れないようにしておきます。これが外れてしまうと、アームが持ち上がりにくくなってしまいます。

Dscn3425

動作にはArduinoが必要です。僕は手持ちのUNOを使いました。テストするときに迷ったのはライブラリをどこからダウンロードするかです。だいぶ探しましたが見つかりません。どうもIDEに組み込まれているようで、最新版をインストールしたらexampleでBraccioのサンプルやライブラリが入ってました。動作の様子です。

ラジコンサーボを使ったものとしては、バランスよくできていると思います。ただ、PWMサーボなので、電源投入時に全体がいきなり動くのでびっくりします。立ち上げサイクルを工夫しないといけないようです。

役に立つかどうかはともかく、Hanabot2に乗っけるとこんな感じになります。なんかいい感じです。

Dscn3427

2016年4月29日 (金)

Hanabot2、ちょっと改良しました

今までのテストを受けて、ちょっと改良しました。

まずはウィリー防止の尾輪の追加です。Hanabot2は重いバッテリーを前部に搭載して、ウィリーしにくいバランスにしたつもりですが、それでも発進時などに尻餅をつくことがあります。これは駆動輪より後ろに支えがないためなので、写真のように「尾輪」を追加しました。

Dscn3415

これは取り付け高42mm、タイヤ径32mmのキャスターを、路面すれすれになるよう木片で高さを揃え、フレームのズレ止めにボンドで接着しただけです。作り方は下記写真をみてください。特に説明は必要ないでしょう。

Dscn3404

Dscn3406  Dscn3405

Dscn3407  Dscn3409

キャスターはなるべく軽いほうがいいでしょう。前記したように尾輪は路面すれすれにします。これだとカーペットに乗り上げた時など、前輪と尾輪が両方接地して駆動輪が浮きそうですが、roombaの駆動輪には路面を押さえつける方向にテンションが掛かっているので、空回りすることはありません。

これでウイリーしなくなったので、本家同様建増ししました。こんな風になります。

Dscn3416  Dscn3417  Dscn3410

高さは本家の図面に合わせています。簡単な木工で完成できるよう工夫しました。寸法は後ほど投稿します。結構しっかりしているので、おなじみLenovoのx201くらいなら載せられます。もう一台ラズパイ2を乗せて、画像認識や音声認識をさせるのも面白いでしょう。ROSを使うと分散処理が簡単なので、こんな実験が気軽にできそうです。

2016年4月19日 (火)

ubuntuラズパイのWiFi接続

この一連の投稿でラズパイ2にubuntu14.04LTSとROS(indigo)のインストール法を解説しました。ただし、無線LAN接続でうまくいかないという話を聞き、追試してみました。

僕の環境では無線LANのセキュリティはWEPですから、むかしの投稿のように/etc/network/interfacesに直接書き込んで接続できています。これには家中のネット機器がつながっていて実験には向かないので、安物のルーターを接続実験用に購入しました。どこかでROSのデモをするときに使えるでしょう。

接続テストをしてみると、一般的なWPAだとこのサイトのようにやっても接続できません。

Dscn3400

ずいぶん調べた結果、wpa_supplicantというものが入ってないためだとわかりました。wpaでの暗号化をサポートするライブラリのようです。下記でインストールできます。

$ sudo apt-get install wpasupplicant

これで参考サイトのようにできるかと安心してはじめましたが、なかなか思うようにいきませんでした。そこで手順をまとめておきます。SSIDやパスワードは写真のルーターのデフォルトのものです。また、ルーターのLANアドレスは192.168.2.100~255になっています。

$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

を実行してエディタでwpa_supplicant.confを作成、下記の内容を書き込みます。今回はパスワードを見えるようにしてありますがwpa_passphraseで暗号化しても問題ありません。

network={
        ssid="elecom2g-28c411"
        psk="4710683369282"                                                    
 key_mgmt=WPA-PSK
 proto=WPA2
}

次はinterfacesを下記のように編集します。IPを192.168.2.152に固定しています。

$ sudo nano /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8) Include files from
# /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

# The loopback network interface
auto lo
 iface lo inet loopback

# The primary network interface(以下2行をコメントアウトすると起動が早い)
auto eth0
 iface eth0 inet dhcp

auto wlan0
 allow-hotplug wlan0
 iface wlan0 inet static
 address 192.168.2.152
 netmask 255.255.255.0
 gateway 192.168.2.1
 network 192.168.2.0
 dns-nameservers 192.168.2.1
 wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

iface default inet dhcp

起動には数分かかかります。イーサネットの接続待ちをしているためのようです。eth0をコメントアウトすると起動がとても早くなりますが、イーサネットで接続できなくなります。

2016年4月16日 (土)

光を追いかけるロボットをROSで作る(おしまい)

回路ができたら前回の投稿と同じ手順で、CDSに懐中電灯で光をあてるとLEDが点灯することを確認しておきます。感度は半固定抵抗VRをドライバーで回して調整します。

Dscn3385

最後にトピックbrinkcontをサブスクライブして、turtlebotを動かすトピックcmd_vel_mux/input/naviをパブリッシュするノードのpythonプログラム、seeker.pyを下記のように作り、パッケージrptestフォルダのscriptsにおきます。

#!/usr/bin/env python
import roslib
import rospy
import time

from geometry_msgs.msg import Twist
from sensor_msgs.msg import Joy

#callback
def joy_callback(light_sens):
    if light_sens.buttons[0] == 1: # light in
        twist.linear.x = 0.1
        twist.angular.z = 0
    else:
        twist.linear.x = 0
        twist.angular.z = 0.4
    pub.publish(twist)


#main
if __name__ == '__main__':
    
    rospy.init_node('light_seeker')
    rospy.Subscriber('brinkcont' , Joy ,joy_callback)    
    pub = rospy.Publisher('cmd_vel_mux/input/navi', Twist, queue_size=10)
    twist = Twist()
        
    rospy.spin()

内容は簡単なので説明は割愛します。ついでにローンチファイルも作っておきましょう。下記内容で、lightseeker.launchという名前のローンチファイルを作り、パッケージrptestフォルダにlaunchフォルダを作り、そこに置きます。

<launch>
    <node pkg="rptest" type="dsens.py" name="dsens" />
    <node pkg="rptest" type="brinker.py" name="brinker" />
    <node pkg="rptest" type="seeker.py" name="lightseeker" />
</launch>

brinkerノードはCDSが反応したかどうかモニターするだけなので起動しなくとも良いのですが、うまく動かない時に原因がわかりやすいので起動しておいたほうが良いです。

下記手順で起動するとビデオのように動きます。試してみてください。

$ roslaunch turtlebot_bringup minimal.launch

$ roslaunch rptest lightseeker.launch

こんな簡単なプロジェクトでも実際にROSで動かすものを作ってみると、いろいろとわかることが多いと思います。

光を追いかけるロボットをROSで作る(1)

ラズパイでROSのまとめとして、小学生が作るようなメカトロロボットを作ってみます。例えばこんなものです。

Dscn3392  Dscn3391_2

これは今から50年以上前、東京オリンピック前年の「模型とラジオ」に掲載された、懐中電灯で操縦する宇宙探検車です。ペンライトで光をあてるとその方向に進んできます。  簡単なセンサーロボットですが、当時はラジコンですらハイテクだったわけですから、少年向けとしてはなかなか高度な製作記事だったと思います。

コレに習い、懐中電灯で光をあてるとその方に寄ってくるロボットを、ROSとHanabot2で作ります。なんでまたこんなことをしてみたかというと、ハードから入ってきたホビーストにはちょっととっつきにくいROSの仕組みが、単純でハードに近いプロジェクトをやってみることで理解がしやすくなるのではないかと思ったからです。ともかくやってみましょう。

完成品の動画です。

見てお判りの通りブレットボードにCDSを利用した光センサを組み立て、前回の実験の押しボタン代わりにしています。ここに懐中電灯で光をあてると、その場で旋回しているロボットが前進するわけです。CDSは筒に入れ、前方の光のみに反応するようにしておけば、ロボットは光の方へ進んで行くということになります。

回路はこのようになりました。CDSは懐中電灯で光を浴びた時に数K〜20Kオームくらいになるものを選んでいます。

Cds_2

以前の投稿のボタンの代わりにCDSが入っているだけです。暗いところではCDSは数百Kオームと高い抵抗値を示しますが、光が入るとCDSの抵抗値が数Kオームまで下がり、入力に設定したGPIO 9ポートが、ボタンを押した時のように0レベルになります。感度は半固定抵抗VRで調整します。VRを回し切るとGPIO 9が電源に直結してしまうので、万一GPIO 9が出力に設定されてしまうと大きな電流が流れ、ポートを壊す可能性があります。そこで470オームの抵抗を入れて電流制限としています。これは100オームくらいから1Kオームくらいまでであれば良いですから、念のため入れておいた方が安心です。

ブレットボードにこのように実装しました。CDSは黒い筒をかぶせて周囲の光をカットしてあります。プラスチックのパイプで作りましたが、それほど厳密に遮光する必要もないので、紙やビニールテープで作っても構いません。

Dscn3383

次回は追跡用のノードとローンチファイルを作ります。

2016年4月 5日 (火)

GPIOをノード間通信で使う

ラズパイ2のI/Oポートを使うと、ROSの機能を、ボタンやLEDのような実際のハードを使って、とてもわかりやすく試すことが出来ます。これは案外ROS入門の良い教材になるのかもしれません。ということで、ちょっとこの辺を掘り下げておきたいと思います。

今回はノードを二つ作ります。デジタル入力の状態をbrinkcontというトピックでパブリッシュするdsensと、それをサブスクライブしてLEDをコントロールするbrinkerです。rqtでモニターするとこうなっています。

Nodemap

トピックbrinkcontのtypeはsensor_msgs/Joy、つまりゲームパッドで使われるトピックです。これは、ボタンの値を入れるint32と、アナログスティックの値を入れるfloat32の配列を受け渡しできるので、複数のデータを渡したいときに便利です。もっとも今回は1ビットだけの情報ですが。

dsensノードのpythonコードdsens.pyです。ポート9を入力に設定し、これが1か0かをJoy型のトピックbrinkcontのbuttons[0]フィールドに入れてパブリッシュします。ポートは数Kオームの抵抗で3.3Vにプルアップし、ボタンを押すとGNDに落ちるように配線します。

buttonsフィールドの要素はbuttons[0,0]とやって二つ定義していますが、うち一つしか使ってませんし、axesにいたっては定義していません。定義しないのはどうかなと思いましたが、基本、サブスクライブ側で使ってなければそれでいいようです。

#!/usr/bin/env python
import roslib
import rospy
import time
import wiringpi
import subprocess
from sensor_msgs.msg import Joy

#main
if __name__ == '__main__':
    ### init io port ###
    subprocess.check_call('gpio export 9 in',shell=True)
    ###
    rospy.init_node('dsens')
    rate = rospy.Rate(10.0)
    # create object from sensor_msgs/Joy
    s = Joy()
    s.buttons = [0,0] # Two button data
    s.header.frame_id = 'base_link' # not use
    # create publisher with topic 'brinkcont'
    pub = rospy.Publisher('brinkcont', Joy, queue_size=10)
    # io pin setting
    io = wiringpi.GPIO(wiringpi.GPIO.WPI_MODE_SYS)
    io.pinMode(9,io.INPUT)  # Setup pin 9 degital input

    while not rospy.is_shutdown():
        s.header.stamp = rospy.get_rostime()
        sens = io.digitalRead(9)
        if sens == 1:
            s.buttons[0] = 0
        else:
            s.buttons[0] = 1
        pub.publish(s)
        rate.sleep()
    print('\n\rStopped')

お次ぎはサブスクライブ側です。brinkerノードのpythonコードbrinker.pyです。これは前回のflash.pyに似ていますが、ポート11に赤、8に緑のLEDを接続しました。いずれも1で点灯するように配線します。このノードはサブスクライブしたトピックbrinkcontのbuttons[0]で赤、[1]で緑のLEDが点灯するようになっています。

#!/usr/bin/env python
import roslib
import rospy
import wiringpi
import subprocess
from sensor_msgs.msg import Joy

#callback
def joy_callback(new_joy):
    if new_joy.buttons[0] == 1:
        io.digitalWrite(11,1) # turn on red
    else:
        io.digitalWrite(11,0) # turn off red
    if new_joy.buttons[1] == 1:
        io.digitalWrite(8,1) # turn on green
    else:
        io.digitalWrite(8,0) # turn off green

#main
if __name__ == '__main__':
    ### init io port ###
    subprocess.check_call('gpio export 11 out',shell=True)
    subprocess.check_call('gpio export 8 out',shell=True)
    ###
    rospy.init_node('brinker')
    # io pin setting
    io = wiringpi.GPIO(wiringpi.GPIO.WPI_MODE_SYS)
    io.pinMode(11,io.OUTPUT)  # Setup pin 11 (red)
    io.pinMode(8,io.OUTPUT)  # Setup pin 8 (green)

    rospy.Subscriber('brinkcont' , Joy ,joy_callback) 

    rospy.spin()

テストするにはroscore、dsens.py、brinker.pyをそれぞれターミナルで起動した後、dsensがハンドルしているボタンを押すと、brinkerが応答して赤いLEDが点灯します。

Dscn3367  Dscn3368

2016年4月 2日 (土)

ROSでLチカ

今回はROSのノードとして実行できるLチカコードを作ります。まずは作業用のパッケージとしてrptestというのを作りました。ラズパイの勉強用パッケージという訳ですが、もちろん、名前は好きなものでかまいません。パッケージの作り方は以前の投稿を見てください。

パッケージのscrptsディレクトリの中にflash.pyという名前でLチカのコードを書きます。実行可能にしておくのをお忘れなく。簡単にはchmod 777 flash.pyで大丈夫です。

#!/usr/bin/env python
import roslib
import rospy
import time
import wiringpi
import subprocess

#main
if __name__ == '__main__':
    ### init io port ###
    subprocess.check_call('gpio export 11 out',shell=True)
    subprocess.check_call('gpio export 8 out',shell=True)
    ###
    rospy.init_node('ledflash')

    io = wiringpi.GPIO(wiringpi.GPIO.WPI_MODE_SYS)
    io.pinMode(11,io.OUTPUT)  # Setup pin 11
    io.pinMode(8,io.OUTPUT)  # Setup pin 8 

    while not rospy.is_shutdown():
        io.digitalWrite(11,1)
        io.digitalWrite(8,0)
        time.sleep(1)
        io.digitalWrite(11,0)
        io.digitalWrite(8,1)
        time.sleep(1)

    print('\rStopped')

最近ようやくきれいにコードをブログに載せることができるようになりました。このコードは11と8に接続したLEDを交互に点滅させるものです。

Dscn3366

注目しておきたいのは、subprocess.check_call('gpio export 11 out',shell=True)とその次の行です。これは括弧内のシェルコマンドを実行する記述で、このシェルコマンドでポート11と8をOUTPUTに設定しています。これを使うにはimport subprocessを記述しておく必要があります。

wiringPi-Pythonのラッパーを使うにはimport wiringpiを記述しておきます。この辺は情報が多く、また錯綜している感があるので、ともかく入出力ができることのみに専念しています。ポートの設定はちょっと苦労しましたが、結局gpio exportをつかうことでsudoなしで実行することができました。これはポートの入出力を設定するgpioコマンドで、このようにするとポートはその後プログラムでoutポートとしてアクセスすることが出来ます。よく例にあるgpio -g modeで設定すると、gpio writeコマンドだと使えますが、プログラムからは使えません。

gpio exportは一度設定すると再ログインするまではそのままなので、このようにプログラムで書かなくとも、シェルスクリプトで一回実行しておく方法でも良いのですが、必要なポートの設定はプログラムに書いた方が使いやすいと思います。

実行するにはroscoreを起動した後、rosrun rptest flash.pyでROSのノードとして実行します。次はメッセージを追加してそれらしくしてみます。

2016年4月 1日 (金)

ROSでラズパイ2のGPIOを使う

以前の投稿でラズパイ2のGPIOをテストしましたが、pythonで書いたLチカ実行にはsudoが必要でした。rosrunで実行しようとするとsudoは出来ないので、ROSのノードからは事実上GPIOが使えません。これでは困るので対策しました。

手っ取り早く対策するには、Wiring PiというラズパイのI/Oにアクセスするモジュールを使えば良いようです。まずはこれをインストールしました。

作業用のディレクトリでインストール作業をします。僕はホーム直下にworkというディレクトリを作ってあり、ここを使っています。作業用のディレクトリに移動し、下記を実行します。

$ git clone git://git.drogon.net/wiringPi

wireingPiというディレクトリが出来るのでそこへ移動し、下記を実行します。

$ cd wiringPi
$ sudo ./build

このままだとpythonで使えないので、ラッパーのWiringPi-Pythonをインストールします。同様に作業用のディレクトリに移動して下記を実行します。

$ git clone https://github.com/WiringPi/WiringPi-Python.git
$ cd WiringPi-Python/
$ git submodule update --init
$ sudo python setup.py install

これでインストール終了です。rebootしたあと、wiringPiの機能の一部であるgpioコマンドを使ってテストします。ラズパイ2のgpio11にLEDを1で点灯するように接続して、下記コマンドを試してみます。

$ gpio export 11 out
$ gpio -g write 11 1

LEDが点灯すればインストール成功です。次回はLチカをROSから動かします。

« 2016年3月 | トップページ | 2016年5月 »