がたぶーのブログ

筆者の開発記録です。

ふと考え事1(メモ)

ふと、鏡で光を反射させる謎解きゲームを思い出し、どうやって実装されてるのかなと考えていた。(特に反射の部分)

 

鏡を光源として扱ってるのかなぁ。

光が当たると光を発するオブジェクトになってるのかなー。

そうすれば光が当たらなくなった場合に光を消すときも、アルゴリズム?が簡単になりそうだなぁ。

鏡の角度はどうやって変えてるのかなぁ。

鏡がタップされてスライドされたとき、そのときの角度を三角関数使って求めれば良さそうだなー。

 

と、考えていた。

この記事はただのメモ書きです。

久々の投稿

物事を続けるのが苦手だ。。。

ラズパイはまた今度書きます。(書くとは言ってない)

 

最近、ssdを買ったのでubuntuを入れました。

Windowsとは、違うディスクに書き込むので特に問題なく簡単にできました。

起動早々パスワードが正しく入力できずログインできないというトラブルはありましたが、GRUBメニューから Advanced option for Ubuntu > (recovery mode) に入り、root権限でユーザーのパスワードを変えるという方法で解決しました。

ubuntuのキーマッピングについてよく知らないので記号が正しく打てていないことがしばしばあります。

 

パスワードって簡単に変えられるんだなぁ...

 

メモ

users でユーザー一覧を見れる。(cat /etc/passwd)

passwd <username> でパスワードを変えられる。

Raspberry Pi3でラジコン製作(10)

本日はAndroid側プログラムについて書きます。

 

プログラムソースについて

Android側のプログラムについてはBluetooth周りのコードは「Androidプログラミングバイブル 布留川英一著」に書かれているものを丸写ししました。

Androidプログラミングバイブル SDK 7/6/5/4対応(布留川英一) | 書籍 本 | ソシム

 

いろいろと自分で試し、BluetoothChatを書き変えて作ろうとしていましたが、Androidのプログラムの書き方自体も理解が甘く、うまくいきませんでした。

 

最近Androidを学びなおしているところなので、細かい解説はしばらく先になるかもしれません。

 

アプリのふるまい


f:id:gataburo:20190213234136j:image

↑アプリ画面のスクリーンショット

 

 

ラズベリーパイの電源を入れた状態で、connectを押して接続すると左右のバーで操作できる状態になります。

それぞれ右タイヤ、左タイヤに対応し、真ん中が停止、上が正回転、下が逆回転です。

disconnectを押すと切断され、ラジコンは停止します。

reset valueを押すと0の位置にバーが移動します。

shutdownを押すとラズパイをシャットダウンできます。

 

アプリの解説

解説と言っても、今回はラズパイ側のプログラムを見て分かる程度しか書きません。

接続された状態でSeekBarが動いたとき、Bluetooth通信で、r20やr-30、l20などの値を送るようになっています。

disconnectではe、shutdownではe0が送られるようになっています。

 

次回

「ラズパイの電源を入れたとき、ラジコン用プログラムが実行されるようにする設定」の解説をします。

Raspberry Pi3でラジコン製作(9)

本日はRaspberryPi側のプログラムの内、Bluetooth通信に関する部分について書きます。

 

ライブラリのインポート

4. import bluetooth

 

接続まわり

 9. PORT = 22

13. bl_socket=bluetooth.BluetoothSocket(bluetooth.RFCOMM)

40. bl_socket.bind*1

42. bl_socket.listen(1)

45. client_socket,address = bl_socket.accept()

82. client_socket.close()

83. bl_socket.close()

なぜ一行だけ13行目に書いているのか...(しかも、定数定義の間...)

分かりにくいのでよくないですね。これはミスです。

 

プログラムの詳細はこちらのサイトで解説されています。Python and Bluetooth

注:筆者は説明できるほどはっきりと理解できていません。

PORTは

Raspberry Pi3でラジコン製作(7)>SDPサーバの準備>2.シリアルポートの...

で設定したchannel番号と一致させる必要があるみたいです。

 

データの受け取り

52. data = client_socket.recv(1024)

54. character = data[0]

55. digit = data[1:]

52行目でデータを受け取っています。

データは文字列で、次のものを想定しています。

"r[数値]"、"l[数値]"、"e" (例えば、"r25"や"l-22")

