Skip to content

Commit 02cd379

Browse files
authored
Merge pull request #24 from Kev1CO/Joss
Article modification
2 parents b119d5a + e4b9b63 commit 02cd379

2 files changed

Lines changed: 148 additions & 172 deletions

File tree

docs/article/paper.bib

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ @article{ibitoye2016strategies
1010
doi={10.1371/journal.pone.0149024},
1111
}
1212

13+
@article{co2025optimal,
14+
title = {Optimal control-driven functional electrical stimulation: A PRISMA-ScR scoping review},
15+
author = {Kevin Co and Mickaël Begon and François Bailly and Florent Moissenet},
16+
journal = {Computers in Biology and Medicine},
17+
volume = {199},
18+
pages = {111311},
19+
year = {2025},
20+
publisher={Elsevier},
21+
doi = {https://doi.org/10.1016/j.compbiomed.2025.111311},
22+
}
23+
1324
@article{hunt1997feedback,
1425
title={Feedback control of unsupported standing in paraplegia. I. Optimal control approach},
1526
author={Hunt, Kenneth J and Munih, Marko and Donaldson, N de N},
@@ -22,12 +33,28 @@ @article{hunt1997feedback
2233
doi={10.1109/86.650287},
2334
}
2435

25-
@article{co2025optimal,
26-
title={Optimal control driven functional electrical stimulation: A scoping review},
27-
author={Co, Kevin and Begon, Micka{\"e}l and Bailly, Fran{\c{c}}ois and Moissenet, Florent},
28-
journal={arXiv preprint arXiv:2508.02899},
29-
year={2025},
30-
doi={10.48550/arXiv.2508.02899},
36+
@article{ding2003mathematical,
37+
title={Mathematical models for fatigue minimization during functional electrical stimulation},
38+
author={Ding, Jun and Wexler, Anthony S and Binder-Macleod, Stuart A},
39+
journal={Journal of Electromyography and Kinesiology},
40+
volume={13},
41+
number={6},
42+
pages={575--588},
43+
year={2003},
44+
publisher={Elsevier},
45+
doi={10.1016/S1050-6411(03)00102-0},
46+
}
47+
48+
@article{veltink1992nonlinear,
49+
title={Nonlinear joint angle control for artificially stimulated muscle},
50+
author={Veltink, Peter H and Chizeck, Howard J and Crago, Patrick E and El-Bialy, Ahmed},
51+
journal={IEEE Transactions on biomedical engineering},
52+
volume={39},
53+
number={4},
54+
pages={368--380},
55+
year={1992},
56+
publisher={IEEE},
57+
doi={10.1109/10.126609},
3158
}
3259

3360
@article{puchaud2023direct,
@@ -64,40 +91,28 @@ @article{le2010identification
6491
doi={10.1016/j.conengprac.2009.12.007},
6592
}
6693

67-
@article{veltink1992nonlinear,
68-
title={Nonlinear joint angle control for artificially stimulated muscle},
69-
author={Veltink, Peter H and Chizeck, Howard J and Crago, Patrick E and El-Bialy, Ahmed},
70-
journal={IEEE Transactions on biomedical engineering},
71-
volume={39},
72-
number={4},
73-
pages={368--380},
74-
year={1992},
75-
publisher={IEEE},
76-
doi={10.1109/10.126609},
77-
}
78-
79-
@article{ding2003mathematical,
80-
title={Mathematical models for fatigue minimization during functional electrical stimulation},
81-
author={Ding, Jun and Wexler, Anthony S and Binder-Macleod, Stuart A},
82-
journal={Journal of Electromyography and Kinesiology},
83-
volume={13},
84-
number={6},
85-
pages={575--588},
86-
year={2003},
87-
publisher={Elsevier},
88-
doi={10.1016/S1050-6411(03)00102-0},
94+
@article{dembia2020opensim,
95+
title={OpenSim Moco: musculoskeletal optimal control},
96+
author={Dembia, Christopher L and Bianco, Nicholas A and Falisse, Antoine and Hicks, Jennifer L and Delp, Scott L},
97+
journal={PLOS Computational Biology},
98+
volume={16},
99+
number={12},
100+
pages={e1008493},
101+
year={2020},
102+
publisher={Public Library of Science San Francisco, CA USA},
103+
doi={10.1371/journal.pcbi.1008493},
89104
}
90105

91-
@article{ding2007mathematical,
92-
title={Mathematical model that predicts the force--intensity and force--frequency relationships after spinal cord injuries},
93-
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},
94-
journal={Muscle \& Nerve: Official Journal of the American Association of Electrodiagnostic Medicine},
95-
volume={36},
96-
number={2},
97-
pages={214--222},
98-
year={2007},
99-
publisher={Wiley Online Library},
100-
doi={10.1002/mus.20806},
106+
@article{geijtenbeek2019,
107+
title={SCONE: Open Source Software for Predictive Simulation of Biological Motion},
108+
author={Geijtenbeek, Thomas},
109+
journal={Journal of Open Source Software},
110+
volume={4},
111+
number={38},
112+
pages={1421},
113+
year={2019},
114+
publisher={The Open Journal},
115+
doi={10.21105/joss.01421},
101116
}
102117

103118
@article{michaud2022bioptim,
@@ -111,3 +126,14 @@ @article{michaud2022bioptim
111126
publisher={IEEE},
112127
doi={10.1109/TSMC.2022.3183831},
113128
}
129+
130+
@article{michaud2021biorbd,
131+
title={biorbd: A c++, python and matlab library to analyze and simulate the human body biomechanics},
132+
author={Michaud, Benjamin and Begon, Micka{\"e}l},
133+
journal={Journal of open source software},
134+
volume={6},
135+
number={57},
136+
pages={2562},
137+
year={2021},
138+
doi={10.21105/joss.02562},
139+
}

docs/article/paper.md

Lines changed: 84 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ reaching, and grasping. FES rehabilitation mostly relies on empirical settings,
4545
populations and muscles. Empirical settings often cause overstimulation and premature fatigue [@ibitoye2016strategies],
4646
shortening rehabilitation sessions and diminishing therapeutic benefit. Consequently, advanced control approaches like
4747
optimal control-driven FES are gaining interest in personalizing and improving FES rehabilitation efficiency, meanwhile
48-
delaying muscle fatigue. To address this need, we designed `Cocofest` (Custom Optimal COntrol for Functional Electrical
49-
STimulation), an open-source Python package for optimal control-driven FES. `Cocofest` provides a framework to generate
50-
personalized pulse trains (Fig. 1) based on nonlinear dynamics models for FES (Table. 1), for several musculoskeletal
51-
models and motor tasks. The package provides more than 10 examples, covering optimization of FES-related pulse train
52-
parameters (including frequency, pulse width, pulse intensity), FES model parameters identification from in vivo
53-
measurements, and long duration predictive simulations.
48+
delaying muscle fatigue [@co2025optimal]. To address this need, we designed `Cocofest` (Custom Optimal COntrol for
49+
Functional Electrical STimulation), an open-source Python package for optimal control-driven FES. `Cocofest` provides a
50+
framework to generate personalized pulse trains (Fig. 1) based on nonlinear dynamics models for FES (Table. 1), for
51+
several musculoskeletal models and motor tasks. The package includes over 10 examples, covering optimization of
52+
FES-related pulse train parameters (including frequency, pulse width, pulse intensity), FES model parameters
53+
identification from in-vivo measurements, and long duration predictive simulations.
5454

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

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

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

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

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

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

91-
Overall, despite its potential, optimal control–driven FES remains unadopted in clinical practice due to its low
92-
technology readiness level [@co2025optimal]. `Cocofest` is a comprehensive package designed to bridge the gaps and
93-
foster clinical adoption. It integrates nonlinear muscle dynamics dedicated to FES, manages muscle fatigue, interfaces
94-
FES with musculoskeletal models, supports customizable cost functions and parameter identification routines. With the
95-
goal of bringing this technology to patient care, we believe this package will contribute to the open-science effort.
96-
`Cocofest` is expected to accelerate the increase of technology readiness level by strengthening knowledge foundation.
97-
98-
\newpage
99-
## An optimization example: Pulse width optimization to match a force profile using the @ding2007mathematical model
100-
101-
This example shows how to optimize a FES pulse width using `Cocofest`, coupled with bioptim [@michaud2022bioptim]
102-
version 3.3.0.
103-
104-
```python
105-
import numpy as np
106-
from bioptim import (ControlType, ObjectiveFcn, ObjectiveList, OdeSolver,
107-
OptimalControlProgram, Node, SolutionMerge)
108-
from cocofest import ModelMaker, OcpFes, FesModel
109-
110-
111-
def prepare_ocp(model: FesModel,
112-
final_time: float,
113-
pw_max: float,
114-
force_tracking: list) -> OptimalControlProgram:
115-
"""
116-
Prepare the Optimal Control Program by setting dynamics, bounds and cost functions.
117-
118-
Parameters
119-
----------
120-
model : DingModelPulseWidthFrequency
121-
The chosen FES model to use as muscle dynamics.
122-
final_time : float
123-
The ending time for the simulation.
124-
pw_max : float
125-
The maximum pulse width, used for stimulation bounds.
126-
force_tracking : list
127-
The force to track.
128-
129-
Returns
130-
-------
131-
ocp : OptimalControlProgram
132-
The Optimal Control Program to solve.
133-
"""
134-
# --- Set dynamics --- #
135-
# Create the number of shooting points for the OCP
136-
n_shooting = model.get_n_shooting(final_time=final_time)
137-
time_series, stim_idx_at_node_list = model.get_numerical_data_time_series(
138-
n_shooting, final_time
139-
) # Retrieve time and indexes at which occurs the stimulation for the FES dynamic
140-
dynamics = OcpFes.declare_dynamics(
141-
model,
142-
time_series,
143-
ode_solver=OdeSolver.RK4(n_integration_steps=10),
144-
# Possibility to use a different solver
145-
# ode_solver=OdeSolver.COLLOCATION(polynomial_degree=3, method="radau"),
146-
)
147-
148-
# --- Set initial guesses and bounds for states and controls --- #
149-
x_bounds = OcpFes.set_x_bounds(model)
150-
x_init = OcpFes.set_x_init(model)
151-
u_bounds = OcpFes.set_u_bounds(model, max_bound=pw_max)
152-
u_init = OcpFes.set_u_init(model)
153-
154-
# --- Set objective functions --- #
155-
objective_functions = ObjectiveList()
156-
# Reshape list to track to match Bioptim's target size
157-
force_to_track = force_tracking[np.newaxis, :]
158-
objective_functions.add(
159-
ObjectiveFcn.Mayer.TRACK_STATE,
160-
key="F",
161-
target=force_to_track,
162-
node=Node.ALL,
163-
quadratic=True,
164-
)
165-
166-
return OptimalControlProgram(
167-
bio_model=[model],
168-
dynamics=dynamics,
169-
n_shooting=n_shooting,
170-
phase_time=final_time,
171-
objective_functions=objective_functions,
172-
x_init=x_init,
173-
x_bounds=x_bounds,
174-
u_bounds=u_bounds,
175-
u_init=u_init,
176-
control_type=ControlType.CONSTANT,
177-
n_threads=20,
178-
)
179-
180-
def main():
181-
final_time = 1
182-
stim = 33
183-
model = ModelMaker.create_model("ding2007",
184-
stim_time=list(np.linspace(0, 1, stim,
185-
end-point=False)))
186-
187-
# --- Building force to track ---#
188-
time = np.linspace(0, 1, 34)
189-
# Example of force to track between 10 and 150 N
190-
force = 10 + (150 - 10) * np.abs(np.sin(time * 5))
191-
force[0] = 0.0 # Ensuring the force starts at 0 N
192-
193-
ocp = prepare_ocp(model=model,
194-
final_time=final_time,
195-
pw_max=0.0006,
196-
force_tracking=force)
197-
sol = ocp.solve()
198-
199-
# --- Show the optimization results --- #
200-
sol.graphs()
201-
202-
203-
if __name__ == "__main__":
204-
main()
205-
```
206-
207-
![Tracked force (grey dots) and optimized force generated (red) by pulse width optimization (blue).](force_profile.svg)
92+
Despite its potential, optimal control–driven FES remains unadopted in clinical practice due to its low technology
93+
readiness level [@co2025optimal]. `Cocofest` is a comprehensive package designed to bridge the gaps and foster clinical
94+
adoption. It integrates nonlinear muscle dynamics dedicated to FES, manages muscle fatigue, interfaces FES with
95+
musculoskeletal models, supports customizable cost functions and parameter identification routines. With the goal of
96+
bringing this technology to patient care, we believe this package will contribute to the open-science effort. `Cocofest`
97+
is expected to accelerate the increase of technology readiness level by strengthening knowledge foundation.
98+
99+
100+
# State of the Field
101+
102+
Several open-source toolkits support optimal control computations for musculoskeletal biomechanics, such as:
103+
- `OpenSim Moco` [@dembia2020opensim], a C++ OpenSim extension that enables motion tracking and prediction using efficient
104+
direct-collocation formulations coupled to nonlinear programming solvers.
105+
- `SCONE` [@Geijtenbeek2019], a C++/C predictive-simulation environment for human and animal motion that optimizes
106+
neuromusculoskeletal controllers to achieve task-level objectives (e.g., stable walking at a target speed).
107+
- `Bioptim` [@michaud2022bioptim], a Python optimal-control framework for biomechanics that supports both direct collocation
108+
and multiple shooting, with flexible interfaces to nonlinear programming solvers.
109+
110+
However, these toolkits are not tailored for FES. They control muscle activation as a piecewise linear/constant
111+
excitation, whereas FES requires optimizing deliverable stimulation patterns under device and safety constraints. As a
112+
result, they lack reusable, validated components for the stimulation-to-force pathway and fatigue/recovery dynamics,
113+
limiting reproducible comparison of FES models and slowing translation to practical stimulation design. `Cocofest`
114+
addresses this gap by implementing published FES models that can drive musculoskeletal models. This design supports
115+
reproducible comparisons of FES modeling assumptions and accelerates prototyping of patient- and task-specific
116+
stimulation optimization. `Cocofest` also includes utilities for model identification and receding-horizon optimization
117+
to support FES research workflows.
118+
119+
120+
# Software Design
121+
122+
`Cocofest` is a Python library that relies on Biorbd, a musculoskeletal physics engine [@michaud2021biorbd], and
123+
Bioptim, an open-source optimization framework for biomechanical problems [@michaud2022bioptim]. Specifically, Bioptim
124+
enables easy OCP customization including cost functions, bounds, constraints, transcription methods (e.g., direct
125+
collocation), integration methods, and solving methods (e.g., full- and receding-horizon OCPs).
126+
127+
In conventional Hill-type muscle model, muscle force ($F_m$) is the product of $a$ the muscle activation, $F_{max}$ the
128+
maximal isometric muscle force, $f_l$ the force-length, $f_v$ the force-velocity and $f_{pas}$ the passive force-length
129+
relationship: $F_m(t) = a(t)\, F_{\max}\, f_l(\tilde{l}_m)\, f_v(\tilde{v}_m) + f_{pas}(\tilde{l}_m)$. `Cocofest`
130+
replaces $a(t)$ × $F_{max}$ by the force obtained using FES models. This approach allows motions driven-FES simulations,
131+
meanwhile benefiting from musculoskeletal model properties (e.g., muscle insertion, inertial parameters).
132+
133+
`Cocofest` was developed to maintain a consistent structure between classes and functions to facilitate the OCP
134+
customization and new FES model implementation. This shared interface promotes reproducible work and comparisons of
135+
optimal control–driven FES strategies.
136+
137+
138+
# Research Impact Statement
139+
140+
`Cocofest` was developed to address several gaps in the literature, including the lack of systematic comparisons of FES
141+
models and OCP formulations, accessible tools for FES model identification, and open-source software for reproducible
142+
research. It enables researchers to generate personalized stimulation patterns, compare alternative OCP formulations,
143+
and simulate realistic FES-driven tasks. By providing a consistent software structure and clear documentation,
144+
`Cocofest` aims to streamline research workflows and support translation toward FES rehabilitation applications.
145+
Although the project is new and targets a niche domain, it already offers a shared, reproducible environment that can
146+
foster discussion, collaboration, and broader adoption of open-source practices within the FES community, which is an
147+
important step toward clinical translation of this technique [@co2025optimal].
148+
149+
150+
# AI Usage Disclosure
151+
152+
The authors used ChatGPT only to improve the manuscript clarity and readability.
153+
After using this tool/service, the authors reviewed and edited the content as needed and took full responsibility for
154+
the content of the publication.
155+
156+
GitHub Copilot and ChatGPT were used to assist in code refactoring and documentation.
157+
Authors made all the core design and architectural decisions.
208158

209159

210160
# Acknowledgements

0 commit comments

Comments
 (0)