Skip to content

Commit 35b0c9b

Browse files
committed
Update docs.
Signed-off-by: James Goppert <james.goppert@gmail.com>
1 parent a5eea9b commit 35b0c9b

File tree

6 files changed

+46
-13
lines changed

6 files changed

+46
-13
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,13 @@ model = model.simulate(0.0, 10.0, 0.01)
7878
# Output:
7979
# Final position: -0.529209
8080
# Final velocity: 0.323980
81-
# Access via: model.trajectory.x.x[0, -1] (position)
82-
# model.trajectory.x.v[0, -1] (velocity)
81+
# Access via: model.trajectory.x.x[-1] (final position)
82+
# model.trajectory.x.v[-1] (final velocity)
83+
# model.trajectory.x.x (full position trajectory, shape: n_steps)
8384
#
8485
# To compute outputs during simulation (optional, costs performance):
8586
# model = model.simulate(0.0, 10.0, 0.01, compute_output=True)
86-
# model.trajectory.y.position[0, :] # output trajectory
87+
# model.trajectory.y.position # output trajectory
8788
```
8889

8990
## Documentation

cyecca/dynamics/composition.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,29 @@ def to_path_string(sig):
240240
self._input_connections[target_model] = {}
241241
self._input_connections[target_model][target_str] = source_str
242242

243+
def get_connections(self, target_model: str = None):
244+
"""Get input connections for a submodel.
245+
246+
Args:
247+
target_model: Name of the target submodel. If None, returns all connections.
248+
249+
Returns:
250+
dict: Dictionary mapping target signals to source signals.
251+
If target_model is None, returns nested dict {model: {target: source}}.
252+
253+
Example:
254+
>>> parent.connect("child2.u.u", "child1.y.y") # doctest: +SKIP
255+
>>> parent.get_connections("child2") # doctest: +SKIP
256+
{'child2.u.u': 'child1.y.y'}
257+
"""
258+
if not hasattr(self, "_input_connections"):
259+
return {} if target_model is None else {}
260+
261+
if target_model is None:
262+
return dict(self._input_connections)
263+
264+
return dict(self._input_connections.get(target_model, {}))
265+
243266
def build_composed(self, integrator: str = "rk4", integrator_options: dict = None):
244267
"""Build a composed model from added submodels.
245268

cyecca/dynamics/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class Trajectory(Generic[TStateTrajectory, TDiscreteStateTrajectory, TDiscreteVa
191191
-------
192192
>>> model = model.simulate(0, 10, 0.01) # doctest: +SKIP
193193
>>> traj = model.trajectory # doctest: +SKIP
194-
>>> plt.plot(traj.t, traj.x.p) # Plot all position components # doctest: +SKIP
194+
>>> plt.plot(traj.t, traj.x.p) # Plot all position components (n_steps, dim) # doctest: +SKIP
195195
"""
196196

197197
t: np.ndarray = field(default_factory=lambda: np.array([]))
@@ -1251,7 +1251,7 @@ def trajectory(self) -> Trajectory:
12511251
Example
12521252
-------
12531253
>>> model = model.simulate(0, 10, 0.01) # doctest: +SKIP
1254-
>>> plt.plot(model.trajectory.t, model.trajectory.x.p[0, :]) # doctest: +SKIP
1254+
>>> plt.plot(model.trajectory.t, model.trajectory.x.p) # doctest: +SKIP
12551255
"""
12561256
if not hasattr(self, '_trajectory'):
12571257
if hasattr(self, '_sim_history'):

docs/user_guide/modeling.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,14 @@ Example: Bouncing ball with restitution coefficient
106106
f_m = ca.vertcat(x.h, -0.8 * x.v)
107107
108108
model.build(f_x=f_x, f_c=f_c, f_m=f_m)
109-
result = model.simulate(0, 10, 0.01, detect_events=True)
109+
model = model.simulate(0, 10, 0.01, detect_events=True)
110+
111+
# Access results via trajectory attribute
112+
traj = model.trajectory
113+
# traj.t - time points
114+
# traj.x.h - height trajectory
115+
# traj.x.v - velocity trajectory
116+
# traj.z.bounces - discrete state trajectory
110117
111118
Linearization & Analysis
112119
------------------------

docs/user_guide/quickstart.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ Build a simple mass-spring-damper system:
5353
model.build(f_x=f_x, integrator='rk4')
5454
5555
# Simulate (uses default initial conditions from States/Inputs/Params)
56-
result = model.simulate(t0=0.0, tf=10.0, dt=0.01)
56+
model = model.simulate(t0=0.0, tf=10.0, dt=0.01)
5757
58-
# Plot results
58+
# Plot results - access via trajectory attribute
5959
import matplotlib.pyplot as plt
60-
plt.plot(result['t'], result['x'][0, :], label='position')
61-
plt.plot(result['t'], result['x'][1, :], label='velocity')
60+
traj = model.trajectory
61+
plt.plot(traj.t, traj.x.x, label='position') # shape: (n_steps,)
62+
plt.plot(traj.t, traj.x.v, label='velocity') # shape: (n_steps,)
6263
plt.legend()
6364
plt.show()
6465

test/test_dynamics.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,9 +754,10 @@ class Outputs:
754754
# Test connection API using string paths
755755
parent.connect("child2.u.u", "child1.y.y")
756756

757-
# Verify connection was stored
758-
assert "child2" in parent._input_connections
759-
assert "child2.u.u" in parent._input_connections["child2"]
757+
# Verify connection was stored using public API
758+
connections = parent.get_connections("child2")
759+
assert "child2.u.u" in connections
760+
assert connections["child2.u.u"] == "child1.y.y"
760761

761762

762763
class TestIntegrators:

0 commit comments

Comments
 (0)