Golang Meetup Prague - GOBOT

Golang Meetup Prague - GOBOT

Talk was about using GoCV and Gobot with Drone DJ Tello.

Examples from talk - https://github.com/abtris/gobot-examples

55d57afc217d360cd3aad3e2a8d4e5a0?s=128

Ladislav Prskavec

September 13, 2018
Tweet

Transcript

  1. GOBOT Next generation robotics/IoT framework with support for 35 different

    platforms
  2. Who am I? 4 Ladislav Prskavec (@abtris) 4 Developer &

    SRE in Oracle Apiary 4 Ruby & Node.js & Go 4 Follow Golang meetup on twitter @GoMeetupPrague
  3. Why you should use Go for computer vision 4 Concurrency

    4 Portability 4 Performance
  4. Frameworks 4 GoCV - wrap up around OpenCV 4 Gobot

    - framework for robots, drones, and the Internet of Things (IoT)
  5. Hello World with Gobot and Drone Tello

  6. package main import ( "fmt" "time" "gobot.io/x/gobot" "gobot.io/x/gobot/platforms/dji/tello" ) func

    main() { drone := tello.NewDriver("8888") var flightData *tello.FlightData var battery int8 work := func() { drone.TakeOff() drone.On(tello.FlightDataEvent, func(data interface{}) { flightData = data.(*tello.FlightData) battery = flightData.BatteryPercentage fmt.Println("Height:", flightData.Height) }) gobot.After(5*time.Second, func() { fmt.Println("Battery:", battery) drone.Land() }) } robot := gobot.NewRobot("tello", []gobot.Connection{}, []gobot.Device{drone}, work, ) robot.Start() }
  7. import ( "fmt" "time" "gobot.io/x/gobot" "gobot.io/x/gobot/platforms/dji/tello" )

  8. func main() { drone := tello.NewDriver("8888") work := func() {

    ... } robot := gobot.NewRobot("tello", []gobot.Connection{}, []gobot.Device{drone}, work, ) robot.Start() }
  9. work := func() { drone.TakeOff() drone.On(tello.FlightDataEvent, func(data interface{}) { flightData

    = data.(*tello.FlightData) battery = flightData.BatteryPercentage fmt.Println("Height:", flightData.Height) }) gobot.After(5*time.Second, func() { fmt.Println("Battery:", battery) drone.Land() }) }
  10. DEMO $GOPATH/go/src/github.com/abtris/dji-tello/workshop/hello-tello

  11. Control Drone Tello with Keyboard

  12. package main import ( "fmt" "gobot.io/x/gobot" "gobot.io/x/gobot/platforms/dji/tello" "gobot.io/x/gobot/platforms/keyboard" )

  13. func main() { drone := tello.NewDriver("8888") keys := keyboard.NewDriver() keys.On(keyboard.Key,

    func(data interface{}) { key := data.(keyboard.KeyEvent) switch key.Key { case keyboard.A: fmt.Println(key.Char) drone.Clockwise(-25) case keyboard.D: fmt.Println(key.Char) drone.Clockwise(25) case keyboard.W: fmt.Println(key.Char) drone.Forward(20) case keyboard.S: fmt.Println(key.Char) drone.Backward(20) case keyboard.K: fmt.Println(key.Char) drone.Down(20) case keyboard.J: fmt.Println(key.Char) drone.Up(20)
  14. case keyboard.Q: fmt.Println(key.Char) drone.Land() case keyboard.P: fmt.Println(key.Char) drone.TakeOff() case keyboard.ArrowUp:

    fmt.Println(key.Char) drone.FrontFlip() case keyboard.ArrowDown: fmt.Println(key.Char) drone.BackFlip() case keyboard.ArrowLeft: fmt.Println(key.Char) drone.LeftFlip() case keyboard.ArrowRight: fmt.Println(key.Char) drone.RightFlip() case keyboard.Escape: resetDronePostion(drone) } })
  15. func resetDronePostion(drone *tello.Driver) { drone.Forward(0) drone.Backward(0) drone.Up(0) drone.Down(0) drone.Left(0) drone.Right(0)

    drone.Clockwise(0) }
  16. var flightData *tello.FlightData work := func() { drone.On(tello.FlightDataEvent, func(data interface{})

    { flightData = data.(*tello.FlightData) fmt.Println("Height:", flightData.Height) }) } robot := gobot.NewRobot("tello", []gobot.Connection{}, []gobot.Device{keys, drone}, work, ) robot.Start() }
  17. DEMO $GOPATH/go/src/github.com/abtris/dji-tello/workshop/hello-keyboard

  18. Video from DJI Tello

  19. package main import ( "fmt" "os/exec" "time" "gobot.io/x/gobot" "gobot.io/x/gobot/platforms/dji/tello" )

  20. func main() { drone := tello.NewDriver("8890") mplayer := exec.Command("mplayer", "-fps",

    "25", "-") mplayerIn, _ := mplayer.StdinPipe() if err := mplayer.Start(); err != nil { fmt.Println(err) return } work := func() { drone.On(tello.ConnectedEvent, func(data interface{}) { fmt.Println("Connected") drone.StartVideo() drone.SetVideoEncoderRate(tello.VideoBitRateAuto) gobot.Every(100*time.Millisecond, func() { drone.StartVideo() }) }) drone.On(tello.VideoFrameEvent, func(data interface{}) { pkt := data.([]byte) if _, err := mplayerIn.Write(pkt); err != nil { fmt.Println(err) } }) } robot := gobot.NewRobot("tello", []gobot.Connection{}, []gobot.Device{drone}, work, ) robot.Start() }
  21. OpenCV with DJI Tello

  22. package main import ( "fmt" "image" "image/color" "io" "os/exec" "strconv"

    "time" "gobot.io/x/gobot" "gobot.io/x/gobot/platforms/dji/tello" "gocv.io/x/gocv" )
  23. const ( frameX = 400 frameY = 300 frameSize =

    frameX * frameY * 3 ) func main() { drone := tello.NewDriver("8890") window := gocv.NewWindow("Tello") xmlFile := "haarcascade_frontalface_default.xml" ffmpeg := exec.Command("ffmpeg", "-hwaccel", "auto", "-hwaccel_device", "opencl", "-i", "pipe:0", "-pix_fmt", "bgr24", "-s", strconv.Itoa(frameX)+"x"+strconv.Itoa(frameY), "-f", "rawvideo", "pipe:1") ffmpegIn, _ := ffmpeg.StdinPipe() ffmpegOut, _ := ffmpeg.StdoutPipe()
  24. work := func() { if err := ffmpeg.Start(); err !=

    nil { fmt.Println(err) return } drone.On(tello.ConnectedEvent, func(data interface{}) { fmt.Println("Connected") drone.StartVideo() drone.SetVideoEncoderRate(tello.VideoBitRateAuto) drone.SetExposure(0) 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) } }) } robot := gobot.NewRobot("tello", []gobot.Connection{}, []gobot.Device{drone}, work, ) // calling Start(false) lets the Start routine return immediately without an additional blocking goroutine robot.Start(false)
  25. // now handle video frames from ffmpeg stream in main

    thread, to be macOS/Windows friendly for { buf := make([]byte, frameSize) if _, err := io.ReadFull(ffmpegOut, buf); err != nil { fmt.Println(err) continue } img, _ := gocv.NewMatFromBytes(frameY, frameX, gocv.MatTypeCV8UC3, buf) if img.Empty() { continue } // detect faces // color for the rect when faces detected blue := color.RGBA{0, 0, 255, 0} // load classifier to recognize faces classifier := gocv.NewCascadeClassifier() defer classifier.Close() if !classifier.Load(xmlFile) { fmt.Printf("Error reading cascade file: %v\n", xmlFile) return } rects := classifier.DetectMultiScale(img) fmt.Printf("found %d faces\n", len(rects)) // draw a rectangle around each face on the original image, // along with text identifying as "Human" for _, r := range rects { gocv.Rectangle(&img, r, blue, 3) size := gocv.GetTextSize("Human", gocv.FontHersheyPlain, 1.2, 2) pt := image.Pt(r.Min.X+(r.Min.X/2)-(size.X/2), r.Min.Y-2) gocv.PutText(&img, "Human", pt, gocv.FontHersheyPlain, 1.2, blue, 2) } window.IMShow(img) if window.WaitKey(1) >= 0 { break } } }
  26. DEMO $GOPATH/go/src/github.com/abtris/dji-tello/workshop/hello-tello- opencv-keyboard

  27. Workshop at Webexpo 4 Control Drone Using Your Computer -

    Golang, Node.js 4 Examples from talk - https://github.com/abtris/ gobot-examples