Skip to content

Commit 759d2cc

Browse files
committed
Rename dynamics file, simplify so_rpy model, simplify models wrapper
1 parent 45a46b6 commit 759d2cc

10 files changed

Lines changed: 12 additions & 67 deletions

File tree

crazyflow/dynamics/core.py

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44

55
import inspect
66
import tomllib
7-
import warnings
87
from enum import Enum
9-
from functools import partial, wraps
8+
from functools import partial
109
from pathlib import Path
1110
from typing import TYPE_CHECKING, Any, Callable, ParamSpec, TypeVar
1211

@@ -15,8 +14,6 @@
1514
if TYPE_CHECKING:
1615
from types import ModuleType
1716

18-
from crazyflow._typing import Array # To be changed to array_api_typing later
19-
2017

2118
F = TypeVar("F", bound=Callable[..., Any])
2219
P = ParamSpec("P")
@@ -26,14 +23,7 @@
2623
def supports(rotor_dynamics: bool = True) -> Callable[[F], F]:
2724
"""Decorator that declares which optional inputs a dynamics function supports.
2825
29-
Wraps the decorated function so that:
30-
31-
* If ``rotor_dynamics=False`` and the caller passes ``rotor_vel``, a ``ValueError`` is raised
32-
immediately.
33-
* If ``rotor_dynamics=True`` and the caller omits ``rotor_vel``, a ``UserWarning`` is issued and
34-
the commanded value is used directly.
35-
36-
The decorator also attaches a ``__dynamics_features__`` attribute to the wrapper, which
26+
The decorator attaches a ``__dynamics_features__`` attribute to the wrapper, which
3727
[dynamics_features][crazyflow.dynamics.dynamics_features] reads.
3828
3929
Args:
@@ -42,30 +32,12 @@ def supports(rotor_dynamics: bool = True) -> Callable[[F], F]:
4232
Defaults to ``True``.
4333
4434
Returns:
45-
A decorator that wraps the dynamics function with the capability checks.
35+
The function decorated with capability flags.
4636
"""
4737

4838
def decorator(fn: F) -> F:
49-
@wraps(fn)
50-
def wrapper(
51-
pos: Array,
52-
quat: Array,
53-
vel: Array,
54-
ang_vel: Array,
55-
cmd: Array,
56-
rotor_vel: Array | None = None,
57-
*args: Any,
58-
**kwargs: Any,
59-
) -> tuple[Array, Array, Array, Array, Array | None]:
60-
if not rotor_dynamics and rotor_vel is not None:
61-
raise ValueError("Rotor dynamics not supported, but rotor_vel is provided.")
62-
if rotor_dynamics and rotor_vel is None:
63-
warnings.warn("Rotor velocity not provided, using commanded rotor velocity.")
64-
return fn(pos, quat, vel, ang_vel, cmd, rotor_vel, *args, **kwargs)
65-
66-
wrapper.__dynamics_features__ = {"rotor_dynamics": rotor_dynamics}
67-
68-
return wrapper # type: ignore
39+
fn.__dynamics_features__ = {"rotor_dynamics": rotor_dynamics}
40+
return fn
6941

7042
return decorator
7143

crazyflow/dynamics/first_principles/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
moment of inertia, \(M\) is the \(3\times 4\) mixing matrix, and \(\mathbf{m}_z\) is its last row.
8383
"""
8484

85-
from crazyflow.dynamics.first_principles.model import (
85+
from crazyflow.dynamics.first_principles.dynamics import (
8686
Params,
8787
dynamics,
8888
sim_dynamics,
File renamed without changes.

crazyflow/dynamics/so_rpy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
\(c_{\dot{\psi}}\), \(c_u\) are identified from flight data.
2727
"""
2828

