From 79ffaab5b47ffe3c29c8e2b3db4f2242b9c51507 Mon Sep 17 00:00:00 2001 From: Ron Evans Date: Wed, 18 Apr 2018 22:46:51 +0200 Subject: [PATCH] tello: can stream drone video thru to opencv Signed-off-by: Ron Evans --- examples/tello_opencv.go | 86 +++++++++++++++++++++++++++++++++++ platforms/dji/tello/README.md | 2 + 2 files changed, 88 insertions(+) create mode 100644 examples/tello_opencv.go diff --git a/examples/tello_opencv.go b/examples/tello_opencv.go new file mode 100644 index 00000000..b6b2a009 --- /dev/null +++ b/examples/tello_opencv.go @@ -0,0 +1,86 @@ +// +build example +// +// Do not build by default. + +/* +You must have ffmpeg and ffplay installed in order to run this code. it will connect to the Tello +and then open a window using ffplay showing the streaming video. + +How to run + + go run examples/tello_opencv.go +*/ + +package main + +import ( + "fmt" + "io" + "os/exec" + "time" + + "gobot.io/x/gobot" + "gobot.io/x/gobot/platforms/dji/tello" + "gobot.io/x/gobot/platforms/opencv" + "gocv.io/x/gocv" +) + +const ( + frameSize = 960 * 720 * 3 +) + +func main() { + drone := tello.NewDriver("8890") + window := opencv.NewWindowDriver() + + work := func() { + ffmpeg := exec.Command("ffmpeg", "-i", "pipe:0", "-pix_fmt", "bgr24", "-vcodec", "rawvideo", + "-an", "-sn", "-f", "rawvideo", "pipe:1") + ffmpegIn, _ := ffmpeg.StdinPipe() + ffmpegOut, _ := ffmpeg.StdoutPipe() + if err := ffmpeg.Start(); err != nil { + fmt.Println(err) + return + } + + go func() { + for { + buf := make([]byte, frameSize) + if _, err := io.ReadFull(ffmpegOut, buf); err != nil { + fmt.Println(err) + continue + } + + img := gocv.NewMatFromBytes(720, 960, gocv.MatTypeCV8UC3, buf) + if img.Empty() { + continue + } + window.ShowImage(img) + window.WaitKey(1) + } + }() + + drone.On(tello.ConnectedEvent, func(data interface{}) { + fmt.Println("Connected") + drone.StartVideo() + gobot.Every(1*time.Second, func() { + drone.StartVideo() + }) + }) + + drone.On(tello.VideoFrameEvent, func(data interface{}) { + pkt := data.([]byte) + if _, err := ffmpegIn.Write(pkt); err != nil { + fmt.Println(err) + } + }) + } + + robot := gobot.NewRobot("tello", + []gobot.Connection{}, + []gobot.Device{drone, window}, + work, + ) + + robot.Start() +} diff --git a/platforms/dji/tello/README.md b/platforms/dji/tello/README.md index 4d22c98f..0c335e9b 100644 --- a/platforms/dji/tello/README.md +++ b/platforms/dji/tello/README.md @@ -59,3 +59,5 @@ https://tellopilots.com/forums/tello-development.8/ Special thanks to [@Kragrathea](https://github.com/Kragrathea) who figured out a LOT of the packets and code as implemented in C#: [https://github.com/Kragrathea/TelloPC](https://github.com/Kragrathea/TelloPC) Also thanks to [@microlinux](https://github.com/microlinux) with the Python library which served as the first example for the Tello community: [https://github.com/microlinux/tello](https://github.com/microlinux/tello) + +Thank you to bluejune for the [https://bitbucket.org/PingguSoft/pytello](https://bitbucket.org/PingguSoft/pytello) repo, especially the Wireshark Lua dissector which has proven indispensable.