You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5e53832
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/examples/index.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -62,9 +62,9 @@ Because the simulator is built entirely from JAX operations, `jax.grad` can diff
62
62
63
63
---
64
64
65
-
## Gradients and state clipping
65
+
## Gradients and command clipping
66
66
67
-
Hard state clips such as the `clip_rotor_vel` stage zero the gradients while the state is saturated. This example ramps a motor command beyond the rotor limits and compares the rotor state and the gradient of the vertical acceleration w.r.t. the command for three options: the default clip, a straight-through clip (clipped forward pass, unclipped gradients), and no clip. Replacing the default clip with the straight-through variant can help gradient-based methods such as trajectory optimization or policy learning, which would otherwise receive zero gradients whenever the motors saturate.
67
+
Hard clips such as the `clip_rotor_vel_cmd` stage zero the gradients while the command is saturated. This example ramps a motor command beyond the rotor limits and compares the rotor state and the gradient of the vertical acceleration w.r.t. the command for three options: the default clip, a straight-through clip (clipped forward pass, unclipped gradients), and no clip. Replacing the default clip with the straight-through variant can help gradient-based methods such as trajectory optimization or policy learning, which would otherwise receive zero gradients whenever the motors saturate.
68
68
69
69
<!-- notest: imported script, covered by tests/integration/test_examples.py -->
Copy file name to clipboardExpand all lines: docs/user-guide/oo-api.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,6 +44,9 @@ Key constructor arguments:
44
44
45
45
See [`Sim`][crazyflow.sim.Sim] in the API reference for the defaults and the full argument list.
46
46
47
+
!!! warning "Low simulation frequencies"
48
+
Explicit integrators are only stable if the step is small compared to the fastest time constant of the dynamics. For the drone models this is the rotor dynamics with time constants down to 20 ms. Euler overshoots once the step exceeds the time constant and diverges beyond twice the time constant. Keep `freq` well above 100 Hz.
49
+
47
50
## Control methods
48
51
49
52
All control methods take an array of shape `(n_worlds, n_drones, command_dim)` and stage it for the next `step` call.
Copy file name to clipboardExpand all lines: docs/user-guide/pipelines.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,19 +22,22 @@ Both pipelines are constructed at `Sim` initialisation and compiled into a singl
22
22
`sim.step_pipeline` contains multiple stages by default:
23
23
24
24
1.**Control functions** — convert the staged command through the control hierarchy (state → attitude → force/torque → rotor velocities, depending on the selected mode)
25
-
2.**Integrator** (`integration`) — advance the ODE one dynamics step (Euler, RK4, or symplectic Euler)
26
-
3.**Rotor clip** (`clip_rotor_vel`) — clip the motor speeds (first principles) or the collective thrust (fitted models) to the physical limits of the motors
5.**Floor clip** (`clip_floor_pos`) — prevent drones from passing through the floor
25
+
2.**Rotor command clip** (`clip_rotor_vel_cmd`) — clip the commanded motor speeds (first principles) or collective thrust (so_rpy models) to the physical limits of the motors
26
+
3.**Integrator** (`integration`) — advance the ODE one dynamics step (Euler, RK4, or symplectic Euler)
27
+
4.**Floor clip** (`clip_floor_pos`) — prevent drones from passing through the floor
We only clip the command, not the rotor state. Real motors deviate from their nominal thrust curve, and randomized motor parameters model exactly that, so the state has to be free to exceed the nominal limits. The command is always saturated, as it is on the real drone.
40
+
38
41
## The reset pipeline
39
42
40
43
`sim.reset_pipeline` holds a single `reset` stage that restores `SimData` to the default state. Every stage appended after it runs in order on the restored data. Each reset stage has the signature `(data: SimData, default_data: SimData, mask: Array | None) -> SimData`. The `default_data` argument holds the freshly-restored default state, which is useful for selectively reverting fields.
The rotor limits are enforced by the `clip_rotor_vel` stage, which clips the rotor state after each integration step. Higher order integration methods like RK4 evaluate the dynamics at intermediate, unclipped states, so the `rotor_vel` seen by the model can transiently exceed the limits within a single step.
136
-
137
137
## Writing a custom stage
138
138
139
139
A step pipeline function must have the signature `(SimData) -> SimData`. A reset pipeline function must have the signature `(SimData, SimData, Array | None) -> SimData` where the second argument is the default (freshly-restored) data. Both must be pure JAX functions with no Python-level side effects, so they can be traced and compiled.
Each call to `sim.step()` runs `sim.step_pipeline`, an ordered collection of named, pure JAX functions that transform `SimData`. By default it contains the control conversion functions, the numerical integrator, a clip of the rotor state to the physical motor limits, a step counter, and a floor clip. Similarly, `sim.reset_pipeline` is applied during `sim.reset()` and is empty by default.
86
+
Each call to `sim.step()` runs `sim.step_pipeline`, an ordered collection of named, pure JAX functions that transform `SimData`. By default it contains the control conversion functions, a clip of the rotor command to the physical motor limits, the numerical integrator, a floor clip, and a step counter. Similarly, `sim.reset_pipeline` is applied during `sim.reset()` and is empty by default.
87
87
88
88
Both pipelines can be extended with custom functions for disturbances, domain randomization, or logging without modifying the core simulator.
0 commit comments