Created by: Debadrata Sarkar, Soumen Sen, Aman Arora

Modular · Reconfigurable · ROS 2 · micro-ROS

Modular, reconfigurable software for wearable robots

ExoStack takes an exosuit or exoskeleton from body-worn sensors to personalized assistance: declarative ESP32 hubs, configuration-driven ROS 2 nodes, human-in-the-loop optimization and a GUI, in one framework.

ROS 2 HumbleUbuntu 22.04 · JetsonESP32 + micro-ROSPolyForm Noncommercial
SoftEXOwalk · knee exosuit
PASE: ExoStack GUI
Hip exosuit
4components, one pipeline
6generic ROS 2 nodes, one per YAML entry
7software filters for every analog input
2optimizers for HIL: CMA-ES and Bayesian
The ExoStack ecosystem

Four parts, one pipeline

Each part is installed where it runs (on the boards worn on the body or on the host computer), and they meet on one ROS 2 graph.

How it works

From body-worn sensors to personalized assistance

Six stages, from the boards worn on the body to the optimizer on the host.

Sense

ESP32 hubs publish every channel of a board as one message on /hub_*.

Synchronize

Hubs share a time base; matched readings appear on /synced_sensors.

Detect

Gait-event plug-ins fire on named channels with a confidence window.

Plan

Lookup tables or an optimizer give parameters; builders and planners turn them into set-points.

Actuate

Float32 set-points drive the actuation hubs or any ROS 2 driver.

Personalize

Per-cycle costs steer CMA-ES or Bayesian optimization in the HIL loop.

ExoStack overview
ExoStack overview. ESA hubs worn on the body exchange sensor data and set-points with the ExoCore nodes through the micro-ROS agent. PASE writes the configuration, launches the nodes, and plots their topics. Each node instance is created from one configuration entry: ×N sensing and ×M actuation hubs, ×R ROS 2 drivers, ×E detectors, and ×P for each assisted motion (planner, profile builder, and, where configured, cost and HIL nodes).
Built for embedded engineers

Declare a hub, don't program it

A board is a device list and five calls. ESA reads analog, digital and I²C devices, filters them, and publishes every channel as one message on a common time base.

  • Seven software filters, pull modes, two I²C buses
  • Self-registering drivers for IMUs, load cells, encoders and valves
  • Wi-Fi or USB transport through micro-ROS
hub_right.ino
#include "ESA.h"
SoftExoWalk exo;

DeviceConfig deviceList[] = {
  { I2C, 0x4A, "IMU_T", MAIN,   9 },   // 9-channel IMU
  { I2C, 0x2A, "LC_F",  MAIN },          // load cell
  { AI,  34,   "FSR",   MEDIAN, 3 },   // filtered analog input
};
const size_t deviceList_len =
    sizeof(deviceList) / sizeof(deviceList[0]);

void setup() {
  exo.setupCommunication("usb");       // or Wi-Fi
  if (exo.initializeSystem()) {
    exo.setupNode("hub_right_node");
    exo.setupPublisher("/hub_right", 100);
    exo.bootSystem();
  }
}
void loop() { exo.readSensorsData(); exo.publish(true); }
Built for ROS 2 developers

Configure the pipeline, plug in your algorithms

Every ExoCore node is created from one YAML entry. Detectors, profile builders, lookup algorithms, planners, cost functions and optimizers are Python plug-ins loaded by name, and PASE lists them automatically.

  • A bilateral or multi-joint device is a few more entries, not more code
  • Signals addressed by name: [hub, channel]
  • Six plug-in types with templates
exo_stack_resources/config
# gait_events.yaml: one detector node per entry
events:
  right_heel_strike:
    sensors: [[hubr, fsr]]
    algorithm: "HeelStrike"    # plug-in, loaded by name
    parameters: [2.0, 0.2]
    output_topic: "/heel_strike_right"

# mplanner.yaml: one planner node per entry
planners:
  right_hip_extension:
    gait_event_topic: "/right_hip_extension_start"
    planner_algorithm: "LinearInterpolatedList"
    output_topic: "/right/hip_ppr_cmd"
Built for researchers

Personalize assistance in the loop

Deployment and human-in-the-loop optimization share the same builders and planners. A candidate number travels through every HIL message, so each measured cost is credited to the parameters that produced it.

  • CMA-ES and Bayesian optimization included
  • Cost per gait cycle, with transient cycles skipped
  • A tuned parameter set becomes a lookup-table row for daily use
ExoCore data flow
ExoCore: the generic ROS 2 nodes and the topics that connect them.
Validated hardware

Two pneumatic exosuits, one code base

Both systems run the same ESA library and ExoCore nodes; only their configuration and plug-ins differ.

Get started

Up and running in minutes

One clone, four installs. The repository ships a complete bilateral configuration to start from.

terminal
# get the code
cd ~/ros2_ws/src
git clone https://github.com/debadrata/ExoStack.git && cd ExoStack

# ESA firmware library and its vendor libraries
cp -r ESA/ESA ~/Arduino/libraries/
cp -r ESA/PREREQUISITE_LIBRARIES_COPY_TO_ARDUINO_LIBRARIES/* \
      ~/Arduino/libraries/

# ExoCore and its workspace
pip3 install -r exo_stack/requirements.txt
cp -r exo_stack_resources ~/
(cd ~/ros2_ws && colcon build --packages-select exo_stack)

# PASE GUI
cd PASE_GUI && pip3 install -r requirements.txt && python3 main.py
Documentation

Everything you need, step by step

Research

Cite ExoStack

ExoStack: A Modular and Reconfigurable Software Framework for Wearable Robotics Using ROS 2

BibTeX
@article{exostack2026,
  title   = {ExoStack: A Modular and Reconfigurable Software Framework for Wearable Robotics Using ROS 2},
  author  = {Sarkar, Debadrata and others},
  journal = {arXiv preprint arXiv:[ARXIV_ID]},
  year    = {2026},
  doi     = {10.48550/arXiv.[ARXIV_ID]}
}

Human Centred Robotics and Cybernetics Group, CSIR–Central Mechanical Engineering Research Institute (CSIR-CMERI), Durgapur, India

Contact

Get in touch

Questions, collaborations and bug reports are welcome, by email or through GitHub Issues.

Debadrata SarkarHuman Centred Robotics and Cybernetics Group, CSIR-CMERI, Durgapurdeba00126@gmail.com · LinkedIn · dsarkarrobotics.com
Aman AroraHuman Centred Robotics and Cybernetics Group, CSIR-CMERI, Durgapuraman.cmeri@nic.in · CSIR-CMERI profile · LinkedIn