rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
log_cadence.h File Reference

The run log's cadence: which pass of the control loop writes a row, and the time that row carries. More...

#include <stdbool.h>
#include <stdint.h>

Go to the source code of this file.

Data Structures

struct  log_cadence_t
 The cadence state of the run log: its clocks and row counts. More...

Macros

#define LOG_CADENCE_MODEL_MS   50u
 The model's period with the link down, in ms: 20 samples a second.
#define LOG_CADENCE_MODEL_MAX_MS   1000u
 The longest step the model is given, in ms.

Enumerations

enum  log_run_kind_t { LOG_RUN_NONE = 0 , LOG_RUN_SERVO , LOG_RUN_SUPPLY , LOG_RUN_MOTOR }

Functions

static bool log_run_armed (log_run_kind_t kind)
 Whether kind is a run of the armed bench, whichever screen armed it.
log_run_kind_t log_cadence_wanted (bool auto_logs, bool armed, bool motor, bool supply_on, log_run_kind_t now)
 The run the log records now, from the run it records (now) and the bench: LOG_RUN_NONE while auto_logs is off, so a run that is under way ends and none starts.
void log_cadence_init (log_cadence_t *c, uint32_t now_ms)
 Once, before the loop: both clocks at now_ms, no rows counted.
bool log_cadence_model_due (log_cadence_t *c, uint32_t now_ms, bool link_up, float *step_s)
 The model's gate, once per pass.
void log_cadence_run_start (log_cadence_t *c, uint32_t now_ms)
 A run starts: its time is 0 at now_ms and its row counts are 0.
bool log_cadence_bench_run (bool bench_kind, bool servo_test)
 Whether the bench log records in this pass: the log's run is an armed bench's (bench_kind) and no automatic servo test is running (servo_test).
bool log_cadence_row (log_cadence_t *c, uint32_t now_ms, bool new_sample, bool bench_run, float *t_s)
 Whether this pass writes a bench row, once per pass and on every pass, with now_ms never behind the call before.
unsigned log_cadence_rows (unsigned windows)
 How many rows a pass writes that log_cadence_row() granted: one for each of the windows INA3221 windows handed over in the pass, and one for a pass with none.
void log_cadence_posted (log_cadence_t *c, bool taken)
 What the logger's queue did with a row: taken, or refused as full.
uint32_t log_cadence_sent (const log_cadence_t *c)
 The run's rows the queue took.
uint32_t log_cadence_lost (const log_cadence_t *c)
 The run's rows the queue refused.

Detailed Description

The run log's cadence: which pass of the control loop writes a row, and the time that row carries.

Owns no clock and no queue. The control task hands in its millisecond tick once per pass and says whether the pass brought a sample; the answer is a row or none, and the row's time. The same code runs in the host suite against a model of the loop's pass grid.

The rules:

  • One row per sample. A pass that brought a sample of an armed bench writes at least one row; a pass that brought none writes none.
  • One row per INA3221 window. A pass that writes rows writes one for each window handed over in it (log_cadence_rows()): the sample is in the last, with the newest window, and each row before it carries its window alone. The rows of one pass carry the same time; the window number orders them.
  • No gate of its own. What bounds the row rate is what bounds the sample rate: the poll's period with the link up, LOG_CADENCE_MODEL_MS for the model with the link down.
  • A row's time is the wall time since the run's start, in seconds. It advances on every pass, with or without a row, so a stretch without samples and a row the logger's queue refused both show as a step in the column. The tick's wrap at 2^32ms does not show in it.
  • A row the queue refuses is counted as lost, a row it takes as sent. Every row log_cadence_row() grants is one or the other.
  • No bench row while an automatic servo test runs (log_cadence_bench_run()). The test writes its own file, one row per reading of its meter, and the bench log's time column steps over the test.
  • No run at all while AUTO LOGS is off on SETUP > SD CARD (log_cadence_wanted()): no row is posted, no number taken, and no card alert of a run can follow.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ LOG_CADENCE_MODEL_MAX_MS

#define LOG_CADENCE_MODEL_MAX_MS   1000u

The longest step the model is given, in ms.

A probe for the IOmcu can hold the loop for its whole timeout; the model then advances by this much and no more. Equal to BENCH_TOTALS_MAX_STEP_S.

Function Documentation

◆ log_cadence_bench_run()

