Gobot – Golang Powered Robotics – gobot.io



Gobot – Golang Powered Robotics – gobot.io

0 0


preso-gothamgo-2014


On Github hybridgroup / preso-gothamgo-2014

Gobot

Golang Powered Robotics

gobot.io

Good Afternoon

This is #gothamgo

I am @deadprogram

Ringleader

@hybrid_group

The other guy is @adzankich

Serious Programming Guy

@hybrid_group

hybridgroup.com

kidsruby.com

Golang Robotics

Starring

A Go Framework for Robotics & the Internet of Things

Multiple Hardware Devices

Different Hardware Devices

At the Same Time!

By its design, Go proposes an approach for the construction of system software on multicore machines Golang FAQ

...the street finds its own uses for things William Gibson

@rob_pike

@mattetti

@codegangsta

Full Stack Robotics

Arduino

package main

import (
  "time"

  "github.com/hybridgroup/gobot"
  "github.com/hybridgroup/gobot/platforms/firmata"
  "github.com/hybridgroup/gobot/platforms/gpio"
)

func main() {
  gbot := gobot.NewGobot()

  firmataAdaptor := firmata.NewFirmataAdaptor("arduino", "/dev/ttyACM0")
  led := gpio.NewLedDriver(firmataAdaptor, "led", "13")

  work := func() {
    gobot.Every(1*time.Second, func() {
      led.Toggle()
    })
  }

  robot := gobot.NewRobot("bot",
    []gobot.Connection{firmataAdaptor},
    []gobot.Device{led},
    work,
  )

  gbot.AddRobot(robot)

  gbot.Start()
}

Beaglebone Black

package main

import (
  "time"

  "github.com/hybridgroup/gobot"
  "github.com/hybridgroup/gobot/platforms/beaglebone"
  "github.com/hybridgroup/gobot/platforms/gpio"
)

func main() {
  gbot := gobot.NewGobot()

  beagleboneAdaptor := beaglebone.NewBeagleboneAdaptor("beaglebone")
  led := gpio.NewLedDriver(beagleboneAdaptor, "led", "P9_12")

  work := func() {
    gobot.Every(1*time.Second, func() {
      led.Toggle()
    })
  }

  robot := gobot.NewRobot("blinkBot",
    []gobot.Connection{beagleboneAdaptor},
    []gobot.Device{led},
    work,
  )

  gbot.AddRobot(robot)

  gbot.Start()
}

Choose Your Own Hardware Adventure!

To win a Sphero, tweet

@gosphero and @gobotio

To win a Spark Core, tweet

@spark_io and @gobotio

To win an AR Drone, tweet

@ardrone and @gobotio

It All Starts With A Customer...

Brewmaster

Drink Dispenser

Intel Edison + MQTT

package main

import (
  "fmt"
  "net/url"
  "time"

  "github.com/hybridgroup/gobot"
  "github.com/hybridgroup/gobot/platforms/gpio"
  "github.com/hybridgroup/gobot/platforms/intel-iot/edison"
  "github.com/hybridgroup/gobot/platforms/mqtt"
)

func main() {
  gbot := gobot.NewGobot()

  e := edison.NewEdisonAdaptor("edison")
  m := mqtt.NewMqttAdaptor("mqtt", "tcp://192.168.0.90:1883", "pump")

  lever := gpio.NewButtonDriver(e, "lever", "2")
  fault := gpio.NewButtonDriver(e, "fault", "4")
  pump := gpio.NewDirectPinDriver(e, "pump", "13")

  work := func() {
    dgram := url.Values{
      "name":         {"Four"},
      "dispenser_id": {"4"},
      "drink_id":     {"0"},
      "event":        {"online"},
      "details":      {"dispenser"},
    }
    pumping := false
    served := byte(0)

    m.On("startPump", func(data []byte) {
      if !pumping {
        pumping = true
        pump.DigitalWrite(1)
        served++
        dgram.Set("event", "online")
        dgram.Set("drink_id", fmt.Sprintf("%v", served))
        m.Publish("pumped", []byte(dgram.Encode()))
        gobot.After(2*time.Second, func() {
          pump.DigitalWrite(0)
          pumping = false
        })
      }
    })

    gobot.On(lever.Event("push"), func(data interface{}) {
      m.Publish("pump", []byte{})
    })

    m.On("startFault", func(data []byte) {
      dgram.Set("event", "error")
      m.Publish("fault", []byte(dgram.Encode()))
    })

    gobot.On(fault.Event("push"), func(data interface{}) {
      m.Publish("startFault", []byte{})
    })
  }

  gbot.AddRobot(gobot.NewRobot("brewmachine",
    []gobot.Connection{e, m},
    []gobot.Device{lever, fault, pump},
    work,
  ))

  gbot.Start()
}

