Skip to content

Instantly share code, notes, and snippets.

@Alphajeez96
Created July 2, 2026 00:25
Show Gist options
  • Select an option

  • Save Alphajeez96/8a5183c057f586b0f52b29ca8bd4abd5 to your computer and use it in GitHub Desktop.

Select an option

Save Alphajeez96/8a5183c057f586b0f52b29ca8bd4abd5 to your computer and use it in GitHub Desktop.
RACEMAKE PRODUCT ENGINEER CHALLENGE SUBMISSION - Prince Chukwudire
import {Hono} from "hono";
import {cors} from "hono/cors";
import {readFileSync} from "fs";
import {fileURLToPath} from "url";
import {resolve, dirname} from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
interface RawFrame {
ts: number;
lap: number;
pos: number;
spd: number;
thr: number;
brk: number;
str: number;
gear: number;
rpm: number;
tyres: {fl: number; fr: number; rl: number; rr: number};
}
interface CleanFrame {
ts: number;
lap: number;
pos: number;
spd: number;
thr: number;
brk: number;
str: number;
gear: number;
rpm: number;
tyres: {fl: number; fr: number; rl: number; rr: number};
}
interface TelemetryData {
schema: string;
frame_count: number;
frames: RawFrame[];
}
interface TyreStats {
avg_c: number;
min_c: number;
max_c: number;
}
interface LapResult {
number: number;
lap_time_s: number;
frame_count: number;
steering: {max: number; avg_abs: number};
classification: "out_lap" | "flying" | "in_lap";
brake: {avg: number; max: number; braking_pct: number};
speeds: {avg_kmh: number; top_kmh: number; min_kmh: number};
gear: {change_count: number; highest: number; lowest: number};
tyres: {fl: TyreStats; fr: TyreStats; rl: TyreStats; rr: TyreStats};
throttle: {
avg: number;
coast_pct: number;
above_90_pct: number;
below_10_pct: number;
full_throttle_pct: number;
};
}
interface LapBoundary {
endIdx: number;
startIdx: number;
lapFromData: number;
}
interface StageResult {
notes: string[];
frames: CleanFrame[];
}
interface StintResponse {
valid_laps: LapResult[];
cleaning_notes: string[];
discarded_laps: LapResult[];
summary: {
cleaned_frames: number;
valid_lap_count: number;
total_raw_frames: number;
anomalies_discarded: number;
discarded_lap_count: number;
};
}
const RPM_MAX = 15000;
const TYRE_SCALE = 10.0;
const SPEED_MAX_KMH = 400;
const TYRE_TEMP_MAX_C = 200;
const TYRE_TEMP_MIN_C = -50;
const COAST_THRESHOLD = 0.05;
const BRAKING_THRESHOLD = 0.05;
const LAP_POS_WRAP_THRESHOLD = 0.5;
const IN_LAP_END_POS_THRESHOLD = 0.9;
const FULL_THROTTLE_THRESHOLD = 0.99;
const OUT_LAP_START_POS_THRESHOLD = 0.1;
const loadTelemetry = (filePath: string): TelemetryData => {
const raw = readFileSync(filePath, "utf-8");
const data = JSON.parse(raw) as TelemetryData;
if (!data.schema || !Array.isArray(data.frames)) {
throw new Error("Invalid telemetry data: missing schema or frames array");
}
return data;
};
// Pipeline helpers
const stageNote = (label: string, count: number, examples: string[]): string =>
`${label}: removed ${count} frame(s)${examples.length ? ` (${examples.join("; ")})` : ""}`;
const rawToClean = (raw: RawFrame[]): CleanFrame[] =>
raw.map((f) => ({
ts: f.ts,
lap: f.lap,
pos: f.pos,
spd: f.spd,
thr: f.thr,
brk: f.brk,
str: f.str,
gear: f.gear,
rpm: f.rpm,
tyres: {...f.tyres},
}));
const sortFrames = (frames: CleanFrame[]): StageResult => {
const sorted = [...frames].sort((a, b) => a.ts - b.ts);
const moved = frames.length > 0 && sorted[0].ts !== frames[0].ts;
return {
frames: sorted,
notes: moved
? ["Sorted frames by timestamp (input order not guaranteed)"]
: [],
};
};
const removeDuplicates = (frames: CleanFrame[]): StageResult => {
const seen = new Set<number>();
const deduped: CleanFrame[] = [];
for (const f of frames) {
if (!seen.has(f.ts)) {
seen.add(f.ts);
deduped.push(f);
}
}
const removed = frames.length - deduped.length;
return {
frames: deduped,
notes:
removed > 0
? [
stageNote("Duplicate timestamps", removed, [
"kept first occurrence — assumes duplicates are redundant reads",
]),
]
: [],
};
};
const removeTimestampRegressions = (frames: CleanFrame[]): StageResult => {
let maxTs = -Infinity;
const valid: CleanFrame[] = [];
const examples: string[] = [];
for (const f of frames) {
if (f.ts >= maxTs) {
valid.push(f);
maxTs = f.ts;
} else if (examples.length < 3) {
examples.push(`ts=${f.ts} < previous ${maxTs}`);
}
}
const removed = frames.length - valid.length;
return {
frames: valid,
notes:
removed > 0
? [stageNote("Timestamp regressions", removed, examples)]
: [],
};
};
const removeInvalidPositions = (frames: CleanFrame[]): StageResult => {
const valid = frames.filter(
(f) => Number.isFinite(f.pos) && f.pos >= 0 && f.pos <= 1,
);
const removed = frames.length - valid.length;
const badExamples = frames
.filter((f) => !(Number.isFinite(f.pos) && f.pos >= 0 && f.pos <= 1))
.slice(0, 3);
return {
frames: valid,
notes:
removed > 0
? [
stageNote(
"Invalid positions (pos < 0 or > 1)",
removed,
badExamples.map((f) => `ts=${f.ts}, pos=${f.pos}`),
),
]
: [],
};
};
const removeInvalidThrottleBrake = (frames: CleanFrame[]): StageResult => {
const valid = frames.filter((f) => {
const thrOk = Number.isFinite(f.thr) && f.thr >= 0 && f.thr <= 1;
const brkOk = Number.isFinite(f.brk) && f.brk >= 0 && f.brk <= 1;
return thrOk && brkOk;
});
const removed = frames.length - valid.length;
return {
frames: valid,
notes:
removed > 0
? [stageNote("Invalid throttle/brake (outside [0, 1])", removed, [])]
: [],
};
};
const removeImpossibleSpeeds = (frames: CleanFrame[]): StageResult => {
const good: CleanFrame[] = [];
const bad: CleanFrame[] = [];
for (const f of frames) {
if (Number.isFinite(f.spd) && f.spd >= 0 && f.spd <= SPEED_MAX_KMH) {
good.push(f);
} else {
bad.push(f);
}
}
const removed = bad.length;
const examples = bad.slice(0, 3).map((f) => `ts=${f.ts}, spd=${f.spd} km/h`);
return {
frames: good,
notes:
removed > 0
? [
stageNote(
`Impossible speeds (not finite, < 0, or > ${SPEED_MAX_KMH} km/h)`,
removed,
examples,
),
]
: [],
};
};
const removeImpossibleRPM = (frames: CleanFrame[]): StageResult => {
const good: CleanFrame[] = [];
const bad: CleanFrame[] = [];
for (const f of frames) {
if (Number.isFinite(f.rpm) && f.rpm >= 0 && f.rpm <= RPM_MAX) {
good.push(f);
} else {
bad.push(f);
}
}
const removed = bad.length;
const examples = bad.slice(0, 3).map((f) => `ts=${f.ts}, rpm=${f.rpm}`);
return {
frames: good,
notes:
removed > 0
? [
stageNote(
`Impossible RPM (not finite, < 0, or > ${RPM_MAX})`,
removed,
examples,
),
]
: [],
};
};
const decodeTyres = (frames: CleanFrame[]): StageResult => {
const decoded = frames.map((f) => ({
...f,
tyres: {
fl: f.tyres.fl / TYRE_SCALE,
fr: f.tyres.fr / TYRE_SCALE,
rl: f.tyres.rl / TYRE_SCALE,
rr: f.tyres.rr / TYRE_SCALE,
},
}));
return {
frames: decoded,
notes: [
`Decoded tyre temperatures: divided raw values by ${TYRE_SCALE} (Rust recorder stores °C × ${TYRE_SCALE} as i16 — see recorder.rs scales::TEMPERATURE)`,
],
};
};
const removeImpossibleTyreTemps = (frames: CleanFrame[]): StageResult => {
const good: CleanFrame[] = [];
const bad: CleanFrame[] = [];
for (const f of frames) {
const {fl, fr, rl, rr} = f.tyres;
if (
[fl, fr, rl, rr].every(
(t) =>
Number.isFinite(t) && t >= TYRE_TEMP_MIN_C && t <= TYRE_TEMP_MAX_C,
)
) {
good.push(f);
} else {
bad.push(f);
}
}
const removed = bad.length;
return {
frames: good,
notes:
removed > 0
? [
stageNote(
`Impossible tyre temperatures (outside ${TYRE_TEMP_MIN_C}${TYRE_TEMP_MAX_C} °C after decode)`,
removed,
[],
),
]
: [],
};
};
// Pipeline
const runPipeline = (raw: RawFrame[]): StageResult => {
let frames = rawToClean(raw);
const notes: string[] = [];
const run = (fn: (f: CleanFrame[]) => StageResult): void => {
const result = fn(frames);
frames = result.frames;
notes.push(...result.notes);
};
run(sortFrames);
run(removeDuplicates);
run(removeTimestampRegressions);
run(removeInvalidPositions);
run(removeInvalidThrottleBrake);
run(removeImpossibleSpeeds);
run(removeImpossibleRPM);
run(decodeTyres);
run(removeImpossibleTyreTemps);
return {frames, notes};
};
// Lap Detection (dual-signal: pos wrap AND lap increment)
const detectLapBoundaries = (
frames: CleanFrame[],
): {
boundaries: LapBoundary[];
notes: string[];
} => {
const notes: string[] = [];
const boundaries: LapBoundary[] = [];
let lapStart = 0;
let inconsistencies = 0;
for (let i = 1; i < frames.length; i++) {
const prev = frames[i - 1];
const curr = frames[i];
const posDrop = prev.pos - curr.pos;
const posWraps = posDrop > LAP_POS_WRAP_THRESHOLD && curr.pos < 0.15;
const lapIncrements = curr.lap === prev.lap + 1;
if (posWraps && lapIncrements) {
boundaries.push({
startIdx: lapStart,
endIdx: i - 1,
lapFromData: prev.lap,
});
lapStart = i;
} else if (posWraps || lapIncrements) {
inconsistencies++;
}
}
if (lapStart < frames.length) {
boundaries.push({
startIdx: lapStart,
endIdx: frames.length - 1,
lapFromData: frames[lapStart].lap,
});
}
notes.push(
`Detected ${boundaries.length} lap(s) via dual-signal detection (position wrapping AND lap counter increment)`,
);
if (inconsistencies > 0) {
notes.push(
`Found ${inconsistencies} telemetry inconsistency(ies) where position and lap counter disagreed — boundaries only created when both signals agree`,
);
}
return {boundaries, notes};
};
// Lap Classification
const classifyLap = (
boundary: LapBoundary,
index: number,
totalLaps: number,
frames: CleanFrame[],
): LapResult["classification"] => {
const startFrame = frames[boundary.startIdx];
const endFrame = frames[boundary.endIdx];
if (index === 0 && startFrame.pos > OUT_LAP_START_POS_THRESHOLD) {
return "out_lap";
}
if (index === totalLaps - 1 && endFrame.pos < IN_LAP_END_POS_THRESHOLD) {
return "in_lap";
}
return "flying";
};
// Analysis
const computeDeltas = (frames: CleanFrame[]): number[] => {
const deltas: number[] = [];
for (let i = 0; i < frames.length; i++) {
deltas.push(i < frames.length - 1 ? frames[i + 1].ts - frames[i].ts : 0);
}
return deltas;
};
const weightedMean = (values: number[], weights: number[]): number => {
let sumW = 0;
let sumV = 0;
for (let i = 0; i < values.length; i++) {
if (weights[i] > 0) {
sumW += weights[i];
sumV += values[i] * weights[i];
}
}
return sumW > 0 ? sumV / sumW : 0;
};
const pct = (weight: number, totalWeight: number): number =>
totalWeight > 0 ? Math.round((weight / totalWeight) * 1000) / 10 : 0;
const analyzeLap = (
boundary: LapBoundary,
frames: CleanFrame[],
classification: LapResult["classification"],
): LapResult => {
const lapFrames = frames.slice(boundary.startIdx, boundary.endIdx + 1);
const n = lapFrames.length;
const deltas = computeDeltas(lapFrames);
const totalWeight = deltas.reduce((s, d) => s + d, 0);
const totalTimeMs = lapFrames[n - 1].ts - lapFrames[0].ts;
const spds = lapFrames.map((f) => f.spd);
const tyreStats = (extract: (f: CleanFrame) => number): TyreStats => {
const vals = lapFrames.map(extract);
return {
avg_c: Math.round(weightedMean(vals, deltas) * 10) / 10,
min_c: Math.round(Math.min(...vals) * 10) / 10,
max_c: Math.round(Math.max(...vals) * 10) / 10,
};
};
// Throttle weighted aggregates
const thrWeightedSum = deltas.reduce(
(s, d, i) => s + lapFrames[i].thr * d,
0,
);
const thrWeightedAvg = totalWeight > 0 ? thrWeightedSum / totalWeight : 0;
const fullThrottleWeight = deltas.reduce(
(s, d, i) => (lapFrames[i].thr >= FULL_THROTTLE_THRESHOLD ? s + d : s),
0,
);
const coastWeight = deltas.reduce(
(s, d, i) => (lapFrames[i].thr <= COAST_THRESHOLD ? s + d : s),
0,
);
const above90Weight = deltas.reduce(
(s, d, i) => (lapFrames[i].thr >= 0.9 ? s + d : s),
0,
);
const below10Weight = deltas.reduce(
(s, d, i) => (lapFrames[i].thr <= 0.1 ? s + d : s),
0,
);
// Brake
const brkWSum = deltas.reduce((s, d, i) => s + lapFrames[i].brk * d, 0);
const brkWeightedAvg = totalWeight > 0 ? brkWSum / totalWeight : 0;
const maxBrk = Math.max(...lapFrames.map((f) => f.brk));
const brakingWeight = deltas.reduce(
(s, d, i) => (lapFrames[i].brk >= BRAKING_THRESHOLD ? s + d : s),
0,
);
// Steering
const strAbsVals = lapFrames.map((f) => Math.abs(f.str));
// Gear
let gearChanges = 0;
let maxGear = 0;
let minGear = 8;
for (let i = 0; i < lapFrames.length; i++) {
const g = lapFrames[i].gear;
if (i > 0 && g !== lapFrames[i - 1].gear) gearChanges++;
if (g > maxGear) maxGear = g;
if (g > 0 && g < minGear) minGear = g;
}
if (minGear === 8) minGear = 0;
return {
number: boundary.lapFromData,
classification,
lap_time_s: Math.round((totalTimeMs / 1000) * 100) / 100,
frame_count: n,
speeds: {
avg_kmh: Math.round(weightedMean(spds, deltas) * 10) / 10,
top_kmh: Math.round(Math.max(...spds) * 10) / 10,
min_kmh: Math.round(Math.min(...spds) * 10) / 10,
},
tyres: {
fl: tyreStats((f) => f.tyres.fl),
fr: tyreStats((f) => f.tyres.fr),
rl: tyreStats((f) => f.tyres.rl),
rr: tyreStats((f) => f.tyres.rr),
},
throttle: {
avg: Math.round(thrWeightedAvg * 1000) / 1000,
full_throttle_pct: pct(fullThrottleWeight, totalWeight),
coast_pct: pct(coastWeight, totalWeight),
above_90_pct: pct(above90Weight, totalWeight),
below_10_pct: pct(below10Weight, totalWeight),
},
brake: {
avg: Math.round(brkWeightedAvg * 1000) / 1000,
max: Math.round(maxBrk * 1000) / 1000,
braking_pct: pct(brakingWeight, totalWeight),
},
steering: {
max: Math.round(Math.max(...strAbsVals) * 1000) / 1000,
avg_abs: Math.round(weightedMean(strAbsVals, deltas) * 1000) / 1000,
},
gear: {
change_count: gearChanges,
highest: maxGear,
lowest: minGear,
},
};
};
// Orchestration
const analyzeStint = (filePath: string): StintResponse => {
const data = loadTelemetry(filePath);
const rawCount = data.frames.length;
const {frames: cleaned, notes: cleanNotes} = runPipeline(data.frames);
const anomaliesDiscarded = rawCount - cleaned.length;
const {boundaries, notes: lapNotes} = detectLapBoundaries(cleaned);
const allLaps: LapResult[] = boundaries.map((b, i) => {
const classification = classifyLap(b, i, boundaries.length, cleaned);
return analyzeLap(b, cleaned, classification);
});
const validLaps = allLaps.filter((l) => l.classification === "flying");
const discardedLaps = allLaps.filter((l) => l.classification !== "flying");
// Engineering-justification notes
const justificationNotes: string[] = [
`Speed threshold: ≤ ${SPEED_MAX_KMH} km/h (F1 top speed ~370 km/h, margin for slipstream/tow; also rejects NaN/Infinity and negative values)`,
`RPM threshold: ≥ 0 and ≤ ${RPM_MAX} (typical F1 rev limit ~15000; also rejects NaN/Infinity)`,
`Lap detection: both position wrapping (pos drop > ${LAP_POS_WRAP_THRESHOLD} from >0.85 to <0.15) AND lap counter increment required — prevents false positives from position glitches`,
`Out-lap classification: first lap with start_pos > ${OUT_LAP_START_POS_THRESHOLD} (recording began mid-track, lap is incomplete) — excluded from valid_laps`,
`In-lap classification: last lap with end_pos < ${IN_LAP_END_POS_THRESHOLD} (recording ended before lap completion) — excluded from valid_laps`,
`Tyre temperature range: sanity-checked to ${TYRE_TEMP_MIN_C}${TYRE_TEMP_MAX_C} °C after ÷${TYRE_SCALE} decode`,
`All averaged metrics are Δt-weighted (weighted by time to next frame) to account for the recorder's non-uniform sample rate — simple arithmetic mean would bias toward denser sampling periods`,
`Lap time derived from first and last valid frame in each detected lap: (last.ts - first.ts) / 1000`,
];
return {
summary: {
total_raw_frames: rawCount,
cleaned_frames: cleaned.length,
anomalies_discarded: anomaliesDiscarded,
valid_lap_count: validLaps.length,
discarded_lap_count: discardedLaps.length,
},
valid_laps: validLaps,
discarded_laps: discardedLaps,
cleaning_notes: [...cleanNotes, ...lapNotes, ...justificationNotes],
};
};
const app = new Hono();
app.use("/*", cors());
// const DATA_PATH = resolve(__dirname, "data", "stint.telemetry.json");
const DATA_PATH = "";
app.get("/stint/analysis", (c) => {
try {
const result = analyzeStint(DATA_PATH);
return c.json(result);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
return c.json({error: message}, 500);
}
});
app.get("/", (c) =>
c.json({
service: "RaceMake Telemetry Analyzer",
endpoints: {"/stint/analysis": "Analyze stint telemetry data"},
}),
);
const PORT = parseInt(process.env.PORT || "3001", 10);
console.log(`Server running on http://localhost:${PORT}`);
export default {port: PORT, fetch: app.fetch};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment