|
STAR
Cal STAR — firmware, DAQ server, and engine design
|
Live calibrated pressures, by ROLE NAME, for the sequencer. More...
#include <PressureFeed.hpp>
Classes | |
| struct | Reading |
Public Types | |
| enum class | Status { Ok , NotSubscribed , NoReading , Stale , Uncalibrated } |
| Why a role could not be read. More... | |
Public Member Functions | |
| PressureFeed ()=default | |
| ~PressureFeed () | |
| PressureFeed (const PressureFeed &)=delete | |
| PressureFeed & | operator= (const PressureFeed &)=delete |
| void | start (const fsw::config::Config &cfg, const std::vector< std::string > &roles, const std::string &host, uint16_t port) |
| Subscribe to exactly the roles given, and nothing else. | |
| void | stop () |
| Status | read (const std::string &role, double &psi) const |
| std::vector< std::string > | subscribedRoles () const |
| Roles this feed is subscribed to, for diagnostics. | |
Static Public Member Functions | |
| static std::string | explain (const std::string &role, Status s) |
| Human phrasing for a refusal, e.g. | |
Static Public Attributes | |
| static constexpr int | kMaxAgeMs = 1000 |
| How old a reading may be and still be acted on. | |
Private Member Functions | |
| void | runLoop (std::string host, uint16_t port) |
Private Attributes | |
| std::thread | thread_ |
| std::atomic< bool > | running_ {false} |
| std::mutex | mtx_ |
| std::map< std::string, Reading > | readings_ |
| std::map< std::pair< uint8_t, uint8_t >, std::string > | role_by_table_ |
| Elodin table id -> canonical role name, built once from config. | |
Live calibrated pressures, by ROLE NAME, for the sequencer.
The sequencer is otherwise pressure-blind — its only recv() is the controller's FIRE ack, and its ElodinClient is publish-only. This is the one thing that reads.
── Why it is keyed by role and not by channel ────────────────────────────────────────────────
ControllerService keys its measurements by channel number, and that is how its P_copv came to be assigned from channel 6 — which on this rig is "GN2 Regulated", the regulated downstream pressure, not the COPV at all. Its subscriber also filters the table id to board 1, which silently drops every sensor on PT board 2, "GN2 High" included. Resolving each role through fsw::config::find_pt_role makes both mistakes unrepresentable: there is no range filter to get wrong, because the table id is computed from the role.
── Why a reading can be refused ──────────────────────────────────────────────────────────────
A PT whose calibration model is "cubic" with no captured points publishes a smooth, plausible 0.0 PSI with calibration_status = 0. A script that reads that for a COPV and takes 90% of it computes a target of zero — and then does nothing at all, successfully, while an operator watches the state enter and cleanly exit believing the tank came up to pressure. A stale reading is the same hazard from the other direction: a press loop cycling a valve against a number that stopped moving. Both are refused rather than returned.
Definition at line 41 of file PressureFeed.hpp.
|
strong |
Why a role could not be read.
Reported so a refusal can say which sensor and why.
| Enumerator | |
|---|---|
| Ok | |
| NotSubscribed | |
| NoReading | |
| Stale | |
| Uncalibrated | |
Definition at line 50 of file PressureFeed.hpp.
|
default |
Referenced by operator=(), and PressureFeed().
| sequencer::PressureFeed::~PressureFeed | ( | ) |
Definition at line 33 of file PressureFeed.cpp.
References stop().
|
delete |
References PressureFeed().
|
static |
Human phrasing for a refusal, e.g.
"GN2 High has no calibrated reading".
Definition at line 224 of file PressureFeed.cpp.
References kMaxAgeMs, NoReading, NotSubscribed, Ok, Stale, and Uncalibrated.
Referenced by sequencer::SequencerService::doTransitionTo(), sequencer::SequencerService::makeScriptEnv(), and sequencer::SequencerService::scriptStatusReport().
|
delete |
References port, and PressureFeed().
| PressureFeed::Status sequencer::PressureFeed::read | ( | const std::string & | role, |
| double & | psi ) const |
Definition at line 195 of file PressureFeed.cpp.
References kMaxAgeMs, lk, mtx_, NoReading, NotSubscribed, Ok, r, readings_, role_by_table_, Stale, and Uncalibrated.
|
private |
Say "still waiting" once, not once a second for the life of the process.
Definition at line 78 of file PressureFeed.cpp.
References comms::CommsMessage< Fields >::deserialize(), comms::CommsMessage< Fields >::getField(), lk, mtx_, comms::CommsMessage< uint64_t, uint8_t, std::array< uint8_t, 3 >, float, uint32_t, uint8_t >::nbytes(), port, r, readings_, role_by_table_, running_, and tables().
Referenced by start().
| void sequencer::PressureFeed::start | ( | const fsw::config::Config & | cfg, |
| const std::vector< std::string > & | roles, | ||
| const std::string & | host, | ||
| uint16_t | port ) |
Subscribe to exactly the roles given, and nothing else.
Elodin has no wildcard — "every subscriber must name what it consumes" — so the list comes from the union of every loaded script's pressure() slugs. A role that no script reads costs no traffic, and with no roles at all the thread never starts.
Safe to call once, at config load. Roles that config cannot resolve to a board+channel are reported and skipped; a script naming one was already refused at load.
Definition at line 37 of file PressureFeed.cpp.
References fsw::config::find_pt_role(), lk, mtx_, port, readings_, role_by_table_, runLoop(), running_, stop(), and thread_.
| void sequencer::PressureFeed::stop | ( | ) |
Definition at line 72 of file PressureFeed.cpp.
References running_, and thread_.
Referenced by start(), and ~PressureFeed().
| std::vector< std::string > sequencer::PressureFeed::subscribedRoles | ( | ) | const |
Roles this feed is subscribed to, for diagnostics.
Definition at line 242 of file PressureFeed.cpp.
References lk, mtx_, and role_by_table_.
|
staticconstexpr |
How old a reading may be and still be acted on.
Definition at line 89 of file PressureFeed.hpp.
|
mutableprivate |
Definition at line 97 of file PressureFeed.hpp.
Referenced by read(), runLoop(), start(), and subscribedRoles().
|
private |
Definition at line 98 of file PressureFeed.hpp.
|
private |
Elodin table id -> canonical role name, built once from config.
Keyed by the whole id: an ESP32 PT ({0x20, lo}) and a LabJack T7 PT ({0x26, lo}) can share a low byte.
Definition at line 101 of file PressureFeed.hpp.
Referenced by read(), runLoop(), start(), and subscribedRoles().
|
private |
Definition at line 95 of file PressureFeed.hpp.
|
private |
Definition at line 94 of file PressureFeed.hpp.