export type UnitKind = | "length" | "angle" | "time" | "mass" | "linear_velocity" | "angular_velocity" | "linear_acceleration" | "angular_acceleration" | "percent"; export interface UnitDefinition { literal: string; kind: UnitKind; siUnit: string; factor: number; } const UNIT_DEFINITIONS: UnitDefinition[] = [ { literal: "m", kind: "length", siUnit: "m", factor: 1 }, { literal: "mm", kind: "length", siUnit: "m", factor: 0.001 }, { literal: "rad", kind: "angle", siUnit: "rad", factor: 1 }, { literal: "deg", kind: "angle", siUnit: "rad", factor: Math.PI / 180 }, { literal: "s", kind: "time", siUnit: "s", factor: 1 }, { literal: "ms", kind: "time", siUnit: "s", factor: 0.001 }, { literal: "kg", kind: "mass", siUnit: "kg", factor: 1 }, { literal: "m/s", kind: "linear_velocity", siUnit: "m/s", factor: 1 }, { literal: "mm/s", kind: "linear_velocity", siUnit: "m/s", factor: 0.001 }, { literal: "rad/s", kind: "angular_velocity", siUnit: "rad/s", factor: 1 }, { literal: "deg/s", kind: "angular_velocity", siUnit: "rad/s", factor: Math.PI / 180 }, { literal: "m/s2", kind: "linear_acceleration", siUnit: "m/s2", factor: 1 }, { literal: "m/s^2", kind: "linear_acceleration", siUnit: "m/s2", factor: 1 }, { literal: "mm/s2", kind: "linear_acceleration", siUnit: "m/s2", factor: 0.001 }, { literal: "mm/s^2", kind: "linear_acceleration", siUnit: "m/s2", factor: 0.001 }, { literal: "rad/s2", kind: "angular_acceleration", siUnit: "rad/s2", factor: 1 }, { literal: "rad/s^2", kind: "angular_acceleration", siUnit: "rad/s2", factor: 1 }, { literal: "deg/s2", kind: "angular_acceleration", siUnit: "rad/s2", factor: Math.PI / 180 }, { literal: "deg/s^2", kind: "angular_acceleration", siUnit: "rad/s2", factor: Math.PI / 180 }, { literal: "%", kind: "percent", siUnit: "ratio", factor: 0.01 } ]; const UNITS = new Map(UNIT_DEFINITIONS.map((definition) => [definition.literal, definition])); export function normalizeUnitLiteral(literal: string): UnitDefinition { const definition = UNITS.get(literal); if (!definition) { throw new Error(`Unknown GRL unit: ${literal}`); } return definition; } export function isGrlUnitLiteral(literal: string): boolean { return UNITS.has(literal); } export function normalizeUnitValue(value: number, unitLiteral: string): number { const unit = normalizeUnitLiteral(unitLiteral); return value * unit.factor; }