Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 64 additions & 38 deletions docs/article/paper.bib
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ @article{ibitoye2016strategies
doi={10.1371/journal.pone.0149024},
}

@article{co2025optimal,
title = {Optimal control-driven functional electrical stimulation: A PRISMA-ScR scoping review},
author = {Kevin Co and Mickaël Begon and François Bailly and Florent Moissenet},
journal = {Computers in Biology and Medicine},
volume = {199},
pages = {111311},
year = {2025},
publisher={Elsevier},
doi = {https://doi.org/10.1016/j.compbiomed.2025.111311},
}

@article{hunt1997feedback,
title={Feedback control of unsupported standing in paraplegia. I. Optimal control approach},
author={Hunt, Kenneth J and Munih, Marko and Donaldson, N de N},
Expand All @@ -22,12 +33,28 @@ @article{hunt1997feedback
doi={10.1109/86.650287},
}

@article{co2025optimal,
title={Optimal control driven functional electrical stimulation: A scoping review},
author={Co, Kevin and Begon, Micka{\"e}l and Bailly, Fran{\c{c}}ois and Moissenet, Florent},
journal={arXiv preprint arXiv:2508.02899},
year={2025},
doi={10.48550/arXiv.2508.02899},
@article{ding2003mathematical,
title={Mathematical models for fatigue minimization during functional electrical stimulation},
author={Ding, Jun and Wexler, Anthony S and Binder-Macleod, Stuart A},
journal={Journal of Electromyography and Kinesiology},
volume={13},
number={6},
pages={575--588},
year={2003},
publisher={Elsevier},
doi={10.1016/S1050-6411(03)00102-0},
}

@article{veltink1992nonlinear,
title={Nonlinear joint angle control for artificially stimulated muscle},
author={Veltink, Peter H and Chizeck, Howard J and Crago, Patrick E and El-Bialy, Ahmed},
journal={IEEE Transactions on biomedical engineering},
volume={39},
number={4},
pages={368--380},
year={1992},
publisher={IEEE},
doi={10.1109/10.126609},
}

@article{puchaud2023direct,
Expand Down Expand Up @@ -64,40 +91,28 @@ @article{le2010identification
doi={10.1016/j.conengprac.2009.12.007},
}

@article{veltink1992nonlinear,
title={Nonlinear joint angle control for artificially stimulated muscle},
author={Veltink, Peter H and Chizeck, Howard J and Crago, Patrick E and El-Bialy, Ahmed},
journal={IEEE Transactions on biomedical engineering},
volume={39},
number={4},
pages={368--380},
year={1992},
publisher={IEEE},
doi={10.1109/10.126609},
}

@article{ding2003mathematical,
title={Mathematical models for fatigue minimization during functional electrical stimulation},
author={Ding, Jun and Wexler, Anthony S and Binder-Macleod, Stuart A},
journal={Journal of Electromyography and Kinesiology},
volume={13},
number={6},
pages={575--588},
year={2003},
publisher={Elsevier},
doi={10.1016/S1050-6411(03)00102-0},
@article{dembia2020opensim,
title={OpenSim Moco: musculoskeletal optimal control},
author={Dembia, Christopher L and Bianco, Nicholas A and Falisse, Antoine and Hicks, Jennifer L and Delp, Scott L},
journal={PLOS Computational Biology},
volume={16},
number={12},
pages={e1008493},
year={2020},
publisher={Public Library of Science San Francisco, CA USA},
doi={10.1371/journal.pcbi.1008493},
}

@article{ding2007mathematical,
title={Mathematical model that predicts the force--intensity and force--frequency relationships after spinal cord injuries},
author={Ding, Jun and Chou, Li-Wei and Kesar, Trisha M and Lee, Samuel CK and Johnston, Therese E and Wexler, Anthony S and Binder-Macleod, Stuart A},
journal={Muscle \& Nerve: Official Journal of the American Association of Electrodiagnostic Medicine},
volume={36},
number={2},
pages={214--222},
year={2007},
publisher={Wiley Online Library},
doi={10.1002/mus.20806},
@article{geijtenbeek2019,
title={SCONE: Open Source Software for Predictive Simulation of Biological Motion},
author={Geijtenbeek, Thomas},
journal={Journal of Open Source Software},
volume={4},
number={38},
pages={1421},
year={2019},
publisher={The Open Journal},
doi={10.21105/joss.01421},
}

@article{michaud2022bioptim,
Expand All @@ -111,3 +126,14 @@ @article{michaud2022bioptim
publisher={IEEE},
doi={10.1109/TSMC.2022.3183831},
}

@article{michaud2021biorbd,
title={biorbd: A c++, python and matlab library to analyze and simulate the human body biomechanics},
author={Michaud, Benjamin and Begon, Micka{\"e}l},
journal={Journal of open source software},
volume={6},
number={57},
pages={2562},
year={2021},
doi={10.21105/joss.02562},
}
218 changes: 84 additions & 134 deletions docs/article/paper.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ reaching, and grasping. FES rehabilitation mostly relies on empirical settings,
populations and muscles. Empirical settings often cause overstimulation and premature fatigue [@ibitoye2016strategies],
shortening rehabilitation sessions and diminishing therapeutic benefit. Consequently, advanced control approaches like
optimal control-driven FES are gaining interest in personalizing and improving FES rehabilitation efficiency, meanwhile
delaying muscle fatigue. To address this need, we designed `Cocofest` (Custom Optimal COntrol for Functional Electrical
STimulation), an open-source Python package for optimal control-driven FES. `Cocofest` provides a framework to generate
personalized pulse trains (Fig. 1) based on nonlinear dynamics models for FES (Table. 1), for several musculoskeletal
models and motor tasks. The package provides more than 10 examples, covering optimization of FES-related pulse train
parameters (including frequency, pulse width, pulse intensity), FES model parameters identification from in vivo
measurements, and long duration predictive simulations.
delaying muscle fatigue [@co2025optimal]. To address this need, we designed `Cocofest` (Custom Optimal COntrol for
Functional Electrical STimulation), an open-source Python package for optimal control-driven FES. `Cocofest` provides a
framework to generate personalized pulse trains (Fig. 1) based on nonlinear dynamics models for FES (Table. 1), for
several musculoskeletal models and motor tasks. The package includes over 10 examples, covering optimization of
FES-related pulse train parameters (including frequency, pulse width, pulse intensity), FES model parameters
identification from in-vivo measurements, and long duration predictive simulations.

![Pulse train parameters that can be optimized in Cocofest](pulse_train.png){ width=90% }

Expand All @@ -64,147 +64,97 @@ hindering standardization and cumulative progress [@co2025optimal]. To address t
scientific progress, `Cocofest` fulfills the following four needs:

Firstly, the relationship between the pulse train parameters (e.g., frequency, pulse width and intensity; Fig. 1) and
the resulting muscle force, joint torque, and muscle fatigue (termed as state variables) can be modeled with different
nonlinear dynamics [@ding2003mathematical; @veltink1992nonlinear] (Table 1). Gathering them within a unified package
would facilitate comparison for more informed modelling choices.
the resulting muscle force, joint torque, and muscle fatigue can be modeled with different nonlinear dynamics
[@ding2003mathematical; @veltink1992nonlinear]. Gathering them within a unified package would facilitate comparison for
more informed modelling choices.

Secondly, no study has compared different optimal control problem (OCP) formulations ap-plied to FES, due to OCP
Secondly, no study has compared different optimal control problem (OCP) formulations applied to FES, due to OCP
implementation challenges [@co2025optimal]. Easily customizable OCP formulation, involving objective functions, models,
and transcriptions is required to provide an adequate research framework. Having the possibility to switch between
several OCP transcriptions, such as direct collocation or direct multiple shooting, is essential when dealing with stiff
differential equations [@puchaud2023direct], often embed in FES models. Muscle fatigue is the primary challenge in FES.
Enabling the development and comparison of different OCP formulations could help address research questions, yield novel
stimulation patterns and enhance fatigue reduction. Moreover, using receding-horizon estimation for longer simulations
reduces the computational complexity associated with time-varying dynamics (e.g., fatigue) [@ding2003mathematical].
various OCP transcriptions (e.g., direct collocation or direct multiple shooting) is essential when dealing with stiff
differential equations [@puchaud2023direct], often embedded in FES models. Muscle fatigue is the primary challenge in
FES. Enabling the development and comparison of different OCP formulations could help address research questions, yield
novel stimulation patterns and enhance fatigue reduction. Moreover, using receding-horizon estimation for longer
simulations reduces the computational complexity associated with time-varying dynamics (e.g., fatigue)
[@ding2003mathematical].

Thirdly, predictive simulations of FES-driven or FES-assisted motions (e.g., walking, cycling, reaching, and grasping)
require the coupling of FES models with the equations of motion as well as adequate muscle force-length-velocity
relationships. Predictive simulations are usually actuated through Hill-type muscle models [@wakeling2023review]. A
package capable of replacing muscle actuation by FES models in multibody musculoskeletal models will allow us to
relationships. Predictive simulations are usually actuated through Hill-type muscle models [@wakeling2023review].
A package capable of replacing muscle actuation by FES models in multibody musculoskeletal models will allow us to
simulate realistic FES-driven tasks.

Fourthly, personalized rehabilitation strategy is required to facilitate the motor recovery. Therefore, identifying the
patient-specific muscle response to FES is a crucial step. Unfortunately, current complex identification methods are a
barrier to clinical translation [@le2010identification]. Providing a robust and customizable framework for the
development of more patient-friendly protocols would help to overcome this barrier.

Overall, despite its potential, optimal control–driven FES remains unadopted in clinical practice due to its low
technology readiness level [@co2025optimal]. `Cocofest` is a comprehensive package designed to bridge the gaps and
foster clinical adoption. It integrates nonlinear muscle dynamics dedicated to FES, manages muscle fatigue, interfaces
FES with musculoskeletal models, supports customizable cost functions and parameter identification routines. With the
goal of bringing this technology to patient care, we believe this package will contribute to the open-science effort.
`Cocofest` is expected to accelerate the increase of technology readiness level by strengthening knowledge foundation.

\newpage
## An optimization example: Pulse width optimization to match a force profile using the @ding2007mathematical model

This example shows how to optimize a FES pulse width using `Cocofest`, coupled with bioptim [@michaud2022bioptim]
version 3.3.0.

```python
import numpy as np
from bioptim import (ControlType, ObjectiveFcn, ObjectiveList, OdeSolver,
OptimalControlProgram, Node, SolutionMerge)
from cocofest import ModelMaker, OcpFes, FesModel


def prepare_ocp(model: FesModel,
final_time: float,
pw_max: float,
force_tracking: list) -> OptimalControlProgram:
"""
Prepare the Optimal Control Program by setting dynamics, bounds and cost functions.

Parameters
----------
model : DingModelPulseWidthFrequency
The chosen FES model to use as muscle dynamics.
final_time : float
The ending time for the simulation.
pw_max : float
The maximum pulse width, used for stimulation bounds.
force_tracking : list
The force to track.

Returns
-------
ocp : OptimalControlProgram
The Optimal Control Program to solve.
"""
# --- Set dynamics --- #
# Create the number of shooting points for the OCP
n_shooting = model.get_n_shooting(final_time=final_time)
time_series, stim_idx_at_node_list = model.get_numerical_data_time_series(
n_shooting, final_time
) # Retrieve time and indexes at which occurs the stimulation for the FES dynamic
dynamics = OcpFes.declare_dynamics(
model,
time_series,
ode_solver=OdeSolver.RK4(n_integration_steps=10),
# Possibility to use a different solver
# ode_solver=OdeSolver.COLLOCATION(polynomial_degree=3, method="radau"),
)

# --- Set initial guesses and bounds for states and controls --- #
x_bounds = OcpFes.set_x_bounds(model)
x_init = OcpFes.set_x_init(model)
u_bounds = OcpFes.set_u_bounds(model, max_bound=pw_max)
u_init = OcpFes.set_u_init(model)

# --- Set objective functions --- #
objective_functions = ObjectiveList()
# Reshape list to track to match Bioptim's target size
force_to_track = force_tracking[np.newaxis, :]
objective_functions.add(
ObjectiveFcn.Mayer.TRACK_STATE,
key="F",
target=force_to_track,
node=Node.ALL,
quadratic=True,
)

return OptimalControlProgram(
bio_model=[model],
dynamics=dynamics,
n_shooting=n_shooting,
phase_time=final_time,
objective_functions=objective_functions,
x_init=x_init,
x_bounds=x_bounds,
u_bounds=u_bounds,
u_init=u_init,
control_type=ControlType.CONSTANT,
n_threads=20,
)

def main():
final_time = 1
stim = 33
model = ModelMaker.create_model("ding2007",
stim_time=list(np.linspace(0, 1, stim,
end-point=False)))

# --- Building force to track ---#
time = np.linspace(0, 1, 34)
# Example of force to track between 10 and 150 N
force = 10 + (150 - 10) * np.abs(np.sin(time * 5))
force[0] = 0.0 # Ensuring the force starts at 0 N

ocp = prepare_ocp(model=model,
final_time=final_time,
pw_max=0.0006,
force_tracking=force)
sol = ocp.solve()

# --- Show the optimization results --- #
sol.graphs()


if __name__ == "__main__":
main()
```

![Tracked force (grey dots) and optimized force generated (red) by pulse width optimization (blue).](force_profile.svg)
Despite its potential, optimal control–driven FES remains unadopted in clinical practice due to its low technology
readiness level [@co2025optimal]. `Cocofest` is a comprehensive package designed to bridge the gaps and foster clinical
adoption. It integrates nonlinear muscle dynamics dedicated to FES, manages muscle fatigue, interfaces FES with
musculoskeletal models, supports customizable cost functions and parameter identification routines. With the goal of
bringing this technology to patient care, we believe this package will contribute to the open-science effort. `Cocofest`
is expected to accelerate the increase of technology readiness level by strengthening knowledge foundation.


# State of the Field

Several open-source toolkits support optimal control computations for musculoskeletal biomechanics, such as:
- `OpenSim Moco` [@dembia2020opensim], a C++ OpenSim extension that enables motion tracking and prediction using efficient
direct-collocation formulations coupled to nonlinear programming solvers.
- `SCONE` [@Geijtenbeek2019], a C++/C predictive-simulation environment for human and animal motion that optimizes
neuromusculoskeletal controllers to achieve task-level objectives (e.g., stable walking at a target speed).
- `Bioptim` [@michaud2022bioptim], a Python optimal-control framework for biomechanics that supports both direct collocation
and multiple shooting, with flexible interfaces to nonlinear programming solvers.

However, these toolkits are not tailored for FES. They control muscle activation as a piecewise linear/constant
excitation, whereas FES requires optimizing deliverable stimulation patterns under device and safety constraints. As a
result, they lack reusable, validated components for the stimulation-to-force pathway and fatigue/recovery dynamics,
limiting reproducible comparison of FES models and slowing translation to practical stimulation design. `Cocofest`
addresses this gap by implementing published FES models that can drive musculoskeletal models. This design supports
reproducible comparisons of FES modeling assumptions and accelerates prototyping of patient- and task-specific
stimulation optimization. `Cocofest` also includes utilities for model identification and receding-horizon optimization
to support FES research workflows.


# Software Design

`Cocofest` is a Python library that relies on Biorbd, a musculoskeletal physics engine [@michaud2021biorbd], and
Bioptim, an open-source optimization framework for biomechanical problems [@michaud2022bioptim]. Specifically, Bioptim
enables easy OCP customization including cost functions, bounds, constraints, transcription methods (e.g., direct
collocation), integration methods, and solving methods (e.g., full- and receding-horizon OCPs).

In conventional Hill-type muscle model, muscle force ($F_m$) is the product of $a$ the muscle activation, $F_{max}$ the
maximal isometric muscle force, $f_l$ the force-length, $f_v$ the force-velocity and $f_{pas}$ the passive force-length
relationship: $F_m(t) = a(t)\, F_{\max}\, f_l(\tilde{l}_m)\, f_v(\tilde{v}_m) + f_{pas}(\tilde{l}_m)$. `Cocofest`
replaces $a(t)$ × $F_{max}$ by the force obtained using FES models. This approach allows motions driven-FES simulations,
meanwhile benefiting from musculoskeletal model properties (e.g., muscle insertion, inertial parameters).

`Cocofest` was developed to maintain a consistent structure between classes and functions to facilitate the OCP
customization and new FES model implementation. This shared interface promotes reproducible work and comparisons of
optimal control–driven FES strategies.


# Research Impact Statement

`Cocofest` was developed to address several gaps in the literature, including the lack of systematic comparisons of FES
models and OCP formulations, accessible tools for FES model identification, and open-source software for reproducible
research. It enables researchers to generate personalized stimulation patterns, compare alternative OCP formulations,
and simulate realistic FES-driven tasks. By providing a consistent software structure and clear documentation,
`Cocofest` aims to streamline research workflows and support translation toward FES rehabilitation applications.
Although the project is new and targets a niche domain, it already offers a shared, reproducible environment that can
foster discussion, collaboration, and broader adoption of open-source practices within the FES community, which is an
important step toward clinical translation of this technique [@co2025optimal].


# AI Usage Disclosure

The authors used ChatGPT only to improve the manuscript clarity and readability.
After using this tool/service, the authors reviewed and edited the content as needed and took full responsibility for
the content of the publication.

GitHub Copilot and ChatGPT were used to assist in code refactoring and documentation.
Authors made all the core design and architectural decisions.


# Acknowledgements
Expand Down
Loading