29-
from crazyflow.dynamics.so_rpy.model import (
29+
from crazyflow.dynamics.so_rpy.dynamics import (
3030
Params,
3131
dynamics,
3232
sim_dynamics,
Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
from __future__ import annotations
1515

16-
import logging
1716
from typing import TYPE_CHECKING
1817

1918
import casadi as cs
@@ -41,7 +40,6 @@ def dynamics(
4140
vel: Array,
4241
ang_vel: Array,
4342
cmd: Array,
44-
rotor_vel: Array | None = None,
4543
dist_f: Array | None = None,
4644
dist_t: Array | None = None,
4745
*,
@@ -63,7 +61,6 @@ def dynamics(
6361
vel: Velocity of the drone (m/s).
6462
ang_vel: Angular velocity of the drone (rad/s).
6563
cmd: Roll pitch yaw (rad) and collective thrust (N) command.
66-
rotor_vel: Speed of the 4 motors (RPMs). Kept for compatibility with the dynamics signature.
6764
dist_f: Disturbance force (N) in the world frame acting on the CoM.
6865
dist_t: Disturbance torque (Nm) in the world frame acting on the CoM.
6966
@@ -92,9 +89,7 @@ def dynamics(
9289
rot = R.from_quat(quat)
9390
euler_angles = rot.as_euler("xyz")
9491

95-
rotor_vel_dot = None
9692
thrust = acc_coef + cmd_f_coef * cmd_f
97-
9893
drone_z_axis = rot.as_matrix()[..., -1]
9994

10095
pos_dot = vel
@@ -121,11 +116,10 @@ def dynamics(
121116
torque = torque - xp.linalg.cross(ang_vel, (J @ ang_vel[..., None])[..., 0])
122117
ang_vel_dot = (J_inv @ torque[..., None])[..., 0]
123118

124-
return pos_dot, quat_dot, vel_dot, ang_vel_dot, rotor_vel_dot
119+
return pos_dot, quat_dot, vel_dot, ang_vel_dot
125120

126121

127122
def symbolic_dynamics(
128-
model_rotor_vel: bool = False,
129123
model_dist_f: bool = False,
130124
model_dist_t: bool = False,
131125
*,
@@ -147,9 +141,6 @@ def symbolic_dynamics(
147141
[symbolic_dynamics][crazyflow.dynamics.first_principles.symbolic_dynamics].
148142
149143
Args:
150-
model_rotor_vel: If ``True``, a scalar rotor-velocity state is appended to ``X`` (for
151-
interface compatibility only — ``so_rpy`` has no thrust dynamics and will log a
152-
warning). Defaults to ``False``.
153144
model_dist_f: If ``True``, a 3-D force disturbance is appended to ``X``.
154145
model_dist_t: If ``True``, a 3-D torque disturbance is appended to ``X``.
155146
mass: Drone mass in kg.
@@ -178,11 +169,8 @@ def symbolic_dynamics(
178169
symbols.rpy = _rpy_quat
179170
symbols.drpy = _drpy_quat
180171
X_dot_euler, X_euler, U_euler, Y_euler = symbolic_dynamics_euler(
181-
model_rotor_vel=model_rotor_vel,
182172
mass=mass,
183173
gravity_vec=gravity_vec,
184-
J=J,
185-
J_inv=J_inv,
186174
acc_coef=acc_coef,
187175
cmd_f_coef=cmd_f_coef,
188176
rpy_coef=rpy_coef,
@@ -194,9 +182,6 @@ def symbolic_dynamics(
194182

195183
# States and Inputs
196184
X = cs.vertcat(symbols.pos, symbols.quat, symbols.vel, symbols.ang_vel)
197-
if model_rotor_vel:
198-
logging.getLogger(__name__).warning("so_rpy dynamics do not support thrust dynamics")
199-
X = cs.vertcat(X, symbols.rotor_vel)
200185
if model_dist_f:
201186
X = cs.vertcat(X, symbols.dist_f)
202187
if model_dist_t:
@@ -234,12 +219,9 @@ def symbolic_dynamics(
234219

235220

236221
def symbolic_dynamics_euler(
237-
model_rotor_vel: bool = False,
238222
*,
239223
mass: float,
240224
gravity_vec: Array,
241-
J: Array,
242-
J_inv: Array,
243225
acc_coef: Array,
244226
cmd_f_coef: Array,
245227
rpy_coef: Array,
@@ -253,12 +235,8 @@ def symbolic_dynamics_euler(
253235
inside CasADi-based solvers.
254236
255237
Args:
256-
model_rotor_vel: If ``True``, a scalar rotor-velocity state is appended
257-
to ``X`` for interface compatibility (no dynamics are modelled).
258238
mass: Drone mass in kg.
259239
gravity_vec: Gravity vector, shape ``(3,)``.
260-
J: Inertia matrix, shape ``(3, 3)``.
261-
J_inv: Inverse inertia matrix, shape ``(3, 3)``.
262240
acc_coef: Scalar acceleration offset coefficient.
263241
cmd_f_coef: Collective-thrust-to-acceleration coefficient.
264242
rpy_coef: RPY state feedback coefficient, shape ``(3,)``.
@@ -275,9 +253,6 @@ def symbolic_dynamics_euler(
275253
"""
276254
# States and Inputs
277255
X = cs.vertcat(symbols.pos, symbols.rpy, symbols.vel, symbols.drpy)
278-
if model_rotor_vel:
279-
logging.getLogger(__name__).warning("so_rpy dynamics do not support thrust dynamics")
280-
X = cs.vertcat(X, symbols.rotor_vel)
281256
U = symbols.cmd_rpyt
282257
cmd_rpy = U[:3]
283258
cmd_thrust = U[-1]
@@ -351,7 +326,7 @@ def create(n_worlds: int, n_drones: int, drone: str, device: Device) -> Params:
351326
def sim_dynamics(data: SimData) -> SimData:
352327
"""Compute the forces and torques from the so_rpy dynamics."""
353328
params: Params = data.params
354-
vel, _, acc, ang_acc, _ = dynamics(
329+
vel, _, acc, ang_acc = dynamics(
355330
pos=data.states.pos,
356331
quat=data.states.quat,
357332
vel=data.states.vel,

crazyflow/dynamics/so_rpy_rotor/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
\(R = {}^{\mathcal{I}}R_{\mathcal{B}}(\mathbf{q})\) is the rotation from body to world frame.
2727
"""
2828

29-
from crazyflow.dynamics.so_rpy_rotor.model import (
29+
from crazyflow.dynamics.so_rpy_rotor.dynamics import (
3030
Params,
3131
dynamics,
3232
sim_dynamics,
File renamed without changes.

crazyflow/dynamics/so_rpy_rotor_drag/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
\(D_b\) is the diagonal body-frame aerodynamic drag matrix.
2929
"""
3030

31-
from crazyflow.dynamics.so_rpy_rotor_drag.model import (
31+
from crazyflow.dynamics.so_rpy_rotor_drag.dynamics import (
3232
Params,
3333
dynamics,
3434
sim_dynamics,
File renamed without changes.

crazyflow/sim/symbolic.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ def symbolic_from_sim(
4040
)
4141
case Dynamics.so_rpy:
4242
return parametrize(so_rpy_symbolic_dynamics, sim.drone)(
43-
model_rotor_vel=model_rotor_vel,
44-
model_dist_f=model_dist_f,
45-
model_dist_t=model_dist_t,
43+
model_dist_f=model_dist_f, model_dist_t=model_dist_t
4644
)
4745
case _:
4846
raise ValueError(f"Dynamics mode {sim.dynamics} not supported")

0 commit comments

Comments
 (0)