|
STAR
Cal STAR — firmware, DAQ server, and engine design
|
Standalone Calibration Service — subscribes directly to Elodin, applies calibration, publishes calibrated VTables back to Elodin. More...
#include <algorithm>#include <array>#include <atomic>#include <chrono>#include <cmath>#include <csignal>#include <cstdlib>#include <cstring>#include <deque>#include <filesystem>#include <fstream>#include <iostream>#include <limits>#include <map>#include <mutex>#include <optional>#include <set>#include <sstream>#include <string>#include <thread>#include <unordered_map>#include <vector>#include "calibration/CaptureWindow.hpp"#include "calibration/CommandDedupe.hpp"#include "calibration/CubicCalibrationStore.hpp"#include "calibration/HpPtCode.hpp"#include "calibration/LcTareStore.hpp"#include "calibration/PTCalibration.hpp"#include "calibration/PtSmoothing.hpp"#include "calibration/RobustCalibrationManager.hpp"#include "calibration/SensorCalibration.hpp"#include "calibration/TypeK.hpp"#include "calibration/ValvePosition.hpp"#include "comms/messages/sensor/CalibratedPTMessage.hpp"#include "comms/messages/sensor/CalibratedSensorMessages.hpp"#include "comms/messages/sensor/T7Messages.hpp"#include "config/Config.hpp"#include "config/LoadActiveBoards.hpp"#include "elodin/DatabaseConfig.hpp"#include "elodin/ElodinClient.hpp"#include "elodin/SubscriptionTracker.hpp"#include "t7/T7Calibration.hpp"#include "t7/T7Convert.hpp"#include "t7/T7Stream.hpp"Go to the source code of this file.
Namespaces | |
| namespace | anonymous_namespace{calibration_main.cpp} |
Enumerations | |
| enum class | anonymous_namespace{calibration_main.cpp}::PtModel { anonymous_namespace{calibration_main.cpp}::Cubic , anonymous_namespace{calibration_main.cpp}::Robust , anonymous_namespace{calibration_main.cpp}::Blend , anonymous_namespace{calibration_main.cpp}::Physics } |
| Which model a PT streams: operator/factory cubic, the robust learner, the 75/25 blend, or the datasheet physics conversion (ratiometric for 0-5 V boards, 4-20 mA for current-loop). More... | |
| enum class | anonymous_namespace{calibration_main.cpp}::LcModel { anonymous_namespace{calibration_main.cpp}::Linear , anonymous_namespace{calibration_main.cpp}::Cubic , anonymous_namespace{calibration_main.cpp}::Physics } |
| Which model an LC streams: a straight-line fit through the operator's captured points, a cubic fit through them, or the datasheet physics conversion (sensitivity/PGA-gain formula). More... | |
Functions | |
| static bool | verbose () |
| static bool | env_flag_true (const char *name) |
| static PtModel | parse_pt_model (const std::string &s) |
| Parse a config model string to the enum; "cubic" and anything unrecognized map to Cubic. | |
| static PtModel | pt_model_for (uint16_t uid) |
| Per-sensor streaming model; sensors absent from the map default to factory cubic. | |
| static double | pt_full_scale_for (uint16_t uid) |
| Per-sensor physics full-scale PSI; default 1000 (0-5 V -> 0-1000 PSI) when unset. | |
| static double | pt_sense_resistor_for (uint16_t uid) |
| Per-sensor 4-20 mA shunt resistance (Ω); default 120 when unset. | |
| static const char * | pt_model_name (PtModel m) |
| Config-string form of a model, for the cubic store's per-uid active_model tag. | |
| static LcModel | parse_lc_model (const std::string &s) |
| Parse a config model string for an LC role: "linear" and "cubic" map to their fits, everything else (including unrecognized/"robust"/"blend", which LC doesn't support) maps to Physics, as it always has. | |
| static LcModel | lc_model_for (uint16_t uid) |
| Per-sensor LC streaming model; a uid absent from g_lc_model defaults to Linear, which streams physics until it has a fit (see select_lc_kg), so an uncaptured LC reads as it always did. | |
| static bool | lc_streams_physics (uint16_t uid, bool fit_ok) |
| True when this LC's published kilograms are its datasheet physics conversion: physics itself, or a linear sensor that has no fit yet. | |
| static double | lc_full_scale_for (uint16_t uid, double fallback) |
| Per-sensor LC physics full-scale kg; falls back to the [calibration.lc] global when unset. | |
| static double | lc_sensitivity_for (uint16_t uid, double fallback) |
| Per-sensor LC sensitivity mV/V; falls back to the [calibration.lc] global when unset. | |
| static double | lc_pga_gain_for (uint16_t uid, double fallback) |
| Per-sensor LC PGA gain; falls back to the [calibration.lc] global when unset. | |
| static const char * | lc_model_name (LcModel m) |
| Config-string form of an LC model, for the cubic store's per-uid active_model tag. | |
| static double | convert_ratiometric_pt_to_pressure (int32_t adc_raw, double full_scale_psi) |
| static double | select_pt_psi (uint16_t uid, double psi_fac, double psi_rob, double psi_phys, bool fac_ok, bool has_robust) |
| The single PT source-selection rule, shared by the streaming path and the Zero-All helper so both agree. | |
| static double | select_lc_kg (uint16_t uid, double kg_fit, double kg_phys, bool fit_ok) |
| The LC source-selection rule, mirroring select_pt_psi minus robust/blend (LC doesn't learn drift). | |
| static double | convert_hp_pt_to_pressure (uint8_t local_ch, uint32_t adc_raw, const fsw::config::PtBoardConfig &board, double full_scale_psi, double sense_resistor_ohms, std::array< uint8_t, 11 > &live_state) |
| 4-20 mA HP PT → PSI. | |
| static double | convert_tc_adc_to_temp_c (int32_t adc_raw, double adc_ref_voltage) |
| K-type thermocouple: raw ADC → voltage → temperature (°C). | |
| static double | clamp_tc_rtd_temp_publish_c (double t_c) |
| TC/RTD calibrated temperature before Elodin publish. | |
| static double | convert_rtd_adc_to_temp_c (int32_t adc_raw, double adc_ref_voltage, double excitation_ua, double r0_ohm) |
| Pt1000 RTD: raw ADC → voltage → resistance → temperature (°C), on the full IEC 60751 curve (rtd::rtd_board_adc_to_temp_c). | |
| static double | convert_act_adc_to_current (uint32_t adc_raw) |
| Actuator current-sense: 12-bit ADC → current (amps). | |
| static double | convert_lc_adc_to_force (int32_t adc_raw, double sensitivity_mv_per_v, double pga_gain, double full_scale_value) |
| Ratiometric load cell: raw ADC → force (kg). | |
| static void | signalHandler (int) |
| static double | unix_now () |
| Monotonic now, in ns. | |
| static uint64_t | mono_ns () |
| static uint16_t | resolve_pt_sensor_uid (uint8_t type_lo, uint8_t ch, const std::vector< fsw::elodin::BoardChannels > &pt_boards) |
| Map Elodin PT raw packet low byte + connector ch → robust calibration uid (board_id*100+ch). | |
| static uint16_t | resolve_lc_sensor_uid (uint8_t type_lo, uint8_t ch, const std::vector< fsw::elodin::BoardChannels > &lc_boards) |
| Map Elodin LC raw packet low byte + connector ch -> LC uid (board_id*100+ch). | |
| static std::optional< int32_t > | invert_abort_psi_to_adc (uint16_t uid, uint8_t pt_log_ch, bool is_loop, const fsw::config::PtBoardConfig *loop_board, double target_psi, bool force_physics, const fsw::calibration::PTCalibrationManager &pt_calibration, fsw::calibration::RobustCalibrationManager &robust_manager) |
| Invert an abort-procedure pressure (the level the boards vent DOWN below before completing an autonomous abort) to the raw ADC code the firmware compares against (dp.data < threshold_adc), for uid's model, by bisecting the SAME forward conversion the stream uses — so the board's "vented to safe" gate fires at exactly the pressure the operator configured on the curve they see. | |
| int | main (int argc, char *argv[]) |
Variables | |
| std::map< uint8_t, std::array< uint8_t, 11 > > | anonymous_namespace{calibration_main.cpp}::g_hp_ma_live |
| Hysteresis: 0 = treat as below loop, 1 = in 4–20 mA band (stops 3.99↔4.01 PSI chatter). | |
| fsw::calibration::PtSmoother | anonymous_namespace{calibration_main.cpp}::g_pt_smoother |
| Per-sensor PT output smoothing (ESP32 and T7), seeded with each sensor's first reading. | |
| std::unordered_map< uint16_t, PtModel > | anonymous_namespace{calibration_main.cpp}::g_pt_model |
| uid (board_id*100 + connector) -> streaming model. | |
| std::unordered_map< uint16_t, std::string > | anonymous_namespace{calibration_main.cpp}::g_uid_role |
| uid -> role name (from [sensor_roles_*]). | |
| std::unordered_map< uint16_t, double > | anonymous_namespace{calibration_main.cpp}::g_pt_full_scale |
| Per-sensor physics-mode parameters (from [calibration_full_scale_*] / [calibration_sense_resistor_*], falling back to the board defaults). | |
| std::unordered_map< uint16_t, double > | anonymous_namespace{calibration_main.cpp}::g_pt_sense_resistor |
| std::optional< PtModel > | anonymous_namespace{calibration_main.cpp}::g_env_override |
| Set once at startup: when a CAL_USE_* PT env var is present it forces every sensor, else nullopt and the per-sensor config governs. | |
| std::unordered_map< uint16_t, LcModel > | anonymous_namespace{calibration_main.cpp}::g_lc_model |
| uid -> LC streaming model. | |
| std::unordered_map< uint16_t, double > | anonymous_namespace{calibration_main.cpp}::g_lc_full_scale |
| Per-sensor LC physics-mode parameters (from [calibration_full_scale_*] / [calibration_sensitivity_*] / [calibration_pga_*], falling back to [calibration.lc] globals). | |
| std::unordered_map< uint16_t, double > | anonymous_namespace{calibration_main.cpp}::g_lc_sensitivity |
| std::unordered_map< uint16_t, double > | anonymous_namespace{calibration_main.cpp}::g_lc_pga_gain |
| std::set< uint16_t > | anonymous_namespace{calibration_main.cpp}::g_lc_uids |
| Every LC uid, populated at startup — the discriminant apply_capture/apply_clear/ reload_live_store use to route a shared uid-keyed cubic_store entry to lc_calibration instead of pt_calibration/robust_manager (PT and LC uids share the store; their board_id ranges never collide, but nothing else tags which kind a uid is). | |
| std::set< uint8_t > | anonymous_namespace{calibration_main.cpp}::g_lc_board_ids |
| Board ids of every LC board, so a connector outside active_connectors still routes as LC. | |
| std::map< uint8_t, double > | anonymous_namespace{calibration_main.cpp}::g_t7_cold_junction_c |
| Latest thermocouple cold-junction temperature (°C) per T7 slot, from t7_bridge's CJC table {0x26, (slot-1)*0x20 + 0x0F}. | |
| static std::atomic< bool > | running {true} |
| constexpr double | kRatiometricPtZeroFrac = 0.1 |
| Ratiometric PT, 0.5-4.5 V at 5 V excitation: excitation is the ADC reference, so the output is 10 % of full code at zero and 90 % at full scale whatever the supply actually is — psi = (adc / 2^31 - 0.1) / 0.8 * full_scale. | |
| constexpr double | kRatiometricPtSpanFrac = 0.8 |
| constexpr int | kMinAbortCalPoints = 3 |
| A sensor needs at least this many captured points before its cubic/robust curve is trusted to invert an abort threshold. | |
Standalone Calibration Service — subscribes directly to Elodin, applies calibration, publishes calibrated VTables back to Elodin.
Connects directly to Elodin DB (port 2240) and subscribes to the raw sensor data (PT, TC, RTD, LC). Publishes calibrated values to the same Elodin instance. No relay dependency — fully independent of the relay and backend restart cycles.
Raw data path (always immediate): daq_bridge → Elodin [0x20xx raw] → relay → backend → GUI Calibrated path (~1 ms behind): calibration_service ─(subscribes)→ Elodin [0x20xx raw] ─(publishes)→ Elodin [0x20xx+0x10 cal] → relay → backend → GUI
Usage: ./calibration_service [–config PATH] [–elodin-host HOST] [–elodin-port PORT] CAL_VERBOSE=1 for per-packet debug output LP PT (non–HP board): default = factory cubic from CSV/JSON (same priority as letsfix / stable stack). RobustCalibrationManager still seeds from that factory curve and loads adjustments.json; streaming uses factory unless you opt into robust below. CAL_USE_ROBUST_PT=1 — 100% robust mean for streaming (when sensor initialized) CAL_USE_ROBUST_BLEND=1 — 75% robust + 25% factory CAL_USE_FACTORY_PT=1 — force factory cubic (same as default; explicit) CAL_BACKUP_PATH — override robust prior JSON (else the latest calibration_backups/ JSON)
Definition in file calibration_main.cpp.
|
static |
TC/RTD calibrated temperature before Elodin publish.
Polynomial fits can diverge when raw ADC is far off-scale (e.g. multi-million counts); thin backend rejects absurd temperature_c.
Definition at line 417 of file calibration_main.cpp.
Referenced by main().
|
static |
Actuator current-sense: 12-bit ADC → current (amps).
3.3V reference, V-to-I transfer function = 1:1.
Definition at line 437 of file calibration_main.cpp.
Referenced by main().
|
static |
4-20 mA HP PT → PSI.
Wire raw is u32 full-scale to 2^31.
A 4-20 mA transmitter regulates its loop current independently of its supply, so the reading is absolute and needs no excitation reference — the shunt voltage against the internal 2.5 V ref is the whole measurement. Optional per-channel mA hysteresis kills threshold flicker at ~4 mA open-circuit noise.
Definition at line 339 of file calibration_main.cpp.
References adc(), and board().
Referenced by invert_abort_psi_to_adc(), and main().
|
static |
Ratiometric load cell: raw ADC → force (kg).
Reference = excitation, so voltage cancels: code_fs = (sensitivity * PGA_gain) * 2^31. force = (code / code_fs) * full_scale_value.
Definition at line 448 of file calibration_main.cpp.
Referenced by main().
|
static |
Definition at line 269 of file calibration_main.cpp.
References kRatiometricPtSpanFrac, and kRatiometricPtZeroFrac.
Referenced by invert_abort_psi_to_adc(), and main().
|
static |
Pt1000 RTD: raw ADC → voltage → resistance → temperature (°C), on the full IEC 60751 curve (rtd::rtd_board_adc_to_temp_c).
NaN for an open or shorted element: publish nothing.
Definition at line 427 of file calibration_main.cpp.
References fsw::calibration::rtd::rtd_board_adc_to_temp_c().
Referenced by main().
|
static |
K-type thermocouple: raw ADC → voltage → temperature (°C).
ITS-90 rational polynomial with 5 sub-ranges (-6.4 mV to 69.6 mV). Coefficients from NIST ITS-90 Thermocouple Database (Type K inverse). Each range: T = T0 + (x * num) / den, where x = V_mV - V0.
Definition at line 403 of file calibration_main.cpp.
References fsw::calibration::type_k_c_from_mv().
Referenced by main().
|
static |
Definition at line 161 of file calibration_main.cpp.
Referenced by main().
|
static |
Invert an abort-procedure pressure (the level the boards vent DOWN below before completing an autonomous abort) to the raw ADC code the firmware compares against (dp.data < threshold_adc), for uid's model, by bisecting the SAME forward conversion the stream uses — so the board's "vented to safe" gate fires at exactly the pressure the operator configured on the curve they see.
force_physics forces the datasheet (ratiometric / 4-20 mA) mapping regardless of the sensor's active model, used when the cubic/robust fit is too sparse to trust (see kMinAbortCalPoints).
Monotonic increasing in adc for every model, so bisection is valid. Returns nullopt when the target is unreachable in [0, 2^31) — e.g. an uncalibrated cubic whose forward is flat 0, or full_scale 0 — so a sensor with no trustworthy mapping gets no threshold (the firmware then relies on its PT_ABORT_THRESHOLD_TIMEOUT) rather than a wrong one.
Definition at line 554 of file calibration_main.cpp.
References a, adc(), fsw::calibration::PTCalibrationManager::calculate_pressure(), convert_hp_pt_to_pressure(), convert_ratiometric_pt_to_pressure(), fsw::calibration::RobustCalibrationManager::has_sensor(), fsw::calibration::PTCalibrationManager::is_calibrated(), fsw::calibration::RobustCalibrationManager::predict_pressure_psi(), pt_full_scale_for(), pt_sense_resistor_for(), and select_pt_psi().
Referenced by main().
|
static |
Per-sensor LC physics full-scale kg; falls back to the [calibration.lc] global when unset.
Definition at line 233 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::g_lc_full_scale.
Referenced by main().
|
static |
Per-sensor LC streaming model; a uid absent from g_lc_model defaults to Linear, which streams physics until it has a fit (see select_lc_kg), so an uncaptured LC reads as it always did.
Definition at line 220 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::g_lc_model, and anonymous_namespace{calibration_main.cpp}::Linear.
Referenced by lc_streams_physics(), main(), and select_lc_kg().
|
static |
Config-string form of an LC model, for the cubic store's per-uid active_model tag.
Definition at line 251 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::Cubic, anonymous_namespace{calibration_main.cpp}::Linear, and anonymous_namespace{calibration_main.cpp}::Physics.
Referenced by main().
|
static |
Per-sensor LC PGA gain; falls back to the [calibration.lc] global when unset.
Definition at line 245 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::g_lc_pga_gain.
Referenced by main().
|
static |
Per-sensor LC sensitivity mV/V; falls back to the [calibration.lc] global when unset.
Definition at line 239 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::g_lc_sensitivity.
Referenced by main().
|
static |
True when this LC's published kilograms are its datasheet physics conversion: physics itself, or a linear sensor that has no fit yet.
Such a reading is "calibrated" in the status sense.
Definition at line 227 of file calibration_main.cpp.
References lc_model_for(), anonymous_namespace{calibration_main.cpp}::Linear, and anonymous_namespace{calibration_main.cpp}::Physics.
Referenced by main().
| int main | ( | int | argc, |
| char * | argv[] ) |
The board's 4-20 mA config, or nullptr when this slot is not a current-loop PT board.
Definition at line 596 of file calibration_main.cpp.
References fsw::calibration::CubicFit::A, fsw::config::Config::abort_pts, fsw::config::ACTUATOR, adc(), fsw::calibration::CaptureResult::adc_avg, fsw::calibration::CubicCalibrationStore::add_point(), fsw::t7::T7CalibrationMap::all(), fsw::elodin::SubscriptionTracker::assign(), fsw::calibration::CubicFit::B, b, fsw::config::BALL_VALVE, fsw::elodin::ball_valve_raw_tables(), fsw::elodin::ElodinClient::begin_batch(), anonymous_namespace{calibration_main.cpp}::Blend, board(), board_id, fsw::calibration::CubicChannel::board_id, fsw::config::Config::boards, fsw::t7::T7CalibrationMap::by_table(), fsw::t7::T7CalibrationMap::by_uid(), fsw::calibration::CubicFit::C, fsw::calibration::cal_target(), fsw::calibration::SensorCalibrationManager::calculate(), fsw::calibration::PTCalibrationManager::calculate_pressure(), fsw::calibration::SensorCalibrationManager::calibrated_count(), fsw::t7::calibrated_entity_name(), fsw::t7::calibrated_field(), fsw::t7::calibrated_table_id(), fsw::config::Config::calibration, fsw::config::Config::calibration_model_for(), fsw::calibration::CaptureWindow::capture(), fsw::calibration::CubicCalibrationStore::channel(), clamp_tc_rtd_temp_publish_c(), fsw::calibration::CaptureWindow::clear(), fsw::calibration::LcTareStore::clear(), fsw::calibration::PTCalibrationManager::clear_calibration(), fsw::calibration::SensorCalibrationManager::clear_calibration(), fsw::calibration::CubicCalibrationStore::clear_channel(), fsw::elodin::ElodinClient::connect(), convert_act_adc_to_current(), convert_hp_pt_to_pressure(), convert_lc_adc_to_force(), convert_ratiometric_pt_to_pressure(), convert_rtd_adc_to_temp_c(), convert_tc_adc_to_temp_c(), count(), anonymous_namespace{calibration_main.cpp}::Cubic, fsw::calibration::CubicFit::D, fsw::calibration::CaptureResult::drift, fsw::calibration::CaptureResult::drift_z, fsw::elodin::SubscriptionTracker::due(), fsw::config::ENCODER, env_flag_true(), fsw::calibration::CubicCalibrationStore::fit_for(), fsw::elodin::ElodinClient::flush_batch(), fsw::calibration::valve_position::from_counts(), fsw::config::Config::full_scale_for(), anonymous_namespace{calibration_main.cpp}::g_env_override, anonymous_namespace{calibration_main.cpp}::g_hp_ma_live, anonymous_namespace{calibration_main.cpp}::g_lc_board_ids, anonymous_namespace{calibration_main.cpp}::g_lc_full_scale, anonymous_namespace{calibration_main.cpp}::g_lc_model, anonymous_namespace{calibration_main.cpp}::g_lc_pga_gain, anonymous_namespace{calibration_main.cpp}::g_lc_sensitivity, anonymous_namespace{calibration_main.cpp}::g_lc_uids, anonymous_namespace{calibration_main.cpp}::g_pt_full_scale, anonymous_namespace{calibration_main.cpp}::g_pt_model, anonymous_namespace{calibration_main.cpp}::g_pt_sense_resistor, anonymous_namespace{calibration_main.cpp}::g_pt_smoother, anonymous_namespace{calibration_main.cpp}::g_t7_cold_junction_c, anonymous_namespace{calibration_main.cpp}::g_uid_role, fsw::calibration::RobustCalibrationManager::has_sensor(), fsw::calibration::hp_pt_shunt_code(), invert_abort_psi_to_adc(), fsw::calibration::PTCalibrationManager::is_calibrated(), fsw::calibration::SensorCalibrationManager::is_calibrated(), fsw::elodin::ElodinClient::is_connected(), fsw::config::is_current_loop(), fsw::elodin::is_error_response(), fsw::elodin::kBallValveCalHi, fsw::elodin::kBallValveRawHi, fsw::t7::kCjcTableOffset, kMinAbortCalPoints, fsw::calibration::kRawUnitMicrovolts, fsw::elodin::kTableCalibrationCommand, fsw::t7::kTypeHi, fsw::calibration::LC, fsw::config::LC, fsw::config::CalibrationConfig::lc_csv_path, lc_full_scale_for(), fsw::config::CalibrationConfig::lc_full_scale_value, fsw::config::CalibrationConfig::lc_json_dir, fsw::t7::lc_kg(), lc_model_for(), lc_model_name(), fsw::config::CalibrationConfig::lc_pga_gain, lc_pga_gain_for(), lc_sensitivity_for(), fsw::config::CalibrationConfig::lc_sensitivity_mv_per_v, lc_streams_physics(), fsw::calibration::lc_tare_entity(), anonymous_namespace{calibration_main.cpp}::Linear, fsw::calibration::CubicChannel::live, fsw::calibration::CubicCalibrationStore::load(), fsw::calibration::LcTareStore::load(), fsw::config::load(), fsw::config::load_active_boards(), fsw::calibration::RobustCalibrationManager::load_adjustments(), fsw::calibration::SensorCalibrationManager::load_calibration(), fsw::calibration::CubicCalibrationStore::load_failed(), fsw::config::load_pt_boards(), fsw::calibration::CubicChannel::logical_ch, mono_ns(), fsw::calibration::CaptureResult::n, fsw::calibration::None, fsw::calibration::CubicCalibrationStore::note_capture(), o, fsw::calibration::CaptureResult::ok, ok, p, parse_lc_model(), parse_pt_model(), fsw::config::Config::pga_gain_for(), anonymous_namespace{calibration_main.cpp}::Physics, pkt_buf, fsw::calibration::CubicChannel::points, fsw::calibration::RobustCalibrationManager::predict_pressure_psi(), fsw::calibration::PT, fsw::config::PT, pt_full_scale_for(), fsw::calibration::pt_logical_calibration_channel(), pt_model_for(), pt_model_name(), fsw::t7::pt_psi(), pt_sense_resistor_for(), fsw::elodin::ElodinClient::publish(), publish(), fsw::calibration::CaptureWindow::push(), r, fsw::elodin::raw_sensor_tables(), fsw::t7::T7CalibrationMap::raw_tables(), fsw::elodin::ElodinClient::read_packet(), fsw::calibration::LcTareStore::recompute(), fsw::calibration::LcTareStore::recompute_all(), fsw::calibration::LcTareStore::recompute_stale(), fsw::elodin::ElodinClient::reconnect(), fsw::elodin::DatabaseConfig::register_ball_valve_calibrated_tables(), fsw::elodin::DatabaseConfig::register_calibrated_tables(), fsw::calibration::CubicCalibrationStore::register_channel(), fsw::elodin::DatabaseConfig::register_t7_calibrated_tables(), fsw::elodin::SubscriptionTracker::rejected(), fsw::calibration::RobustCalibrationManager::reseed_sensor(), fsw::elodin::SubscriptionTracker::reset(), fsw::calibration::RobustCalibrationManager::reset_adjustment(), resolve_lc_sensor_uid(), resolve_pt_sensor_uid(), anonymous_namespace{calibration_main.cpp}::Robust, fsw::calibration::CubicChannel::role, fsw::config::RTD, fsw::config::CalibrationConfig::rtd_adc_ref_voltage, fsw::t7::rtd_c(), fsw::config::CalibrationConfig::rtd_csv_path, fsw::config::CalibrationConfig::rtd_excitation_ua, fsw::config::CalibrationConfig::rtd_json_dir, fsw::config::CalibrationConfig::rtd_r0_ohm, running, fsw::calibration::CubicCalibrationStore::save(), fsw::calibration::LcTareStore::save(), fsw::calibration::RobustCalibrationManager::save_adjustments(), fsw::calibration::CommandDedupe::seen(), select_lc_kg(), select_pt_psi(), fsw::config::Config::sense_resistor_for(), fsw::config::Config::sensitivity_for(), fsw::config::Config::sensor_roles_for(), fsw::calibration::LcTareStore::set(), fsw::calibration::PTCalibrationManager::set_calibration(), fsw::calibration::SensorCalibrationManager::set_calibration(), fsw::calibration::LcTareStore::set_curves_trusted(), fsw::calibration::PTCalibrationManager::set_default_paths(), fsw::calibration::CubicCalibrationStore::set_fit_curve(), fsw::elodin::ElodinClient::set_recv_timeout_ms(), fsw::calibration::CaptureResult::settled, signalHandler(), fsw::calibration::CaptureResult::spread, fsw::calibration::PtSmoother::step(), fsw::elodin::ElodinClient::subscribe_table(), t7(), fsw::config::Config::t7_boards, fsw::t7::t7_counts(), fsw::config::Config::t7_errors, fsw::t7::t7_volts(), tables(), fsw::calibration::LcTareStore::tare_for(), target, fsw::config::TC, fsw::config::CalibrationConfig::tc_adc_ref_voltage, fsw::t7::tc_c(), fsw::config::CalibrationConfig::tc_csv_path, fsw::config::CalibrationConfig::tc_json_dir, fsw::calibration::CaptureWindow::uids(), fsw::calibration::CubicCalibrationStore::uids(), fsw::calibration::LcTareStore::uids(), unix_now(), fsw::calibration::RobustCalibrationManager::update_calibration(), fsw::calibration::CubicFit::valid, verbose(), volts(), and fsw::calibration::CaptureResult::window_ms.
|
static |
Definition at line 473 of file calibration_main.cpp.
Referenced by main().
|
static |
Parse a config model string for an LC role: "linear" and "cubic" map to their fits, everything else (including unrecognized/"robust"/"blend", which LC doesn't support) maps to Physics, as it always has.
Definition at line 212 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::Cubic, anonymous_namespace{calibration_main.cpp}::Linear, and anonymous_namespace{calibration_main.cpp}::Physics.
Referenced by main().
|
static |
Parse a config model string to the enum; "cubic" and anything unrecognized map to Cubic.
Definition at line 167 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::Blend, anonymous_namespace{calibration_main.cpp}::Cubic, anonymous_namespace{calibration_main.cpp}::Physics, and anonymous_namespace{calibration_main.cpp}::Robust.
Referenced by main().
|
static |
Per-sensor physics full-scale PSI; default 1000 (0-5 V -> 0-1000 PSI) when unset.
Definition at line 184 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::g_pt_full_scale.
Referenced by invert_abort_psi_to_adc(), and main().
|
static |
Per-sensor streaming model; sensors absent from the map default to factory cubic.
Definition at line 178 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::Cubic, and anonymous_namespace{calibration_main.cpp}::g_pt_model.
Referenced by main(), and select_pt_psi().
|
static |
Config-string form of a model, for the cubic store's per-uid active_model tag.
Definition at line 196 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::Blend, anonymous_namespace{calibration_main.cpp}::Physics, and anonymous_namespace{calibration_main.cpp}::Robust.
Referenced by main().
|
static |
Per-sensor 4-20 mA shunt resistance (Ω); default 120 when unset.
Definition at line 190 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::g_pt_sense_resistor.
Referenced by invert_abort_psi_to_adc(), and main().
|
static |
Map Elodin LC raw packet low byte + connector ch -> LC uid (board_id*100+ch).
Mirrors resolve_pt_sensor_uid (kept as a separate copy rather than a shared/generalized helper so the PT/abort-threshold path is untouched by this change).
Definition at line 510 of file calibration_main.cpp.
References ch().
Referenced by main().
|
static |
Map Elodin PT raw packet low byte + connector ch → robust calibration uid (board_id*100+ch).
Uses the same slot rule as daq_bridge: slot = board_id % 10, with 0 treated as 10.
Definition at line 483 of file calibration_main.cpp.
References ch().
Referenced by main().
|
static |
The LC source-selection rule, mirroring select_pt_psi minus robust/blend (LC doesn't learn drift).
kg_fit / fit_ok are this uid's fitted curve — linear or cubic per its model, since the store fits to the model's degree and that one curve is what lc_calibration holds. A cubic uid with no fit reads 0, the "physics-or-nothing" rule PT's cubic mode uses once explicitly opted in. A linear uid with no fit streams physics instead: linear is the default for every LC, so it must read exactly what an unconfigured LC read before it existed.
Definition at line 319 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::Cubic, lc_model_for(), anonymous_namespace{calibration_main.cpp}::Linear, and anonymous_namespace{calibration_main.cpp}::Physics.
Referenced by main().
|
static |
The single PT source-selection rule, shared by the streaming path and the Zero-All helper so both agree.
physics (the datasheet conversion — ratiometric or 4-20 mA per the board) is also the universal fallback: a cubic/robust sensor that isn't yet fit/seeded streams physics rather than
Definition at line 286 of file calibration_main.cpp.
References anonymous_namespace{calibration_main.cpp}::Blend, anonymous_namespace{calibration_main.cpp}::Cubic, anonymous_namespace{calibration_main.cpp}::g_env_override, anonymous_namespace{calibration_main.cpp}::Physics, pt_model_for(), and anonymous_namespace{calibration_main.cpp}::Robust.
Referenced by invert_abort_psi_to_adc(), and main().
|
static |
|
static |
Monotonic now, in ns.
The capture window judges liveness on OUR clock and never the board's, so a board whose clock is skewed or has just reset cannot make a dead channel look live (or a live one look stale). Wall-clock unix seconds, for stamping a record a human will read.
Definition at line 468 of file calibration_main.cpp.
Referenced by main().
|
static |
Definition at line 156 of file calibration_main.cpp.
Referenced by StarOTA::anonymous_namespace{STAR_EthernetOTA.cpp}::logf(), and main().
|
constexpr |
A sensor needs at least this many captured points before its cubic/robust curve is trusted to invert an abort threshold.
Below it, the fit is too loose — a 1-2 point cubic can invert to an ADC far from the intended pressure — so the abort threshold falls back to physics (the datasheet mapping), which is always monotonic and sane. See invert_abort_psi_to_adc / write_abort_thresholds.
Definition at line 537 of file calibration_main.cpp.
Referenced by main().
|
constexpr |
Definition at line 268 of file calibration_main.cpp.
Referenced by convert_ratiometric_pt_to_pressure().
|
constexpr |
Ratiometric PT, 0.5-4.5 V at 5 V excitation: excitation is the ADC reference, so the output is 10 % of full code at zero and 90 % at full scale whatever the supply actually is — psi = (adc / 2^31 - 0.1) / 0.8 * full_scale.
Used by the physics model on non-loop boards. The bench calibrations of 2026-02 put four of the stand's PTs within ~1.5 % of this.
Definition at line 267 of file calibration_main.cpp.
Referenced by convert_ratiometric_pt_to_pressure().
|
static |
Definition at line 154 of file calibration_main.cpp.
Referenced by bringup_task(), main(), signal_handler(), and signalHandler().