TeslasuitDocumentation
Frameworks

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.

FieldUnitNotes
PelvisTiltdegPelvic tilt (forward/backward)
PelvisListdegPelvic list (lateral lean)
PelvisRotationdegPelvic axial rotation
HipFlexExtR / HipFlexExtLdegHip flexion/extension
HipAddAbdR / HipAddAbdLdegHip adduction/abduction
HipRotR / HipRotLdegHip rotation
KneeFlexExtR / KneeFlexExtLdegKnee flexion/extension
AnkleFlexExtR / AnkleFlexExtLdegAnkle dorsi/plantarflexion
AnkleProSupR / AnkleProSupLdegAnkle pronation/supination
ShoulderFlexExtR / ShoulderFlexExtLdegShoulder flexion/extension
ShoulderAddAbdR / ShoulderAddAbdLdegShoulder adduction/abduction
ShoulderRotR / ShoulderRotLdegShoulder rotation
ElbowFlexExtR / ElbowFlexExtLdegElbow flexion/extension
ForearmProSupR / ForearmProSupLdegForearm pronation/supination
WristFlexExtR / WristFlexExtLdegWrist flexion/extension
WristDeviationR / WristDeviationLdegWrist 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.

FieldTypeDefaultNotes
left_foot_contactboolTrueTrue = left foot in stance phase
right_foot_contactboolTrueTrue = 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.

FieldTypeDefaultRangeNotes
IsMutedboolTrueTrue = no pulses delivered this cycle
PulseWidthint010–140 μsPulse duration (device range: 10–140)
Periodfloat0.0> 0 msTime between pulses; 1000 / Period = Hz
Amplitudeint00–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)#

FieldAnatomy
quadriceps_left / quadriceps_rightAnterior thigh
hamstring_left / hamstring_rightPosterior thigh
gastrocnemius_left / gastrocnemius_rightCalf
tibialis_anterior_left / tibialis_anterior_rightShin
gluteus_left / gluteus_rightButtock

Upper body (10)#

FieldAnatomy
deltoid_left / deltoid_rightShoulder
biceps_left / biceps_rightAnterior upper arm
triceps_left / triceps_rightPosterior upper arm
wrist_flexors_left / wrist_flexors_rightAnterior forearm
wrist_extensors_left / wrist_extensors_rightPosterior 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 = 40

Carries an _on_change callback (private, not serialised across processes) for auto-send patterns. See Messaging.


UtilityMessage#

Framework-defined system flags. Do not subclass.

FieldTypeNotes
FesIsActiveboolGlobal FES kill switch. When False, the framework mutes every muscle regardless of ems_output.
RecordingIsActiveboolWhether session recording is engaged (set by GUI; framework does not consume).
CalibrationLoopIsActiveboolWhether calibration is in progress (set by GUI; framework does not consume).
TSAPIStepDetectionIsActiveboolStep-detection mode flag (only mode supported by current framework).
BiomechanicalDataCollectionIsActiveboolGates DataStreamer's expensive biomech-angle SDK call.
FolderPathstrRecording 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:

FieldTypeNotes
boneIdintSDK bone ID
q6Q6Quaternion(w, x, y, z)6DOF orientation
accelAcceleration(x, y, z)Accelerometer (m/s²)
gyroGyroscope(x, y, z)Angular velocity (rad/s)
linear_accelLinearAcceleration(x, y, z)Acceleration with gravity removed (m/s²)

Same 20 bones as ProcessedData.


HeartRateData#

Populated only when DataStreamer.ppg_available is True.

FieldTypeDefaultNotes
heart_rateint0Beats per minute
is_heart_rate_validboolFalseWhether the SDK considers the reading valid
timestampint0SDK timestamp

HRVData#

Heart-rate variability metrics, populated only when PPG is available.

FieldDefaultNotes
hrv0.0Aggregate HRV measure
mean_rr0.0Mean inter-beat interval (ms)
sdnn0.0Standard deviation of NN intervals (ms)
sdsd0.0Standard deviation of successive differences
rmssd0.0Root mean square of successive differences
sd10.0Poincaré plot SD1
sd20.0Poincaré plot SD2
hlf0.0LF/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.

FieldTypeNotes
ir_datalist[int]Infrared photodiode readings
red_datalist[int]Red photodiode readings
blue_datalist[int]Blue photodiode readings
green_datalist[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.

FieldTypeDefaultNotes
playable_idint0SDK playable ID; 0 means uninitialised
IsMutedboolTrueToggle to fire/silence
is_loopedboolTrueWhether the SDK loops the playable
period_multfloat1.0Live multiplier on period
amplitude_multfloat1.0Live multiplier on amplitude
pulse_width_multfloat1.0Live 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.

TypeFieldsDefault values
Accelerationx, y, z: float0.0
Gyroscopex, y, z: float0.0
LinearAccelerationx, y, z: float0.0
Q6Quaternionw, x, y, z: float0.0
BonePositionx, y, z: float0.0
BoneRotationw, x, y, z: float0.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#