RPiでRAMディスクに画像保存&別マシンから1fps程度の画像閲覧

RAMディスクを用意

Raspberry PiのSDカード/マイクロSDカードの寿命を延ばす | ものづくりエクスペリメント

これをみてdphys-swapfileをapt-get remove

スワップファイルというのは

スワップとは|swap : 意味/定義 - IT用語辞典

課題とは関係ないけれどもSDカードの寿命を伸ばすために、/tmp等をRAMディスクにするというのもやっておいたほうがよさそう。これはあとでやる。

SDカードをすべてリードオンリーにするということもできる。これはシステムが出来上がってからやったらよいのかもしれない。

Raspberry Pi でfsprotectを試す | よもやま雑記帳

RAMディスクをどこにどう作るか

Linux Tips – RAMディスク(/dev/shm)のIO性能をチューニングに活用する方法

Linuxキーワード - RAMディスク:ITpro

このへんを見ると/dev/shmをそのまま使ってもよさそう

新たに作るならこれが参考になりそう

マイクラ鯖に持って来い!!、LinuxでRAMディスク!! | 純規の暇人趣味ブログ

シャットダウン時にデータが消えないようにSDカードに書くという動作を加えるというやり方も書いてある。電源が急に切れた場合に対応するにはcronで一日おきにsdカードに保存するなど。

 

Raspberry Pi 3にssh接続

connection refusedと出たが、下記を見て、raspi-configを実行してsshを有効にしたら接続できるようになった

pi 3 - No SSH (Connection refused) using raspbian with pixel - Raspberry Pi Stack Exchange

 

USBカメラ画像を取得して保存&ソケットで画像を飛ばす

Cでデバイスファイル開いて扱ってもいいが、 OpenCVを使うことにする。

Cプログラミングによる画像処理(1)

pythonでやることにする。

$ sudo apt-get install libopencv-dev

$ sudo apt-get install python-opencv

Raspberry Pi で OpenCV(リベンジ) - Qiita

ここのテストプログラムは動いた。

Pythonによる通信処理 - Qiita

これでとりあえずソケットの形に。複数接続するには

socketプログラムの初歩から初める - Keep on moving

  1. threadを使う
  2. forkする
  3. selectなどを使う

の三つがあるそう。selectを使うのはこんな感じ

Pythonでネットワークプログラミング | saito's memo

 windows側からpython実行するのに下記のやり方をググった。

import os

os.chdir("C:\\ほげほげ")

os.getcwd()

execfile("hoge.py")

 windowspythonにnumpyをインストール

WindowsでPython3, numpy, pandas, matplotlibなどインストール - Qiita

> python -m pip install numpy

これでインストールできた

import cv2.cv as cvではなくimport cv2だけで使えるように下記のを参考

Python+OpenCVでカメラキャプチャ - Qiita

ソケットで画像を飛ばすのは下記

OpenCVでRaspberry Piから画像を転送する - kivantium活動日記

 ソケットで接続するWindows側クライアント

 クライアントはCSでwinのformで作る。文字列にエンコードしたjpegをデコードする。

TCPクライアント・サーバープログラムを作成する: .NET Tips: C#, VB.NET

デリゲートについて

デリゲート - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

マルチスレッドについて。threadやtaskやasync/awaitを使う方法があるらしい。このうちTaskと、async/awaitが現行のやり方でそれ以外は古いらしい。

ThreadじゃなくTaskを使おうか? - Qiita

Taskを極めろ!async/await完全攻略 - Qiita

できる!C#で非同期処理(Taskとasync-await) – kekyoの丼

マルチスレッド - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

 書き方の例

