added math signals

This commit is contained in:
Martino Ferrari committed 2026-10-03 17:28:17 +02:00
1 parent 02620ca946
commit aa2508e431
10 files changed
+1773 -27

No files matched your search

+15
View File
@@ -395,6 +395,7 @@ void Acquisition::on_data(const udps_frame_t* frame) {
acc_channels_ = channels.size();
value_acc_.assign(channels.size(), 0.0);
value_acc_n_.assign(channels.size(), 0);
math_sample_.assign(channels.size(), std::nanf(""));
time_acc_ = 0.0;
time_acc_n_ = 0;
}
@@ -528,6 +529,12 @@ void Acquisition::on_data(const udps_frame_t* frame) {
for (std::size_t i = 0; i < channels.size(); ++i) {
const ChannelInfo& ch = channels[i];
// A derived channel is filled by `push_math_sample()` below, once per stored slot, from the
// values the streamed ones just pushed. Reading it from the packet would give zero (it has no
// signal) and pushing that would advance its value ring twice per time slot -- which is an
// alternation between the value and 0 while the buffer is filling, and a complete loss of the
// pairing once both rings wrap.
if (ch.math) continue;
// A signal's columns are consecutive samples of the same channel: a scalar
// (one element) carries one value per batched cycle, a block signal carries
// the cycle's sample at element `k`. Either way element 0 is the channel.
@@ -549,6 +556,9 @@ void Acquisition::on_data(const udps_frame_t* frame) {
value_acc_[i] = 0.0;
value_acc_n_[i] = 0;
store.values(i).push(value);
// This slot's value, for the math channels below. Every channel is pushed on the same slot
// (per-channel strides are 1 by design), so the vector is complete by the time the loop ends.
if (i < math_sample_.size()) math_sample_[i] = value;
// The trigger sees the *stored* signal, not the wire signal. An edge found in a
// sample that is not in the buffer would be cut from data that does not contain it,
// and with the filter in front of it a spike above the stored Nyquist is exactly
@@ -560,6 +570,11 @@ void Acquisition::on_data(const udps_frame_t* frame) {
}
}
}
// The derived channels: once per *stored* slot, and **before** the latch publishes.
// `publish_event()` clamps its snapshot to every value ring's `produced()`, so a derived
// channel pushed after it would be missing its newest sample from the capture -- the same
// one-sample clamp the deferred latch above exists for.
if (tick % g == g - 1) model_.push_math_sample(math_sample_);
if (latch_here) latch(latch_edge);
}
last_stamp_ = last_stamp_used;