System Architecture

The system is organized around two crutches connected through the MADS broker. The master crutch hosts the control and logging services, while both crutches run the sensing agents that publish data to the network.

Overview

Each crutch is based on a Raspberry Pi Zero 2 W and runs a small set of MADS agents. The master side coordinates the acquisition workflow, stores data, and exposes the web interface. The slave side focuses on local sensing and publishes the same acquisition streams so the master can merge them into a single recording.

Role Split

System Diagram

Instrumented Crutches architecture diagram

Open diagram in a new tab

Data Flow

The Web Server issues commands to the Coordinator through the MADS broker. The Coordinator drives the sensing agents, the Status Handler reports the live health of the system, and the HDF5 Writer persists the data streams that are later consumed by the visualization and download tools.

Agent Details

Each agent is shown in its own transposed table for readability.

Master-only agents

web_server
Agent typeFilter
RoleFastAPI backend and UI host. Manages acquisitions, test metadata, comments, conditions, plotting, and CSV download.
Sub topicsstatus
Pub topicsws_command
JSON output format{"command": "...", ...} with allowed values for command: start, stop, set_offset, get_agents_status, datetime_update, condition, pupil_neon_connect, pupil_neon_disconnect
coordinator
Agent typeFilter
RoleCommand router and state gate. Validates transitions and forwards normalized commands to all agents.
Sub topicsws_command
Accepted command
  • start, stop, condition, datetime_update
  • get_agents_status, set_offset
  • pupil_neon_connect, pupil_neon_disconnect
Pub topicscoordinator
JSON output format
  • Command: {"command":..., "id"?:n, "label"?:s, "subject_id"?:n, "session_id"?:n}
  • Heartbeat: {"agent_status":"idle|recording"}
status_handler
Agent typeFilter
RoleStatus aggregator and normalizer. It merges agent events and health messages into a single stream and marks agents unreachable after a timeout.
Sub topics
  • agent_event
  • coordinator
  • ups
  • hdf5_writer
  • tip_loadcell
  • handle_loadcell
  • ppg
  • pupil_neon
Accepted commandget_agents_status
Pub topicsstatus
JSON output format{"status":{"source","level","status","message","side"?}}
hdf5_writer
Agent typeFilter
RoleHDF5 logger. During recording, appends configured keypaths to topic groups and finalizes files on stop.
Sub topics
  • coordinator
  • tip_loadcell
  • handle_loadcell
  • ppg
  • pupil_neon
  • ups
Accepted command
  • start
  • stop
Pub topicshdf5_writer
JSON output formatHeartbeat: {"agent_status":"idle|recording"}
pupil_neon
Agent typeFilter
RolePupil Neon integration: device discovery/connection, recording control, condition events, and time-sync metrics.
Sub topicscoordinator
Accepted command
  • pupil_neon_connect
  • start
  • condition
  • stop
  • pupil_neon_disconnect
Pub topicspupil_neon
JSON output format
  • Heartbeat: {"agent_status":...,"error"?:...}
  • Sync: time_offset_ms_*, roundtrip_duration_ms_*, (*mean, median, and std)

Agents deployed on both crutches

tip_loadcell
Agent typeFilter
RoleHX711-based tip force acquisition with side-specific scale and offset handling.
Sub topicscoordinator
Accepted command
  • start
  • stop
  • set_offset
Pub topicstip_loadcell
JSON output format
  • Recording: {"force":n,"side":"left|right"}
  • Heartbeat: {"agent_status":"idle|recording","side":"left|right"}
  • Offset: {"info":{"offset":{"value":n,"test":n}},"side":"left|right"}
handle_loadcell
Agent typeFilter
Role8-channel ADS1263 handle-force acquisition with channel map, range conversion, and offset calibration.
Sub topicscoordinator
Accepted command
  • start
  • stop
  • set_offset
Pub topicshandle_loadcell
JSON output format
  • Recording: {"force":{"sensor_label":...},"side":"left|right"}
  • Offset: {"info":{"offset":{"value":{"sensor_label":...},"test":{"sensor_label":...}}},"side":"left|right"}
  • Heartbeat: {"agent_status":"idle|recording","side":"left|right"}

    Sensor labels are up_front, up_back, right_front, right_back, left_front, left_back, down_front, down_back.
ppg
Agent typeFilter
RoleMAX30100-based PPG acquisition; publishes IR/RED samples while recording plus status heartbeat.
Sub topicscoordinator
Accepted command
  • start
  • stop
Pub topicsppg
JSON output format
  • Heartbeat: {"agent_status":"idle|recording","side":"left|right"}
  • Samples: {"ir":n,"red":n,"side":"left|right"}
ups
Agent typeSource
RoleINA219 power monitor; computes battery percentage and estimated remaining time and publishes periodic telemetry.
Pub topicsups
JSON output format
  • {"agent_status":"idle","side":"left|right","info":{"voltage","current","power","percent","remaining_battery_time"}}