Inputs
IMU-GPS-ESKF is built to run on input data from one of two sources:
- nuScenes CAN-bus scene data named
scene-XXXX_pose.json,scene-XXXX_ms_imu.json, andscene-XXXX_zoe_veh_info.json, released in February 2020. [1], [2], [3] - the
scene_pose.json,scene_ms_imu.json, andscene_zoe_veh_info.jsonfiles bundled with the app. These files were generated by simulation to follow the same input fact-patterns documented on this page.
Because all of the above files have been verified to follow the fact-patterns documented on this page, and since IMU-GPS-ESKF only runs on said files, runtime data verification that would always be guaranteed to pass wasn’t included.
nuScenes input sets
The upstream nuScenes CAN-bus download stores the scene-XXXX_pose.json, scene-XXXX_ms_imu.json, and scene-XXXX_zoe_veh_info.json files under nuscenes/can_bus/. Using nuScenes input requires a separate nuScenes download. [1], [2]
nuScenes scene inventory
The nuScenes CAN-bus download provides 979 scene IDs with matching scene-XXXX_pose.json, scene-XXXX_ms_imu.json, and scene-XXXX_zoe_veh_info.json files. Scene IDs are sparse and range from scene-0001 through scene-1110. [1], [2], [3], [4]
nuScenes file-name variation
The CAN-bus README prose sometimes says scene_XXXX_imu.json, but the API code and examples use scene-XXXX_ms_imu.json. [1], [2]
Runtime input selection
At runtime, the app selects the active input set from scenarios.
Selection follows this rule:
- if exactly one matching nuScenes input set is present, the app uses that scene’s
scene-XXXX_pose.json,scene-XXXX_ms_imu.json, and matchingscene-XXXX_zoe_veh_info.json - otherwise, the bundled simulated set supplies the default run
Pose input (*_pose.json)
Purpose in IMU-GPS-ESKF
This file provides the reference pose stream used for truth lookup, checks, and evaluation. [1], [5], [6]
nuScenes provenance
For nuScenes scenes, the pose stream comes from the nuScenes localization pipeline: offline lidar HD map construction followed by online Monte Carlo Localization with lidar and odometry. Reported localization error is <= 10 cm. This localization output is the pose stream. [1], [5]
Example record
[
{
"utime": 1700000000000000,
"pos": [120.0, -45.0, 0.0],
"orientation": [0.9939560979566968, 0.0, 0.0, 0.10977830083717481],
"vel": [8.272592839624389, 0.0, 0.0],
"accel": [1.4902411831299034, 6.58109833210669e-14, 9.8],
"rotation_rate": [0.0, 0.0, 7.95530308295156e-15]
}
]Record schema
Across all 979 checked pose files, every record uses the exact key set accel, orientation, pos, rotation_rate, utime, vel. Vector lengths are always:
Field semantics
utime: integer timestamp in microsecondspos: global-frame position in meters [1]orientation: orientation quaternionvel: ego-frame velocity in \(\mathrm{m}/\mathrm{s}\) [1]accel: ego-frame acceleration in \(\mathrm{m}/\mathrm{s}^2\) [1]rotation_rate: ego-frame angular velocity in \(\mathrm{rad}/\mathrm{s}\) [1]
Position structure
Across 952,103 checked pose records, pos has exact planar form pos = [x, y, 0]. [3]
Orientation structure
Across the same checked pose records, orientation has exact yaw-only form orientation = [w, 0, 0, z]. Pose quaternions are unit length to machine precision. [3]
Velocity structure
Across the same checked pose records, vel has exact forward-only form vel = [forward, 0, 0]. [3]
Dynamic-channel statistics
Despite the planar and yaw-only structure above, the ego-frame dynamic channels are nontrivial. In checked pose records, pose.accel[2] mean/med/min/max = 9.784/9.789/4.818/15.063, and |pose.rotation_rate[0]|, |pose.rotation_rate[1]|, |pose.rotation_rate[2]| med/max = (0.0074, 0.0079, 0.0086)/(0.3223, 0.4490, 0.6947) \(\mathrm{rad}/\mathrm{s}\). [3]
IMU input (*_ms_imu.json)
Purpose in IMU-GPS-ESKF
This file provides the IMU stream used for initialization and propagation.
Example record
[
{
"utime": 1700000000000000,
"linear_accel": [1.543318572672857, -0.03916157510402117, 9.804608745997307],
"rotation_rate": [-0.0018336573502681383, -0.0014580203316534287, -0.001036707959881021],
"q": [0.9568021423210139, 0.0, 0.0, 0.29073985012364273]
}
]Record schema
Across all 979 checked ms_imu files, every record uses the exact key set linear_accel, q, rotation_rate, utime. Vector lengths are always:
Field semantics
utime: integer timestamp in microsecondslinear_accel: specific force in frameI, in \(\mathrm{m}/\mathrm{s}^2\) [1], [7]rotation_rate: angular velocity in frameI, in \(\mathrm{rad}/\mathrm{s}\) [1]q: IMU-to-gravity-aligned orientation quaternion \({}^{A}q_{\fsub{I}}\); frame names and transform notation are defined onConventions[1]
Specific-force convention
After rotating linear_accel into the gravity-aligned frame defined by q and restricting to near-stationary moments, samples cluster near [0, 0, 9.8], not [0, 0, 0]. In 147006 matched stationary samples, the mean is [0.00016, 0.00224, 9.79705] and the median is [-0.00007, 0.00126, 9.79619]. [1], [3], [7]
Quaternion normalization
IMU q is essentially unit length. The maximum observed norm error is about 1.36e-7. [3]
Quaternion tilt content
IMU q is not pure yaw. Observed |q[1]|, |q[2]| med/mean/max = (0.0071, 0.0080)/(0.0098, 0.0101)/(0.0712, 0.0701). [3]
Acceleration dimensionality
linear_accel is genuinely 3D. Observed |linear_accel[0]|, |linear_accel[1]| med/mean/max = (0.389, 0.241)/(0.522, 0.349)/(5.491, 4.541), and linear_accel[2] mean/med/min/max = 9.784/9.786/-2.802/21.610. [1], [3], [7]
Wheel-speed input (*_zoe_veh_info.json)
Purpose in IMU-GPS-ESKF
This file provides the wheel-speed stream used during startup.
Required fields
Startup uses these four fields from each record:
FL_wheel_speedFR_wheel_speedRL_wheel_speedRR_wheel_speed
Each record also includes integer microsecond utime on the same scene time axis used by the pose and IMU files. [1]
Pose samples after IMU end
Observed pattern
In 616 of the 979 scenes, one final pose sample has a timestamp greater than the timestamp of the final IMU sample. There are never two or more pose samples after the final IMU sample.
The largest such pose-over-IMU gap is 34,654 us.
Runtime handling
IMU-GPS-ESKF treats these single trailing pose entries as extraneous and never uses them at runtime.
Effect on synthetic GPS generation
This matters only during synthetic GPS generation. There are 110 scenes where the GPS generation algorithm would otherwise have used one of these 616 trailing pose samples.
Supported nuScenes scenes
This section applies only to nuScenes CAN-bus inputs. The bundled simulated set remains supported independently of the nuScenes scene list on this page.
For nuScenes CAN-bus inputs, IMU-GPS-ESKF is intended to be used only on the scene IDs listed in metadata/supported_nuscenes_scenes.txt in the app repo. The manifest contains 876 supported nuScenes scenes.
The app does not check scene membership at runtime. Users are expected to supply only scene IDs from the supported-scene manifest.
Supported-scene manifest
The supported-scene manifest is a fixed offline operating set for this project.
This project is meant to focus on the filter side rather than the initialization side. For that reason, the supported nuScenes scene IDs are the ones that satisfy both of the following conditions:
- From the startup reference pose, the loaded pose stream reaches at least
10 mof maximum true radial distance traveled. - The startup window reaches at least
10 mof distance from integrated robust wheel speed early enough for startup to leave the live filter at least one GPS update to process.
Here, startup_begin_utime is defined on the loaded pose stream the app actually uses, after the single-trailing-pose drop described above when that case occurs. It is the timestamp of the first synthetic GPS sample whose time is not earlier than the first IMU sample. The startup reference pose is the loaded pose sample at startup_begin_utime.
The pruning rule above is not part of runtime scene selection. It defines the supported nuScenes operating set listed in metadata/supported_nuscenes_scenes.txt.