Wearable Notifications

Intel Edison + Pebble + MQTT

watchbot.io

package main

import (
  "fmt"
  "net/http"
  "net/url"

  "github.com/hybridgroup/gobot"
  "github.com/hybridgroup/gobot/api"
  "github.com/hybridgroup/gobot/platforms/mqtt"
  "github.com/hybridgroup/gobot/platforms/pebble"
)

func pebbleRobot() *gobot.Robot {
  p := pebble.NewPebbleAdaptor("pebble")
  m := mqtt.NewMqttAdaptor("mqtt", "tcp://192.168.0.90:1883", "pebble")
  watch := pebble.NewPebbleDriver(p, "pebble")

  work := func() {
    m.On("watch", func(data []byte) {
      watch.SendNotification(string(data))
    })
  }

  return gobot.NewRobot("pebble",
    []gobot.Connection{p, m},
    []gobot.Device{watch},
    work,
  )
}

func hqRobot() *gobot.Robot {
  m := mqtt.NewMqttAdaptor("mqtt", "tcp://192.168.0.90:1883", "hq")

  work := func() {
    watch := func(msg string) {
      fmt.Println(msg)
      m.Publish("watch", []byte(msg))
    }

    post := func(val []byte) {
      v, _ := url.ParseQuery(string(val))
      _, err := http.PostForm("https://brewmachine.herokuapp.com/drinks",
        v,
      )
      if err != nil {
        fmt.Println(err)
      }
    }
    m.On("pump", func(data []byte) {
      m.Publish("startPump", []byte{})
    })

    m.On("pumped", func(data []byte) {
      go post(data)
      v, _ := url.ParseQuery(string(data))
      watch(fmt.Sprintf("Customers served: %v", v.Get("drink_id")))
    })
    m.On("fault", func(data []byte) {
      go post(data)
      watch("There was a fault!")
    })
    m.On("drone", func(data []byte) {
      go post(data)
      watch(fmt.Sprintf("Message from drone: %v", string(data)))
    })
    m.On("gcs", func(data []byte) {
      fmt.Println(string(data))
      go post(data)
    })
  }

  return gobot.NewRobot("mqtt",
    []gobot.Connection{m},
    work,
  )
}

func main() {
  gbot := gobot.NewGobot()
  api.NewAPI(gbot).Start()

  gbot.AddCommand("pump", func(params map[string]interface{}) interface{} {
    return gbot.Robot("mqtt").Connection("mqtt").(*mqtt.MqttAdaptor).Publish("startPump", []byte{})
  })
  gbot.AddCommand("fault", func(params map[string]interface{}) interface{} {
    return gbot.Robot("mqtt").Connection("mqtt").(*mqtt.MqttAdaptor).Publish("startFault", []byte{})
  })

  gbot.AddRobot(hqRobot())
  gbot.AddRobot(pebbleRobot())

  gbot.Start()
}

Mobile Control

Intel Edison + Pebble + Commander + MQTT

commander.io

Common Protocol for Programming Physical Input/Output

cppp.io

