FCからの命令で写真撮影

おそらくGoProにアンテナつけて水中に沈めて写真撮影しているのは、「うみねこカンパニー」くらいだと思います。

ラジコンの設定

ラジコンのスイッチを以下のように設定しました。設定はラジコン自体のセットアップで決定します。

コンポーネント間接続

だんだんややこしくなっていく理由は多くの接続が必要だからでしょう。
(FCとはフライトコントローラーの略です)

  • GoProカメラとコンパニオンコンピューターがWiFi接続されていること)設定
  • FCとコンパニオンコンピューター間のGPIO接続され、コントロールされていること(シャッター)gopro_fc.py
  • FCとコンパニオンコンピューター間がシリアル通信接続されていて、FCからデータを取得できること(MAVLink) gps.py
  • FCとPC間のワイヤレスシリアル接続 (ミッションプランナー)設定
  • PCはインターネット接続されていること

さらに

設定のため、コンパニオンコンピューターとPCがイーサーネットなどでつながっていること。sshで接続し、設定します。

自動撮影システム

Goproカメラ

スマホのQUIKアプリからプレビュー指定によりWIFIを起動します。そのWIFIアクセスポイントにコンパニオンコンピュータを接続します。

PixHawk 6X

Mission Plannerのフルパラメーター設定で設定します。
なお、Pixhawk 6x miniのピンレイアウトはここ。かなり特殊なので買わないほうがいいです。普通のPixhawk 6xのほうがわかりやすいです。

CAM1_TYPE=2

カメラ1をリレーモードでコントロールする、という意味。これをセットして、リブートします。
すると必要なパラメーターがいろいろ現れます。

CAM1_INTERVAL_MIN = 3

Goproはシャッターを切ってから保管するまで少し時間がかかります。3秒くらいのインターバルを確保します。

次にAUX OUTのどれを使うかを指定しなくてはいけません。Pixhawk 6xシリーズはAUXは1から8まであります。

とはいえ、ここではPin 54(AuxOut 5)を使うことにします。理由は古いPixhawkではAUXOUT5,AUXOUT6はリレー用に設定されているからです。6xではそんな制限はないようですが、設定が増えています。

Relay1に54を設定することで、AUXOUT5と関連づけられます。

RELAY1_PIN=54

さらにrelayの役割の設定が重要です。

RELAY1_FUNCTION=4

4はカメラの意味で、これを設定しないとシャッターパルスをあげてくれません。
たぶん、Pixhawk 6xでは関係ないようですが、servo13の役割はGPIOなので以下であることを確認

SERVO13_FUNCTION=-1

カメラトリガースイッチは最初に決めたようにラジコンコントローラーのスイッチD(Ch7)とします。

RC7_OPTION=9

このあたりはフライトコントローラーによって微妙に設定が異なるため、苦労します。古いpixhawkについては英語ですが、こちらを参照してください。

Raspiコンパニオンコンピューター

GPIOを監視し、シャッターポートが上がったら、GoProにシャッター指令を送ります。
PixhawkのAux5をGPIO26に接続することを前提としています。

Pythonプログラム(gopro-fc.py)
*このプログラムはGoPro12以降を前提としています。media/lastcapturedがGoPro12以降でないと動作しません。

import requests
import time
import datetime
import json
import threading
import gps
from gpiozero import Button

SIGNAL_PORT = 26
GOPRO_BASE_URL = "http://10.5.5.9:8080"

from logging import getLogger

def init():
    log = getLogger("gopro-fc2")
     # Try camera mode.
    url = GOPRO_BASE_URL + "/gopro/camera/presets/set_group"
    querystring = {"id":"1001"}
    response = requests.get(url, params=querystring, timeout=3)
    # request_cmd("/gopro/camera/shutter/stop") # release
    # if not good, throw error.
    response.raise_for_status()

    log.info("GoPro in camera mode.")


def shutter_process():
    global listname

    log = getLogger("gopro-fc2")

    log.info("Shutter requested")

    response = requests.get(GOPRO_BASE_URL
                            +"/gopro/camera/shutter/start",
                            timeout=3)
    time.sleep(1)
    response.raise_for_status()

    response = requests.get(GOPRO_BASE_URL
                            + "/gopro/camera/shutter/stop",
                            timeout=3)
    time.sleep(1)
    resp=response.raise_for_status()
    
    # get last taken photo file name.
    response = requests.get(GOPRO_BASE_URL
                            + "/gopro/media/last_captured", timeout=2)

    time.sleep(1)    
    response.raise_for_status()
    dic = json.loads(response.text)
    filename = dic["file"]
    
    log.info("file name :"+filename+" Generated.")
    # get GPS location, compass heading.
    loc = gps.getlocation()
    lat = str(loc[0])
    lon = str(loc[1])
    alt = str(loc[2])
    heading = str(loc[3])
    # picture download needs a few minutes. we cannot wait.
    # then we create location file.
    
    # picture list name
    now = datetime.datetime.now()
    listname = './piclist/' + now.strftime("%Y%m%d")+'.txt'
    
    with open(listname,'a') as fs:
        print(f"{filename}:{lat}:{lon}:{alt}:{heading}", file=fs)
                
if __name__ == '__main__':
    init()

    # GPIO event listner
    button = Button(SIGNAL_PORT, pull_up=False)
    button.when_pressed = shutter_process

    # Loop
    while True:
        time.sleep(10)

実行前にプログラムと同じレベルにpiclistというフォルダーを作ってください。日付のついたファイルが作られます。

なお、GoProの設定で「一般」->「電源の自動オフ」を「なし」にします。

ミッションプランナー

フライトコントローラーと独自ワイヤレスシリアルでつながっていることと、海上でもインターネット接続のあること(地図とスナップショットを使うため)

運用

  1. 手動でRC6スイッチをオン、オフすることでシャッターが動作し写真が取れることを確認
  2. サーベイモードプランを制作(一回におよそ230枚以下)
  3. プラン転送
  4. AUTOスタート
  5. 終了まで待つ
タイトルとURLをコピーしました