Skip to content

Commit 650dcd6

Browse files
committed
Replace KF & KM with thrust curves, add B500 model
1 parent fda4677 commit 650dcd6

3 files changed

Lines changed: 62 additions & 29 deletions

File tree

drone_controllers/mellinger/control.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ def attitude2force_torque(
153153
pwm_min: float,
154154
pwm_max: float,
155155
L: float,
156-
KM: float,
157-
KF: float,
156+
thrust2torque: float,
158157
mixing_matrix: Array,
159158
) -> tuple[Array, Array, Array]:
160159
"""Compute the attitude to desired force-torque part of the Mellinger controller.
@@ -186,8 +185,7 @@ def attitude2force_torque(
186185
prev_ang_vel: Previous angular velocity in rad/s.
187186
prev_ang_vel_des: Previous angular velocity command in rad/s.
188187
L: Distance from the center of the quadrotor to the center of the rotor in m.
189-
KM: Torque constant (Nm/RPM).
190-
KF: Force constant (N/RPM).
188+
thrust2torque: Conversion factor (m).
191189
mixing_matrix: Mixing matrix for the motor forces with shape (4, 3).
192190
193191
Returns:
@@ -252,7 +250,7 @@ def attitude2force_torque(
252250
# controllers within drone_models, we still want to return SI forces and torques. We thus need
253251
# to convert the legacy output to SI units.
254252
# l. 310 ff
255-
torque_des = (mixing_matrix @ motor_forces[..., None])[..., 0] * xp.stack([L, L, KM / KF])
253+
torque_des = (mixing_matrix @ motor_forces[..., None])[..., 0] * xp.stack([L, L, thrust2torque])
256254
force_des = xp.sum(motor_forces, axis=-1)[..., None]
257255
return force_des, torque_des, r_int_error
258256

@@ -270,8 +268,8 @@ def force_torque2rotor_vel(
270268
thrust_min: float,
271269
thrust_max: float,
272270
L: float,
273-
KM: float,
274-
KF: float,
271+
rpm2thrust: Array,
272+
thrust2torque: float,
275273
mixing_matrix: Array,
276274
) -> Array:
277275
"""Convert desired collective thrust and torques to rotor speeds.
@@ -293,8 +291,8 @@ def force_torque2rotor_vel(
293291
thrust_min: Minimum thrust in N.
294292
thrust_max: Maximum thrust in N.
295293
L: Distance from the center of the quadrotor to the center of the rotor in m.
296-
KM: Torque constant (Nm/RPM).
297-
KF: Force constant (N/RPM).
294+
rpm2thrust: Force constants (N/RPM, N/RPM**2).
295+
thrust2torque: Conversion factor (m).
298296
mixing_matrix: Mixing matrix for the motor forces with shape (4, 3).
299297
300298
Returns:
@@ -303,9 +301,11 @@ def force_torque2rotor_vel(
303301
xp = array_namespace(torque)
304302
assert torque.shape[-1] == 3, f"Torque must have shape (..., 3), but has {torque.shape}"
305303
assert force.shape[-1] == 1, f"Force must have shape (..., 1), but has {force.shape}"
306-
torque_forces = (torque * xp.asarray([1 / L, 1 / L, KF / KM])) @ mixing_matrix
304+
torque_forces = (torque * xp.asarray([1 / L, 1 / L, 1 / thrust2torque])) @ mixing_matrix
307305
motor_forces = (torque_forces + force) / 4
308306
# Clip motor forces on the thrust instead of PWM level.
309307
motor_forces = xp.where(xp.all(force == 0), 0.0, xp.clip(motor_forces, thrust_min, thrust_max))
310308
# Assume perfect battery compensation and calculate the desired motor speeds directly
311-
return motor_force2rotor_vel(motor_forces, KF)
309+
return motor_force2rotor_vel(
310+
motor_forces, rpm2thrust[2]
311+
) # TODO change function to take all rpm2thrust params

drone_controllers/mellinger/params.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ class AttitudeParams(NamedTuple):
5050
pwm_min: float
5151
pwm_max: float
5252
L: float
53-
KF: float
54-
KM: float
53+
thrust2torque: float
5554
mixing_matrix: Array
5655

5756
@staticmethod
@@ -72,8 +71,8 @@ class ForceTorqueParams(NamedTuple):
7271
thrust_min: float
7372
thrust_max: float
7473
L: float
75-
KF: float
76-
KM: float
74+
rpm2thrust: Array
75+
thrust2torque: float
7776
mixing_matrix: Array
7877

7978
@staticmethod

drone_controllers/mellinger/params.toml

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ pwm_min = 20000.0
77
pwm_max = 65535.0
88
torque_pwm_max = [32000.0, 32000.0, 32000.0]
99
L = 0.03253
10-
KF = 3.16e-10 # TODO: Check what the firmware uses
11-
KM = 7.94e-12
10+
rpm2thrust = [0.0, 0.0, 3.16e-10] # TODO
11+
rpm2torque = [0.0, 0.0, 7.94e-12] # TODO
12+
thrust2torque = 0.002513 # TODO
1213
mixing_matrix = [
13-
[-1.0, -1.0, 1.0, 1.0],
14+
[-1.0, -1.0, 1.0, 1.0],
1415
[-1.0, 1.0, 1.0, -1.0],
15-
[-1.0, 1.0, -1.0, 1.0]
16+
[-1.0, 1.0, -1.0, 1.0]
1617
]
1718
gravity_vec = [0.0, 0.0, -9.81]
1819

@@ -29,31 +30,64 @@ ki_m = [0.0, 0.0, 500.0]
2930
kd_omega = [200.0, 200.0, 0.0]
3031
int_err_max = [1.0, 1.0, 1500.0]
3132

32-
[cf2x_B500.core]
33-
mass = 0.034
33+
[cf2x_P250.core]
34+
mass = 0.033
3435
mass_thrust = 132000
35-
thrust_min = 0.03
36-
thrust_max = 0.18
36+
thrust_min = 0.02
37+
thrust_max = 0.1125
3738
pwm_min = 20000.0
3839
pwm_max = 65535.0
3940
torque_pwm_max = [32000.0, 32000.0, 32000.0]
4041
L = 0.03253
41-
KF = 3.16e-10 # TODO: Check what the firmware uses
42-
KM = 7.94e-12
42+
rpm2thrust = [0.0, 0.0, 5.792654323957372e-10] # TODO
43+
rpm2torque = [0.0, 0.0, 7.94e-12] # TODO
44+
thrust2torque = 0.001371 # TODO
4345
mixing_matrix = [
44-
[-1.0, -1.0, 1.0, 1.0],
46+
[-1.0, -1.0, 1.0, 1.0],
4547
[-1.0, 1.0, 1.0, -1.0],
46-
[-1.0, 1.0, -1.0, 1.0]
48+
[-1.0, 1.0, -1.0, 1.0]
4749
]
4850
gravity_vec = [0.0, 0.0, -9.81]
4951

50-
[cf2x_B500.state2attitude]
52+
[cf2x_P250.state2attitude]
53+
kp = [0.4, 0.4, 1.25]
54+
kd = [0.2, 0.2, 0.5]
55+
ki = [0.05, 0.05, 0.05]
56+
int_err_max = [2.0, 2.0, 0.4]
57+
58+
[cf2x_P250.attitude2force_torque]
59+
kR = [70000.0, 70000.0, 60000.0]
60+
kw = [20000.0, 20000.0, 12000.0]
61+
ki_m = [0.0, 0.0, 500.0]
62+
kd_omega = [200.0, 200.0, 0.0]
63+
int_err_max = [1.0, 1.0, 1500.0]
64+
65+
[cf21B_500.core]
66+
mass = 0.04338
67+
gravity_vec = [0.0, 0.0, -9.81]
68+
mass_thrust = 132000
69+
thrust_min = 0.03
70+
thrust_max = 0.18
71+
pwm_min = 20000.0
72+
pwm_max = 65535.0
73+
torque_pwm_max = [32000.0, 32000.0, 32000.0]
74+
L = 0.035355
75+
rpm2thrust = [0.0, -8.357406697944084e-07, 4.716909960828207e-10]
76+
rpm2torque = [0.0, 2.435151264350409e-09, 2.424629050055297e-12]
77+
thrust2torque = 0.00593893393599368
78+
mixing_matrix = [
79+
[-1.0, -1.0, 1.0, 1.0],
80+
[-1.0, 1.0, 1.0, -1.0],
81+
[-1.0, 1.0, -1.0, 1.0]
82+
]
83+
84+
[cf21B_500.state2attitude]
5185
kp = [0.4, 0.4, 1.25]
5286
kd = [0.2, 0.2, 0.5]
5387
ki = [0.05, 0.05, 0.05]
5488
int_err_max = [2.0, 2.0, 0.4]
5589

56-
[cf2x_B500.attitude2force_torque]
90+
[cf21B_500.attitude2force_torque]
5791
kR = [70000.0, 70000.0, 60000.0]
5892
kw = [20000.0, 20000.0, 12000.0]
5993
ki_m = [0.0, 0.0, 500.0]

0 commit comments

Comments
 (0)