package core import ( "errors" "git.timovolkmann.de/gyrogpsc/ublox" "github.com/tidwall/gjson" "log" "math" "time" "github.com/m7shapan/njson" ) /*{ "smartphone": { // hier daten von hyperimu }, "serial": { // hier Daten von M8U: "timestamp": 37539672354 "position": [0, 0, 0], "orientation": [0, 0, 0] } } */ type sourceId string const ( SOURCE_TCP sourceId = "SOURCE_TCP" SOURCE_SERIAL sourceId = "SOURCE_SERIAL" ) type Sensordata struct { itow uint32 SourceId sourceId Timestamp int64 Position [3]float64 Orientation [3]float64 } func (s Sensordata) isSameEpoch(n Sensordata) bool { if n.itow == 0 { return false } return s.itow == n.itow } func (s Sensordata) Consolidate(n Sensordata) Sensordata { if (s.SourceId != n.SourceId && s != Sensordata{}) { log.Println(s) log.Println(n) log.Fatalln("Do not consolidate Sensordata from different Sources") } if s.isSameEpoch(n) { null := Sensordata{} //if s.Timestamp == null.Timestamp { s.Timestamp = n.Timestamp } //if s.Position == null.Position { s.Position = n.Position } //if s.Orientation == null.Orientation { s.Orientation = n.Orientation } if n.Timestamp != null.Timestamp && s.Timestamp != n.Timestamp { s.Timestamp = n.Timestamp } if n.Position != null.Position && s.Position != n.Position { s.Position = n.Position } if n.Orientation != null.Orientation && s.Orientation != n.Orientation { s.Orientation = n.Orientation } return s } return n } func (s Sensordata) Consolidate2(n Sensordata) Sensordata { null := Sensordata{} //if s.Timestamp == null.Timestamp { s.Timestamp = n.Timestamp } //if s.Position == null.Position { s.Position = n.Position } //if s.Orientation == null.Orientation { s.Orientation = n.Orientation } //if n.Timestamp == null.Timestamp { // n.Timestamp = s.Timestamp //} if n.Position == null.Position { n.Position = s.Position } if n.Orientation == null.Orientation{ n.Orientation = s.Orientation } return n } var ( errNotImplemented = errors.New("message not implemented") errRawMessage = errors.New("raw message") ) func ConvertUbxToSensorData(msg interface{}) (*Sensordata, error) { sd := &Sensordata{ SourceId: SOURCE_SERIAL, } switch v := msg.(type) { case *ublox.NavPvt: //log.Println("NAV-PVT") sd.itow = v.ITOW_ms sd.Timestamp = time.Date(int(v.Year_y), time.Month(v.Month_month), int(v.Day_d), int(v.Hour_h), int(v.Min_min), int(v.Sec_s), int(v.Nano_ns), time.UTC).UnixNano() sd.Position[0] = float64(v.Lat_dege7) / 1e+7 sd.Position[1] = float64(v.Lon_dege7) / 1e+7 sd.Position[2] = float64(v.HMSL_mm) / 1e+3 // mm in m case *ublox.HnrPvt: //log.Println("HNR-PVT") sd.itow = v.ITOW_ms sd.Timestamp = time.Date(int(v.Year_y), time.Month(v.Month_month), int(v.Day_d), int(v.Hour_h), int(v.Min_min), int(v.Sec_s), int(v.Nano_ns), time.UTC).UnixNano() sd.Position[0] = float64(v.Lat_dege7) / 1e+7 sd.Position[1] = float64(v.Lon_dege7) / 1e+7 sd.Position[2] = float64(v.HMSL_mm) / 1e+3 // mm in m case *ublox.NavAtt: //log.Println("NAV-ATT") sd.itow = v.ITOW_ms sd.Orientation[0] = float64(v.Pitch_deg) * 1e-5 sd.Orientation[1] = float64(v.Roll_deg) * 1e-5 sd.Orientation[2] = float64(v.Heading_deg) * 1e-5 case *ublox.RawMessage: //class := make([]byte, 2) //binary.LittleEndian.PutUint16(class, v.ClassID()) //log.Printf("%#v, %#v", class[0],class[1]) return nil, nil default: return nil, errNotImplemented } return sd, nil } func ConvertSensorDataPhone(jsonData []byte) (*Sensordata, error) { if gjson.Get(string(jsonData), "os").String() == "hyperimu" { return convertAndroidHyperImu(jsonData) } return convertIPhoneSensorLog(jsonData) } func convertIPhoneSensorLog(jsonData []byte) (*Sensordata, error) { timestamp := gjson.Get(string(jsonData), "locationTimestamp_since1970").Float() lat := gjson.Get(string(jsonData), "locationLatitude").Float() lon := gjson.Get(string(jsonData), "locationLongitude").Float() alt := gjson.Get(string(jsonData), "locationAltitude").Float() pitch := gjson.Get(string(jsonData), "motionPitch").Float() * 180 / math.Pi roll := gjson.Get(string(jsonData), "motionRoll").Float() * 180 / math.Pi yaw := gjson.Get(string(jsonData), "motionYaw").Float() * 180 / math.Pi sd := &Sensordata{ SourceId: SOURCE_TCP, Timestamp: int64(timestamp * float64(time.Second)), //Timestamp: time.Unix(0, prep.Timestamp * int64(time.Millisecond)), Position: [3]float64{lat, lon, alt}, Orientation: [3]float64{pitch, roll, yaw}, } //log.Println(string(pretty.Pretty(jsonData))) //log.Println(sd) return sd, nil } func convertAndroidHyperImu(jsonData []byte) (*Sensordata, error) { prep := struct { Timestamp int64 `njson:"Timestamp"` Position [3]float64 `njson:"GPS"` Orientation [3]float64 `njson:"orientation"` }{} err := njson.Unmarshal(jsonData, &prep) if err != nil { return nil, err } sd := &Sensordata{ Timestamp: prep.Timestamp * int64(time.Millisecond), //Timestamp: time.Unix(0, prep.Timestamp * int64(time.Millisecond)), Position: prep.Position, Orientation: prep.Orientation, } return sd, nil }