package anki import "encoding/binary" const ( VehicleMsgMaxSize = 20 VehicleMsgPayloadMaxSize = 18 VehicleMsgBaseSize = 1 ) // Identifier for a vehicle message const ( // BLE Connection VehicleMsgC2VDisconnect = 0x0d // Ping request / response VehicleMsgC2VPingRequest = 0x16 VehicleMsgV2CPingResponse = 0x17 // Messages for checking vehicle version info VehicleMsgC2VVersionRequest = 0x18 VehicleMsgV2CVersionResponse = 0x19 // Baterry level VehicleMsgC2VBatteryLevelRequest = 0x1a VehicleMsgV2CBatteryLevelResponse = 0x1b // Lights VehicleMsgC2VSetLights = 0x1d // Driving Commands VehicleMsgC2VSetSpeed = 0x24 VehicleMsgC2VChangeLane = 0x25 VehicleMsgC2VCancelLaneChange = 0x26 VehicleMsgC2VTurn = 0x32 // Vehicle position updates VehicleMsgV2CLocalizationPositionUpdate = 0x27 VehicleMsgV2CLocalizationTransitionUpdate = 0x29 VehicleMsgV2CLocalizationIntersectionUpdate = 0x2a VehicleMsgV2cVehicleDelocalized = 0x2b VehicleMsgC2VSetOffsetFromRoadCenter = 0x2c VehicleMsgV2COffsetFromRoadCenterUpdate = 0x2d // Light Patterns VehicleMsgC2VLightsPattern = 0x33 // Vehicle Configuration Prameters VehicleMsgC2VSetConfigParams = 0x45 // SDK Mode VehicleMsgC2VSDKMode = 0x90 // Unknown events // // Status Update // 05 3F 01 00 01 00 // 05 3F 00 00 01 00 // // Collision Detected // 03 4D 01 00 // 03 4D 00 01 // // Speed Update // 07 36 20 03 98 3A 2A 00 // 07 36 00 00 E8 03 50 00 ) type VehicleMsg struct { Size uint8 MsgID uint8 Payload [VehicleMsgMaxSize]byte } type VehicleMsgVersionResponse struct { Size uint8 MsgID uint8 Version uint16 // uint32 ? } type VehicleBatteryLevelResponse struct { Size uint8 MsgID uint8 BatteryLevel uint16 } type VehicleMsgSDKMode struct { Size uint8 MsgID uint8 On uint8 Flags uint8 } func (v *VehicleMsgSDKMode) Set(on, flags uint8) { v.Size = uint8(binary.Size(v) - 1) v.MsgID = VehicleMsgC2VSDKMode v.On = on v.Flags = flags } type VehicleMsgSetSpeed struct { Size uint8 MsgID uint8 Speed uint16 // mm/sec Accel uint16 // mm/secĀ² SpeedLimit uint8 // respect road piece speed limit } func (v *VehicleMsgSetSpeed) Set(speed, accel uint16) { v.Size = uint8(binary.Size(v) - 1) v.MsgID = VehicleMsgC2VSetSpeed v.Speed = speed v.Accel = accel } const ( VehicleTurnNone = iota VehicleTurnLeft VehicleTurnRight VehicleTurnUTurn VehicleTurnUTurnJump ) const ( VehicleTurnTriggerImmediate = iota // Run immediately VehicleTurnTriggerIntersection // Run at the next intersection ) type VehicleMsgTurn struct { Size uint8 MsgID uint8 Type uint8 Trigger uint8 } type VehicleMsgSetOffsetFromRoadCenter struct { Size uint8 MsgID uint8 Offset float32 // mm } func (v *VehicleMsgSetOffsetFromRoadCenter) Set(offset float32) { v.Size = uint8(binary.Size(v) - 1) v.MsgID = VehicleMsgC2VSetOffsetFromRoadCenter v.Offset = offset } type VehicleMsgChangeLane struct { Size uint8 MsgID uint8 HorizontalSpeed uint16 // mm/sec HorizontalAccel uint16 // mm/secĀ² Offset float32 // from road center mm HopIntent uint8 Tag uint8 } func (v *VehicleMsgChangeLane) Set(hspeed, haccel uint16, offset float32) { v.Size = uint8(binary.Size(v) - 1) v.MsgID = VehicleMsgC2VChangeLane v.HorizontalSpeed = hspeed v.HorizontalAccel = haccel v.Offset = offset } const ( ParseflagsMaskNumBits = 0x0f ParseflagsMaskInvertedColor = 0x80 ParseflagsMaskReverseParsing = 0x40 ParseflagsMaskReverseDriving = 0x20 ) type VehicleLocalizationPositionUpdate struct { Size uint8 MsgID uint8 LocalizationID uint8 RoadPieceID uint8 Offset float32 // from road center mm Speed uint16 // mm/sec ParsingFlags uint8 // ACK commands received LastRecvLaneChangeCmdID uint8 LastExecLaneChangeCmdID uint8 LastDesiredHorizontalSpeed uint16 // mm/sec LastDesiredSpeed uint16 // mm/sec } // VehicleDrivingDirection const ( Forward uint8 = iota Reverse ) type VehicleMsgLocalizationTransitionUpdate struct { Size uint8 MsgID uint8 RoadPieceIDX uint8 RoadPieceIDXPrev uint8 Offset float32 // from road center mm Direction uint8 // driving direction // ACK commands received LastRecvLaneChangeCmdID uint8 LastExecLaneChangeCmdID uint8 LastDesiredHorizontalSpeed uint16 // mm/sec LastDesiredSpeed uint16 // mm/sec // track grade detection UphillCounter uint8 DownhillCounter uint8 // wheel displacement (cm) since last transition bar LeftWheelDist uint8 // cm RightWheelDist uint8 // cm } const ( IntersectionCodeEntryFirst = iota IntersectionCodeExitFirst IntersectionCodeEntrySecond IntersectionCodeExitSecond ) type VehicleMsgLocalizationIntersectionUpdate struct { Size uint8 MsgID uint8 RoadPieceIDX uint8 Offset float32 // from road center mm Direction uint8 // driving direction IntersectionCode uint8 IntersectionTurn uint8 IsExiting uint8 } type VehicleMsgOffsetFromRoadCenterUpdate struct { Size uint8 MsgID uint8 Offset float32 // from road center mm LaneChangeID uint8 } // Lights // The bits in the simple light message corresponding to each type of light const ( LightHeadlights = 1 << iota LightBrakelights LightFrontlights LightEngine ) type VehicleMsgSetLights struct { Size uint8 MsgID uint8 LightMask uint8 // valid and value bits for lights } func (v *VehicleMsgSetLights) Set(mask uint8) { v.Size = uint8(binary.Size(v) - 1) v.MsgID = VehicleMsgC2VSetLights v.LightMask = mask } const ( VehicleMaxLightIntensity = 14 VehicleMaxLightTime = 11 ) // LED channel definitions - for RGB engine, front, and tail lights const ( LightRed = iota LightTail LightBlue LightGreen LightFrontL LightFrontR ) const ( EffectSteady = iota // Simply set the light intensity to 'start' value EffectFade // Fade intensity from 'start' to 'end' EffectThrob // Fade intensity from 'start' to 'end' and back to 'start' EffectFlash // Tun on LED between time 'start' and time 'end' inclusive EffectRandom // Flash the LED erratically - ignoring start/end ) type VehicleLightConfig struct { Channel uint8 Effect uint8 Start uint8 End uint8 Cycles uint8 // per 10 sec } func (v *VehicleLightConfig) Set(channel, effect uint8, start, end uint8, cycles uint16) { v.Channel = channel v.Effect = effect v.Start = start if v.Start > VehicleMaxLightIntensity { v.Start = VehicleMaxLightIntensity } v.End = end if v.End > VehicleMaxLightIntensity { v.End = VehicleMaxLightIntensity } cpm := cycles if cpm > VehicleMaxLightTime { cpm = VehicleMaxLightTime } v.Cycles = uint8(cpm / 6) } type VehicleMsgLightsPattern struct { Size uint8 MsgID uint8 ChannelCount uint8 ChannelConfig [3]VehicleLightConfig } func (v *VehicleMsgLightsPattern) Set(config VehicleLightConfig) { v.Size = uint8(binary.Size(v) - 1) v.MsgID = VehicleMsgC2VLightsPattern if int(v.ChannelCount) < len(v.ChannelConfig) { v.ChannelConfig[v.ChannelCount] = config v.ChannelCount++ } } const ( TrackMaterialPlastic = iota TrackMaterialVinyl ) const ( SupercodeNone = iota SupercodeBoostJump ) type VehicleMsgSetConfigParams struct { Size uint8 MsgID uint8 SuperCodeParseMask uint8 TrackMaterial uint8 }