@@ -31,8 +31,8 @@ def dynamics(
3131 gravity_vec : Array ,
3232 J : Array ,
3333 J_inv : Array ,
34- KF : float ,
35- KM : float ,
34+ rpm2thrust : Array ,
35+ rpm2torque : Array ,
3636 L : float ,
3737 mixing_matrix : Array ,
3838 thrust_tau : float ,
@@ -59,8 +59,8 @@ def dynamics(
5959 [0, 0, -9.81].
6060 J: Inertia matrix (kg m^2).
6161 J_inv: Inverse inertia matrix (1/kg m^2).
62- KF: Motor force constant (N/rad ^2).
63- KM: Motor torque constant (Nm/rad ^2).
62+ rpm2thrust: Propeller force constant (N min ^2).
63+ rpm2torque: Propeller torque constant (Nm min ^2).
6464 L: Distance from the CoM to the motor (m).
6565 mixing_matrix: Mixing matrix denoting the turn direction of the motors (4x3).
6666 thrust_tau: Thrust time constant (s).
@@ -74,8 +74,18 @@ def dynamics(
7474 More information https://ahrs.readthedocs.io/en/latest/filters/angular.html
7575 """
7676 xp = array_namespace (pos )
77- mass , gravity_vec , J , J_inv , KF , KM , L , mixing_matrix , thrust_tau = to_xp (
78- mass , gravity_vec , J , J_inv , KF , KM , L , mixing_matrix , thrust_tau , xp = xp , device = device (pos )
77+ mass , gravity_vec , J , J_inv , rpm2thrust , rpm2torque , L , mixing_matrix , thrust_tau = to_xp (
78+ mass ,
79+ gravity_vec ,
80+ J ,
81+ J_inv ,
82+ rpm2thrust ,
83+ rpm2torque ,
84+ L ,
85+ mixing_matrix ,
86+ thrust_tau ,
87+ xp = xp ,
88+ device = device (pos ),
7989 )
8090 rot = R .from_quat (quat )
8191 # Rotor dynamics
@@ -84,11 +94,17 @@ def dynamics(
8494 else :
8595 rotor_vel_dot = 1 / thrust_tau * (cmd - rotor_vel ) # - 1 / KM * rotor_vel**2
8696 # Creating force and torque vector
87- forces_motor = KF * rotor_vel ** 2
97+ forces_motor = rpm2thrust [0 ] + rpm2thrust [1 ] * rotor_vel + rpm2thrust [2 ] * rotor_vel ** 2
98+ torques_motor = rpm2torque [0 ] + rpm2torque [1 ] * rotor_vel + rpm2torque [2 ] * rotor_vel ** 2
8899 forces_motor_tot = xp .sum (forces_motor , axis = - 1 )
89100 zeros = xp .zeros_like (forces_motor_tot )
90101 forces_motor_vec = xp .stack ((zeros , zeros , forces_motor_tot ), axis = - 1 )
91- torque = (mixing_matrix @ (rotor_vel ** 2 )[..., None ])[..., 0 ] * xp .stack ([KF * L , KF * L , KM ])
102+
103+ torque_vec = (mixing_matrix @ (forces_motor )[..., None ])[..., 0 ] * xp .stack (
104+ [L , L , xp .asarray (0.0 )]
105+ ) + (mixing_matrix @ (torques_motor )[..., None ])[..., 0 ] * xp .stack (
106+ [xp .asarray (0.0 ), xp .asarray (0.0 ), xp .asarray (1.0 )]
107+ )
92108
93109 # Linear equation of motion
94110 forces_motor_vec_world = rot .apply (forces_motor_vec )
@@ -101,10 +117,10 @@ def dynamics(
101117
102118 # Rotational equation of motion
103119 if dist_t is not None :
104- torque = torque + rot .apply (dist_t , inverse = True )
120+ torque_vec = torque_vec + rot .apply (dist_t , inverse = True )
105121 quat_dot = rotation .ang_vel2quat_dot (quat , ang_vel )
106- torque = torque - xp .linalg .cross (ang_vel , (J @ ang_vel [..., None ])[..., 0 ])
107- ang_vel_dot = (J_inv @ torque [..., None ])[..., 0 ]
122+ torque_vec = torque_vec - xp .linalg .cross (ang_vel , (J @ ang_vel [..., None ])[..., 0 ])
123+ ang_vel_dot = (J_inv @ torque_vec [..., None ])[..., 0 ]
108124 return pos_dot , quat_dot , vel_dot , ang_vel_dot , rotor_vel_dot
109125
110126
@@ -117,8 +133,8 @@ def symbolic_dynamics(
117133 gravity_vec : Array ,
118134 J : Array ,
119135 J_inv : Array ,
120- KF : float ,
121- KM : float ,
136+ rpm2thrust : Array ,
137+ rpm2torque : Array ,
122138 L : float ,
123139 mixing_matrix : Array ,
124140 thrust_tau : float ,
@@ -138,13 +154,21 @@ def symbolic_dynamics(
138154 if model_rotor_vel :
139155 # Thrust dynamics
140156 rotor_vel_dot = 1 / thrust_tau * (U - symbols .rotor_vel ) # - 1 / KM * symbols.rotor_vel**2
141- forces_motor = KF * symbols .rotor_vel ** 2
157+ forces_motor = (
158+ rpm2thrust [0 ] + rpm2thrust [1 ] * symbols .rotor_vel + rpm2thrust [2 ] * symbols .rotor_vel ** 2
159+ )
160+ torques_motor = (
161+ rpm2torque [0 ] + rpm2torque [1 ] * symbols .rotor_vel + rpm2torque [2 ] * symbols .rotor_vel ** 2
162+ )
142163 else :
143- forces_motor = KF * U ** 2
164+ forces_motor = rpm2thrust [0 ] + rpm2thrust [1 ] * U + rpm2thrust [2 ] * U ** 2
165+ torques_motor = rpm2torque [0 ] + rpm2torque [1 ] * U + rpm2torque [2 ] * U ** 2
144166
145167 # Creating force and torque vector
146- forces_motor_vec = cs .vertcat (0 , 0 , cs .sum1 (forces_motor ))
147- torques_motor_vec = mixing_matrix @ forces_motor * cs .vertcat (L , L , KM / KF )
168+ forces_motor_vec = cs .vertcat (0.0 , 0.0 , cs .sum1 (forces_motor ))
169+ torques_motor_vec = mixing_matrix @ forces_motor * cs .vertcat (
170+ L , L , 0.0
171+ ) + mixing_matrix @ torques_motor * cs .vertcat (0.0 , 0.0 , 1.0 )
148172
149173 # Linear equation of motion
150174 forces_motor_vec_world = symbols .rot @ forces_motor_vec
0 commit comments