Darkside(リンクエラー修正しました)

2019年05月の記事

<< 前のページ

2019年5月31日(金) 21:14

サンプルコード


 ストリーミング送信の動画確認のため、現在使用している python スクリプト。
 最初の方で numpy がないとか Flask がないとかエラーが出るようであれば、インストールが必要。あと、Gstreamer を使用している。

■カメラを認識する

 OpenCV の VideoCapture で可能だが、番号を指定すれば良いだけのUSBカメラ(未確認)と異なり、ラスパイカメラは面倒なパラメーターを指定せねばならない。ハード的に対応していないパラメーターを与えてしまうと、無視されてデフォルトになる。ラズパイカメラだと最高解像度になってしまうため、画像の取り込みが無駄に遅くなる。
 17〜21行目は動画ファイルを保存するための設定であり、このサンプルでは実は全くの不用。しかし、カメラから動画を取り込めているかどうかを確認する初期段階で役に立った。

■画像取得から加工し送信まで

 33行目で、カメラから映像を取得する。img に入る。
 35〜38行目は、取得した映像に長方形をスーパーインポーズしている。
 43行目は、映像を jpe 形式に変換している。
 44行目は、jpeg を文字列に変換している(配信のため)。
 45行目で、配信実行。
 51行目には、Jetson Nano の実際のローカルIPアドレスを記述すること。

#!/usr/bin/env python3
import cv2
import numpy as np
from flask import Flask, render_template, Response, request
app = Flask(__name__)
GST_STR = 'nvarguscamerasrc \
    ! video/x-raw(memory:NVMM), width=1280, height=720 \
    ! nvvidconv ! video/x-raw, width=(int)960, height=(int)540, format=(string)BGRx \
    ! videoconvert \
    ! appsink'
cam = cv2.VideoCapture(GST_STR, cv2.CAP_GSTREAMER) # ラズパイカメラオブジェクト作る
#cam = cv2.VideoCapture(1) # USBカメラオブジェクト作る
fps = cam.get(cv2.CAP_PROP_FPS)
height = cam.get(cv2.CAP_PROP_FRAME_HEIGHT)
width  = cam.get(cv2.CAP_PROP_FRAME_WIDTH)
fourcc = cv2.VideoWriter_fourcc('m','p','4','v')
out = cv2.VideoWriter('./output.mp4', int(fourcc), fps, (int(width), int(height)))
@app.route('/')
def index():
    return render_template('index.html')
@app.route('/video_feed')
def video_feed():
    return Response(get_image(), mimetype='multipart/x-mixed-replace; boundary=frame')
def get_image():
    while True:
        ret, img = cam.read()     # カメラから画像データを受け取る
        cv2.rectangle(img, (50, 10), (125, 60), (255, 0, 0))
        cv2.rectangle(img, (50, 80), (125, 130), (0, 255, 0), thickness=-1)
        cv2.rectangle(img, (50, 150), (125, 200), (0, 0, 255), thickness=-1)
        cv2.rectangle(img, (50, 150), (125, 200), (255, 255, 0))
        # cv2.imwrite('./1.jpg', img) # 静止画として保存する場合
        # out.write(img) # 動画として保存する場合
        ret, jpeg = cv2.imencode('.jpg', img)
        jpeg = jpeg.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + jpeg + b'\r\n')
if __name__ == '__main__':
    try:
        app.run(host='192.168.XXX.XXX', debug=True, threaded=True, use_reloader=False)
    except KeyboardInterrupt:
        pass
    finally:
        out.release()
        cam.release()'

■動画配信サーバー

 Flask でサーバー機能を実現するが、ホームディレクトリに templates というサブディレクトリを作成し、その中に、index.html を入れておくこと。

<!DOCTYPE html>
<html>
<head>
  <title>Video Streaming</title>
  <meta charset="utf-8">
</head>
<body>
  <div id="videoArea">
    <img src="{{ url_for('video_feed') }}" width="960"
height="540">
  </div>
</body>
</html>

 これで、有線LAN接続によりカメラ映像をホストPC上で確認可能となる。Jetson Nano にGUI環境が無くても大丈夫だ。ただし、無線で通信速度が遅い場合は表示できないかもしれない。
 屋外のラジコン操縦では、解像度が320×240ていどしか無くても実用的である。圧縮形式や圧縮率も、今後煮詰める必要がある。

written by higashino [Sタンク 1/16] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

この記事へのトラックバックPingURL

2019年5月30日(木) 21:29

