diff --git a/docs/impl/plans/INITIAL.md b/docs/impl/plans/INITIAL.md index 0b6903d..895a821 100644 --- a/docs/impl/plans/INITIAL.md +++ b/docs/impl/plans/INITIAL.md @@ -24,7 +24,7 @@ directly. `mark` forwarded to the recorder's control socket, mock state behind `--mock`. Protocol in contracts [`docs/BOUNDARY.md`](gitea:yukart/contracts). **Bus input** — in place (2026-10-12): subscribes to `yukart/vehicle/+`, - `yukart/host/+` and `yukart/gnss/+`, keeps the newest envelope per signal, marks stale after 5 s + `yukart/host/+`, `yukart/gnss/+` and `yukart/imu/+`, keeps the newest envelope per signal, marks stale after 5 s or when known only from a retained copy. Bus or mock, never both. 1. Static file serving for the basemap — smallest useful thing, unblocks the map. 2. Nav HTTP proxy to [svc-nav](gitea:yukart/svc-nav). diff --git a/src/bus.rs b/src/bus.rs index 48538c7..5b7658c 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -15,7 +15,7 @@ use std::time::{Duration, Instant}; use rumqttc::{Client, Event, MqttOptions, Packet, QoS}; use serde_json::{json, Map, Value}; -const TOPICS: [&str; 3] = ["yukart/vehicle/+", "yukart/host/+", "yukart/gnss/+"]; +const TOPICS: [&str; 4] = ["yukart/vehicle/+", "yukart/host/+", "yukart/gnss/+", "yukart/imu/+"]; const STALE: Duration = Duration::from_secs(5); struct Entry { diff --git a/src/mock.rs b/src/mock.rs index b4923c9..1592582 100644 --- a/src/mock.rs +++ b/src/mock.rs @@ -52,6 +52,19 @@ impl Mock { } else { put("obd_intake_air_temp_c", json!((31.0 + (t * 0.05).sin()).round()), None); } + // IMU in the car's frame: pulling away 4 km/h/s (0.11 g), braking 6 km/h/s, and a + // gentle weave while cruising. Body roll follows lateral g, pitch follows longitudinal. + let lon = match phase { + p if (10.0..25.0).contains(&p) => 0.11, + p if (45.0..55.0).contains(&p) => -0.17, + _ => 0.0, + } + 0.01 * (t * 5.3).sin(); + let lat = if (25.0..45.0).contains(&phase) { 0.3 * (t * 0.9).sin() } else { 0.0 } + 0.01 * (t * 4.1).sin(); + put("imu_accel_lon_g", json!((lon * 100.0_f64).round() / 100.0), None); + put("imu_accel_lat_g", json!((lat * 100.0_f64).round() / 100.0), None); + put("imu_roll_deg", json!((lat * 30.0_f64).round() / 10.0), None); + put("imu_pitch_deg", json!((-lon * 20.0_f64).round() / 10.0), None); + put("imu_yaw_rate_dps", json!(if speed > 1.0 { ((-lat * 9.81 / (speed / 3.6)).to_degrees() * 10.0).round() / 10.0 } else { 0.0 }), None); // Fuel level is known but has no value: the registry has it, the car never sent it. put("obd_fuel_level_pct", Value::Null, None); s