func main() {
	panicChan := make(chan interface{})
	defer func() {
		if r := recover(); r != nil {
			panicChan <- r
		}
	}()

	go func() {
		select {
		case m := <-panicChan:

			log.Fatalf("Version %v -- Received a panic error -- exiting: %v", Version, m)
		}
	}()

	ws := webserver.New(Version)
	ws.SetPanicChan(panicChan)
	ws.SetPilot(&fakePilot{})
	ws.SetTracer(&fakeTracer{points: []types.Point{{
		Latitude:  45.,
		Longitude: 5.,
		Time:      types.JSONTime(time.Now())}}})
	ws.SetDashboard(queryable{leds: map[string]bool{
		dashboard.NoGPSFix:                true,
		dashboard.InvalidGPSData:          true,
		dashboard.SpeedTooLow:             false,
		dashboard.HeadingErrorOutOfBounds: true,
		dashboard.CorrectionAtLimit:       true,
	}})
	ws.Start()

	// Wait until we receive a signal
	utils.WaitForInterrupt(func() {
		log.Info("Interrupted - exiting")
		log.Info("Exiting -- version %v", Version)
	})

}
Exemple #2
0
func (s *Stepper) processGPSMessage(m pilot.GPSFeedBackAction) {
	// Update the state
	s.mu.Lock()
	defer s.mu.Unlock()

	now := time.Now()

	switch s.plan.State {

	case GO:
		s.plan.Input.Heading = m.Heading
		s.plan.State = PREPARING
		s.plan.Start = types.JSONTime(now)
		s.plan.Points = []Point{{
			Timestamp:     types.JSONTime(now),
			FixDate:       m.Date,
			FixTime:       m.Time,
			Course:        m.Heading,
			Speed:         m.Speed,
			DeltaSteering: 0,
			Latitude:      m.Latitude,
			Longitude:     m.Longitude,
			Validity:      m.Validity,
		}}

	case PREPARING:
		if time.Time(s.plan.Start).Add(time.Duration(s.plan.Input.Duration)).Before(now) {
			// send message to steering -- that's where we punch the system
			s.steeringChan <- steering.NewMessage(s.plan.Input.Step, true)

			s.plan.Points = append(s.plan.Points, Point{
				Timestamp:     types.JSONTime(now),
				FixDate:       m.Date,
				FixTime:       m.Time,
				Course:        m.Heading,
				Speed:         m.Speed,
				DeltaSteering: s.plan.Input.Step,
				Latitude:      m.Latitude,
				Longitude:     m.Longitude,
				Validity:      m.Validity,
			})

			s.plan.State = RUNNING
		} else {
			s.plan.Points = append(s.plan.Points, Point{
				Timestamp:     types.JSONTime(now),
				FixDate:       m.Date,
				FixTime:       m.Time,
				Course:        m.Heading,
				Speed:         m.Speed,
				DeltaSteering: 0,
				Latitude:      m.Latitude,
				Longitude:     m.Longitude,
				Validity:      m.Validity,
			})
		}

	case RUNNING:
		s.plan.Points = append(s.plan.Points, Point{
			Timestamp:     types.JSONTime(now),
			FixDate:       m.Date,
			FixTime:       m.Time,
			Course:        m.Heading,
			Speed:         m.Speed,
			DeltaSteering: 0,
			Latitude:      m.Latitude,
			Longitude:     m.Longitude,
			Validity:      m.Validity,
		})

		if time.Time(s.plan.Start).Add(time.Duration(2 * s.plan.Input.Duration)).Before(now) {
			// Time is up
			// write to file
			f, err := os.Create("/tmp/systemCalibration-" + time.Now().Format(time.RFC3339))
			if err != nil {
				log.Error("Failed to open experiment log file: %v", err)
				break
			}
			defer f.Close()
			json.NewEncoder(f).Encode(s.plan)

			// tell the pilot the calibration test is over and data can be collected
			log.Notice("The bump test is over. You can disable the autopilot, stop the program and start another test.")

			s.steeringChan <- steering.NewMessage(0, false)

			s.plan.State = DONE
		}
	case DONE:
		// Nothing
		log.Notice("DONE")
	}

}
			tracer.SetInputChan(c)

			tracer.Start()
		})

		It("has no points at first", func() {
			Expect(tracer.GetPoints()).To(Equal([]types.Point{}))
		})

		It("doesn't store any point", func() {

			m := types.Point{
				Latitude:  45.,
				Longitude: 4.,
				Time:      types.JSONTime(time.Now()),
			}

			c <- MkAddPointMessage(m)

			Consistently(tracer.GetPoints).Should(Equal([]types.Point{}))

		})

	})

	Describe("with some seats", func() {
		var (
			tracer *Tracer
			c      chan interface{}
		)
Exemple #4
0
func (g GPS) doReceiveGPSMessages() {
	c := &serial.Config{Name: g.deviceName, Baud: g.baud}

	s, err := serial.OpenPort(c)
	if err != nil {
		log.Panicf("Failed to open serial port: %v", err)

		return
	}

	// Close the serial port when we have to leave this method
	defer s.Close()

	bufferedReader := bufio.NewReader(s)

	defer func() {
		if r := recover(); r != nil {
			log.Warning("Recovered in f", r)
		}
	}()

	for {
		str, err := bufferedReader.ReadString('\n')
		// log.Debug("[%s]", str)
		if err != nil {
			log.Error("Failed to read from serial port: %v", err)
			g.errorChan <- err
			// Exit this method to close the port, and re-open it later
			return
		}

		m, err := nmea.Parse(strings.TrimSuffix(str, "\r\n"))
		if err != nil {
			if !strings.HasSuffix(err.Error(), "not implemented") {
				g.errorChan <- err
			}
			// Here we don't return as it is a non-fatal error and the next line
			// will be better
			continue
		}

		switch t := m.(type) {
		default:
			// don't care
			// log.Debug("%+v\n", m)
		case nmea.GPGGA:
			fix, err := strconv.Atoi(t.FixQuality)
			if err != nil {
				log.Error("Failed to parse FixQuality [%s] : %v", t.FixQuality, err)

			} else {
				log.Info("[GPGGA] fixQuality: %v hdop: %s sat: %s\n", fix, t.HDOP, t.NumSatellites)
				g.messagesChan <- pilot.FixStatus(fix)
			}
		case nmea.GPRMC:
			log.Info("[GPRMC] validity: %v heading: %v[˚] speed: %v[knots] \n", t.Validity == "A", t.Course, t.Speed)
			g.messagesChan <- pilot.GPSFeedBackAction{
				Heading:   t.Course,
				Validity:  t.Validity == "A",
				Speed:     t.Speed,
				Longitude: t.Longitude,
				Latitude:  t.Latitude,
				Date:      t.Date,
				Time:      t.Time,
			}
			if t.Validity == "A" {
				g.headingChan <- ap100.NewMessage(uint16(t.Course))
				g.tracerChan <- tracer.MkAddPointMessage(types.Point{
					Latitude:  float64(t.Latitude),
					Longitude: float64(t.Longitude),
					Time:      types.JSONTime(time.Now()),
				})
			}

		}
	}
}