Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6038c7d
Torque driven predictive gait simulation.
moorepants Oct 16, 2025
fc968ae
Removed control flow for old matplotlib.
moorepants Oct 16, 2025
c53ceba
Commit before trying muscles.
moorepants Oct 16, 2025
ab58d96
Add cyipopt for opty.
moorepants Oct 23, 2025
7c545df
Adjust h bounds.
moorepants Oct 23, 2025
e149eb0
Add back random initial guess and bump up torque bounds.
moorepants Oct 28, 2025
17f2298
Simpler extraction of torques.
moorepants Feb 1, 2026
4a8567d
Fixed merge conflict.
moorepants Feb 1, 2026
b575bac
Enable sphinx gallery.
moorepants Feb 1, 2026
264ec55
Pull constants from new location.
moorepants Feb 1, 2026
e6c2a14
Added a gallery header file for examples.
moorepants Feb 1, 2026
1af5eaa
Use prior version of SciPy.
moorepants Feb 1, 2026
d184aec
Try earlier numpy version.
moorepants Feb 1, 2026
18801c0
Make sure output of objectie is a scalar.
moorepants Feb 1, 2026
029bdfa
Remove numpy and scipy pins.
moorepants Feb 1, 2026
096dda8
Cleaned up some text and duplicate code.
moorepants Feb 1, 2026
5af6239
Use the pygait2d animation function in the example.
moorepants Feb 3, 2026
be554d8
Set x and y limits on animation in example.
moorepants Feb 3, 2026
2a09bc0
Add examples to index page.
moorepants Feb 3, 2026
19ceb99
Add some options for the html theme.
moorepants Feb 3, 2026
56dc86c
Rename the example file.
moorepants Feb 3, 2026
4b67f98
Rename run.py to be a sphinx gallery example.
moorepants Feb 3, 2026
5b7ddfc
Prep for example and move pydy viz to notebook.
moorepants Feb 3, 2026
ead2efd
Use an xlimit also to keep equal aspect.
moorepants Feb 3, 2026
358f8c2
Add ability to follow the x location of a point in the animation.
moorepants Feb 3, 2026
04cd9e2
Fix merge conflict.
moorepants Feb 3, 2026
536e60c
Add pydy/autolev comparison to forward simulation example.
moorepants Feb 4, 2026
a2511f6
Spelling and formatting fixes.
moorepants Feb 4, 2026
30080b5
Merge branch 'master' into torque-driven-predictive
moorepants Feb 4, 2026
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
25 changes: 24 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import algait2de
import pygait2d

DOCS_CONF_PATH = os.path.realpath(__file__)
DOCS_DIR = os.path.dirname(DOCS_CONF_PATH)
REPO_DIR = os.path.realpath(os.path.join(DOCS_DIR, '..'))

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

Expand All @@ -27,7 +31,7 @@
'sphinx.ext.mathjax',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
#'sphinx_gallery.gen_gallery',
'sphinx_gallery.gen_gallery',
]

templates_path = ['_templates']
Expand All @@ -43,5 +47,24 @@
html_theme = 'alabaster'
html_static_path = ['_static']

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'github_repo': 'gait2d',
'github_type': 'star',
'github_user': 'csu-hmc',
'page_width': '1080px', # 960 doesn't show 79 linewidth examples
}

# Display long function signatures better.
maximum_signature_line_length = 50

# -- sphinx-gallery settings --------------------------------------------------
sphinx_gallery_conf = {
'examples_dirs': os.path.join(REPO_DIR, 'examples'),
'gallery_dirs': 'examples',
'matplotlib_animations': True,
'remove_config_comments': True,
}
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Gait2D documentation
:maxdepth: 2
:caption: Contents:

examples/index.rst
api.rst