rはrightを意味し、lはleftを、eはexitを意味しています。

例えば、r24を受け取ると

右タイヤの逆回転用のPINの出力を切り、

右タイヤの正解転用のPINのPWMを(24/50に)セットします。

 

参考にしたサイト

Python and Bluetooth

RaspberryPi同士でbluetooth通信 - Qiita

 

コードの再掲

  1. # -*- coding: utf-8 -*-
  2.  
  3. import os
  4. import bluetooth
  5. import pigpio
  6. from time import sleep
  7.  
  8. #SerialPortは22番に設定している。
  9. PORT = 22
  10. #パッケージbluetooth内のBluetoothSocketクラスのインスタンスの生成
  11. #引数はRFCOMM,L2CAP,HCI,SCOから使うプロトコルを選択する。(初期化メソッドを使用)
  12. #RFCOMMはbluetoothモジュールの中で宣言されているためbluetooth.が必要
  13. bl_socket=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
  14. PIN_RF = 16 #右タイヤ前回転
  15. PIN_LF = 19 #左タイヤ前回転
  16. PIN_RR = 20 #右タイヤ後ろ回転
  17. PIN_LR = 26 #左タイヤ後ろ回転
  18. FREQ = 50
  19. RANGE = 50
  20.  
  21. pi = pigpio.pi()
  22.  
  23. def setPWM(pin, speed):
  24.         if 0 <= speed and speed <= RANGE:
  25.                 pi.set_PWM_frequency(pin, FREQ)
  26.                 pi.set_PWM_range(pin,RANGE)
  27.                 pi.set_PWM_dutycycle(pin, speed)
  28.  
  29. def stopCar():
  30.         setPWM(PIN_RF, 0)
  31.         setPWM(PIN_RR, 0)
  32.         setPWM(PIN_LF, 0)
  33.         setPWM(PIN_LR, 0)
  34.  
  35. stopCar()
  36. print "connect..."
  37.  
  38. #BluetoothSocketに定義されたbind関数を使用
  39. #bind(addrport)で使う。RFCOMMだと引数addrportは(host, channnel)
  40. bl_socket.bind( ("", PORT ))
  41. #受信可能状態にする。
  42. bl_socket.listen(1)
  43.  
  44. #接続がされるまで待ち、接続されたらそれを新しい通信として扱い、そのソケットとアドレスを返す。
  45. client_socket,adress = bl_socket.accept()
  46.  
  47. print "connection success"
  48.  
  49. while 1:
  50.               try:
  51.                 #1024バイトまでのデータを受け取る。
  52.                 data = client_socket.recv(1024)
  53.                 print "receive = %s" % data
  54.                 character = data[0]
  55.                 digit = data[1:]
  56.                 if digit.isdigit() or (digit[0] == '-' and digit[1:].isdigit()):
  57.                         speed = int(digit)
  58.                         #print "%d convert to number" % speed
  59.                         if character == 'r':
  60.                                 if speed >= 0:
  61.                                         setPWM(PIN_RR, 0)
  62.                                         setPWM(PIN_RF, speed)
  63.                                 else:
  64.                                         speed = -speed
  65.                                         setPWM(PIN_RF, 0)
  66.                                         setPWM(PIN_RR, speed)
  67.                         elif character == 'l':
  68.                                 if speed >= 0:
  69.                                         setPWM(PIN_LR, 0)
  70.                                         setPWM(PIN_LF, speed)
  71.                                 else:
  72.                                         speed = -speed
  73.                                         setPWM(PIN_LF, 0)
  74.                                         setPWM(PIN_LR, speed)
  75.                 if character == 'e':
  76.                         stopCar();
  77.                         if digit[0] == '0':
  78.                                 os.system("sudo shutdown -h now")
  79.                         break
  80.               except KeyboardInterrupt: #Ctrl+cでの中断時
  81.                 stopCar()
  82.                             client_socket.close()
  83.                             bl_socket.close()
  84.                             break
  85.               except: #何かしらのエラーが発生したとき
  86.                             print "error"
  87.                             print '\n'
  88.                 stopCar()
  89.                             client_socket.close()
  90.                             bl_socket.close()
  91.                             break

 

*1:"", PORT

Raspberry Pi3でラジコン製作(8)

さぼりで投稿が遅れてます(;・∀・)

本日はAndroidのBluetoothChatについて書きます。

 

