Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/rivian/parallax/dynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,20 @@ def decode_gear(m: dynamics_pb2.Gear) -> dict[str, Any]:
return {"gearStatus": _enum(_GEAR_MAP, m.gear, what="gear")}


# Some vehicles send the fix time as GPS time (milliseconds since the GPS
# epoch, 1980-01-06, without leap seconds) instead of Unix time. Any time
# before 2020 is taken as GPS time.
# Vehicles send the fix time in Unix milliseconds, Unix seconds, or GPS time
# (milliseconds since the GPS epoch, 1980-01-06, without leap seconds). Any
# time below 10^11 (1973 in ms, year 5138 in seconds) is taken as seconds, and
# then any time before 2020 as GPS time.
_GPS_EPOCH_OFFSET_MS: Final = 315_964_800_000
_GPS_LEAP_SECONDS_MS: Final = 18_000
_GPS_TIME_CUTOFF_MS: Final = 1_577_836_800_000 # 2020-01-01 in Unix ms
_SECONDS_CUTOFF: Final = 100_000_000_000


def _gnss_unix_ms(time: int) -> int:
"""A GNSS fix time as Unix epoch milliseconds."""
if 0 < time < _SECONDS_CUTOFF:
time *= 1000
if 0 < time < _GPS_TIME_CUTOFF_MS:
return time + _GPS_EPOCH_OFFSET_MS - _GPS_LEAP_SECONDS_MS
return time
Expand Down
2 changes: 1 addition & 1 deletion src/rivian/parallax/proto/dynamics.proto
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ message Gnss {
float position_vertical_error = 7; // meters
float speed_error = 8; // m/s
float bearing_error = 9; // degrees
int64 time = 10; // epoch ms (Unix, or GPS on some vehicles); the whole fix
int64 time = 10; // Unix ms, Unix seconds or GPS ms, by vehicle; the whole fix
}

// dynamics.vehicle.location
Expand Down
9 changes: 9 additions & 0 deletions tests/parallax/test_dynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ def test_gnss_gps_time() -> None:
assert result["gnssTimeStamp"] == epoch(1790553428211)


def test_gnss_unix_seconds() -> None:
"""A fix time in Unix seconds is converted to milliseconds."""
result = decode(
"dynamics.vehicle.gnss", dynamics.Gnss(latitude=1.0, time=1794604023)
)
assert result["gnssTimeStamp"] == epoch(1794604023000)
assert result["gnssLocation"]["timeStamp"] == epoch(1794604023000)


def test_gnss_empty() -> None:
"""An empty payload has no fix, so nothing is reported."""
assert decode("dynamics.vehicle.gnss") == {}
Expand Down
Loading