環境設定

 Jestson Nano の環境を整備するには、案の定それなりに時間が必要。更に、トラブルも多発。

 最初に行うのは、公式の JetPack 4.2 を入れること。OSイメージとしてダウンロードし、展開すると12ギガバイト以上になる。それをマイクロSDカードに転送。Jetson Nano に挿して電源を入れると、起動する。速度などはMAX化しておく。基本情報は大抵、ネットで入手可能。
 OSが使えるようになったら、キードもマウスもモニターも必須ではなくなる。有線LANケーブルだけ接続し、プライベートネットワークへようこそ。その状態で Windows PC から、SSH接続すれば良い。ターミナルは Putty で行けるし、WinSCP はファイラーとして使えるので実機上で操作するよりむしろ使い勝手は良い。ただし当然、カメラ映像までは確認できない。画像ファイルや動画ファイルに落とさないと、閲覧不能だ。

 そもそもカメラ映像を取得するとか、それを加工するとか、何を使うのが楽だろうか?
 調べた結果、OpenCV が良さそうだ。

最新の OpenCV 4.1.0をビルドしてインストールする
 この記事を参考にすると、最初にGUIが無効になる。これは、少しでもメモリーを節約するためだが、ラジコン戦車の頭脳として使う分にはGUIなどメモリーを食うだけの無能なので、そのままずっと無効にしておく。ビルドには4ギガバイト以上のメモリーと、3時間半を要する。

python3 をデフォルトにする
 なぜか python2.7 あたりがデフォルトになっていて、python3 とタイプしないと ver3 が使用されない。python3 とタイプできる状況であれば良いが、例えば pip をインストールすると python2 環境に入ってしまい python3 には pip が無いという羽目になる。いろいろ厄介なので、デフォルトが ver3 になるように変更しておく。Jetson Nano では python をメイン言語にせざるを得ないので、非常に重要。

 画像送信に関しては、自分がやろうとしていることとほぼ同じことをやっている記事があった。

iPad(ブラウザ)とRaspberry Pi 3+Webカメラで遠隔操作するタミヤのタンクを作る
 これはあくまでラズパイ使用なので、OpenCV の入れ方などは前述の記事の方を参考にする。それよりも何よりも、GitHub で公開されているプログラムが、非常に参考になる。ラズパイ(自分の場合は Jetson Nano だが)上でWEBサーバーを動かし、動画閲覧ページを作っておく。カメラから映像を取得したら(必要に応じて加工し)、閲覧ページに送り込む。スマホ側はブラウザを立ち上げ、無線で接続された同一ネットワーク内の動画閲覧ページURLを指定。
 え?Webサーバーをセットアップする方法が分からない?

3.WEBサーバのインストール
 Looking Glass の記事でラジコンとは何の関係も無いですが、Jetson Nano に Apache を入れる手順が分かり易い。

pythonスクリプトをdaemonにする
 画像合成&送信プログラムは、電源Onで自動実行されないと困る。そこで、python で記述したスクリプトをサービスとして登録する。Windows とは異なり、サービス定義ファイルを作成しておけば、何でもかんでもサービスに出来るのが便利。systemctl コマンドの文法は、ググっておくこと。

 結論として、有線LAN接続でのストリーミング受信は成功した。WiFiでスマホと接続し、ストリーミング可能かどうかは次の課題だ。センサーの読み取りも必要。

■カメラはラズパイ用のv2を接続
 OpenCV で映像を読み取り、OpenCV で画像加工し、OpenCV で jpeg 化する。
 望遠カメラは、USBカメラか?

■ストリーミング配信は Flask で行う
 pip install Flask とかやる時に、python3 に pip が入っていなかったりすると大騒ぎだ。

 Jetson Nano の問題点としては、起動まで時間が掛かる他に、GPIOがオマケということもある。SPIに至っては、Linux の入った別のパソコンを用意し、非公式のパッチをセーフモードから送り込まないと有効にならない!
 通常のIOポートも、ミリ秒単位でLチカやるぐらいは簡単っぽい。だが、マイクロ秒単位で精緻な制御(例えばソフトウェアSPI)やれるかどうか不明。python は低速であり、AI系や画像処理の重い処理を呼び出す司令塔としては優秀でも、ちまちまとIF文やIO操作を記述していたら猛烈に遅くなる。

 高速でセンサーを読み出す、というだけでトラブル大の悪寒。頼むから使い物になってくれ・・・Cython。

written by higashino [Sタンク 1/16] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

この記事へのトラックバックPingURL

2019年5月29日(水) 21:19

Jetson Nano

 やりたいことを、ラズパイなら実現可能だろうか?
 そう思ってラズパイについて調査を始めたところ、とんでもないものを発見した。Jetson Nano というマイコンだ。ハードウェアスペックは、ゲームマシンの任天堂スイッチと、ほぼ同等。

 映像を作成できる能力が充分にあるのは確実だ。その映像をスマホ受信可能な形式でWiFi送信可能かどうかは不明だが、方法が存在する可能性は高い。そこの不確実性は、どのマイコンを選択しても同様に存在する。
 更に、ラジコン戦車のAI化など、将来の楽しみも増える。

 仮に使い物にならなくても、自作監視カメラには使える。
 価格性能比は良好だし、ここは実物を入手して試すに限る。という訳で、さっそく入手。実際は即座に手に入れるのは至難なのだが、ここまでのような考察は遥か以前に済ませていた訳で、発注も遥か以前に済ませていた。

 ドリル戦車のような大型ラジコンには、強力なメインCPUとして STM32F7 Discovery の搭載を考えていた。しかし同 Discovery は期待していた F4 版を F7 に差し替えただけというシンプルなバージョンアップではなく、液晶画面をビルトインした大袈裟なシロモノになっていた。一般人気も F4 版ほどではないようだ。
 それなら、ラズパイや Jetson Nano のようなワンボードマイコンというかマイクロパソコンでも良いだろう。

 ただし、ラズパイや Jetson Nano のような半パソコンには、致命的な問題がある。それは、OSを搭載しているために起動が遅いこと。Jetson Nano だと、電源を接続してから実際に使用可能となるまで、35秒前後待たされる。
 つまりはこれでカメラ映像処理した場合、ラジコン戦車の電源を入れて40秒ぐらい経たないと、搭載カメラの映像は送られて来ないのだ。

 PICや Discovery のようにOSを積んでいないマイコンの場合は、電源接続から0.1秒で使用可能になる。この差は、途轍もなく大きい。AIロボならば電源入れて稼動開始まで1分近くを要しても、実用的にはそれほど問題ないかもしれない。しかし、ラジコンでは大問題だ。ただし、内蔵カメラだけに限定すると、1分待つことはできる。
 電源投入直後のラジコン戦車は足元に存在するのであり、1分ではそれほど遠くまで走行しない。だから、カメラ映像無しでも普通にラジコンとして遊べる。

 つまり、ラジコン戦車としての操作はすべてPICだけで可能にしておき、Jetson Nano はカメラ映像の処理と送信だけを受け持つのが良いだろう。

 カメラ映像を元にAI処理等を行い、その結果として何らかの自動操作を行いたくなった場合は、Jetson Nano からPICへと指令を送信する・・・という方式だ。
 当面は画像合成だけで、AI処理を活用しない。だが、近未来に活用してみたくなるのは確実だろう。それを考えると、最初から Jetson Nano を搭載できるようにSタンクを製作しておくべきだ。ましてSタンクは、メカの部分に非常に力を入れて製作しているのだから、いろいろ活用しないともったいない。

 当初は車体後部装甲の銅板から Jetson Nano の放熱を行う構想だったが、その場合は後部装甲を開閉式にするのは困難となる。後部装甲が固定だと、バッテリーの出し入れは車体上部をオープンせねばならない。
 バッテリー交換はラジコンにおいては頻繁であり、車体上部を頻繁に取り外せるようにするのは設計上からり厄介。可能なら、バッテリーは車体後部装甲ハッチを開けて交換できるようにしたい。これは、使い勝手を相当に左右する。

 バトルタンクだって、車体を外すことなく容易にバッテリー交換可能だ。市販品の時点から。

 そうなると、Jetson Nano の放熱は別の場所から行わねばならず、厄介。だが、放熱問題を解決しないと、Sタンクに搭載するのは無理だ。

written by higashino [Sタンク 1/16] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

この記事へのトラックバックPingURL

2019年5月28日(火) 21:03

