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

Search for a servo mechanical limit by current: the state machine. More...

#include "servo_limit.h"
#include <string.h>

Macros

#define BASELINE_STEPS   3u

Functions

static bool elapsed (uint32_t now, uint32_t then, uint32_t ms)
 Tell whether a millisecond span has elapsed.
static uint16_t clamp_travel (const servo_limit_cfg_t *cfg, int32_t us)
 Clamp a pulse width to the search travel and the pulse range.
void servo_limit_defaults (servo_limit_cfg_t *cfg, uint16_t centre_us, bool positive)
 Defaults for a hobby servo on a control surface.
void servo_limit_init (servo_limit_t *lf, const servo_limit_cfg_t *cfg)
 Start a limit search.
static void finish (servo_limit_t *lf, servo_limit_state_t state, servo_limit_fault_t fault)
 Finish the search with the surface returned to centre.
static bool advance (servo_limit_t *lf)
 Move one step further out.
static void judge (servo_limit_t *lf, float avg_a)
 One position's averaged current has arrived; decide what it means.
uint16_t servo_limit_step (servo_limit_t *lf, float current_a, uint32_t now_ms)
 Advance the search with one current reading, and return the pulse width the servo should be commanded to.
float servo_limit_progress (const servo_limit_t *lf)
 How far the search has gone, 0..1, for a progress bar.

Detailed Description

Search for a servo mechanical limit by current: the state machine.

SPDX-License-Identifier: MIT

Function Documentation

◆ advance()

bool advance ( servo_limit_t * lf)
static

Move one step further out.

A step that would pass the end of the permitted travel stops at that end, so the end itself is measured. With the end measured free, the surface is free over the whole range asked about, and that is reported as NO_LIMIT rather than as a mechanical limit.

Returns false if the search ended here.

Parameters
lfSearch state to advance.
Returns
false if the search ended here, true if the command moved.

◆ clamp_travel()

uint16_t clamp_travel ( const servo_limit_cfg_t * cfg,
int32_t us )
static

Clamp a pulse width to the search travel and the pulse range.

Parameters
cfgConfiguration whose centre_us and max_travel_us bound the travel.
usPulse width to clamp, us.
Returns
the clamped width, SERVO_LIMIT_MIN_US to SERVO_LIMIT_MAX_US.

◆ elapsed()

bool elapsed ( uint32_t now,
uint32_t then,
uint32_t ms )
inlinestatic

Tell whether a millisecond span has elapsed.

Parameters
nowCurrent time, ms.
thenStart of the span, ms.
msSpan length, ms.
Returns
true when now - then is at least ms, across a counter wrap.

◆ finish()

void finish ( servo_limit_t * lf,
servo_limit_state_t state,
servo_limit_fault_t fault )
static

Finish the search with the surface returned to centre.

Parameters
lfSearch state to update.
stateFinal state to store.
faultFault code to store.

◆ judge()

void judge ( servo_limit_t * lf,
float avg_a )
static

One position's averaged current has arrived; decide what it means.

Parameters
lfSearch state to update.
avg_aCurrent averaged over the measure phase at this position, A.

◆ servo_limit_defaults()

void servo_limit_defaults ( servo_limit_cfg_t * cfg,
uint16_t centre_us,
bool positive )

Defaults for a hobby servo on a control surface.

Parameters
cfgConfiguration to fill. Does nothing when NULL.
centre_usCentre pulse width, us.
positivetrue to step toward longer pulse widths, false toward shorter ones; the step is 10us either way.

◆ servo_limit_init()

void servo_limit_init ( servo_limit_t * lf,
const servo_limit_cfg_t * cfg )

Start a limit search.

Parameters
lfSearch state to initialise. Does nothing when NULL.
cfgConfiguration to copy. Does nothing when NULL.

◆ servo_limit_progress()

float servo_limit_progress ( const servo_limit_t * lf)

How far the search has gone, 0..1, for a progress bar.

Parameters
lfSearch state.
Returns
progress from 0.0 (centre) to 1.0; 1.0 when the state is not RUNNING, 0.0 when lf is NULL or max_travel_us is 0.

◆ servo_limit_step()

uint16_t servo_limit_step ( servo_limit_t * lf,
float current_a,
uint32_t now_ms )

Advance the search with one current reading, and return the pulse width the servo should be commanded to.

Call it at the sampling rate of the current sensor. Calling after the search has finished is safe; the returned width then holds the servo at centre, so a finished search leaves no surface deflected.

Parameters
lfSearch state. A NULL lf gives 0.
current_aCurrent reading, A. At or above hard_limit_a, or NaN, aborts the search.
now_msTime of the reading, ms.
Returns
pulse width to command, us; 0 when lf is NULL.