STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
fsw::calibration::LcTareStore Class Reference

Owns the per-channel tares for the calibration service. More...

#include <LcTareStore.hpp>

Collaboration diagram for fsw::calibration::LcTareStore:
[legend]

Public Types

using Evaluator = std::function<double(double adc)>
 adc -> kg through whichever model this uid streams (select_lc_kg: cubic fit or the datasheet physics conversion).

Public Member Functions

 LcTareStore (std::string file_path)
bool set (uint16_t uid, const std::string &entity, double adc_at_tare, const Evaluator &eval)
 Record a tare for uid at adc_at_tare and derive its offset.
void clear (uint16_t uid)
void clear_all ()
void recompute (uint16_t uid, const Evaluator &eval)
 Re-derive offset_kg for one uid under the current curve.
void recompute_all (const std::function< Evaluator(uint16_t)> &eval_for)
 Re-derive every tare; eval_for supplies each uid's evaluator.
size_t recompute_stale (const std::function< Evaluator(uint16_t)> &eval_for)
 Re-derive only the tares whose recorded fingerprint disagrees with the curve now live, and return how many those were.
void set_curves_trusted (bool trusted)
 False while the curves cannot be trusted — set when the cubic store failed to load.
bool curves_trusted () const
const LcTare * tare_for (uint16_t uid) const
std::vector< uint16_t > uids () const
size_t size () const
bool save () const
 Atomically write the JSON record (temp + rename).
size_t load ()
 Load the JSON record.
bool load_failed () const
 Set when load() could not read an existing file; blocks save() so an unreadable store is never replaced by the empty one we fell back to.

Static Public Member Functions

static uint64_t fingerprint (const Evaluator &eval)
 A fingerprint of what a curve does, not of the coefficients that describe it: the evaluator is sampled at fixed probe codes and the results hashed.

Private Member Functions

std::string serialize () const
bool recompute_locked (LcTare &t, const Evaluator &eval)
 Caller holds mutex_.

Private Attributes

std::mutex mutex_
std::string file_path_
bool load_failed_ = false
bool curves_trusted_ = true
std::map< uint16_t, LcTare > tares_

Detailed Description

Owns the per-channel tares for the calibration service.

Thread-safe, persisted atomically to one JSON file (temp + rename) that the Node backend reads to apply the subtraction — the service never sends the value, because [0x46,0x00] is one-way and there is no reply packet. This mirrors how cubic calibration already reaches the UI.

Ownership, which is deliberately asymmetric: C++ is the STEADY-STATE writer. Node may remove the file, but only while sensor-calibration is not running. That is what lets a tare be cleared at session start and still survive a service restart inside a session — two requirements that together force a file that is persistent AND externally cleared. Neither half is redundant; do not "simplify" one away.

Definition at line 71 of file LcTareStore.hpp.

Member Typedef Documentation

◆ Evaluator

using fsw::calibration::LcTareStore::Evaluator = std::function<double(double adc)>

adc -> kg through whichever model this uid streams (select_lc_kg: cubic fit or the datasheet physics conversion).

Taken as a callable so this class never learns which.

Definition at line 77 of file LcTareStore.hpp.

Constructor & Destructor Documentation

◆ LcTareStore()

fsw::calibration::LcTareStore::LcTareStore ( std::string file_path)
explicit

Definition at line 35 of file LcTareStore.cpp.

References file_path_.

Member Function Documentation

◆ clear()

void fsw::calibration::LcTareStore::clear ( uint16_t uid)

Definition at line 94 of file LcTareStore.cpp.

References lock, mutex_, and tares_.

Referenced by main().

◆ clear_all()

void fsw::calibration::LcTareStore::clear_all ( )

Definition at line 99 of file LcTareStore.cpp.

References lock, mutex_, and tares_.

◆ curves_trusted()

bool fsw::calibration::LcTareStore::curves_trusted ( ) const

Definition at line 153 of file LcTareStore.cpp.

References curves_trusted_, lock, and mutex_.

◆ fingerprint()

uint64_t fsw::calibration::LcTareStore::fingerprint ( const Evaluator & eval)
static

A fingerprint of what a curve does, not of the coefficients that describe it: the evaluator is sampled at fixed probe codes and the results hashed.

Model-agnostic by construction, so a cubic re-fit, a cleared channel and a flip to the physics conversion all move it, and a no-op re-save does not. Cheap defence in depth — if some future path mutates a curve without calling recompute, a mismatched fingerprint makes the stale offset visible instead of silently subtracted.

Definition at line 38 of file LcTareStore.cpp.

References probe().

Referenced by anonymous_namespace{test_lc_tare.cpp}::fingerprint_tracks_what_the_curve_does(), recompute_locked(), and recompute_stale().

◆ load()

◆ load_failed()

bool fsw::calibration::LcTareStore::load_failed ( ) const

Set when load() could not read an existing file; blocks save() so an unreadable store is never replaced by the empty one we fell back to.

Mirrors CubicCalibrationStore.

Definition at line 178 of file LcTareStore.cpp.

References load_failed_, lock, and mutex_.

