GNSS受信器キットを使用した走行ルート確認アプリ

Hardware & Software
Pocket

※機能はドラレコ相当ですが、正確性と確実性の面から、ドラレコとしての使用は想定していません。
<アプリ実行時の画面> ソースリスト約400行、実行ファイルサイズ約54MB 
【概要】
こちら(→)で作成したソフトをベースに、機能を追加したGNSSデータ受信アプリを作成し、
実際に使用してみた。

利用方法例)
 走行中に記録した映像と位置情報を元に、気になった建物、交差点名等を後から調べることができ、
 再度行くときの参考にできる。
【追加機能】
GNSS受信データをファイルへ保存する。 → 下記フローの スレッド処理1に追加
  保存するデータは、時刻、緯度と経度。
  各データ間にスペース区切りを入れて、csv形式で保存
GNSS受信失敗時の処理を追加。→ 下記フローの スレッド処理1に追加
  例)トンネル内で受信できない状況が発生しても、受信可能になればアプリの動作が再開する。
    但し、シリアル接続、USB接続が外れた場合は、正常動作への復帰はしない。
USBカメラによる映像に時刻と位置情報を追加表示して、avi形式で録画を行う。
 
               → 下記フローの スレッド処理2を新規作成(ソースを最下段に掲載)

 GNSS受信ができない場合は、映像の表示と録画は継続するが、時刻と位置情報は更新されない。
メインとスレッドの主な処理内容>
【使用機器】
開発機材(PC,OS,言語)、GNSS受信キット、USB変換モジュールは、ベースと同じ。

評価機材
PC: Surface i5-4300U 8GB Windows10-Pro(64bit) -> 車載評価で使用
カメラ: Panasonic製HX-A1H -> 車載評価で使用
     ロジクール製C170

【実験方法】
開発したソースリストをpyinstallerで、実行ファイルに変換して評価用PCで起動する。 
車で下記のルートを2回走行し、本アプリによるGNSSデータと映像の記録を行った。
 浜崎橋JCT→C1外回り→向島線→深川線→湾岸線→台場線→浜崎橋JCT 

走行時間 約30分/回
走行終了後、保存したデータを地図アプリに読み込み、位置ずれを確認した。

【結果】
走行中の車内に置いて受信した場合では、0m~50m程度のズレであった。
周囲が開けた場所を走行時のデータは、実際の走行車線とほぼ同一レベル。

映像ファイル(avi)サイズ 約20GB/30分、数値データファイル(csv)サイズ 約200kB/30分 
当HP管理人が使用する分には、充分な性能であったので、本開発は終了。

【備忘録】
 pythonのbyte型とstr型とhex型が、相変わらず良くわからない。毎回、数値と数字の取り扱いで悩む。
 保存された映像の画質が荒い気がする。カメラ単独で録画した方がきれいな気がする。
 映像表示処理に入れた"while cv2.waitKey(10) < 0:"の必要性がわからない。無くてもOKな時がある。
  1. # ビデオ映像の表示と録画 ・・・ スレッド処理
  2. class Video_IN(threading.Thread):
  3.     def __init__(self):
  4.         threading.Thread.__init__(self)
  5.         global file_name                                    # グローバル変数として定義されていることを宣言
  6.         global JST_time                                    # グローバル変数として定義されていることを宣言
  7.         global latitude                                        # グローバル変数として定義されていることを宣言
  8.         global longitude                                    # グローバル変数として定義されていることを宣言
  9.         self.video_thread_state = PAUSE
  10.     def run(self):
  11.         while True:
  12.             while self.video_thread_state == PAUSE :{}                        # RUNボタンが押されるまで、ここで待機
  13.             # カメラの情報を取得
  14.             cap = cv2.VideoCapture(0)                                            # カメラの情報は(1)番から取得。 取得できないなら、他の番号(0等)にしてみる。
  15.             # → SurfacePro はこっち → cap = cv2.VideoCapture(2)                                        # カメラの情報は(2)番から取得。 PC内蔵カメラが0と1
  16.             fps = int(cap.get(cv2.CAP_PROP_FPS))                        # カメラのFPSを取得
  17.             w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))            # カメラの横幅を取得
  18.             h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))            # カメラの縦幅を取得
  19.             # <1> C-170 の時
  20.             fourcc = cv2.VideoWriter_fourcc('I','Y','U','V')        # カメラの出力コーデックを、IYUVに設定
  21.             Extens = '.avi'                                                # ファイルの拡張子を、aviに設定
  22.             video = cv2.VideoWriter(file_name + Extens, fourcc, fps, (w, h))                 # 録画ファイルの生成
  23.             print('Movie File Name =' + file_name + Extens)    #debug用
  24.             self.video_thread_state = RUN                            # これを入れないと、RUNボタンの2回押しが必要だったので、state変数をRUN状態へ再設定する。
  25.             while True:
  26.                 while self.video_thread_state == RUN :
  27.                     while cv2.waitKey(10) < 0:                        # これを入れないと映像が出力されないので追加した。 time.sleepでの待ち時間生成でもダメだった。 
  28.                         ret, frame = cap.read()                        # ビデオ映像を取得 (実際は1/30S毎の静止画)
  29.                         #print(self.cap.read()) <-- #debug 未接続のカメラ番号の場合は、配列の中身が0
  30.                         cv2.putText(frame, str(gnss_thread.JST_time), (10, 400), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, 8)
  31.                         cv2.putText(frame, str(gnss_thread.latitude), (10, 430), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, 8)
  32.                         cv2.putText(frame, str(gnss_thread.longitude), (10, 460), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, 8)
  33.                         cv2.imshow('Video', frame)                    # フレームを画面に表示
  34.                         cv2.imwrite('nomean.jpg', frame)            # 文字の表示 (と 静止画ファイル作成。 <- このファイルは不要なので後で手動で削除)
  35.                         video.write(frame)                                # 録画
  36.                         if self.video_thread_state == PAUSE:
  37.                             break
  38.                 # 映像終了とウィンドウの解放(thread_state = PAUSEの時)
  39.                 cap.release()
  40.                 cv2.destroyAllWindows()
  41.                 break;

Hardware & Software
スポンサーリンク
シェアする
MTNブログ

コメント