package fields // NumericValueStatus is the status of the numeric values, such as air speed, velocity, etc. type NumericValueStatus byte const ( NVSNoInformation NumericValueStatus = iota // No velocity information NVSRegular // Velocity is computed on the linear scale value of field * factor NVSMaximum // Velocity field value indicates velocity greater the maximum of the scale ) // ParseHeightDifference reads the Height difference from a 56 bits data field func ParseHeightDifference(data []byte) (int16, NumericValueStatus) { negative := data[6]&0x80 != 0 difference := int16(data[6] & 0x7F) if difference == 0 { return 0, NVSNoInformation } else if difference >= 127 { if negative { return -3150, NVSMaximum } else { return 3150, NVSMaximum } } difference = (difference - 1) * 25 if negative { difference = -difference } return difference, NVSRegular } // VerticalRateSource is the Source Bit for Vertical Rate definition // // Specified in Doc 9871 / Table A-2-9 type VerticalRateSource byte const ( VerticalRateSourceGNSS VerticalRateSource = iota // GNSS source VerticalRateSourceBarometric // Barometric source ) // DirectionNorthSouth is the Direction Bit NS Velocity definition // // Specified in Doc 9871 / Table A-2-9 type DirectionNorthSouth byte func ParseDirectionNorthSouth(data []byte) DirectionNorthSouth { return DirectionNorthSouth((data[3] & 0x80) >> 7) } func ParseVelocityNorthSouthNormal(data []byte) (velocity uint16, status NumericValueStatus) { velocity = (uint16(data[3]&0x7F)<<8 | uint16(data[4]&0xE0)) >> 5 if velocity == 0 { return 0, NVSNoInformation } else if velocity >= 1023 { return 1023, NVSMaximum } return velocity - 1, NVSRegular } func ParseVelocityNorthSouthSupersonic(data []byte) (velocity uint16, status NumericValueStatus) { velocity = (uint16(data[3]&0x7F)<<8 | uint16(data[4]&0xE0)) >> 5 if velocity == 0 { return 0, NVSNoInformation } else if velocity >= 1023 { return 4088, NVSMaximum } return (velocity - 1) * 4, NVSRegular } const ( DNSNorth DirectionNorthSouth = iota // North DNSSouth // South ) // DirectionEastWest is the Direction Bit EW Velocity definition // // Specified in Doc 9871 / Table A-2-9 type DirectionEastWest byte func ParseDirectionEastWest(data []byte) DirectionEastWest { return DirectionEastWest((data[1] & 0x04) >> 2) } func ParseVelocityEastWestNormal(data []byte) (velocity uint16, status NumericValueStatus) { velocity = (uint16(data[1]&0x03) | uint16(data[2])) if velocity == 0 { return 0, NVSNoInformation } else if velocity >= 1023 { return 1023, NVSMaximum } return velocity - 1, NVSRegular } func ParseVelocityEastWestSupersonic(data []byte) (velocity uint16, status NumericValueStatus) { velocity = (uint16(data[1]&0x03) | uint16(data[2])) if velocity == 0 { return 0, NVSNoInformation } else if velocity >= 1023 { return 4088, NVSMaximum } return (velocity - 1) * 4, NVSRegular } const ( DEWEast DirectionEastWest = iota // East DEWWest // West ) func ParseIntentChange(data []byte) bool { return (data[1]&0x80)>>7 != 0 } func ParseIFRCapability(data []byte) bool { return (data[1]&0x40)>>6 != 0 } // NavigationUncertaintyCategory is the Navigation Uncertainty Category definition // // Specified in Doc 9871 / Table A-2-9 type NavigationUncertaintyCategory byte const ( NUCPUnknown NavigationUncertaintyCategory = iota // Unknown NUCPHorizontalLowerThan10VerticalLowerThan15Point2 // Horizontal < 10m/s and Vertical < 15.2m/s NUCPHorizontalLowerThan3VerticalLowerThan4Point6 // Horizontal < 3m/s and Vertical < 4.6m/s NUCPHorizontalLowerThan1VerticalLowerThan1Point5 // Horizontal < 1m/s and Vertical < 1.5m/s NUCPHorizontalLowerThan0Point3VerticalLowerThan0Point46 // Horizontal < 0.3m/s and Vertical < 0.46m/s ) func ParseeNavigationUncertaintyCategory(data []byte) NavigationUncertaintyCategory { return NavigationUncertaintyCategory((data[1] & 0x38) >> 3) } func ParseMagneticHeading(data []byte) (heading float64, status bool) { status = (data[1]&0x04)>>2 != 0 value := uint16(data[1]&0x03)<<8 | uint16(data[2]) heading = float64(value) * 360 / 1024.0 return } func ParseAirspeedNormal(data []byte) (speed uint16, status NumericValueStatus) { velocity := (uint16(data[3]&0x7F)<<8 | uint16(data[4]&0xE0)) >> 5 if velocity == 0 { return 0, NVSNoInformation } else if velocity >= 1023 { return 1023, NVSMaximum } return velocity - 1, NVSRegular } func ParseAirspeedSupersonic(data []byte) (speed uint16, status NumericValueStatus) { velocity := (uint16(data[3]&0x7F)<<8 | uint16(data[4]&0xE0)) >> 5 if velocity == 0 { return 0, NVSNoInformation } else if velocity >= 1023 { return 4088, NVSMaximum } return (velocity - 1) * 4, NVSRegular } func ParseVerticalRateSource(data []byte) VerticalRateSource { return VerticalRateSource((data[4] & 0x10) >> 4) } func ParseVerticalRate(data []byte) (rate int16, status NumericValueStatus) { negative := data[4]&0x08 != 0 rate = int16(uint16(data[4]&0x07)<<8 | uint16(data[5]&0xFC)) if rate == 0 { return 0, NVSNoInformation } else if rate >= 511 { if negative { return -32640, NVSMaximum } return 32640, NVSMaximum } rate = (rate - 1) * 64 if negative { rate = -rate } return rate, NVSRegular } func ParseHeightDifferenceFromBaro(data []byte) (difference int16, status NumericValueStatus) { negative := data[6]&0x80 != 0 difference = int16(data[6] & 0x7F) if difference == 0 { return 0, NVSNoInformation } else if difference >= 127 { if negative { return -3150, NVSMaximum } else { return 3150, NVSMaximum } } difference = (difference - 1) * 25 if negative { difference = -difference } return difference, NVSRegular }