22
33from __future__ import annotations
44
5- import warnings
65from typing import TYPE_CHECKING
76
87import casadi as cs
98from array_api_compat import array_namespace
9+ from array_api_compat import device as xp_device
1010from scipy .spatial .transform import Rotation as R
1111
1212import drone_models .symbols as symbols
1313from drone_models .core import register_model_parameters , supports
1414from drone_models .so_rpy_rotor .params import SoRpyRotorParams
1515from drone_models .transform import motor_force2rotor_vel
16- from drone_models .utils import rotation
16+ from drone_models .utils import rotation , to_xp
1717
1818if TYPE_CHECKING :
1919 from array_api_typing import Array
@@ -54,31 +54,52 @@ def dynamics(
5454 vel: Velocity of the drone (m/s).
5555 ang_vel: Angular velocity of the drone (rad/s).
5656 cmd: Roll pitch yaw (rad) and collective thrust (N) command.
57- constants: Containing the constants of the drone.
5857 rotor_vel: Speed of the 4 motors (rad/s). If None, the commanded thrust is directly
5958 applied (not recommended). If value is given, rotor dynamics are calculated.
6059 dist_f: Disturbance force acting on the CoM (N).
6160 dist_t: Disturbance torque acting on the CoM (Nm).
6261
62+ mass: Mass of the drone (kg).
63+ gravity_vec: Gravity vector (m/s^2). We assume the gravity vector points downwards, e.g.
64+ [0, 0, -9.81].
65+ KF: Motor force constant (N/rad^2).
66+ KM: Motor torque constant (Nm/rad^2).
67+ J: Inertia matrix (kg m^2).
68+ J_inv: Inverse inertia matrix (1/kg m^2).
69+ rotor_coef: Coefficient for the rotor dynamics (1/s).
70+ acc_coef: Coefficient for the acceleration (1/s^2).
71+ cmd_f_coef: Coefficient for the collective thrust (N/rad^2).
72+ rpy_coef: Coefficient for the roll pitch yaw dynamics (1/s).
73+ rpy_rates_coef: Coefficient for the roll pitch yaw rates dynamics (1/s^2).
74+ cmd_rpy_coef: Coefficient for the roll pitch yaw command dynamics (1/s).
75+
6376 Returns:
6477 tuple[Array, Array, Array, Array, Array | None]: _description_
6578 """
6679 xp = array_namespace (pos )
80+ # Convert constants to the correct framework and device
81+ device = xp_device (pos )
82+ mass , gravity_vec , KF , KM , J , J_inv = to_xp (
83+ mass , gravity_vec , KF , KM , J , J_inv , xp = xp , device = device
84+ )
85+ rotor_coef , acc_coef , cmd_f_coef = to_xp (rotor_coef , acc_coef , cmd_f_coef , xp = xp , device = device )
86+ rpy_coef , rpy_rates_coef , cmd_rpy_coef = to_xp (
87+ rpy_coef , rpy_rates_coef , cmd_rpy_coef , xp = xp , device = device
88+ )
89+
6790 cmd_f = cmd [..., - 1 ]
6891 cmd_rotor_vel = motor_force2rotor_vel (cmd_f / 4 , KF )
6992 cmd_rpy = cmd [..., 0 :3 ]
7093 rot = R .from_quat (quat )
7194 euler_angles = rot .as_euler ("xyz" )
7295
7396 if rotor_vel is None :
74- rotor_vel_dot = None
75- rotor_vel = cmd_rotor_vel
76- warnings .warn ("Rotor velocity is not provided, using commanded rotor velocity directly." )
97+ rotor_vel , rotor_vel_dot = cmd_rotor_vel [..., None ], None
7798 else :
7899 rotor_vel_dot = 1 / rotor_coef * (cmd_rotor_vel [..., None ] - rotor_vel ) - KM * rotor_vel ** 2
79- forces_motor = xp . sum ( KF * rotor_vel ** 2 , axis = - 1 )
80- forces_sum = xp .sum (forces_motor , axis = - 1 )
81- thrust = acc_coef + cmd_f_coef * forces_sum
100+
101+ forces_motor = KF * xp .sum (rotor_vel ** 2 , axis = - 1 )
102+ thrust = acc_coef + cmd_f_coef * forces_motor
82103
83104 drone_z_axis = rot .as_matrix ()[..., - 1 ]
84105
@@ -98,11 +119,11 @@ def dynamics(
98119 # adding torque disturbances to the state
99120 # angular acceleration can be converted to total torque given the inertia matrix
100121 torque = ang_vel_dot @ J .mT + xp .linalg .cross (ang_vel , ang_vel @ J .mT )
101-
102122 # adding torque
103123 torque = torque + rot .apply (dist_t , inverse = True ) # TODO rotation into body frame
104124 # back to angular acceleration
105- ang_vel_dot = J_inv @ (torque - xp .linalg .cross (ang_vel , J @ ang_vel ))
125+ torque = torque - xp .linalg .cross (ang_vel , (J @ ang_vel [..., None ])[..., 0 ])
126+ ang_vel_dot = (J_inv @ torque [..., None ])[..., 0 ]
106127
107128 return pos_dot , quat_dot , vel_dot , ang_vel_dot , rotor_vel_dot
108129
0 commit comments