Referenced by anonymous_namespace{test_lc_tare.cpp}::save_load_round_trip(), and anonymous_namespace{test_lc_tare.cpp}::unreadable_file_is_not_overwritten().

◆ recompute()

◆ recompute_all()

void fsw::calibration::LcTareStore::recompute_all ( const std::function< Evaluator(uint16_t)> & eval_for)

Re-derive every tare; eval_for supplies each uid's evaluator.

Call after any change to an LC curve: a capture, a clear, a profile swap, or startup.

Definition at line 118 of file LcTareStore.cpp.

References curves_trusted_, lock, mutex_, probe(), recompute_locked(), and tares_.

Referenced by anonymous_namespace{test_lc_tare.cpp}::loaded_tare_is_corrected_by_recompute(), and main().

◆ recompute_locked()

bool fsw::calibration::LcTareStore::recompute_locked ( LcTare & t,
const Evaluator & eval )
private

Caller holds mutex_.

Returns false when the curve yields a non-finite offset.

Definition at line 60 of file LcTareStore.cpp.

References fingerprint().

Referenced by recompute(), recompute_all(), recompute_stale(), and set().

◆ recompute_stale()

size_t fsw::calibration::LcTareStore::recompute_stale ( const std::function< Evaluator(uint16_t)> & eval_for)

Re-derive only the tares whose recorded fingerprint disagrees with the curve now live, and return how many those were.

Zero is the expected answer: every path that moves a curve is supposed to recompute already.

A non-zero answer means one didn't, and the caller should say so loudly — it is the audit that makes a missed recompute hook visible instead of silently subtracting kilograms derived from a curve that no longer exists. In particular it catches the startup ordering mistake of reading this file AFTER the live store reload, where the reload's own recompute runs over an empty map and every restored offset stays stale.

Definition at line 131 of file LcTareStore.cpp.

References curves_trusted_, fingerprint(), lock, mutex_, probe(), recompute_locked(), and tares_.

Referenced by main(), and anonymous_namespace{test_lc_tare.cpp}::stale_audit_finds_a_missed_recompute().

◆ save()

◆ serialize()

◆ set()

bool fsw::calibration::LcTareStore::set ( uint16_t uid,
const std::string & entity,
double adc_at_tare,
const Evaluator & eval )

Record a tare for uid at adc_at_tare and derive its offset.

entity is the publish-path name (LC<slot>_Cal.CH<connector>) computed by the caller from the same board_number/channel the LC publish path uses; Node keys on this string and must never re-derive it, because slot is board_id % 10 and two boards of different kinds share a slot — the collision that put a load cell's curve on a 5000 psi transducer in Sep 2026.

Returns false and records nothing when the curve yields a non-finite offset (a degenerate one-point fit does), because a NaN offset downstream silently kills the whole series.

Definition at line 71 of file LcTareStore.cpp.

References lock, mutex_, recompute_locked(), and tares_.

Referenced by anonymous_namespace{test_lc_tare.cpp}::fingerprint_tracks_what_the_curve_does(), main(), anonymous_namespace{test_lc_tare.cpp}::non_finite_offset_is_never_recorded(), anonymous_namespace{test_lc_tare.cpp}::recompute_carries_tare_across_a_better_fit(), anonymous_namespace{test_lc_tare.cpp}::save_load_round_trip(), anonymous_namespace{test_lc_tare.cpp}::stale_audit_finds_a_missed_recompute(), anonymous_namespace{test_lc_linear_fit.cpp}::tared_reading(), and anonymous_namespace{test_lc_tare.cpp}::untrusted_curves_keep_the_last_good_offset().

◆ set_curves_trusted()

void fsw::calibration::LcTareStore::set_curves_trusted ( bool trusted)

False while the curves cannot be trusted — set when the cubic store failed to load.

A recompute then keeps the last good offset rather than replacing it with one computed against a zeroed curve, which would read as a confident wrong number.

Definition at line 148 of file LcTareStore.cpp.

References curves_trusted_, lock, and mutex_.

Referenced by main(), and anonymous_namespace{test_lc_tare.cpp}::untrusted_curves_keep_the_last_good_offset().

◆ size()

size_t fsw::calibration::LcTareStore::size ( ) const

◆ tare_for()

◆ uids()

std::vector< uint16_t > fsw::calibration::LcTareStore::uids ( ) const

Definition at line 164 of file LcTareStore.cpp.

References lock, mutex_, and tares_.

Referenced by main().

Member Data Documentation

◆ curves_trusted_

bool fsw::calibration::LcTareStore::curves_trusted_ = true
private

◆ file_path_

std::string fsw::calibration::LcTareStore::file_path_
private

Definition at line 148 of file LcTareStore.hpp.

Referenced by LcTareStore(), load(), and save().

◆ load_failed_

bool fsw::calibration::LcTareStore::load_failed_ = false
private

Definition at line 149 of file LcTareStore.hpp.

Referenced by load(), load_failed(), and save().

◆ mutex_

std::mutex fsw::calibration::LcTareStore::mutex_
mutableprivate

◆ tares_

std::map<uint16_t, LcTare> fsw::calibration::LcTareStore::tares_
private

The documentation for this class was generated from the following files: