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

The sweep. See servo_sweep.h. More...

#include "servo_sweep.h"
#include <math.h>
#include <stddef.h>

Data Structures

struct  cycle_t
 One cycle in microseconds: the motion's period, a quarter of it, the dwell and the whole cycle with both dwells. Integers, because a sweep can run for hours and a float of milliseconds stops counting single ones after four and a half. More...

Functions

bool sweep_cfg_valid (const sweep_cfg_t *cfg)
 Whether cfg is one a sweep can run: a curve, a speed and an amplitude in range, and a dwell no longer than SWEEP_DWELL_MAX_MS.
bool sweep_start (sweep_t *w, const sweep_cfg_t *cfg, uint32_t now_ms)
 Start cfg at now_ms. False, and stopped, for a configuration sweep_cfg_valid() refuses.
void sweep_stop (sweep_t *w)
 Stop, and forget any paused phase.
void sweep_pause (sweep_t *w, uint32_t now_ms)
 Stop a running sweep at now_ms and keep how far into it it was, so sweep_resume() carries on from there: the same point of the curve, the same dwell, the movements reached so far. Nothing for a sweep that is not running, finished included.
bool sweep_resume (sweep_t *w, uint32_t now_ms)
 Carry a paused sweep on at now_ms from where it was paused. False, and nothing changes, when nothing is paused: never paused, stopped or started since.
static cycle_t cycle_of (const sweep_cfg_t *c)
 Derive the cycle lengths of a sweep.
static uint64_t elapsed_us (const sweep_t *w, uint32_t now_ms)
 Microseconds since the sweep started.
static uint64_t ends_by (const cycle_t *y, uint64_t t)
 Ends reached by t microseconds into the sweep, with no limit.
static uint64_t done_at (const cycle_t *y, uint32_t n)
 When the dwell at the n-th end is over, n at least 1.
uint32_t sweep_moves (const sweep_t *w, uint32_t now_ms)
 How many ends the sweep has reached by now_ms, the moves limit included once reached.
bool sweep_slew_limited (const sweep_cfg_t *cfg, uint16_t slew_per_s)
 Whether a slew of slew_per_s command units a second is slower than the fastest change cfg's curve asks for, so the slew and not the curve decides how the output moves. The fastest change, at amplitude A and f = mhz / 1000 cycles a second, is 2 pi f A for a sine (at the centre) and 4 f A for a triangle (throughout). A square jumps, so any slew limits it. The dwell does not enter: it adds time at the ends, not to the motion.
static float shape (sweep_kind_t kind, float x)
 The curve's position, -1..1, a fraction x of the way through its motion.
bool sweep_step (sweep_t *w, uint32_t now_ms, uint16_t *command)
 The command at now_ms into command. True while the sweep runs; false once it has stopped or made its movements, with command at the centre. The clock may wrap.

Detailed Description

The sweep. See servo_sweep.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ cycle_of()

cycle_t cycle_of ( const sweep_cfg_t * c)
static

Derive the cycle lengths of a sweep.

Parameters
cConfiguration. mhz must not be 0.
Returns
the cycle lengths, microseconds.

◆ done_at()

uint64_t done_at ( const cycle_t * y,
uint32_t n )
static

When the dwell at the n-th end is over, n at least 1.

Parameters
yCycle lengths.
nIndex of the end, 1 or more.
Returns
time into the sweep, us, at which the dwell at the n-th end is over.

◆ elapsed_us()

uint64_t elapsed_us ( const sweep_t * w,
uint32_t now_ms )
static

Microseconds since the sweep started.

Parameters
wSweep state.
now_msCurrent time, ms; the difference wraps with the 32-bit clock.
Returns
microseconds since the sweep started.

◆ ends_by()

uint64_t ends_by ( const cycle_t * y,
uint64_t t )
static

Ends reached by t microseconds into the sweep, with no limit.

Parameters
yCycle lengths.
tTime into the sweep, us.
Returns
ends reached by t, with no limit.

◆ shape()

float shape ( sweep_kind_t kind,
float x )
static

The curve's position, -1..1, a fraction x of the way through its motion.

Parameters
kindShape of the curve.
xFraction of the motion, 0 to 1.
Returns
position on the curve, -1 to 1; 0 for SWEEP_OFF and SWEEP_KIND_COUNT.

◆ sweep_cfg_valid()

bool sweep_cfg_valid ( const sweep_cfg_t * cfg)

Whether cfg is one a sweep can run: a curve, a speed and an amplitude in range, and a dwell no longer than SWEEP_DWELL_MAX_MS.

Parameters
cfgConfiguration to check.
Returns
true when cfg is not NULL, its kind is not SWEEP_OFF, mhz is SWEEP_MHZ_MIN to SWEEP_MHZ_MAX, amplitude is at most SWEEP_AMPLITUDE_MAX and dwell_ms at most SWEEP_DWELL_MAX_MS.

◆ sweep_moves()

uint32_t sweep_moves ( const sweep_t * w,
uint32_t now_ms )

How many ends the sweep has reached by now_ms, the moves limit included once reached.

Parameters
wSweep state. NULL or an invalid sweep gives 0.
now_msCurrent time, ms.
Returns
ends reached, at most the moves limit when moves is not 0; saturates at UINT32_MAX.

◆ sweep_pause()

void sweep_pause ( sweep_t * w,
uint32_t now_ms )

Stop a running sweep at now_ms and keep how far into it it was, so sweep_resume() carries on from there: the same point of the curve, the same dwell, the movements reached so far. Nothing for a sweep that is not running, finished included.

Parameters
wSweep state. NULL is ignored.
now_msTime of the pause, ms.

◆ sweep_resume()

bool sweep_resume ( sweep_t * w,
uint32_t now_ms )

Carry a paused sweep on at now_ms from where it was paused. False, and nothing changes, when nothing is paused: never paused, stopped or started since.

Parameters
wSweep state. NULL gives false.
now_msTime of the resume, ms.
Returns
true when a paused sweep was resumed; false for a NULL w or when nothing is paused.

◆ sweep_slew_limited()

bool sweep_slew_limited ( const sweep_cfg_t * cfg,
uint16_t slew_per_s )

Whether a slew of slew_per_s command units a second is slower than the fastest change cfg's curve asks for, so the slew and not the curve decides how the output moves. The fastest change, at amplitude A and f = mhz / 1000 cycles a second, is 2 pi f A for a sine (at the centre) and 4 f A for a triangle (throughout). A square jumps, so any slew limits it. The dwell does not enter: it adds time at the ends, not to the motion.

A slew of 0 is no limit, as on an output channel, and limits nothing. False for a configuration sweep_cfg_valid() refuses and for an amplitude of 0, which asks for no change.

Parameters
cfgConfiguration of the curve.
slew_per_sSlew limit, command units a second. 0 is no limit.
Returns
true when the slew limits the curve; false for an invalid cfg, a slew of 0 or an amplitude of 0.

◆ sweep_start()

bool sweep_start ( sweep_t * w,
const sweep_cfg_t * cfg,
uint32_t now_ms )

Start cfg at now_ms. False, and stopped, for a configuration sweep_cfg_valid() refuses.

Parameters
wSweep state. NULL gives false.
cfgConfiguration to run, checked by sweep_cfg_valid().
now_msStart time, ms.
Returns
true when the sweep started; false for a NULL w or an invalid cfg.

◆ sweep_step()

bool sweep_step ( sweep_t * w,
uint32_t now_ms,
uint16_t * command )

The command at now_ms into command. True while the sweep runs; false once it has stopped or made its movements, with command at the centre. The clock may wrap.

Parameters
wSweep state. Stops the sweep once its moves are made.
now_msCurrent time, ms.
commandOut: command in units, 0 to 2 x SWEEP_CENTRE. NULL to skip.
Returns
true while the sweep runs; false for a NULL w, a stopped sweep or one whose moves are made.

◆ sweep_stop()

void sweep_stop ( sweep_t * w)

Stop, and forget any paused phase.

Parameters
wSweep state. NULL is ignored.