照準用カメラ

 今回のSタンクは、徹底的に命中精度にこだわる。狙って当てる楽しみを追求する、というのがコンセプトだ。
 命中させるには、エアガンの性能も重要だが照準方法もそれに劣らず重要である。極端な話、市販箱出しのままのバトルタンクでは、照準できない。狙いが付けられない。

 エアガン搭載ラジコンで照準する方法は、昔からほぼ2通りである。すなわち、レーザーポインターと車載カメラ。
 改造バトルタンクでやったように、自分は昔からレーザーポインターを使っていた。だが、問題も多い。まず、遠射に向かない。主砲候補エアガンの実射試験を行うためにレーザーポインターを持って行ったところ、全く役に立たなかった。収束が悪いのだ。典型的なレーザーポインターの光束は、品質の高いものでも1ミリラジアンである。つまり、30メートル先では3センチに広がる。
 相当な高品質モジュールでさえ、そんなものだ。中華モジュールの大半は、それより遥かに悪い。より大きなスポットに広がるだけでなく、歪んでいたりする。これでは、マトモにセンターを狙えない。

 仮に収束の良いレーザーポインターが手に入っても、遠くなれば視認困難になる。最大30メートル先を狙うのは想定内だ。例えばラジコン戦車が自分から20メートル離れた場所にいるとき、更に30メートル先を狙うと操縦者は50メートル先を見ることになる。そこで空き缶に照準を合わせるって、かなり面倒だし可能ではあっても快適ではあるまい。
 また、曲がり角の向こうにラジコン戦車を送り込み、横を狙えば照準点が辻に隠れて見えない。そう、レーザーポインターでは操縦者がターゲットを直視可能でなければ照準できないのだ。

 これまでレーザーポインターが効果的だったのは、射程が数メートルしかなかったからである。

 次に、レーザーは物体に当たらないと見えない。強力なグリーンレーザーは横からでもビームが見えるが、それは室内の話。ピーカン屋外で横からビームを視認しようとすれば、光出力が数十ワット必要だ。そのようなレーザー発振器はラジコンに搭載できるサイズではないし、仮に搭載出来るならエアガンではなくレーザーを主砲にしたくなる。
 ブルーレーザーなら近未来に数十ワットをラジコンに積めるようになるかもしれないが、比視感度が低いため数十ワットでは視認できないと思われる。
 要するに、何かに当たってくれないと、レーザーは目に見えず照準の現在位置も分からないということだ。これは、屋外で動画撮影なんてやると実感する。実用性が、相当に劣る。室内で四方どこでも壁があるような状況では、実感できないのだが。

 その点、車載カメラであれば、どこを向いていても照準位置が分かる。
 しかし車載カメラもまた、遠射に向かない。どう考えても、操縦用の標準メインカメラと、照準用の超望遠カメラ・・・最低2つが必要だ。すなわち、カメラの切り替え機構と、そもそも30メートル先の空き缶が充分に大きく写せるほどの超望遠カメラを入手せねばならない。
 マルチカメラの切り替えとなると、WiFi無線カメラとして市販されている製品では難しい。基本的にすべて、1対1での使用が前提だ。受信はスマホが前提だし、スマホは一度に1つのWiFiしか接続できない。

 それだけではない。どうせなら、カメラ映像にスーパーインポーズしたい。

 エースコンバットなどの空戦ゲームの画面にありがちなパターン。
 機体の傾斜や俯角仰角が表示される。

 Sタンクの車載カメラ映像に、傾斜センサーの結果をスーパーインポーズする。上下左右の傾斜角をグラフィカルに把握できる合成映像が送られて来ると、かなりカッコいいのではなかろうか。そして、照準時には、画面中央に超望遠カメラの映像を小さく重ね合わせる。

 そのような処理は、スーパーインポーズ用の専用ICか何かで実現できるものではない。強力なマイコンが必要だ。もしかすると、遂にラズパイに手を出すときが来たのかもしれない。

 やりたいこと。
 傾斜センサーを読み、メインカメラの画像に傾斜情報をスーパーインポーズ。更に、遠隔指示で画像中央に超望遠カメラ映像を上書き表示。そっちには、照準線をスーパーインポーズ。
 完成した合成映像を、WiFiで送信。それは、スマホで受信し映像表示可能なものとする。

written by higashino [Sタンク 1/16] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

この記事へのトラックバックPingURL

2019年5月27日(月) 21:32

転輪関連一式

 サスアームを冶具として使用したせいで、フラックスなどがベタベタくっついてしまった。

 そこでこれも、最強洗浄でピカピカにする。

 過熱によるメッキの変色までは、洗浄できない。

 シャフトストッパーのイモネジ位置に合わせ、その両側をマスキング。

 イモネジ位置に回転ストッパーの切れ込みを入れて、サスアーム完成。

 転輪絡みのパーツが、遂に出揃った。

 実際に組み立てる際は、この切れ込みのせいでサスアームとストッパーの角度が一意に決まってしまう。そのため、サスアームの角度はサーボ側で調整せねばならない。しかし、サーボ側もスリップ防止のギザギザがあるため、挿してから角度を調整するということはできない。
 要するに、サスアームの角度を適切に調整するという行為が、極めて面倒になっているのだ。メンテナンス性が、非常に悪い。だが、対案も無いので、やむを得ない。

 メンテナンスが困難だが、「不可能ではない」という一点で我慢する。

 転輪そのものも、ゴム巻きが8つとも終了し出番を待っている。最終的には、仕上げ作業が必要だが。

 ゴムは厚さ6ミリが必要と判断したが、実際には曲げることで厚くなるオチ。5ミリを巻くだけで、良かったようだ。しかし、僅かに直径が大きいぐらいでは支障が無いので、このままにしておく。僅かに小さい、よりはいい。

written by higashino [Sタンク 1/16] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

この記事へのトラックバックPingURL

<< 前のページ

Darkside(リンクエラー修正しました)

Generated by MySketch GE 1.4.1

Remodelling origin is MySketch 2.7.4