Linux活用レシピ > ドローンに活用 > ドローンをRaspberryPiとGoで自動飛行させカメラ動画を撮影し録画する方法
このページでは、ドローン「TELLO」をRaspberry PiとGoで自動飛行させカメラ動画を撮影し録画する方法を紹介します。


ドローンをキーボードで操作し撮影(録画)する方法
カメラ動画を録画

ここでは、自動飛行ではないのですが、キーボードでTelloを操作するコードを紹介します。
このレシピで作成した環境で、ドローン(Tello)を操作し、屋根を点検した動画が以下になります。

キーボードでTelloを操作しカメラ動画を録画できるコード

    これまで作ったコードを利用し、自動飛行の部分をキーボードから入力されたキーを判定し、Telloの動きを制御しながらカメラの映像を録画する内容に書き換えたものを紹介します。

    まず、Raspbianのメニューから赤枠の部分をクリックしてターミナルを起動します。


    カレントディレクトリに「tello_keybord_play.go」をviで作成します。
    pi@raspberrypi:~ $ vi tello_keybord_rec.go[ENTER]
    

    package main
    
    import (
        "fmt"
        "os/exec"
        "time"
        "os"
    
        "gobot.io/x/gobot"
        "gobot.io/x/gobot/platforms/keyboard"
        "gobot.io/x/gobot/platforms/dji/tello"
    )
    
    func main() {
        drone := tello.NewDriver("8890")
        keys := keyboard.NewDriver()
        var filename string = "drone.mp4"
    
        work := func() {
            /**
            ファイル制御
            */
            if f, err := os.Stat(filename); os.IsNotExist(err) || f.IsDir() {
                fmt.Println("ファイルは存在しません!")
            } else {
                fmt.Println("存在するファイルです削除します")
                if err := os.Remove(filename); err != nil {
                    fmt.Println(err)
                }
            }
            /**
            ドローンカメラアクセス
            */
            ffmpeg := exec.Command("ffmpeg", "-i", "-", "-acodec", "copy",
                                   "-vcodec", "copy", filename)
            ffmpegIn, _ := ffmpeg.StdinPipe()
            if err := ffmpeg.Start(); err != nil {
                fmt.Println(err)
                return
            }
    
            drone.On(tello.ConnectedEvent, func(data interface{}) {
                fmt.Println("Connected")
                drone.StartVideo()
                drone.SetVideoEncoderRate(4)
                gobot.Every(100*time.Millisecond, func() {
                    drone.StartVideo()
                })
            })
    
            drone.On(tello.VideoFrameEvent, func(data interface{}) {
                pkt := data.([]byte)
                if _, err := ffmpegIn.Write(pkt); err != nil {
                    fmt.Println(err)
                }
            })
    
            /**
            ドローン制御
            */
            keys.On(keyboard.Key, func(data interface{}) {
                key := data.(keyboard.KeyEvent)
    
                if key.Key == keyboard.C {
                    fmt.Println("Command Test")
                } else if key.Key == keyboard.T{
                    fmt.Println("Take Off!")
                    drone.TakeOff() //離陸
                } else if key.Key == keyboard.L{
                    fmt.Println("Land")
                    drone.Land() //着陸
                } else if key.Key == keyboard.A{
                    fmt.Println("(")
                    drone.Clockwise(-25) //反時計回
                } else if key.Key == keyboard.S{
                    fmt.Println(")")
                    drone.Clockwise(25) //時計回
                } else if key.Key == keyboard.ArrowUp{
                    fmt.Println("↑")
                    drone.Forward(10) //前進
                } else if key.Key == keyboard.ArrowDown{
                    fmt.Println("↓")
                    drone.Backward(10) //後退
                } else if key.Key == keyboard.ArrowRight{
                    fmt.Println("→")
                    drone.Right(10) //右へ
                } else if key.Key == keyboard.ArrowLeft{
                    fmt.Println("←")
                    drone.Left(10) //左へ
                } else if key.Key == keyboard.U{
                    fmt.Println("Up")
                    drone.Up(10) //上昇
                } else if key.Key == keyboard.D{
                    fmt.Println("Down")
                    drone.Down(10) //下降
                } else if key.Key == keyboard.F{
                    fmt.Println("Front Flip")
                    drone.FrontFlip() //フリップ
                } else if key.Key == keyboard.B{
                    fmt.Println("Back Flip")
                    drone.BackFlip() //バックフリップ
                } else if key.Key == keyboard.Escape{
                    fmt.Println("Stop")
                    drone.Forward(0)
                    drone.Backward(0)
                    drone.Up(0)
                    drone.Down(0)
                    drone.Left(0)
                    drone.Right(0)
                    drone.Clockwise(0)
                } else {
                    fmt.Println("keyboard event!", key, key.Char)
                }
            })
        }
    
        robot := gobot.NewRobot("tello",
            []gobot.Connection{},
            []gobot.Device{drone, keys}, //droneとkeysの二つのアダプタ
            work,
        )
    
        robot.Start()
    }
    