func main() {
  gbot := gobot.NewGobot()
  api.NewAPI(gbot).Start()

  gbot.AddCommand("pump", func(params map[string]interface{}) interface{} {
    return gbot.Robot("mqtt").Connection("mqtt").(*mqtt.MqttAdaptor).Publish("startPump", []byte{})
  })
  gbot.AddCommand("fault", func(params map[string]interface{}) interface{} {
    return gbot.Robot("mqtt").Connection("mqtt").(*mqtt.MqttAdaptor).Publish("startFault", []byte{})
  })
...

Drone Delivery

Intel Edison + MQTT + ARDrone + Commander + Pebble + DigiSpark

package main

import (
  "fmt"
  "math"
  "net/url"
  "time"

  "github.com/hybridgroup/gobot"
  "github.com/hybridgroup/gobot/platforms/ardrone"
  "github.com/hybridgroup/gobot/platforms/joystick"
  "github.com/hybridgroup/gobot/platforms/mqtt"
)

type pair struct {
  x float64
  y float64
}

func main() {
  gbot := gobot.NewGobot()

  m := mqtt.NewMqttAdaptor("mqtt", "tcp://192.168.0.90:1883", "gcs")
  ardroneAdaptor := ardrone.NewArdroneAdaptor("Drone", "192.168.0.40")
  joystickAdaptor := joystick.NewJoystickAdaptor("ps3")

  joystick := joystick.NewJoystickDriver(joystickAdaptor,
    "ps3",
    "./dualshock3.json",
  )

  drone := ardrone.NewArdroneDriver(ardroneAdaptor, "Drone")

  work := func() {
    dgram := url.Values{
      "name":         {"gcs"},
      "dispenser_id": {"3"},
      "drink_id":     {"0"},
      "event":        {"available"},
      "details":      {"drone"},
    }
    m.Publish("gcs", []byte(dgram.Encode()))
    offset := 32767.0
    rightStick := pair{x: 0, y: 0}
    leftStick := pair{x: 0, y: 0}

    m.On("drone", func(data []byte) {
      dgram.Set("event", "delivery complete")
      m.Publish("gcs", []byte(dgram.Encode()))
    })

    gobot.On(joystick.Event("circle_press"), func(data interface{}) {
      fmt.Println("Drop!")
      m.Publish("drop", []byte{})
    })
    gobot.On(joystick.Event("square_press"), func(data interface{}) {
      drone.TakeOff()
      dgram.Set("event", "en route")
      m.Publish("gcs", []byte(dgram.Encode()))
    })
    gobot.On(joystick.Event("triangle_press"), func(data interface{}) {
      drone.Hover()
    })
    gobot.On(joystick.Event("x_press"), func(data interface{}) {
      drone.Land()
      dgram.Set("event", "available")
      m.Publish("gcs", []byte(dgram.Encode()))
    })
    gobot.On(joystick.Event("left_x"), func(data interface{}) {
      val := float64(data.(int16))
      if leftStick.x != val {
        leftStick.x = val
      }
    })
    gobot.On(joystick.Event("left_y"), func(data interface{}) {
      val := float64(data.(int16))
      if leftStick.y != val {
        leftStick.y = val
      }
    })
    gobot.On(joystick.Event("right_x"), func(data interface{}) {
      val := float64(data.(int16))
      if rightStick.x != val {
        rightStick.x = val
      }
    })
    gobot.On(joystick.Event("right_y"), func(data interface{}) {
      val := float64(data.(int16))
      if rightStick.y != val {
        rightStick.y = val
      }
    })

    gobot.Every(10*time.Millisecond, func() {
      pair := leftStick
      if pair.y < -10 {
        drone.Forward(validatePitch(pair.y, offset))
      } else if pair.y > 10 {
        drone.Backward(validatePitch(pair.y, offset))
      } else {
        drone.Forward(0)
      }

      if pair.x > 10 {
        drone.Right(validatePitch(pair.x, offset))
      } else if pair.x < -10 {
        drone.Left(validatePitch(pair.x, offset))
      } else {
        drone.Right(0)
      }
    })

    gobot.Every(10*time.Millisecond, func() {
      pair := rightStick
      if pair.y < -10 {
        drone.Up(validatePitch(pair.y, offset))
      } else if pair.y > 10 {
        drone.Down(validatePitch(pair.y, offset))
      } else {
        drone.Up(0)
      }

      if pair.x > 20 {
        drone.Clockwise(validatePitch(pair.x, offset))
      } else if pair.x < -20 {
        drone.CounterClockwise(validatePitch(pair.x, offset))
      } else {
        drone.Clockwise(0)
      }
    })
  }

  robot := gobot.NewRobot("ardrone",
    []gobot.Connection{joystickAdaptor, ardroneAdaptor, m},
    []gobot.Device{joystick, drone},
    work,
  )

  gbot.AddRobot(robot)

  gbot.Start()
}

func validatePitch(data float64, offset float64) float64 {
  value := math.Abs(data) / offset
  if value >= 0.1 {
    if value <= 1.0 {
      return float64(int(value*100)) / 100
    }
    return 1.0
  }
  return 0.0
}
package main

import (
  "github.com/hybridgroup/gobot"
  "github.com/hybridgroup/gobot/platforms/digispark"
  "github.com/hybridgroup/gobot/platforms/gpio"
  "github.com/hybridgroup/gobot/platforms/mqtt"
)

func main() {
  gbot := gobot.NewGobot()

  m := mqtt.NewMqttAdaptor("mqtt", "tcp://192.168.0.90:1883", "drone")
  digisparkAdaptor := digispark.NewDigisparkAdaptor("digispark")

  servo := gpio.NewServoDriver(digisparkAdaptor, "servo", "0")

  work := func() {
    servo.Move(10)
    m.On("drop", func(data []byte) {
      servo.Move(150)
      m.Publish("drone", []byte("Dropped"))
    })
  }

  robot := gobot.NewRobot("servoBot",
    []gobot.Connection{digisparkAdaptor, m},
    []gobot.Device{servo},
    work,
  )

  gbot.AddRobot(robot)

  gbot.Start()
}

Was that fun?

Join the Robot Evolution!

watchbot.io

commander.io

gobot.io

@gobotio

Thank you!

@deadprogram

@adzankich