Skip to main content

uniform_sensor_compensation/
uniform_sensor_compensation.rs

1//! Uniform/Uniform compensation over two evenly coded operating inputs.
2//!
3//! Both axes are exact arithmetic progressions, so Uniform stores no knot
4//! arrays: location is one subtraction and one division per axis, not a search.
5//! That is not zero work in cycles; measure the division on the target if
6//! timing matters. See the strategy guide (not packaged):
7//! <https://github.com/photon-circus/ph-surfaces/blob/v0.1.0/docs/choosing-a-strategy.md>.
8//!
9//! Host `main` is an assertion harness. Declarations are `static` and
10//! `core`-compatible. Payload figures are referenced element bytes, not total
11//! flash or RAM.
12
13use ph_surfaces::{AxisLookup, BilinearSurface, UniformAxis};
14
15// X codes 0, 100, 200 and Y codes 0, 50, 100 — described, not stored.
16type Compensation = BilinearSurface<3, 3, UniformAxis<3, 0, 100>, UniformAxis<3, 0, 50>>;
17
18static VALUES: [[i32; 3]; 3] = [[0, 20, 40], [10, 30, 50], [20, 40, 60]];
19
20static SURFACE: Compensation =
21    BilinearSurface::from_axes(UniformAxis::new(), UniformAxis::new(), &VALUES);
22
23// Equivalent default surface over the same described knots, for equality.
24static X: [u16; 3] = [0, 100, 200];
25static Y: [u16; 3] = [0, 50, 100];
26static DEFAULT: BilinearSurface<3, 3> = BilinearSurface::new(&X, &Y, &VALUES);
27
28fn main() {
29    // Endpoint accessors reconstruct the arithmetic progression.
30    assert_eq!(SURFACE.x_knot(0), 0);
31    assert_eq!(SURFACE.x_knot(2), 200);
32    assert_eq!(SURFACE.y_knot(1), 50);
33
34    // Interior: lower-X 10, upper-X 20, Y 15. Hand-computable plane.
35    assert_eq!(SURFACE.evaluate(50, 25), Ok(15));
36    assert_eq!(SURFACE.evaluate(200, 100), Ok(60));
37    for x in [0u16, 50, 100, 199, 200] {
38        for y in [0u16, 25, 50, 99, 100] {
39            assert_eq!(SURFACE.evaluate(x, y), DEFAULT.evaluate(x, y));
40        }
41    }
42
43    assert_eq!(<UniformAxis<3, 0, 100>>::KNOT_BYTES, 0);
44    assert_eq!(<UniformAxis<3, 0, 50>>::KNOT_BYTES, 0);
45    assert_eq!(<UniformAxis<3, 0, 100>>::MAX_SEARCH_COMPARISONS, 0);
46    assert_eq!(Compensation::VALUE_BYTES, 36);
47    assert_eq!(Compensation::PAYLOAD_BYTES, 36);
48    assert_eq!(BilinearSurface::<3, 3>::PAYLOAD_BYTES, 48);
49    assert_eq!(
50        Compensation::HANDLE_BYTES,
51        core::mem::size_of::<Compensation>()
52    );
53}