Data Types Reference
Field-by-field reference for every dataclass in
fes_framework.data.types. For the conceptual overview, see
Data Types.
Source: fes_framework/data/types.py
BiomechanicalData#
29 joint angles in degrees. Updated each cycle by DataStreamer
(when set_biomech_collection(True) is in effect). Read via
self.joints in your strategy.
PascalCase fields mirror the Teslasuit SDK enum names; the framework's
parse_ctypes_to_dataclass matches by name.
| Field | Unit | Notes |
|---|---|---|
PelvisTilt | deg | Pelvic tilt (forward/backward) |
PelvisList | deg | Pelvic list (lateral lean) |
PelvisRotation | deg | Pelvic axial rotation |
HipFlexExtR / HipFlexExtL | deg | Hip flexion/extension |
HipAddAbdR / HipAddAbdL | deg | Hip adduction/abduction |
HipRotR / HipRotL | deg | Hip rotation |
KneeFlexExtR / KneeFlexExtL | deg | Knee flexion/extension |
AnkleFlexExtR / AnkleFlexExtL | deg | Ankle dorsi/plantarflexion |
AnkleProSupR / AnkleProSupL | deg | Ankle pronation/supination |
ShoulderFlexExtR / ShoulderFlexExtL | deg | Shoulder flexion/extension |
ShoulderAddAbdR / ShoulderAddAbdL | deg | Shoulder adduction/abduction |
ShoulderRotR / ShoulderRotL | deg | Shoulder rotation |
ElbowFlexExtR / ElbowFlexExtL | deg | Elbow flexion/extension |
ForearmProSupR / ForearmProSupL | deg | Forearm pronation/supination |
WristFlexExtR / WristFlexExtL | deg | Wrist flexion/extension |
WristDeviationR / WristDeviationL | deg | Wrist ulnar/radial deviation |
All fields default to 0.0. Sign convention follows the Teslasuit
SDK; check the SDK docs
for details.
StepDetectorData#
Foot contact state.
| Field | Type | Default | Notes |
|---|---|---|---|
left_foot_contact | bool | True | True = left foot in stance phase |
right_foot_contact | bool | True | True = right foot in stance phase |
Source: SDK's built-in step detector (foot-IMU acceleration
threshold). Read via self.contacts.
EMSParamData#
Single muscle's stimulation parameters.
| Field | Type | Default | Range | Notes |
|---|---|---|---|---|
IsMuted | bool | True | — | True = no pulses delivered this cycle |
PulseWidth | int | 0 | 10–140 μs | Pulse duration (device range: 10–140) |
Period | float | 0.0 | > 0 ms | Time between pulses; 1000 / Period = Hz |
Amplitude | int | 0 | 0–100 % | Stimulation intensity (% of device max) |
IsMuted defaults to True so unwritten EmsData() slots are
silent — see the docstring in types.py for why.
EmsData#
EMS parameters for all 20 muscles. Each field is an EMSParamData.
Default factory yields a muted instance. Write via
self.ems_output.<muscle> = EMSParamData(...).
Lower body (10)#
| Field | Anatomy |
|---|---|
quadriceps_left / quadriceps_right | Anterior thigh |
hamstring_left / hamstring_right | Posterior thigh |
gastrocnemius_left / gastrocnemius_right | Calf |
tibialis_anterior_left / tibialis_anterior_right | Shin |
gluteus_left / gluteus_right | Buttock |
Upper body (10)#
| Field | Anatomy |
|---|---|
deltoid_left / deltoid_right | Shoulder |
biceps_left / biceps_right | Anterior upper arm |
triceps_left / triceps_right | Posterior upper arm |
wrist_flexors_left / wrist_flexors_right | Anterior forearm |
wrist_extensors_left / wrist_extensors_right | Posterior forearm |
These names come from muscle_map_4R.json. To add a muscle, edit
both this dataclass and the JSON config in lockstep.
EMSCalibrationData#
Same 20 muscle slots as EmsData, each holding an
EmsMultiplierData(minimum: float, maximum: float). Used by
applications that calibrate per-user comfortable amplitude ranges.
The base framework instantiates one (engine.ems_calibration_data)
but does not populate or consume it; applications can use it as a
shared store.
ControlMessage (subclass to use)#
Empty base class. Application defines fields by subclassing:
@dataclass
class MyControlMessage(ControlMessage):
threshold_deg: float = 15.0
quad_amplitude: int = 40Carries an _on_change callback (private, not serialised across
processes) for auto-send patterns. See Messaging.
UtilityMessage#
Framework-defined system flags. Do not subclass.
| Field | Type | Notes |
|---|---|---|
FesIsActive | bool | Global FES kill switch. When False, the framework mutes every muscle regardless of ems_output. |
RecordingIsActive | bool | Whether session recording is engaged (set by GUI; framework does not consume). |
CalibrationLoopIsActive | bool | Whether calibration is in progress (set by GUI; framework does not consume). |
TSAPIStepDetectionIsActive | bool | Step-detection mode flag (only mode supported by current framework). |
BiomechanicalDataCollectionIsActive | bool | Gates DataStreamer's expensive biomech-angle SDK call. |
FolderPath | str | Recording target folder (set by GUI). |
_on_change callback is supported, same as ControlMessage.
ProcessedData#
20 bones, each with position and rotation. Used by visualisation / LSL outlets. Most strategies don't read this directly.
ProcessedData(
Hips: MocapBoneData,
LeftUpperLeg: MocapBoneData,
RightUpperLeg: MocapBoneData,
LeftLowerLeg: MocapBoneData,
RightLowerLeg: MocapBoneData,
LeftFoot: MocapBoneData,
RightFoot: MocapBoneData,
Spine: MocapBoneData,
Chest: MocapBoneData,
UpperChest: MocapBoneData,
Neck: MocapBoneData,
Head: MocapBoneData,
LeftShoulder: MocapBoneData,
RightShoulder: MocapBoneData,
LeftUpperArm: MocapBoneData,
RightUpperArm: MocapBoneData,
LeftLowerArm: MocapBoneData,
RightLowerArm: MocapBoneData,
LeftHand: MocapBoneData,
RightHand: MocapBoneData,
)MocapBoneData has position: BonePosition(x, y, z) and
rotation: BoneRotation(w, x, y, z).
RawData#
20 bones, each with raw IMU readings. Plus a timestamp: int = 0.
Each segment is a SensorData:
| Field | Type | Notes |
|---|---|---|
boneId | int | SDK bone ID |
q6 | Q6Quaternion(w, x, y, z) | 6DOF orientation |
accel | Acceleration(x, y, z) | Accelerometer (m/s²) |
gyro | Gyroscope(x, y, z) | Angular velocity (rad/s) |
linear_accel | LinearAcceleration(x, y, z) | Acceleration with gravity removed (m/s²) |
Same 20 bones as ProcessedData.
HeartRateData#
Populated only when DataStreamer.ppg_available is True.
| Field | Type | Default | Notes |
|---|---|---|---|
heart_rate | int | 0 | Beats per minute |
is_heart_rate_valid | bool | False | Whether the SDK considers the reading valid |
timestamp | int | 0 | SDK timestamp |
HRVData#
Heart-rate variability metrics, populated only when PPG is available.
| Field | Default | Notes |
|---|---|---|
hrv | 0.0 | Aggregate HRV measure |
mean_rr | 0.0 | Mean inter-beat interval (ms) |
sdnn | 0.0 | Standard deviation of NN intervals (ms) |
sdsd | 0.0 | Standard deviation of successive differences |
rmssd | 0.0 | Root mean square of successive differences |
sd1 | 0.0 | Poincaré plot SD1 |
sd2 | 0.0 | Poincaré plot SD2 |
hlf | 0.0 | LF/HF ratio (low-to-high frequency power) |
RawPPGData#
Raw photodiode readings. PPG runs at ~200 Hz; the framework keeps the most recent 2 samples per cycle.
| Field | Type | Notes |
|---|---|---|
ir_data | list[int] | Infrared photodiode readings |
red_data | list[int] | Red photodiode readings |
blue_data | list[int] | Blue photodiode readings |
green_data | list[int] | Green photodiode readings |
CustomPlayable#
A single named slot in a HapticLibrary. Holds the SDK playable
ID, mute state, looped flag, and three live-modulation
multipliers.
| Field | Type | Default | Notes |
|---|---|---|---|
playable_id | int | 0 | SDK playable ID; 0 means uninitialised |
IsMuted | bool | True | Toggle to fire/silence |
is_looped | bool | True | Whether the SDK loops the playable |
period_mult | float | 1.0 | Live multiplier on period |
amplitude_mult | float | 1.0 | Live multiplier on amplitude |
pulse_width_mult | float | 1.0 | Live multiplier on pulse width |
Populated via SuitHandler.create_haptic_touch() or
SuitHandler.load_haptic_asset().
HapticLibrary (subclass to use)#
Empty base class. Subclass to declare named CustomPlayable slots.
@dataclass
class ArmHaptics(HapticLibrary):
biceps_burst: CustomPlayable = field(default_factory=CustomPlayable)
reach_forward: CustomPlayable = field(default_factory=CustomPlayable)HapticLibrary.iter_playables() yields (name, CustomPlayable)
pairs for every slot. Used internally by LibraryStimulator.
Vector dataclasses#
Used inside SensorData and MocapBoneData. Mostly internal — you
read them off self.suit_handler.streamer.processed_data if you
need them; strategies usually don't.
| Type | Fields | Default values |
|---|---|---|
Acceleration | x, y, z: float | 0.0 |
Gyroscope | x, y, z: float | 0.0 |
LinearAcceleration | x, y, z: float | 0.0 |
Q6Quaternion | w, x, y, z: float | 0.0 |
BonePosition | x, y, z: float | 0.0 |
BoneRotation | w, x, y, z: float | 0.0 |
shared_memory_frame (numpy dtype)#
Pre-built numpy structured dtype for SharedRingBuffer. Includes
timestamp + the 29 BiomechanicalData fields + the 2 step
detector flags + backend_sample_rate. Total: 33 fields.
Use it for the standard biomech + step-detector layout. Build your
own if you need more fields (see examples/walking_fes/walking_types.py).
import numpy as np
from fes_framework.data.types import shared_memory_frame
buffer = SharedRingBuffer(name="fes", frame_dtype=shared_memory_frame, capacity=1000)See also#
- Data Types — concept-level overview
- API Reference — class signatures
- Source:
fes_framework/data/types.py