[C#]ざっくりマルチスレッド(非同期処理) – gomokulog

[C#]async/awaitの使い方メモ、その1。 | Kimux.Net

別スレッドからフォームのコントロールにアクセスするのはスレッドセーフではないらしい

方法 : Windows フォーム コントロールのスレッド セーフな呼び出しを行う

排他処理のやり方も気を付ける必要があるらしい

.NET TIPS:非同期:awaitを含むコードをロックするには?(SemaphoreSlim編)[C#、VB] - @IT

→timerを使えば解決

だけど、スレッドを使えるようになりたいのでそれはそれであとで勉強しておく

複数カメラの接続はserver*.pyを複数立ち上げることで実現することにする。シェルスクリプトでやる。

pgrepという便利コマンドがある

pgrep, pkill を使用してプロセスを殺す - 技術メモ帳

kill `pgrep -f hogehoge`とpkill -f hogehogeとは同じかもしれない。

 

 ソケットでの画像の送受信のやり方について

受信バッファの準備ができないうちに送信したり、受信しないうちに受信バッファを読み込みに行ったりしているのではないか。その問題を解決するのに、1)受信バッファのサイズを十分な大きさに指定する 2)アプリケーションレイヤでハンドシェークする というののいずれかをすればよいだろうということでこれの様子をみる。

1)受信バッファのサイズを指定する

Win32APIの(?)Winsockで、ポートごとのバッファの設定ができるのか調べた。

setsockopt function (Windows)

これのSO_RCVBUFが関係しそう

受信バッファ - odawaraの「はてな de メモ」

 

そもそもソケット通信がよくわかってない

ƒ\ƒPƒbƒg

バイナリとアスキーではどちらのほうがサイズが大きいのか?→パッと調べたところではバイナリのほうがデータが大きい場合もあるようなので、ファイルの詳細な形式によるということだと思う。

SocketのReceiveBufferSizeプロパティでbufferサイズはいじれる模様

Socket.ReceiveBufferSize プロパティ (System.Net.Sockets)

 

INIファイルの読み込み

C#.NET Tips

 

サーバ側でカメラをホットプラグにする処理

opencvのエラーをキャッチできないためにカメラを抜いた状態で

g_capture.read()をしてもret1やframeが直前の状態(ret1 = True)をキープしてしまい、カメラの接続が外れたことを検知できない。

しかたないので、pythonからシェルスクリプト実行して/dev/video*の存在を見ることでデバイスの接続有無を判定するようにした

 

サーバ側の画像保存を厳密に一定時間になるように時間の制御を加えた

 

Rapsberry piのカメラ画像の表示処理結果に遅延→カメラ画像取得に遅延?

OpenCVでバッファリングしてるところがあるのでそこでのバッファをしないという風にする↓の方法を試してみる

OpenCV カメラの遅延の対策 | ぴよちゃんの工房

 cap.get(cv2.cv.CV_CAP_PROP_FPS)してみたら

HIGHGUI ERROR; V4L2; unable to get proprty <unknown property string>というエラーで-1の値が返ってくるので、この方法が使えないポイ。

はんだ日和: Raspberry Pi でOpenCVのサンプルを動かす(カメラと顔認識)

ここに書いてあるような、CaptureFromCAMをして得られるCaptureオブジェクトに対しても同様に、CV_CAP_PROP_FRAME_WIDTHはちゃんとgetできるが、CV_CAP_PROP_FPSはgetできない。何の仕様が違うのかな、、ともあれ仕方ないので、やはりOpenCVのソースをいじるしかないのかな?

今はOpenCV 2.4.9を使っているが、OpenCV 3.xなら解決しているかもしれない

OpenCV: C API for video I/O

上記のURLをみると、三通りの方法がある。

1.CV_CAP_PROP_BUFFERSIZEというパラメタを使う

2.フレームのクエリに必要な時間を計測し、その時間がある値以上であれば読み捨てる(バッファからのクエリはそうでない場合よりも時間がかかるので)

3.別スレッドを立てて画像を読み捨てさせてバッファを空にする

CV_CAP_PROP_BUFFERSIZEは上記のとおりそんなオプションはないと出るので、2.の方法をトライしたがうまくいかない。単純に2,3フレーム読み捨ててから使うようにしたら遅延がなくなったので、3.の方法を参考に、別スレッドを立てて画像を読み込む専用のスレッドと、表示と保存をするスレッドを用意するのがよさそう。

