|
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | | -from typing import TYPE_CHECKING, NamedTuple |
| 5 | +from typing import TYPE_CHECKING |
6 | 6 |
|
7 | 7 | import array_api_extra as xpx |
8 | | -import numpy as np |
9 | 8 | from array_api_compat import array_namespace |
10 | 9 | from scipy.spatial.transform import Rotation as R |
11 | 10 |
|
| 11 | +from drone_models.controller.core import register_controller_parameters |
| 12 | +from drone_models.controller.mellinger.params import AttitudeParams, ForceTorqueParams, StateParams |
12 | 13 | from drone_models.transform import force2pwm, motor_force2rotor_vel, pwm2force |
13 | 14 |
|
14 | 15 | if TYPE_CHECKING: |
15 | 16 | from array_api_typing import Array |
16 | 17 |
|
17 | 18 |
|
| 19 | +@register_controller_parameters(StateParams) |
18 | 20 | def state2attitude( |
19 | 21 | pos: Array, |
20 | 22 | quat: Array, |
@@ -130,6 +132,7 @@ def state2attitude( |
130 | 132 | return command_rpyt, int_pos_err |
131 | 133 |
|
132 | 134 |
|
| 135 | +@register_controller_parameters(AttitudeParams) |
133 | 136 | def attitude2force_torque( |
134 | 137 | pos: Array, |
135 | 138 | quat: Array, |
@@ -259,6 +262,7 @@ def force_torque_pwms2pwms(force_pwm: Array, torque_pwm: Array, mixing_matrix: A |
259 | 262 | return force_pwm[..., None] + (mixing_matrix @ torque_pwm[..., None])[..., 0] |
260 | 263 |
|
261 | 264 |
|
| 265 | +@register_controller_parameters(ForceTorqueParams) |
262 | 266 | def force_torque2rotor_vel( |
263 | 267 | force: Array, |
264 | 268 | torque: Array, |
@@ -300,127 +304,3 @@ def force_torque2rotor_vel( |
300 | 304 | motor_forces = xp.where(xp.all(force == 0), 0.0, xp.clip(motor_forces, thrust_min, thrust_max)) |
301 | 305 | # Assume perfect battery compensation and calculate the desired motor speeds directly |
302 | 306 | return motor_force2rotor_vel(motor_forces, KF) |
303 | | - |
304 | | - |
305 | | -class MellingerStateParams(NamedTuple): |
306 | | - """Parameters for the Mellinger state controller.""" |
307 | | - |
308 | | - mass: float |
309 | | - kp: Array |
310 | | - kd: Array |
311 | | - ki: Array |
312 | | - gravity_vec: Array |
313 | | - mass_thrust: float |
314 | | - int_err_max: Array |
315 | | - thrust_max: float |
316 | | - pwm_max: float |
317 | | - |
318 | | - @staticmethod |
319 | | - def load(drone_model: str) -> MellingerStateParams: |
320 | | - """Load the parameters from the config file.""" |
321 | | - params = MellingerStateParams._load_fake_model() |
322 | | - return MellingerStateParams(**params) |
323 | | - |
324 | | - @staticmethod |
325 | | - def _load_fake_model() -> dict[str, Array | float]: |
326 | | - """Load the parameters from the config file.""" |
327 | | - # TODO: Remove this once we can load proper params |
328 | | - return { |
329 | | - "mass": 0.032999999821186066, |
330 | | - "mass_thrust": 132000 * 0.034 / 0.027, |
331 | | - "kp": np.array([0.4, 0.4, 1.25]), |
332 | | - "kd": np.array([0.2, 0.2, 0.5]), |
333 | | - "ki": np.array([0.05, 0.05, 0.05]), |
334 | | - "int_err_max": np.array([2.0, 2.0, 0.4]), |
335 | | - # TODO: Double-check if we want this |
336 | | - "gravity_vec": np.array([0.0, 0.0, -9.8100004196167]), |
337 | | - "thrust_max": 0.1125, |
338 | | - "pwm_max": 65535.0, |
339 | | - } |
340 | | - |
341 | | - |
342 | | -class MellingerAttitudeParams(NamedTuple): |
343 | | - """Parameters for the Mellinger attitude controller.""" |
344 | | - |
345 | | - kR: Array |
346 | | - kw: Array |
347 | | - ki_m: Array |
348 | | - kd_omega: Array |
349 | | - int_err_max: Array |
350 | | - torque_pwm_max: Array |
351 | | - thrust_max: float |
352 | | - pwm_min: float |
353 | | - pwm_max: float |
354 | | - L: float |
355 | | - KF: float |
356 | | - KM: float |
357 | | - mixing_matrix: Array |
358 | | - |
359 | | - @staticmethod |
360 | | - def load(drone_model: str) -> MellingerAttitudeParams: |
361 | | - """Load the parameters from the config file.""" |
362 | | - params = MellingerAttitudeParams._load_fake_model() |
363 | | - return MellingerAttitudeParams(**params) |
364 | | - |
365 | | - @staticmethod |
366 | | - def _load_fake_model() -> dict[str, Array | float]: |
367 | | - """Load the parameters from the config file.""" |
368 | | - # TODO: Remove this once we can load proper params |
369 | | - # fmt: off |
370 | | - mixing_matrix = np.array([[-1.0, -1.0, -1.0], |
371 | | - [-1.0, 1.0, 1.0], |
372 | | - [ 1.0, 1.0, -1.0], |
373 | | - [ 1.0, -1.0, 1.0]] |
374 | | - ) |
375 | | - # fmt: on |
376 | | - return { |
377 | | - "kR": np.array([70_000.0, 70_000.0, 60_000.0]), |
378 | | - "kw": np.array([20_000.0, 20_000.0, 12_000.0]), |
379 | | - "ki_m": np.array([0.0, 0.0, 500.0]), |
380 | | - "kd_omega": np.array([200.0, 200.0, 0.0]), |
381 | | - "int_err_max": np.array([1.0, 1.0, 1500.0]), |
382 | | - "torque_pwm_max": np.array([32_000.0, 32_000.0, 32_000.0]), |
383 | | - "thrust_max": 0.1125, |
384 | | - "pwm_min": 20_000.0, |
385 | | - "pwm_max": 65_535.0, |
386 | | - "L": 0.03253, |
387 | | - "KF": 8.7e-10, |
388 | | - "KM": 7.94e-12, |
389 | | - "mixing_matrix": mixing_matrix, |
390 | | - } |
391 | | - |
392 | | - |
393 | | -class MellingerForceTorqueParams(NamedTuple): |
394 | | - """Parameters for the Mellinger force torque controller.""" |
395 | | - |
396 | | - thrust_min: float |
397 | | - thrust_max: float |
398 | | - L: float |
399 | | - KF: float |
400 | | - KM: float |
401 | | - mixing_matrix: Array |
402 | | - |
403 | | - @staticmethod |
404 | | - def load(drone_model: str) -> MellingerForceTorqueParams: |
405 | | - """Load the parameters from the config file.""" |
406 | | - params = MellingerForceTorqueParams._load_fake_model() |
407 | | - return MellingerForceTorqueParams(**params) |
408 | | - |
409 | | - @staticmethod |
410 | | - def _load_fake_model() -> dict[str, Array | float]: |
411 | | - """Load the parameters from the config file.""" |
412 | | - # fmt: off |
413 | | - mixing_matrix = np.array([[-1.0, -1.0, -1.0], |
414 | | - [-1.0, 1.0, 1.0], |
415 | | - [ 1.0, 1.0, -1.0], |
416 | | - [ 1.0, -1.0, 1.0]] |
417 | | - ) |
418 | | - # fmt: on |
419 | | - return { |
420 | | - "thrust_min": 0.02, |
421 | | - "thrust_max": 0.1125, |
422 | | - "L": 0.03253, |
423 | | - "KF": 8.701227710666256e-10, |
424 | | - "KM": 7.94e-12, |
425 | | - "mixing_matrix": mixing_matrix, |
426 | | - } |
0 commit comments