openaliro
Aliro reader: UWB/CCC core and ESP32-S3/C5/C6 port
Loading...
Searching...
No Matches
aliro_approach.h File Reference

Configuration and state for approach detection and predictive unlock: unlock/relock thresholds in centimeters, sample-count dwell times, motor retraction time, scheduling margin, minimum closing speed, and a flag to enable or disable predictive ToA unlock. More...

#include <stdbool.h>
#include <stdint.h>
Include dependency graph for aliro_approach.h:

Go to the source code of this file.

Data Structures

struct  aliro_approach_cfg
 Configuration for approach detection: unlock_cm (presence radius and ETA target), relock_cm (departure threshold), near_dwell/far_dwell (sample counts to unlock/relock), motor_ms (bolt retraction time), margin_ms (scheduling slack, >= 192 ms to avoid missing discrete samples), vmin_cm_s (min closing speed to arm prediction), predict_en (false disables prediction and leaves presence path unchanged; also false whenever RSSI power gate is active). More...
 
struct  aliro_approach
 State machine and Kalman filter for approach detection and predictive unlock. More...
 

Functions

void aliro_approach_defaults (struct aliro_approach_cfg *cfg)
 Initialize an approach configuration with factory defaults: unlock at 100 cm, relock at 250 cm, dwell times 2 s and 3 s, motor delay 500 ms, margin 250 ms, velocity floor 30 cm/s, predictive unlock enabled.
 
void aliro_approach_init (struct aliro_approach *ap, const struct aliro_approach_cfg *cfg)
 Initialize an approach controller to locked state with zero velocity and no prediction in flight.
 
enum aliro_approach_action aliro_approach_feed (struct aliro_approach *ap, int64_t now_ms, int32_t cm)
 Update the Kalman filter state with a new range measurement, compute estimated time-to-arrival (ETA) at the unlock radius, track presence via a median-filter window, and supervise predictive unlock (fire early when closing speed and ETA permit, abort if the phone stops or moves away).
 
void aliro_approach_observe_departure (struct aliro_approach *ap, int64_t now_ms, int32_t cm)
 Record a range for the DEPARTURE decision alone, trust gate or no trust gate.
 
enum aliro_approach_action aliro_approach_tick (struct aliro_approach *ap, int64_t now_ms)
 Advance the approach state machine by one tick: handle predictive unlock abort on deadline, departure by silence when measurements stop after the phone leaves the relock threshold, and return the triggered action or HOLD if no action occurred.
 
enum aliro_approach_action aliro_approach_gone (struct aliro_approach *ap)
 Reset the approach controller to locked state while preserving its configuration.
 
bool aliro_approach_locked (const struct aliro_approach *ap)
 Return true if the door is locked, false if unlocked.
 
int32_t aliro_approach_est_cm (const struct aliro_approach *ap)
 Return the current estimated distance in centimeters.
 
int32_t aliro_approach_vel_cm_s (const struct aliro_approach *ap)
 Return the current velocity in centimeters per second (positive = approaching, negative = receding).
 
int32_t aliro_approach_eta_ms (const struct aliro_approach *ap)
 Return the estimated time in milliseconds until approach completes (unlock reaches the door).
 

Detailed Description

Configuration and state for approach detection and predictive unlock: unlock/relock thresholds in centimeters, sample-count dwell times, motor retraction time, scheduling margin, minimum closing speed, and a flag to enable or disable predictive ToA unlock.

Function Documentation

◆ aliro_approach_est_cm()

int32_t aliro_approach_est_cm ( const struct aliro_approach ap)

Return the current estimated distance in centimeters.

Returns -1 if the Kalman filter has not been initialized (no valid measurement yet); otherwise returns the rounded estimate.

◆ aliro_approach_eta_ms()

int32_t aliro_approach_eta_ms ( const struct aliro_approach ap)

Return the estimated time in milliseconds until approach completes (unlock reaches the door).

Value is -1 if not yet computed, or the reader has already locked the door.

◆ aliro_approach_feed()

enum aliro_approach_action aliro_approach_feed ( struct aliro_approach ap,
int64_t  now_ms,
int32_t  cm 
)

Update the Kalman filter state with a new range measurement, compute estimated time-to-arrival (ETA) at the unlock radius, track presence via a median-filter window, and supervise predictive unlock (fire early when closing speed and ETA permit, abort if the phone stops or moves away).

Return the action code: UNLOCK_THRESHOLD (entered unlock zone), RELOCK_DEPART (exited relock zone), UNLOCK_PREDICT (fired a predictive unlock), or HOLD (no action).

◆ aliro_approach_gone()

enum aliro_approach_action aliro_approach_gone ( struct aliro_approach ap)

Reset the approach controller to locked state while preserving its configuration.

Return RELOCK_DEPART if the door was unlocked before the reset, otherwise HOLD.

◆ aliro_approach_init()

void aliro_approach_init ( struct aliro_approach ap,
const struct aliro_approach_cfg cfg 
)

Initialize an approach controller to locked state with zero velocity and no prediction in flight.

If cfg is NULL, load factory defaults; otherwise copy the provided configuration.

◆ aliro_approach_observe_departure()

void aliro_approach_observe_departure ( struct aliro_approach ap,
int64_t  now_ms,
int32_t  cm 
)

Record a range for the DEPARTURE decision alone, trust gate or no trust gate.

Ranges beyond relock_cm are precisely the ones the range-integrity consensus declines to vouch for, so a walk-away can never satisfy a "seen beyond relock_cm" condition through aliro_approach_feed(). Measured 2026-08-02: the trace showed 252 cm then 309 cm as the credential left, while the controller had last been FED 210 cm, and both the silence rule and far_dwell refused – correctly, on the data they had.

Using an unvouched range here is safe in the one direction that matters. The trust gate exists to stop a forged NEAR range opening a door; a forged FAR range can only CLOSE one, and an attacker gains nothing by locking a lock. So departure may read what the radio saw, while the unlock decision keeps requiring what the radio can vouch for.

Ignores anything nearer than relock_cm, which is what keeps the asymmetry honest: an unvouched range can cause a relock and can never prevent or delay one. Feed it only FRESH ranges – the caller's generation epoch says which – or the silence in aliro_approach_tick() never accumulates.

Record a range for the DEPARTURE decision alone, trust gate or no trust gate.

If the prediction deadline has passed, abort and relock the door. Return HOLD otherwise.

◆ aliro_approach_vel_cm_s()

int32_t aliro_approach_vel_cm_s ( const struct aliro_approach ap)

Return the current velocity in centimeters per second (positive = approaching, negative = receding).

Returns 0 if the Kalman filter has not been initialized.