---
kind: concept
slug: finite-state-machine
title: Finite-state machine
summary: >-
  A finite-state machine (FSM) switches between a few modes, and each switch is a threshold test on one scalar feature, so no classifier runs at decision time. Used for walk, sit and stair transitions on lower-limb exoskeletons. The thresholds can be personalized from user statistics or by Bayesian optimization on labelled transitions. Only one paper so far, with author-reported gains.
tags: [control, embedded, transition-detection, personalization]
papers: ["2411.12573"]
related: [bayesian-optimization, gaussian-process, human-in-the-loop]
status: draft
updated_at: 2026-10-25
---

## Overview

A device that assists movement has to know which mode the user is in, and
when the mode changes. The problem is to detect each change quickly enough
for the assistance to match it [arxiv:2411.12573 §1]. The core idea in this
paper is a small FSM with four states: Sit, Walk, Stair Ascent and Stair
Descent. Level walking, standing and ramp walking are merged into Walk
[arxiv:2411.12573 §2.1]. Each transition between states is one binary
decision, and each decision uses one instantaneous characteristic feature
(ICF) [arxiv:2411.12573 §2.1]. Gait events, namely maximum hip flexion and
heel strike, are taken from separate detectors that use the thigh angle and
the ground reaction force [arxiv:2411.12573 §2.1].

The invariant the paper relies on is that the device runs no classifier when
it decides. The authors trained several classifiers offline, then kept the
two best performers, a linear SVM and a logistic regression, and replaced
them with if/else thresholds on the one-dimensional ICF [arxiv:2411.12573
§2.2]. The thresholds are therefore the whole decision rule at run time.

Only one card lists this slug so far. The page describes that one variant
and its personalization options, and other FSM designs are not covered yet.

## Variants

### Offline-trained threshold FSM

Each transition has a threshold on one ICF. The thresholds come from the
offline classifiers, trained on the Reznick et al. dataset with a 90/10 split
[arxiv:2411.12573 §2.1] [arxiv:2411.12573 §2.2]. Table 1 gives the values.
The thresholds are shared by both exoskeletons except one, W-SD / SD-W, which
differs for eWalk and autonomyo [arxiv:2411.12573 tab. 1]. The non-personalized
version is the comparison baseline in the paper's accuracy tests
[arxiv:2411.12573 §4.2]. Card: [Locomotion Mode Transitions](/papers/2411.12573).

### Statistics-based rescaling (SBA)

Each threshold is multiplied by the ratio between the mean plus or minus the
standard deviation of the new user's ICF and the same statistic from the
training data [arxiv:2411.12573 §2.5.1] [arxiv:2411.12573 eq. 6]. The card
does not state which sign applies to which transition, so this step needs
the paper text before it is implemented [arxiv:2411.12573 §2.5.1].

### Bayesian-optimization tuning (BO)

Each threshold pair for one transition pair is searched with Bayesian
optimization. A Gaussian-process surrogate (RBF kernel) is fitted to the
observed costs, and an acquisition function with weight 0.5 picks the next
candidate [arxiv:2411.12573 §2.5.2] [arxiv:2411.12573 eq. 8] [arxiv:2411.12573
eq. 9]. The cost is computed from labelled ground-truth transitions, so this
variant is supervised [arxiv:2411.12573 alg. 2]. The paper runs 30 iterations
and compares them with 100 evaluations of a grid search [arxiv:2411.12573
§4.3]. Card: [Locomotion Mode Transitions](/papers/2411.12573).

## When to use which

The choice depends on what the deployed device has available. The paper's
results are the only evidence here, and they come from 10 subjects per
exoskeleton [arxiv:2411.12573 §3].

| Situation | Use | Why |
|---|---|---|
| Embedded device, decisions must be cheap at run time | Threshold FSM | The device runs no classifier, only one comparison per transition [arxiv:2411.12573 §2.2] |
| No labelled transitions from the new user, a rescaling step is acceptable | SBA | It needs only ICF statistics from the new user. It gave small gains on eWalk (for example W-S from 92% to 94%) and no gain on autonomyo [arxiv:2411.12573 §4.2] |
| Labelled transitions from the new user are available, and tuning can run offline | BO | It raised accuracy on both devices, for example autonomyo W-S from 77.5% to 90% [arxiv:2411.12573 §4.2]. It takes about 2 minutes on a PC [arxiv:2411.12573 §5.4] |
| Tuning must run in real time on the device | Not supported by the paper | The authors state that BO was not run in real time [arxiv:2411.12573 §5.5] |
| Autonomyo hip-angle offset | Linear hip-angle mapping, before the FSM | It moved the mean MHF angle from 73.87 to 55.27 deg against a literature value of 60.55 deg [arxiv:2411.12573 §4.1]. Its effect on transition accuracy was mixed [arxiv:2411.12573 §4.2] |

## Implementation sketch

Language-agnostic outline of the common core. The card does not give the
transition list per state in text, so the table is read from [fig. 1] and
must be checked against the paper. The direction of each comparison is also
not stated on the card [arxiv:2411.12573 §2.1].

```pseudocode
# The four states  [arxiv:2411.12573 §2.1]
SIT, WALK, STAIR_ASC, STAIR_DESC = range(4)

# Feature extraction at each gait event  [arxiv:2411.12573 §2.1] [tab. 1]
def extract_icfs(gait_cycle):
    # ICF-1: thigh angle at maximum hip flexion (MHF)
    icf1 = gait_cycle.thigh_angle_at_mhf
    # ICF-2: MHF-minus-heel-strike difference, as defined in §2.1
    icf2 = gait_cycle.mhf_minus_hs
    # ICF-3: thigh angular velocity inside the thigh-angle window THR
    icf3 = gait_cycle.thigh_velocity_in_thr
    return {"ICF-1": icf1, "ICF-2": icf2, "ICF-3": icf3}

# Transition table: current state -> (target, ICF name, threshold name)
# Which transitions leave each state is read from [fig. 1]
TRANSITIONS = {
    WALK: [(SIT, "ICF-3", "W-S"), (STAIR_ASC, "ICF-1", "W-SA"),
           (STAIR_DESC, "ICF-2", "W-SD")],
    # ...reverse transitions, read from [fig. 1]
}

# One binary decision per transition, each on one ICF  [arxiv:2411.12573 §2.1]
def step(state, icfs, thresholds):
    for target, icf_name, th_name in TRANSITIONS.get(state, []):
        # Comparison direction per transition: check §2.1 before use
        if compare(icfs[icf_name], thresholds[th_name]):
            return target
    return state
```

```pseudocode
# Personalize one threshold with statistics  [arxiv:2411.12573 §2.5.1] [eq. 6]
def rescale_threshold(th_train, icf_train, icf_new, sign):
    # sign is +1 or -1 per transition; the assignment is not stated on the card
    num = mean(icf_new) + sign * std(icf_new)
    den = mean(icf_train) + sign * std(icf_train)
    return th_train * num / den
```

## Contradictions

None known across papers, since only one card lists this slug. Within the
card, the subject S2 is reported differently in two places. The results say
W-S was missed before tuning and detected after [arxiv:2411.12573 §4.2]. The
discussion says W-S and S-W improved from 80% and 60% to 100% [arxiv:2411.12573
§5.3]. Both statements come from the same paper and do not match.

## Papers

- [Exoskeleton mode-transition paper (arXiv:2411.12573)](/papers/2411.12573): an FSM with ICF thresholds for walk, sit and stair transitions, with statistics-based rescaling and Bayesian-optimization tuning, tested on two exoskeletons.