bool log_cadence_bench_run ( bool bench_kind,
bool servo_test )

Whether the bench log records in this pass: the log's run is an armed bench's (bench_kind) and no automatic servo test is running (servo_test).

The answer is log_cadence_row()'s bench_run.

Parameters
bench_kindtrue for an armed bench run.
servo_testtrue while an automatic servo test runs.
Returns
true when the bench log records in this pass.

◆ log_cadence_init()

void log_cadence_init ( log_cadence_t * c,
uint32_t now_ms )

Once, before the loop: both clocks at now_ms, no rows counted.

Parameters
cThe cadence state to set up.
now_msThe time, in ms.

◆ log_cadence_lost()

uint32_t log_cadence_lost ( const log_cadence_t * c)

The run's rows the queue refused.

Parameters
cThe cadence state.
Returns
The number of rows the queue refused.

◆ log_cadence_model_due()

bool log_cadence_model_due ( log_cadence_t * c,
uint32_t now_ms,
bool link_up,
float * step_s )

The model's gate, once per pass.

Opens when LOG_CADENCE_MODEL_MS or more have passed since it last opened, and its clock moves then whatever link_up says, so the first step after a link is lost is not the whole time the link was up.

Returns
true when the model takes a step in this pass: the gate opened and the link is down. step_s is then the time since the gate last opened, at most LOG_CADENCE_MODEL_MAX_MS, in seconds; otherwise 0.
Parameters
cThe cadence state.
now_msThe time, in ms.
link_uptrue while the IOmcu link is up.
step_sReceives the time of the step, in s.

◆ log_cadence_posted()

void log_cadence_posted ( log_cadence_t * c,
bool taken )

What the logger's queue did with a row: taken, or refused as full.

Parameters
cThe cadence state.
takentrue when the queue took the row.

◆ log_cadence_row()

bool log_cadence_row ( log_cadence_t * c,
uint32_t now_ms,
bool new_sample,
bool bench_run,
float * t_s )

Whether this pass writes a bench row, once per pass and on every pass, with now_ms never behind the call before.

The run's time advances by the ticks since the last call, modulo 2^32.

Parameters
new_samplethe pass brought a sample: an answered bench read, or a step of the model
bench_runthe log is recording an armed bench
t_sthe row's time in seconds since the run's start; written only when a row is granted
Returns
true exactly when new_sample and bench_run are both true.
Parameters
cThe cadence state.
now_msThe time, in ms.

◆ log_cadence_rows()

unsigned log_cadence_rows ( unsigned windows)

How many rows a pass writes that log_cadence_row() granted: one for each of the windows INA3221 windows handed over in the pass, and one for a pass with none.

Each is posted and counted with log_cadence_posted().

Parameters
windowsThe INA3221 windows handed over in the pass.
Returns
The number of rows the pass writes.

◆ log_cadence_run_start()

void log_cadence_run_start ( log_cadence_t * c,
uint32_t now_ms )

A run starts: its time is 0 at now_ms and its row counts are 0.

Parameters
cThe cadence state.
now_msThe time, in ms.

◆ log_cadence_sent()

uint32_t log_cadence_sent ( const log_cadence_t * c)

The run's rows the queue took.

Parameters
cThe cadence state.
Returns
The number of rows the queue took.

◆ log_cadence_wanted()

log_run_kind_t log_cadence_wanted ( bool auto_logs,
bool armed,
bool motor,
bool supply_on,
log_run_kind_t now )

The run the log records now, from the run it records (now) and the bench: LOG_RUN_NONE while auto_logs is off, so a run that is under way ends and none starts.

An armed bench (armed) is the run whatever the supply is doing: now while that is an armed run, since an arm's roles change only through a disarm, and otherwise LOG_RUN_MOTOR or LOG_RUN_SERVO by motor (log_name_armed_prefix() is LOG_PREFIX_MOTOR). Else LOG_RUN_SUPPLY while supply_on.

Parameters
auto_logstrue while automatic logging is on.
armedtrue while the bench is armed.
motortrue for the motor run rather than the servo run.
supply_ontrue while the supply output is on.
nowThe run the log records now.
Returns
The run the log records next.

◆ log_run_armed()

bool log_run_armed ( log_run_kind_t kind)
inlinestatic

Whether kind is a run of the armed bench, whichever screen armed it.

Parameters
kindThe run kind.
Returns
true for an armed bench run.