* @Author: Sebastien Soudan * @Date: 2015-09-22 11:55:49 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 12:53:12 */ package control import ( "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" "time" ) var log = logger.Log("control") // Control is a component that monitors change on a types.Readable and Enable or Disable its target type Control struct { controlHandler types.Readable target types.Enablable stateEnable bool // channels shutdownChan chan interface{} panicChan chan interface{} } // New creates a new Control component func New(controlHandler types.Readable, target types.Enablable) *Control { return &Control{controlHandler: controlHandler, target: target, shutdownChan: make(chan interface{})}
* @Author: Sebastien Soudan * @Date: 2015-09-21 15:42:21 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 14:21:19 */ package alarm import ( "sync" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" ) var log = logger.Log("alarm") // Alarm is the component that manage the external alarm type Alarm struct { alarmHandler types.Enablable mu sync.RWMutex alarmState bool // protected by mu // channels inputChan chan interface{} shutdownChan chan interface{} panicChan chan interface{} } // New creates a new Alarm component for an types.Enablable
*/ /* * @Author: Sebastien Soudan * @Date: 2015-10-13 17:12:30 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-19 15:34:13 */ package ap100 import ( "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("ap100") // AP100 is the component that send the course to an external device (via a sin/cos interface) type AP100 struct { output Compass // channels inputChan chan interface{} shutdownChan chan interface{} panicChan chan interface{} } // Compass is something on which we can update the course (in degree) type Compass interface { UpdateCourse(course uint16) error }
package webserver import ( "fmt" "io" "net/http" "github.com/ant0ine/go-json-rest/rest" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" "github.com/ssoudan/edisonIsThePilot/pilot" ) var log = logger.Log("webserver") // VersionEndpoint is the endpoint providing the version of this piece of software func VersionEndpoint(version string) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, fmt.Sprintf("Edison is the pilot - %s", version)) } } func redirect(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "static/", 301) } // Control is the serializable structure used to change the autopilot state type Control struct {
/* * @Author: Sebastien Soudan * @Date: 2015-10-21 15:37:36 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-22 18:10:06 */ package tracer import ( "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" ) var log = logger.Log("tracer") // Tracer is the component that stores the recent position history type Tracer struct { maxPoints uint32 nextPosition uint32 points []types.Point fullyInitialized bool // Channels inputChan chan interface{} shutdownChan chan interface{} panicChan chan interface{} } // New creates a new Tracer component
"encoding/json" "fmt" "net/http" "os" "sync" "time" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" "github.com/ssoudan/edisonIsThePilot/pilot" "github.com/ssoudan/edisonIsThePilot/steering" "github.com/adrianmo/go-nmea" ) var log = logger.Log("stepper") // Input is the definition of a step type Input struct { Duration types.JSONDuration Heading float64 Step float64 } // Point is the structure collected when a step is RUNNING type Point struct { Timestamp types.JSONTime FixTime string FixDate string Course float64 Speed float64
* @Last Modified time: 2015-10-21 12:59:58 */ package main import ( "github.com/jessevdk/go-flags" "time" "github.com/ssoudan/edisonIsThePilot/conf" "github.com/ssoudan/edisonIsThePilot/drivers/motor" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("motorControl") // Options are the command line options for this tool type Options struct { Clockwise bool `short:"c" long:"clockwise" description:"clockwise rotation" default:"false"` Speed uint32 `short:"s" long:"speed" description:"rotation speed pps" default:"600"` Duration float64 `short:"d" long:"duration" description:"duration (seconds)" default:"1"` Repetition int `short:"r" long:"rep" description:"repetitions" default:"1"` Pause float64 `short:"p" long:"pause" description:"pause" default:"0"` } var opts Options var parser = flags.NewParser(&opts, flags.Default) func step(motor *motor.Motor, clockwise bool, stepsBySecond uint32, duration time.Duration) {
* @Last Modified time: 2015-10-21 14:23:56 */ package main import ( "github.com/jessevdk/go-flags" "time" "github.com/ssoudan/edisonIsThePilot/conf" "github.com/ssoudan/edisonIsThePilot/drivers/motor" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("mario") // Options are the command line options for mario tool type Options struct { Clockwise bool `short:"c" long:"clockwise" description:"clockwise rotation" default:"false"` // Speed uint32 `short:"s" long:"speed" description:"rotation speed pps" default:"600"` // Duration float64 `short:"d" long:"duration" description:"duration (seconds)" default:"1"` } var opts Options var parser = flags.NewParser(&opts, flags.Default) func doStep(motor *motor.Motor, clockwise bool, stepsBySecond uint32, duration time.Duration) { motor.Enable() log.Info("Moving clockwise[%v] for %v at %v[steps/s]", clockwise, duration, stepsBySecond)
"net/http" "time" "github.com/ssoudan/edisonIsThePilot/conf" "github.com/ssoudan/edisonIsThePilot/control" "github.com/ssoudan/edisonIsThePilot/drivers/gpio" "github.com/ssoudan/edisonIsThePilot/drivers/motor" "github.com/ssoudan/edisonIsThePilot/gps" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/utils" "github.com/ssoudan/edisonIsThePilot/infrastructure/webserver" "github.com/ssoudan/edisonIsThePilot/steering" "github.com/ssoudan/edisonIsThePilot/stepper" ) var log = logger.Log("systemCalibration") // Version is the version of this code -- sets at compilation time var Version = "unknown" // Options are the command line options of this tool type Options struct { Step float64 `short:"s" long:"step" description:"step intensity (motor rotation in degree)" required:"true"` Duration int64 `short:"d" long:"duration" description:"duration (seconds)" required:"true"` Description string `short:"D" long:"description" description:"description of the test" required:"true"` } var opts Options var parser = flags.NewParser(&opts, flags.Default)
"bufio" "strconv" "strings" "time" "github.com/ssoudan/edisonIsThePilot/ap100" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" "github.com/ssoudan/edisonIsThePilot/pilot" "github.com/ssoudan/edisonIsThePilot/tracer" "github.com/adrianmo/go-nmea" "github.com/tarm/serial" ) var log = logger.Log("gps") // GPS is a driver for a serial attached NMEA GPS type GPS struct { deviceName string baud int // channels messagesChan chan interface{} headingChan chan interface{} errorChan chan interface{} panicChan chan interface{} tracerChan chan interface{} } // New creates a new GPS component
* @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 12:48:18 */ package pilot import ( "github.com/ssoudan/edisonIsThePilot/alarm" "github.com/ssoudan/edisonIsThePilot/conf" "github.com/ssoudan/edisonIsThePilot/dashboard" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/steering" "time" ) var log = logger.Log("pilot") // Pilot is the main type for the component that decide what correction to apply depending // on the provided course and setpoint and various other configuration parameters type Pilot struct { heading float64 // target heading (set point) headingOffset float64 bound float64 course float64 speed float64 alarm Alarm enabled bool headingSet bool leds map[string]bool
* @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 14:25:26 */ package mcp4725 import ( "bitbucket.org/gmcbay/i2c" "encoding/binary" "github.com/ssoudan/edisonIsThePilot/drivers/gpio" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("mcp4725") const ( // writeDacCommand is the MCP4725 command to set the output writeDacCommand = 0x40 // writedacEepromCommand is the MCP4725 command to set the output and store the value in the eeprom writedacEepromCommand = 0x60 ) // MCP4725 is a driver for the MCP4725 i2c 12 bits DAC type MCP4725 struct { bus byte address byte i2c *i2c.I2CBus }
* @Author: Sebastien Soudan * @Date: 2015-09-22 13:18:01 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-22 15:13:00 */ package conf import ( "github.com/spf13/viper" "github.com/ssoudan/edisonIsThePilot/dashboard" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("conf") // MessagePin is the mapping of pin to a message type MessagePin struct { Message string Pin byte } // MessageToPin contains the mapping of the dashboard messages to the LED pin var MessageToPin = []MessagePin{ {dashboard.NoGPSFix, 43}, // J19 - pin 11 {dashboard.InvalidGPSData, 48}, // J19 - pin 6 {dashboard.SpeedTooLow, 40}, // J19 - pin 10 {dashboard.HeadingErrorOutOfBounds, 82}, // J19 - pin 13 {dashboard.CorrectionAtLimit, 83}, // J19 - pin 14 }
import ( "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" ) // Warning/Error leds const ( NoGPSFix = "NoGPSFix" InvalidGPSData = "InvalidGPSData" SpeedTooLow = "SpeedTooLow" HeadingErrorOutOfBounds = "HeadingErrorOutOfBounds" CorrectionAtLimit = "CorrectionAtLimit" ) var log = logger.Log("dashboard") // Dashboard is the component that receives the alarms and warnings and enable or disable the corresponding LEDs type Dashboard struct { leds map[string]bool ledHandler map[string]types.Enablable // channels inputChan chan interface{} shutdownChan chan interface{} panicChan chan interface{} } // New creates a new Dashboard component func New() *Dashboard { return &Dashboard{
* @Author: Sebastien Soudan * @Date: 2015-10-12 19:20:55 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 12:12:32 */ package sincos import ( "math" "github.com/ssoudan/edisonIsThePilot/drivers/mcp4725" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("sincos") // ToSinCos returns the Sine/Cosine values as expected by the Robertson autopilots (+/- 2V centered on 2.5V) func ToSinCos(theta uint16) (uint16, uint16) { s, c := math.Sincos(float64(theta) * math.Pi / 180) // MCP4725 is a 12 bits DAC between 0 and Vcc(=5V) sf := float64(0xfff) * (0.5 + 0.4*s) cf := float64(0xfff) * (0.5 + 0.4*c) return uint16(sf), uint16(cf) } // SinCos is a Sine/Cosine interace -- based on two MCP4725 DACs -- as used by AP100 autopilot to get the heading type SinCos struct { sin *mcp4725.MCP4725
* @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 14:21:42 */ package main import ( "time" "github.com/ssoudan/edisonIsThePilot/alarm" "github.com/ssoudan/edisonIsThePilot/conf" "github.com/ssoudan/edisonIsThePilot/drivers/pwm" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("alarmControl") func main() { panicChan := make(chan interface{}) go func() { select { case m := <-panicChan: log.Fatal("Received a panic error - exiting: %v", m) } }() //////////////////////////////////////// // a nice and delicate alarm //////////////////////////////////////// alarmPwm := func(pin byte, pwmId byte) *pwm.Pwm {
* @Date: 2015-09-21 18:58:22 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 13:09:34 */ package motor import ( "time" "github.com/ssoudan/edisonIsThePilot/drivers/gpio" "github.com/ssoudan/edisonIsThePilot/drivers/pwm" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" ) var log = logger.Log("motor") // Motor is a driver for a stepper motor type Motor struct { dirGPIO gpio.Gpio sleepGPIO gpio.Gpio stepPwm *pwm.Pwm } func check(err error) { if err != nil { log.Fatal(err) } }
* @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-09-25 11:59:31 */ package main import ( "fmt" "github.com/ssoudan/edisonIsThePilot/conf" "github.com/ssoudan/edisonIsThePilot/drivers/motor" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "math" "time" ) var log = logger.Log("motorCalibration") var numberOfSteps = float64(200) func rotationInDegreeToMove(speed uint32, rotationInDegree float64) (clockwise bool, duration time.Duration) { clockwise = rotationInDegree > 0. duration = time.Duration( math.Abs(rotationInDegree/360.*numberOfSteps/float64(speed)) * float64(time.Second)) return } func doStep(motor *motor.Motor, s step) { clockwise, duration := rotationInDegreeToMove(s.stepsBySecond, s.rotationInDegree) motor.Enable()
* @Date: 2015-09-21 17:40:00 * @Last Modified by: Sebastien Soudan * @Last Modified time: 2015-10-21 12:31:39 */ package steering import ( "math" "time" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/types" ) var log = logger.Log("steering") const ( numberOfSteps = 200 rotationSpeedInStepPerSeconds = 2 * numberOfSteps // aka 2 rotation per second ) // Steering is the component driving the steering wheel through an Actionner type Steering struct { actionner Actionner // channels inputChan chan interface{} shutdownChan chan interface{} panicChan chan interface{} }
"github.com/ssoudan/edisonIsThePilot/dashboard" "github.com/ssoudan/edisonIsThePilot/drivers/gpio" "github.com/ssoudan/edisonIsThePilot/drivers/motor" "github.com/ssoudan/edisonIsThePilot/drivers/pwm" "github.com/ssoudan/edisonIsThePilot/drivers/sincos" "github.com/ssoudan/edisonIsThePilot/gps" "github.com/ssoudan/edisonIsThePilot/infrastructure/logger" "github.com/ssoudan/edisonIsThePilot/infrastructure/pid" "github.com/ssoudan/edisonIsThePilot/infrastructure/utils" "github.com/ssoudan/edisonIsThePilot/infrastructure/webserver" "github.com/ssoudan/edisonIsThePilot/pilot" "github.com/ssoudan/edisonIsThePilot/steering" "github.com/ssoudan/edisonIsThePilot/tracer" ) var log = logger.Log("edisonIsThePilot") // Version is the version of this code -- sets at compilation time var Version = "unknown" func main() { log.Info("Starting -- version %s", Version) panicChan := make(chan interface{}) defer func() { if r := recover(); r != nil { panicChan <- r } }() go func() {