1818if TYPE_CHECKING :
1919 from array_api_typing import Array
2020
21- from drone_models .utils .constants import Constants
22-
2321
2422@register_model_parameters (SoRpyRotorParams )
2523@supports (rotor_dynamics = True )
@@ -35,10 +33,10 @@ def dynamics(
3533 * ,
3634 mass : float ,
3735 gravity_vec : Array ,
38- KF : Array ,
39- KM : Array ,
4036 J : Array ,
4137 J_inv : Array ,
38+ KF : Array ,
39+ KM : Array ,
4240 rotor_coef : Array ,
4341 acc_coef : Array ,
4442 cmd_f_coef : Array ,
@@ -62,10 +60,10 @@ def dynamics(
6260 mass: Mass of the drone (kg).
6361 gravity_vec: Gravity vector (m/s^2). We assume the gravity vector points downwards, e.g.
6462 [0, 0, -9.81].
65- KF: Motor force constant (N/rad^2).
66- KM: Motor torque constant (Nm/rad^2).
6763 J: Inertia matrix (kg m^2).
6864 J_inv: Inverse inertia matrix (1/kg m^2).
65+ KF: Motor force constant (N/rad^2).
66+ KM: Motor torque constant (Nm/rad^2).
6967 rotor_coef: Coefficient for the rotor dynamics (1/s).
7068 acc_coef: Coefficient for the acceleration (1/s^2).
7169 cmd_f_coef: Coefficient for the collective thrust (N/rad^2).
@@ -118,54 +116,71 @@ def dynamics(
118116 if dist_t is not None :
119117 # adding torque disturbances to the state
120118 # angular acceleration can be converted to total torque given the inertia matrix
121- torque = ang_vel_dot @ J .mT + xp .linalg .cross (ang_vel , ang_vel @ J .mT )
122- # adding torque
123- torque = torque + rot .apply (dist_t , inverse = True ) # TODO rotation into body frame
119+ torque = (J @ ang_vel_dot [..., None ])[..., 0 ]
120+ torque = torque + xp .linalg .cross (ang_vel , (J @ ang_vel [..., None ])[..., 0 ])
121+ # adding torque. TODO: This should be a linear transformation. Can't we just transform the
122+ # disturbance torque to an ang_vel_dot summand directly?
123+ torque = torque + rot .apply (dist_t , inverse = True )
124124 # back to angular acceleration
125125 torque = torque - xp .linalg .cross (ang_vel , (J @ ang_vel [..., None ])[..., 0 ])
126126 ang_vel_dot = (J_inv @ torque [..., None ])[..., 0 ]
127127
128128 return pos_dot , quat_dot , vel_dot , ang_vel_dot , rotor_vel_dot
129129
130130
131- def dynamics_symbolic (
132- constants : Constants ,
133- calc_rotor_vel : bool = False ,
134- calc_dist_f : bool = False ,
135- calc_dist_t : bool = False ,
131+ @register_model_parameters (SoRpyRotorParams )
132+ def symbolic_dynamics (
133+ model_rotor_vel : bool = False ,
134+ model_dist_f : bool = False ,
135+ model_dist_t : bool = False ,
136+ * ,
137+ mass : float ,
138+ gravity_vec : Array ,
139+ J : Array ,
140+ J_inv : Array ,
141+ KF : Array ,
142+ KM : Array ,
143+ rotor_coef : Array ,
144+ acc_coef : Array ,
145+ cmd_f_coef : Array ,
146+ rpy_coef : Array ,
147+ rpy_rates_coef : Array ,
148+ cmd_rpy_coef : Array ,
136149) -> tuple [cs .MX , cs .MX , cs .MX , cs .MX ]:
137150 """The fitted double integrator (DI) model with optional motor delay (D).
138151
139152 TODO.
140153 """
141154 # States and Inputs
142155 X = cs .vertcat (symbols .pos , symbols .quat , symbols .vel , symbols .ang_vel )
143- if calc_rotor_vel :
156+ if model_rotor_vel :
144157 X = cs .vertcat (X , symbols .rotor_vel )
145- if calc_dist_f :
158+ if model_dist_f :
146159 X = cs .vertcat (X , symbols .dist_f )
147- if calc_dist_t :
160+ if model_dist_t :
148161 X = cs .vertcat (X , symbols .dist_t )
149162 U = cs .vertcat (symbols .cmd_roll , symbols .cmd_pitch , symbols .cmd_yaw , symbols .cmd_thrust )
150163 cmd_rpy = cs .vertcat (symbols .cmd_roll , symbols .cmd_pitch , symbols .cmd_yaw )
151164
152165 # Defining the dynamics function
153- if calc_rotor_vel :
166+ if model_rotor_vel :
154167 # motor_force2rotor_vel
155- cmd_rotor_vel = cs .sqrt (symbols .cmd_thrust / 4 / constants .KF )
156- rotor_vel_dot = 1 / constants .DI_D_ACC [2 ] * (cmd_rotor_vel - symbols .rotor_vel )
157- thrust = constants .KF * cs .sum1 (symbols .rotor_vel ** 2 )
168+ cmd_rotor_vel = cs .sqrt (symbols .cmd_thrust / 4 / KF )
169+ rotor_vel_dot = (
170+ 1 / rotor_coef * (cmd_rotor_vel - symbols .rotor_vel ) - KM * symbols .rotor_vel ** 2
171+ )
172+ forces_motor = KF * cs .sum1 (symbols .rotor_vel ** 2 )
158173 else :
159- thrust = symbols .cmd_thrust
174+ forces_motor = symbols .cmd_thrust
160175 # Creating force vector
161- forces_motor_vec = cs .vertcat (0 , 0 , constants . DI_D_ACC [ 0 ] + constants . DI_D_ACC [ 1 ] * thrust )
176+ forces_motor_vec = cs .vertcat (0 , 0 , acc_coef + cmd_f_coef * forces_motor )
162177
163178 # Linear equation of motion
164179 pos_dot = symbols .vel
165- vel_dot = symbols .rot @ forces_motor_vec / constants . MASS + constants . GRAVITY_VEC
166- if calc_dist_f :
180+ vel_dot = symbols .rot @ forces_motor_vec / mass + gravity_vec
181+ if model_dist_f :
167182 # Adding force disturbances to the state
168- vel_dot = vel_dot + symbols .dist_f / constants . MASS
183+ vel_dot = vel_dot + symbols .dist_f / mass
169184
170185 # Rotational equation of motion
171186 euler_angles = rotation .cs_quat2euler (symbols .quat )
@@ -175,26 +190,18 @@ def dynamics_symbolic(
175190 )
176191 quat_dot = 0.5 * (xi @ symbols .quat )
177192 rpy_rates = rotation .cs_ang_vel2rpy_rates (symbols .quat , symbols .ang_vel )
178- rpy_rates_dot = (
179- constants .DI_D_PARAMS [:, 0 ] * euler_angles
180- + constants .DI_D_PARAMS [:, 1 ] * rpy_rates
181- + constants .DI_D_PARAMS [:, 2 ] * cmd_rpy
182- )
193+ rpy_rates_dot = rpy_coef * euler_angles + rpy_rates_coef * rpy_rates + cmd_rpy_coef * cmd_rpy
183194 ang_vel_dot = rotation .cs_rpy_rates_deriv2ang_vel_deriv (symbols .quat , rpy_rates , rpy_rates_dot )
184- if calc_dist_t :
195+ if model_dist_t :
185196 # adding torque disturbances to the state
186197 # angular acceleration can be converted to total torque
187- torque = constants .J @ ang_vel_dot + cs .cross (
188- symbols .ang_vel , constants .J @ symbols .ang_vel
189- )
198+ torque = J @ ang_vel_dot + cs .cross (symbols .ang_vel , J @ symbols .ang_vel )
190199 # adding torque
191200 torque = torque + symbols .rot .T @ symbols .dist_t
192201 # back to angular acceleration
193- ang_vel_dot = constants .J_INV @ (
194- torque - cs .cross (symbols .ang_vel , constants .J @ symbols .ang_vel )
195- )
202+ ang_vel_dot = J_inv @ (torque - cs .cross (symbols .ang_vel , J @ symbols .ang_vel ))
196203
197- if calc_rotor_vel :
204+ if model_rotor_vel :
198205 X_dot = cs .vertcat (pos_dot , quat_dot , vel_dot , ang_vel_dot , rotor_vel_dot )
199206 else :
200207 X_dot = cs .vertcat (pos_dot , quat_dot , vel_dot , ang_vel_dot )
0 commit comments