mirror of
https://codeberg.org/portospaceteam/ground-dashboard.git
synced 2024-11-25 08:26:26 +00:00
99 lines
3.0 KiB
Go
99 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
"errors"
|
|
"math"
|
|
"strings"
|
|
|
|
"github.com/johnjones4/model-rocket-telemetry/dashboard/core"
|
|
)
|
|
|
|
func telemetryFloatFromByteIndex(bytes []byte, index int) float64 {
|
|
start := 8 * index
|
|
end := start + 8
|
|
if start >= len(bytes) || end >= len(bytes) {
|
|
return 0
|
|
}
|
|
bits := binary.LittleEndian.Uint64(bytes[start:end])
|
|
float := math.Float64frombits(bits)
|
|
return float
|
|
}
|
|
|
|
func telemetryIntFromBytes(b []byte) int16 {
|
|
buffer := bytes.NewReader(b)
|
|
if len(b) != 2 {
|
|
return 0
|
|
}
|
|
var val int16
|
|
binary.Read(buffer, binary.LittleEndian, &val)
|
|
return val
|
|
}
|
|
|
|
func decodeTelemetryBytes(bytes []byte) ([]byte, []byte, error) {
|
|
parts := strings.Split(string(bytes), ",")
|
|
if len(parts) != 3 || parts[0] != "T" {
|
|
return nil, nil, errors.New("bad telemetry")
|
|
}
|
|
telemetryBytes, err := base64.StdEncoding.DecodeString(parts[1])
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
rssiBytes, err := base64.StdEncoding.DecodeString(parts[2])
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return telemetryBytes, rssiBytes, nil
|
|
}
|
|
|
|
func bytesToDataSegment(stream core.FlightData, bytes []byte) ([]core.DataSegment, float64, core.Coordinate, error) {
|
|
telemetryBytes, rssiBytes, err := decodeTelemetryBytes(bytes)
|
|
if err != nil {
|
|
return nil, 0, core.Coordinate{}, err
|
|
}
|
|
|
|
segments := make([]core.DataSegment, PointsPerDataFrame)
|
|
var basePressure float64
|
|
var origin core.Coordinate
|
|
for i := len(segments) - 1; i >= 0; i-- {
|
|
offset := 1 + (i * 13)
|
|
raw := core.RawDataSegment{
|
|
WriteProgress: telemetryFloatFromByteIndex(telemetryBytes, 0),
|
|
Timestamp: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexTimestamp),
|
|
Pressure: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexPressure),
|
|
Temperature: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexTemperature),
|
|
Acceleration: core.XYZ{
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexAccelerationX),
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexAccelerationY),
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexAccelerationZ),
|
|
},
|
|
Magnetic: core.XYZ{
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexMagneticX),
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexMagneticY),
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexMagneticZ),
|
|
},
|
|
Coordinate: core.Coordinate{
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexCoordinateLat),
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexCoordinateLon),
|
|
},
|
|
GPSInfo: core.GPSInfo{
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexGpsQuality),
|
|
telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexGpsSats),
|
|
},
|
|
Rssi: telemetryIntFromBytes(rssiBytes),
|
|
}
|
|
|
|
var computed core.ComputedDataSegment
|
|
computed, basePressure, origin = core.ComputeDataSegment(stream, raw)
|
|
|
|
segments[i] = core.DataSegment{
|
|
raw,
|
|
computed,
|
|
}
|
|
}
|
|
|
|
return segments, basePressure, origin, nil
|
|
}
|