RE paperConfirmed

Reverse engineering paper #3 — no heading signal on the vehicle bus

No yaw rate, no steering angle, no compass anywhere in the 277-class BYD SDK. Heading is not published — it always has to be derived.

BYD LabVerified 7 min read

N E S W no heading on the bus no yaw rate · no steering angle · no compass what the catalogue does carry speed — a magnitude gear — the sign for it road grade — pitch, not yaw heading is always derived: GNSS course, the on-board gyro, gear-signed speed

Our own app. Sealion 7 Pilot is developed by BYD Lab. It is held to the same standards as every other app on this site — read with that in mind.

Tested on

Vehicle
BYD Sealion 7 · Morocco
Head-unit version
51.1.4.2606220.1
Android
11
Verified

The car will tell you how fast it is going, which gear it is in and how steep the road is (paper #2 is the catalogue). It will not tell you which way it is pointing.

Question#

Does the export Sealion 7 publish a vehicle heading — a yaw rate, a steering angle, a compass or a bearing — anywhere an ordinary app can read it?

Environment#

Decompiled read-only with jadx 1.5.5: the 277-class android.hardware.bydauto.* SDK bundled inside BydSpotifyMusic.apk, and CarAdapterService.apk (com.ts.appservice.caradapter). The SDK was searched class by class for anything heading-shaped rather than grepped for one expected name. On the car, probed over adb with dumpsys location, dumpsys sensorservice and a read of the Qualcomm izat gps.conf.

Observation#

Nothing in the vehicle catalogue is a heading. Searching the whole SDK for a yaw rate, a steering angle, a compass or a bearing returns nothing; the only entries whose name contains “direction” are HVAC airflow.

The class that sounds like it should be the answer is not. android.hardware.bydauto.sensor.BYDAutoSensorDevice — the BYD “sensor” device, with its own SensorHalId map — carries slope, temperature, light and humidity. It is an environmental sensor block, not an inertial measurement unit.

What the car does publish, and what is adjacent to the question, is motion along the road rather than orientation of the car: speed magnitude, the gear that gives it a sign, and road grade.

Two things on the unit can produce a heading, and neither of them is the vehicle bus: the standard Android gps provider, and a real IMU sitting on the Android sensor stack.

Evidence#

The heading-adjacent signals that do exist, with the ids and names read from the SDK’s tsimpl HAL-id maps:

Name Decimal Hex What it is
ID_SPEED_VALUE_R 559957505 0x21604601 Vehicle speed — the primary one the car adapter reads
ID_CURRENT_SPEEDR 557867014 0x21406006 Speed, instantaneous
ID_SPEED_ALIVE_COUNTER_R 559942916 0x21600D04 Rolling freshness counter for the speed signal
ID_IPB_VEHICLE_SPEED_STATUS_R 559942915 0x21600D03 Speed validity flag
ID_GEAR_R 557857290 0x21403A0A Gear — the sign source for signed speed
ID_SLOPE 557861635 0x21404B03 Road grade, i.e. pitch, in the BYD “sensor” device

Speed and grade are scalars. Grade is pitch, not yaw: it gives the slope of the road under the car, not the direction the car faces. Nothing in this list is an orientation.

Log
mTopHalCapabilities = 0xd1 (SCHEDULING ON_DEMAND_TIME MEASUREMENTS NAV_MESSAGES)

The observed consumers of gps were com.byd.vrassistant (voice, every 10 s), TwilightService (every 10 min), and com.ali.sealion7pilot at 400 ms. No provider on the unit is doing app-visible dead reckoning.

The values that bear on the question:

Android property
NMEA_PROVIDER = 0
NMEA_REPORT_RATE = NHZ
PPS_DEVICENAME = /dev/pps0
SUPL_VER = 0x10000
LPP_PROFILE = 2
CAPABILITIES = 0x17
DR_SYNC_ENABLED = 0
Sensor Type Backed by Rate
accelerometer 1 Bosch SMI230 200 Hz
gyroscope 4 Bosch SMI230 200 Hz
game_rotation_vector 15 AOSP virtual — gyro + accel, no magnetometer —
linear_acceleration 10 AOSP virtual —

These are ordinary Android sensors. They are reachable with a vanilla SensorManager and need no permission — no BYDAUTO permission, no platform signature, no car-adapter binding.

Interpretation#

The absence is structural, not an oversight in one build.

game_rotation_vector having no magnetometer behind it is the tell. It is a relative orientation: it tracks how much the car has turned, off a gyroscope the platform advertises at 200 Hz — and it has no idea where north is. The unit has a yaw-rate source and no absolute reference of its own.

Every heading on this platform is therefore a derived quantity, and there are exactly three ways to derive one:

  • GNSS course. Location.getBearing(), from a provider fed multi-Hz NMEA. Absolute, and it degrades exactly where a car marker most needs help — at walking pace, in car parks, under cover.
  • The vehicle-fused orientation. BYDAutoLocationDevice defines LOCATION_ORIENTATION 0–359°, 360 meaning invalid — a heading computed vehicle-side. The contract exists in the SDK; whether an app can reach the implementation is a separate question, and it is paper #4.
  • Gyro integration. The SMI230, integrated about gravity, with something absolute to anchor it against drift.

None of these is the vehicle bus. What the bus uniquely gives is the other half of the problem: signed speed — magnitude from 0x21604601, sign from the gear at 0x21403A0A, or the same pair as BYDAutoSpeedDevice and BYDAutoGearboxDevice. A GNSS course flips 180° when a car reverses out of a parking bay, because the receiver reports direction of travel and the car is travelling backwards. Only the gear says the nose never moved. That is what keeps a heading stable through a reverse and through a slow U-turn, and it is not something a phone can supply for itself.

What this does not mean: it does not mean the physical bus carries no yaw rate. It means nothing in BYD’s own SDK catalogue, and nothing in the car adapter an app binds to, exposes one.

Result#

Confirmed: no heading, yaw rate, steering angle or compass appears anywhere in BYD’s own SDK catalogue on this unit, or in the car adapter an app binds to. Heading is not one of the signals this platform hands an app; it is something you compute.

The practical consequence is that an app that needs to know where the car is pointing has to fuse it itself — GNSS course for the absolute reference, the SMI230 gyro for the low-speed and no-signal case, gear-signed vehicle speed to keep both honest through a reverse.

One smaller consequence follows. The one thing the car contributes here that a phone cannot is signed speed, which makes the vehicle-signal path worth binding even for an app whose position comes entirely from GNSS.

Limitations#

One car, one market, one head-unit build. Other export markets and other builds have not been checked. Nothing here applies to domestic Chinese units, whose navigation stack is a different one entirely (paper #1).

The search covers the SDK bundled in the Scout app on this unit. A different app or a later build could bundle a larger SDK, and the absence of a signal from a catalogue is not proof that the VHAL implements no such property — we did not brute-force the vendor property id space, and we did not put a scope on the physical bus. The honest claim is the exposed surface, not the wire.

The IMU and the GNSS capability bits were read from dumpsys on a stationary probe. We report what the platform advertises: 200 Hz, 6-axis, zero clients. We did not characterise the gyro’s bias or drift, and we did not measure how the 0xd1 raw-measurement capability behaves under load. “Reachable with no permission” follows from these being standard AOSP sensor types; it was not tested by a deliberate permission-denied run.

BYDAutoLocationDevice’s orientation field is read from SDK constants. Nothing here was observed returning a live heading from that device, and paper #4 covers why.

Reproduction#

On a car with adb reachable (our guide covers getting there):

Shell
adb shell dumpsys location
adb shell dumpsys sensorservice
adb shell find /vendor /system/etc /etc -name gps.conf

Read dumpsys location for mTopHalCapabilities and for the list of current gps clients; read dumpsys sensorservice for the sensor list and the client count against each one. find locates gps.conf without assuming a path — then cat it.

For the catalogue search, pull the Scout app and decompile it:

Shell
adb shell pm path com.telenav.scoutivi.spotify.byd
adb pull <the path that command prints> BydSpotifyMusic.apk
jadx -d scout-out BydSpotifyMusic.apk
grep -rniE 'yaw|steer|compass|heading|bearing|azimuth|direction' scout-out/sources/android/hardware/bydauto/

The grep is the fast check; it is not the proof. The result that matters is an absence, and an absence is only established by reading the device classes and their tsimpl HAL-id maps in full — sensor/, speed/, gearbox/, vehicledata/ and adas/ in particular. The only entries direction matches are HVAC airflow.