The Speed dimension carries five units and none of them is km/s:
|
FootPerSecond |
KilometerPerHour |
Knot |
MeterPerSecond |
MilePerHour |
KilometerPerSecond |
Speed |
✓ |
✓ |
✓ |
✓ (base) |
✓ |
missing |
Velocity1D |
✓ |
✓ |
✓ |
✓ |
✓ |
missing |
So a library that can express a car's speed five ways cannot express a satellite's at all without arithmetic at the call site.
Why this is #240's loose end rather than a new request
#240 added GravitationalParameter with CubicKilometerPerSecondSquared, whose summary says it exists because "the unit published values of mu are quoted in" is km³/s². That reasoning is exactly right and it applies more strongly one dimension down. The library today has:
Kilometer for lengths ✓
CubicKilometerPerSecondSquared for μ ✓
- nothing for speed ✗
Kilometres are there for the distance and for the gravitational parameter, but not for the velocity that sits between them in every state vector. An orbital state is quoted in km and km/s, together, in every source that publishes one — Vallado, the SGP4 verification set, CelesTrak, Space-Track, JPL Horizons.
What a consumer does today
From ktsu-dev/Osculator, converting an SGP4 residual (SGP4 emits km/s):
private static Velocity1D<T> PerSecond(T kilometersPerSecond) =>
Velocity1D<T>.FromMeterPerSecond(kilometersPerSecond * T.CreateChecked(1000));
The multiplication is exact in every storage type, so this is not a precision complaint — it is that the one factor of a thousand the whole domain is written in has to be spelled by hand, in a library whose entire point is that units are not spelled by hand.
Design
One unit and one conversion constant. No new dimension, no new type name, no relationship, so nothing for SEM008 to check.
units.json — a KilometerPerSecond entry, added to the Speed dimension's availableUnits.
conversions.json — KilometerPerSecondToMeterPerSecond, value "1000". Exact by definition, comfortably inside double, and a plain decimal literal, so SEM009 has nothing to say about it.
Naming follows the existing neighbours exactly — KilometerPerHourToMeterPerSecond, FootPerSecondToMeterPerSecond, KnotToMeterPerSecond — and the factory name follows the singular-lemma rule (#49) mechanically: FromKilometerPerSecond, beside FromKilometerPerHour.
Scope, and one difference from #240 worth checking rather than assuming
The alias props should not change. #240's note about Generate-AliasProps.ps1 applied because it added type names. This does not: I checked ktsu.Semantics.Quantities.Double.props and all 220 aliases name generic quantity types (Acceleration1D<double>); not one names a unit, because units are non-generic types in ktsu.Semantics.Quantities.Units and need no alias. Worth re-running the script and confirming a clean diff anyway, since verify-generated will fail the PR either way.
The vector forms are unaffected. Velocity2D/3D/4D have no From* factories at all — they expose Cross, Dot, Length, Magnitude, Normalize, DistanceTo and are built from components. So this adds Speed.FromKilometerPerSecond and Velocity1D.FromKilometerPerSecond, and the vector forms benefit only through whatever builds their components.
Worth considering alongside, but not in this issue
Acceleration has the same shape: MeterPerSecondSquared is the base and KilometerPerSecondSquared is likewise absent, and that is the unit perturbation accelerations are quoted in. I have not checked whether anything needs it yet, so I am not asking for it here — noting it so the two can be decided together if that is cheaper.
Raised from ktsu-dev/Osculator, where a doc comment claimed this had been filed upstream before it actually had. Filing it makes that comment true.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Dn4fyZp3kQhh2199arTU6p
The Speed dimension carries five units and none of them is km/s:
FootPerSecondKilometerPerHourKnotMeterPerSecondMilePerHourKilometerPerSecondSpeedVelocity1DSo a library that can express a car's speed five ways cannot express a satellite's at all without arithmetic at the call site.
Why this is #240's loose end rather than a new request
#240 added
GravitationalParameterwithCubicKilometerPerSecondSquared, whose summary says it exists because "the unit published values of mu are quoted in" is km³/s². That reasoning is exactly right and it applies more strongly one dimension down. The library today has:Kilometerfor lengths ✓CubicKilometerPerSecondSquaredfor μ ✓Kilometres are there for the distance and for the gravitational parameter, but not for the velocity that sits between them in every state vector. An orbital state is quoted in km and km/s, together, in every source that publishes one — Vallado, the SGP4 verification set, CelesTrak, Space-Track, JPL Horizons.
What a consumer does today
From
ktsu-dev/Osculator, converting an SGP4 residual (SGP4 emits km/s):The multiplication is exact in every storage type, so this is not a precision complaint — it is that the one factor of a thousand the whole domain is written in has to be spelled by hand, in a library whose entire point is that units are not spelled by hand.
Design
One unit and one conversion constant. No new dimension, no new type name, no relationship, so nothing for SEM008 to check.
units.json— aKilometerPerSecondentry, added to the Speed dimension'savailableUnits.conversions.json—KilometerPerSecondToMeterPerSecond, value"1000". Exact by definition, comfortably insidedouble, and a plain decimal literal, so SEM009 has nothing to say about it.Naming follows the existing neighbours exactly —
KilometerPerHourToMeterPerSecond,FootPerSecondToMeterPerSecond,KnotToMeterPerSecond— and the factory name follows the singular-lemma rule (#49) mechanically:FromKilometerPerSecond, besideFromKilometerPerHour.Scope, and one difference from #240 worth checking rather than assuming
The alias props should not change. #240's note about
Generate-AliasProps.ps1applied because it added type names. This does not: I checkedktsu.Semantics.Quantities.Double.propsand all 220 aliases name generic quantity types (Acceleration1D<double>); not one names a unit, because units are non-generic types inktsu.Semantics.Quantities.Unitsand need no alias. Worth re-running the script and confirming a clean diff anyway, sinceverify-generatedwill fail the PR either way.The vector forms are unaffected.
Velocity2D/3D/4Dhave noFrom*factories at all — they exposeCross,Dot,Length,Magnitude,Normalize,DistanceToand are built from components. So this addsSpeed.FromKilometerPerSecondandVelocity1D.FromKilometerPerSecond, and the vector forms benefit only through whatever builds their components.Worth considering alongside, but not in this issue
Accelerationhas the same shape:MeterPerSecondSquaredis the base andKilometerPerSecondSquaredis likewise absent, and that is the unit perturbation accelerations are quoted in. I have not checked whether anything needs it yet, so I am not asking for it here — noting it so the two can be decided together if that is cheaper.Raised from
ktsu-dev/Osculator, where a doc comment claimed this had been filed upstream before it actually had. Filing it makes that comment true.🤖 Generated with Claude Code
https://claude.ai/code/session_01Dn4fyZp3kQhh2199arTU6p