ちなみにバッファからの読み込みは20msec程度。(でも測り方によっては30msec程度)

結局、表示と保存と読み込みの三つにスレッドを分けた。

クライアント側のソケットのタイムアウト問題

C#で書いたクライアント側のソケットの接続確立のところで、もし相手方のサーバのIPが違っていた場合に数秒単位で待たされる。IPがあっていてポートが異なる場合でも数十ミリ秒ほど待たされている感じがする。

Implementation of Connecting a Socket with Timeout in C# - CodeProject

これを見てasyncなソケットのオープンを実装

他にもいろいろな書き方があるポイ

timeout - C# How do I stop a tcpClient.Connect() process when i'm ready for the program to end? It just sits there for like 10 seconds! - Stack Overflow

非同期 TCP 通信。 · GitHub

C#でタイムアウト処理 そのに - のえら

TcpClient.BeginConnect メソッド (String, Int32, AsyncCallback, Object) (System.Net.Sockets)

Socket.BeginConnect メソッド (String, Int32, AsyncCallback, Object) (System.Net.Sockets)

 

ソケットのクライアントの処理をformのmainのスレッドとは別スレッドとして処理するか検討

一方のカメラが接続されていなかったら、もう一方の正しく接続されているカメラについても画像の更新が遅くなる?一個のカメラでも十分遅いし接続タイムアウトが効いているのでそんなに気にならない

 

jpegの圧縮率を設定

TCPHandlerに値を渡す方法

With python socketserver how can I pass a variable to the constructor of the handler class - Stack Overflow

下手なところでキーボードインタラプトが入らないようにする方法

How to prevent a block of code from being interrupted by KeyboardInterrupt in Python? - Stack Overflow

 

フォルダをsambaで共有する

Raspberry Piでファイルサーバ、Part1 Samba基本編 | ものづくりエクスペリメント

sambaのrestartがうまくいかなかったのでsmbdとnmbdを別々に再起動

Unit samba.service is masked のエラー : プログラマー社長の「日々発見」

 

ソケットの接続確立を毎回やってるのを、初回だけ接続確立して接続断を検知して再接続するプログラムに変更

 

 

 

kivy

ubuntu16.04へのインストールはこれを見て実行(ubuntu版)

Installation on Linux — Kivy 1.9.2.dev0 documentation

 

入門記事

Kivy 超入門(1):インストールからHello, World! まで

Kivy 超入門(2):ウィンドウのレイアウト,入力フォーム

Kivy 超入門(3):レイアウトを簡単に調整する(kvファイル)

Kivy 超入門(4):ボタンを作成する,ウィジェットの作成

 

 

python勉強記録

命名規約

Googleコーディングガイドを読みつつ、いろいろな命名規約を比較してみる | KentaKomai Blog

[Python] コーディング規約(PEP8)を学んで、Pythonらしいコードを書く - YoheiM .NET

 flake8というツールで書式のチェック。

apt-get install flake8

flake8 hogehoge.py

 

lambda式

lambda式はすごく面白い - 元理系院生の新入社員がPythonとJavaで色々頑張るブログ

 

内包表記

Pythonの内包表記の使い方まとめ - Life with Python

 

dispatchとはなにかよくわからない

 

with構文

with構文とは何なのか - 年中アイス

try~ exceptよりもこっちのほうがバリエーションあるのかな

クラスを使ってwith構文にしたほうがよいのかな?

with構文(Python) - Qiita

 

thread

実行中のスレッドに対し外から操作をする - Qiita

 

ubuntuの上で作成した、kivyを使うmain.pyをPyinstallerでビルド済み配布ファイルにすることをトライ。

pyinstallerはpipでインストールした。

>pyinstaller main.py

で出てきたエラーが

no module named enchant

 

unable to find

/usr/share/gir-1.0/Gtk-3.0.gir

/usr/share/gir-1.0/Gio-2.0.gir

/usr/share/gir-1.0/GObject-2.0.gir

 

enchantはpip install pyenchantだったかな

Gtk-3.0.girについてはlibgtk-3-devを入れたら見つかるようになった。(gtk+3.0 package : Ubuntuを参照)

のこりのgirについては

Debian -- パッケージのファイル一覧: libgirepository1.0-dev/sid/i386

を参考にlibgirepository1.0-devを入れたら見つかった

 次に、libgstcoreelements.soが見つからないと出たので、いろいろいじくって、gstreamerっぽいのをいれたり、ubuntu-restricted-extrasをインストールしたりしたがうまくいかない

仕方ないのでとりあえず、kivyをインストールしたマシンでmain.pyを走らせる方向でいったん。

ROS勉強

usb_camについて

zumashi.blogspot.jp

 

AMCL adaptive Monte Carlo localization の

 

tfについて

myenigma.hatenablog.com

 

ps3のコントローラ(horipad3)を使うには

> sudo apt-get install ros-kinetic-joy

> rosrun joy joy_node

> rostopic echo /joy

(下記の情報は古いぽい)

PS3コントローラ (DUALSHOCK3; SIXAXIS)をROSに接続する(無線編) - Qiita

ROS勉強記録: PS3のコントローラーを使う

 

publisherとsubscriberの簡単なサンプル

ja/ROS/Tutorials/WritingPublisherSubscriber(python) - ROS Wiki

 

これをみてopencvをインストール

Ubuntu 16.04 LTSにOpenCV2.4.13をインストール | ShumiLinux

 OpenCVとROSのブリッジ

ロボットビジョンの準備

cv2やcv、cv3との互換性ってそんなにない?ともあれ上記のコードをいじってOpenCV使えるようにした

opencv3のインストール方法は下記

Raspberry Pi 2へのROS Indigo/Ubuntu/OpenCV3他開発環境のインストール(ログ) - Qiita

まだインストールはしてない

 

 kobuki_playground.launchやturtlebot_world.launchで立ち上げたgazeboの中で、kobukiのバンパーが反応せず、/mobile_base/event/bumperトピックをsubscribeしても何もsubできない

Bump Sensors on Simulated TurtletBot in kinetic - ROS Answers: Open Source Q&A Forum

このへんを読むといいのかもしれないが結局ギブアップしてるっぽい

 

gazeboが" process has died [pid ***, exit code 134. ***"というエラーが出ることがある

おそらくこれはグラボの力が足りないため。上記のバンパーが反応しないのもこれに起因するかもしれない

 

下記の物が使えるようになるとよさげ

東大JSKが公開しているクールなROS可視化ライブラリを使ってみる - MyEnigma

 

RasPi3にROS_Commをインストールする方法

Raspberry Pi 3 に ROS をインストールしてみた - Qiita

これだけだと、from geometry_msgs.msg import Twistなどが動かないので、ROS desktopのインストールされたマシンの/opt/ros/kinetic/lib/python-2.7/dist-packages/のところにあるgeometry_msgs/などをコピーしてくる

 

usb_cam - ROS Wiki

これを使ったときに、

[swscaler @ xxxxxxx] deprecated pixel format used, make sure you did set range correctly

というwarningが出る。 

 

gitの備忘録

ローカルでリポジトリを作ってからリモートにpush

> git init

> git add *

> git commit -m ""

> git remote add origin https://github.com/*/*

> git push origin master

 

qiita.com

 

ブランチ一覧を見る

git branch

ブランチを切る

git branch <branch name>

git checkout <branch name>

 

gitのリモートリポジトリの更新を確認する - Qiita

 

更新したファイルだけ一括でaddしたいとき

 

git add . はワーキングツリーに新規作成された、もしくは変更されたファイルをaddします。つまり、rmコマンドなどで削除されたファイルはaddされません。

git add -u は一つ前と最新のステージを比較して、変更があった部分のみをaddします。つまり、新しく作られたファイルはaddされません。

最初にも述べたように、git add -A は git add . と git add -u を足したものですから、新規作成、修正、削除といった全てのファイルをaddします。

git add -A と git add . と git add -u の違い - Qiita