.. include:: ../README.rst
3 changes: 3 additions & 0 deletions examples/GALLERY_HEADER.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
========
Examples
========
17 changes: 16 additions & 1 deletion examples/animate.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@
"run run.py"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "56e6819d-3a31-44e9-a135-79f35f04c6cf",
"metadata": {},
"outputs": [],
"source": [
"from pydy.viz import Scene\n",
"scene = Scene(symbolics.inertial_frame, symbolics.origin, *symbolics.viz_frames)\n",
"scene.states_symbols = symbolics.states\n",
"scene.constants = constant_values\n",
"scene.states_trajectories = trajectories\n",
"scene.times = time_vector"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -37,7 +52,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.5"
"version": "3.14.2"
}
},
"nbformat": 4,
Expand Down
File renamed without changes.
101 changes: 101 additions & 0 deletions examples/plot_forward_sim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""
Forward Simulation
==================

This example simulates and visualizes the uncontrolled motion of the model such
that the model falls down on the treadmill. It also compares the evaluation
speed of PyDy's and Autolev's models.
"""
import timeit

from algait2de.gait2de import evaluate_autolev_rhs
from pydy.codegen.ode_function_generators import generate_ode_function
from pygait2d import derive, simulate
from pygait2d import utils
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import numpy as np
import sympy as sm
import yaml

# %%
# Derive the equations of motion, including a constant treadmill motion.
symbolics = derive.derive_equations_of_motion(treadmill=True)

# %%
# Load a parameter mapping from pygait2d symbol to numerical value, as well as
# a mappig of the symbol string to numerical value.
try:
par_map = simulate.load_constants(symbolics.constants,
'example_constants.yml')
with open('example_constants.yml', 'r') as f:
constants_dict = yaml.load(f, Loader=yaml.SafeLoader)
except FileNotFoundError:
par_map = simulate.load_constants(symbolics.constants,
'examples/example_constants.yml')
with open('examples/example_constants.yml', 'r') as f:
constants_dict = yaml.load(f, Loader=yaml.SafeLoader)

# %%
# Use PyDy to generate a function that can evaluate the right hand side of the
# ordinary differential equations of the multibody system. This uses PyDy's
# code geenration settings that result in the fastest numerical evaluation
# times at the cost of a slower code generation and compilation time.
rhs = generate_ode_function(
symbolics.kanes_method.forcing,
symbolics.coordinates,
symbolics.speeds,
constants=list(par_map.keys()),
mass_matrix=symbolics.kanes_method.mass_matrix,
coordinate_derivatives=sm.Matrix(symbolics.speeds),
specifieds=symbolics.specifieds,
generator='cython',
linear_sys_solver='sympy',
constants_arg_type='array',
specifieds_arg_type='array',
)

# %%
# Prepare numerical arrays to be passed to the ODE functions.
specifieds_vals = np.zeros(len(symbolics.specifieds))
specifieds_vals[-1] = 1.0

args = (specifieds_vals, np.array(list(par_map.values())))

initial_conditions = np.zeros(len(symbolics.states))
initial_conditions[1] = 1.0 # set hip above ground
initial_conditions[3] = np.deg2rad(5.0) # right hip angle
initial_conditions[6] = -np.deg2rad(5.0) # left hip angle

# %%
# Time the average execution of PyDy's ODE function evaluation.
print('PyDy evaluation time:',
timeit.timeit(lambda: rhs(initial_conditions, 0.0, *args), number=1000))

# %%
# Time the average execution of Autolev s ODE function evaluation.
autolev_constants_dict = simulate.map_values_to_autolev_symbols(constants_dict)
print('Autolev evaluation time:',
timeit.timeit(lambda: evaluate_autolev_rhs(initial_conditions[:9],
initial_conditions[9:],
specifieds_vals,
autolev_constants_dict),
number=1000))

# %%
# Simulate the model for two seconds using the LSODA integrator (switches
# between stiff and non-stiff modes).
time_vector = np.linspace(0.0, 2.0, num=61)
trajectories = odeint(rhs, initial_conditions, time_vector, args=args)

# %%
# Visualization of the resulting motion from the forward simulation.
scene, fig, ax = utils.plot(symbolics, time_vector, initial_conditions,
args[0], args[1])
ax.set_xlim((-0.8, 0.8))
ax.set_ylim((-0.2, 1.4))
ani = utils.animate(scene, fig, time_vector, trajectories,
np.zeros((len(time_vector), len(symbolics.specifieds))),
args[1])

plt.show()
Loading
Loading