BluetoothChatとは

Android SDKのサンプルコードの一つ。

Bluetoothを利用して双方向テキストチャットができる。

BluetoothChat - Bluetooth Chat | Android Developers

 

インストール

サンプルコードのダウンロードは次のページを参考にしました。

Java - bluetooth chat (android sdk サンプルコード内のもの)について|teratail

 

※BluetoothChatの中身はまだ理解していません。またの機会に中身について書こうと思います。

 

次回、Raspberry Pi3側プログラムの内、Bluetooth通信に関する部分について書きます。

Raspberry Pi3でラジコン製作(7)

本日はBluetoothでデータを送るテストをコマンドライン上でした話を書きます。

 

ペアリング

下記サイトを参考に、bluetoothctlでペアリングしました。

Linux PCにBluetooth機器を接続する - Qiita

 

SDPサーバの準備

下記サイトを参考に行いました。

ラズパイとBlueToothで通信してみるまでの話 - Qiita

  1. SDPサーバが使えることの確認。
    コマンドラインでsdptool browse localを実行。すると、今有効なサービスが確認できる。
  2. シリアルポートのサービスを追加
    コマンドラインでsdptool add --channel=22 SPを実行。
    channel22番でシリアルポートのサービスを追加。

 

通信のテスト

再びこちらのサイトを参考にしました。

ラズパイとBlueToothで通信してみるまでの話 - Qiita

  • rfcommをリッスン状態にする。
    コマンドライン上でsudo rfcomm listen /dev/rfcomm0 22を実行。
    (22はchannel番号、/dev/rfcomm0は通信相手とやり取りする窓口的な場所。sudo rfcomm listen 0 22とやっても同様の動作が得られる。)
  • PCからTeraTermを使用して接続。(AndroidからBluetoothChatを用いて接続※)
  • TeraTermのwindowで文字列を入力すると、Raspberry Pi側の/dev/rfcomm0に書き込まれる。
  • catコマンドやlessコマンドで/dev/rfcomm0を確認。※

 

AndroidのBluetoothChatについては次の機会に書きます。

※/dev/rfcomm0を見るときは別のコマンドプロンプトを開く。
 rfcommコマンドをバックグラウンドで実行させるのもありです。

ちなみに筆者はrfcommコマンドを終了させ、ファイルを開こうとしてました。rfcommコマンドで/dev/rfcomm0を一時的に作っているので、コマンドを終了させるとファイルがなくなり開けません。

 

※バックグラウンドでの実行について(忘れていたのでメモしておきます。)

バックグラウンドプロセス(ジョブ)の管理 - satake7’s memo

最後に&をつければ、バックグラウンドで起動。
jobsでプロセスを表示して、killで終了させる。

Raspberry Pi3でラジコン製作(6)

本日はBlueZについて書きます。

 

BlueZとは

BluZはLinuxおよびAndroidで動作するオープンソースBluetoothプロトコルスタックです。

Bluetoothのはなし(4)|Wireless・のおと|サイレックス・テクノロジー株式会社

筆者はBlueZとはなにか、まだつかめていません。。bluetoothをシリアルポートとして扱い、データをやり取りするために必要なのだと筆者は認識しています。
次回以降登場するbluetooth周りのコマンドなどは、ほぼ全てBlueZに含まれています。

公式サイトのABOUTもご参照ください。BlueZ

 

BlueZのインストール

こちらのサイトを参考に作業しました。

Raspberry Pi 3でBluetoothデバイス接続 - Tech Blog by Akanuma Hiroaki

ざっくりとしたことを書きます。

  1. bluez-5.45.tar.xzをインストール
  2. 解凍(2重に圧縮されているので2回)
  3. makefileを作る。
    (bluez-5.45/configureを実行するとmakeファイルが作られる。)
    ※足りないライブラリがあるとインストールするように指示されるのでインストールする。
  4. 生成されたmakeファイルを実行する。
  5. インストール(make install)

ちなみに...

makeファイルについて

makeファイルはコンパイルを行ってくれるものです。こちらのサイトに詳しく書かれています。第5章 Makeの基本 

 

make installについて

make install を実行するとmakeで生成されたバイナリファイルが既定のディレクトリにコピーされます。
make uninstallでアンインストールでき、make -n install でインストール先のディレクトリが知れる。(このときインストールはされない)