Telloを接続しコードを実行して、キーボードで操縦開始

    TELLOを制御するにはWiFiで接続する必要がありますので、接続できていない場合は以下の通り接続しましょう。

    まずは、TELLOの電源を入れます。

    TELLOの正面のLEDが激しく点滅したら準備完了です。
    以下の通り、OS「Raspbian」で、右上のネットワーク部分をクリック


    「TELLO-」から始まるTELLOのSIDを選択します。

    以下の通りWiFiの表示が変わったら、Raspberry PiとTELLOがWiFiで接続できました。


    動画はカレントディレクトリの「drone.mp4」に上書き保存(厳密にはdrone.mp4ファイルがあれば削除してから「drone.mp4」ファイルを作成し記録)しますので、前回のフライト動画が残っている場合は、以下のコマンドでバックアップしておくなど注意してください。
    pi@raspberrypi:~ $ cp -ip drone.mp4 保存するファイル名.mp4[ENTER]
    

    準備が出来れば「tello_keybord_rec.go」を実行します。
    pi@raspberrypi:~ $ go run tello_keybord_rec.go[ENTER]
    

    「tello_keybord_rec.go」の操縦は以下のとおり行います。
    Telloを以下の通りキー入力(大文字小文字区別なし)で操作出来ます。
    キー入力 Telloの動作 備考
    T 離陸 最初にこのキーで飛び立ちます
    L 着陸 最後にこのキーで着陸させます
    A 反時計回り 反時計回りに旋回をはじめます。
    D 時計回り 時計回りに旋回をはじめます。
    前進 前進をはじめます。
    後退 後退をはじめます。
    右平行移動 右に平行移動をはじめます。
    左平行移動 左に平行移動をはじめます。
    U 上昇 上昇をはじめます。離陸ではありません。
    D 下降 下降をはじめます。着陸ではありません。
    F フリップ フリップを行います。
    B バックフリップ バックフリップを行います。
    [ESC] 静止 静止します。
    操作のコツですが、キー入力毎にそれぞれの動作を始めますので、その動作を止める場合は「ESC」キーを押してください。
    「ESC」が押されるとその場で静止しますので、またキーを入力して、次の動作に移らせてください。
    なので、例えば「D」を押した後、「U」を押すと時計回りに旋回をしながら上昇していくという動作になります。
    なお、GoのTelloへの命令セットはよくわかっていないので、「→」右に平行移動後に「←」を入力するとカウンターがあたりその場で静止するイメージですが、そうではなさそう(動作が不安定)なので、次の動作に移る場合は「ESC」キーを入力(全方位に(0)を展開し静止)した後に、入力すると安定して動作するようです。

Telloの操縦を終了する


    Telloの操縦を終了する場合は、「L」を入力して着陸させます。
    キー入力 Telloの動作 備考
    L 着陸 最後にこのキーで着陸させます
    着陸後は、コンソールから「CTRL」+「C」を入力して、Goプログラムを終了させます。

    以上で操縦は終了です。

    なお、フライト動画はカレントディレクトリに「drone.mp4」で保存されていますので、以下の通りファイルマネージャで表示させて、ダブルクリックして閲覧しましょう。