|
10 | 10 | from crazyflow.control.control import KF, KM
|
11 | 11 |
|
12 | 12 | SYS_ID_PARAMS = {
|
13 |
| - "acc_k1": 20.91, |
14 |
| - "acc_k2": 3.65, |
15 |
| - "roll_alpha": -3.96, |
16 |
| - "roll_beta": 4.08, |
17 |
| - "pitch_alpha": -6.00, |
18 |
| - "pitch_beta": 6.21, |
19 |
| - "yaw_alpha": 0.00, |
20 |
| - "yaw_beta": 0.00, |
| 13 | + "acc": jnp.array([20.91, 3.65]), |
| 14 | + "roll_acc": jnp.array([-130.3, -16.33, 119.3]), |
| 15 | + "pitch_acc": jnp.array([-99.94, -13.3, 84.73]), |
| 16 | + "yaw_acc": jnp.array([0.0, 0.0, 0.0]), |
21 | 17 | }
|
22 | 18 |
|
23 | 19 |
|
@@ -60,27 +56,24 @@ def surrogate_identified_collective_wrench(
|
60 | 56 | rot = R.from_quat(quat)
|
61 | 57 | thrust = rot.apply(jnp.array([0, 0, collective_thrust]))
|
62 | 58 | drift = rot.apply(jnp.array([0, 0, 1]))
|
63 |
| - prev_rpy_rates = rot.apply(rpy_rates, inverse=True) |
64 |
| - a1, a2 = SYS_ID_PARAMS["acc_k1"], SYS_ID_PARAMS["acc_k2"] |
65 |
| - acc = thrust * a1 + drift * a2 |
66 |
| - # rpy_rates_deriv have no real meaning in this context, since the identified dynamics set the |
67 |
| - # rpy_rates to the commanded values directly. However, since we use a unified integration |
68 |
| - # interface for all physics models, we cannot access states directly. Instead, we calculate |
69 |
| - # which rpy_rates_deriv would have resulted in the desired rpy_rates, and return that. |
70 |
| - roll_cmd, pitch_cmd, yaw_cmd = attitude |
| 59 | + rpy_rates_local = rot.apply(rpy_rates, inverse=True) |
| 60 | + k1, k2 = SYS_ID_PARAMS["acc"] |
| 61 | + acc = thrust * k1 + drift * k2 |
71 | 62 | rpy = rot.as_euler("xyz")
|
72 |
| - roll_rate = SYS_ID_PARAMS["roll_alpha"] * rpy[0] + SYS_ID_PARAMS["roll_beta"] * roll_cmd |
73 |
| - pitch_rate = SYS_ID_PARAMS["pitch_alpha"] * rpy[1] + SYS_ID_PARAMS["pitch_beta"] * pitch_cmd |
74 |
| - yaw_rate = SYS_ID_PARAMS["yaw_alpha"] * rpy[2] + SYS_ID_PARAMS["yaw_beta"] * yaw_cmd |
75 |
| - rpy_rates_local = jnp.array([roll_rate, pitch_rate, yaw_rate]) |
76 |
| - rpy_rates_local_deriv = (rpy_rates_local - prev_rpy_rates) / dt |
| 63 | + k1, k2, k3 = SYS_ID_PARAMS["roll_acc"] |
| 64 | + roll_rate_deriv = k1 * rpy[0] + k2 * rpy_rates_local[0] + k3 * attitude[1] |
| 65 | + k1, k2, k3 = SYS_ID_PARAMS["pitch_acc"] |
| 66 | + pitch_rate_deriv = k1 * rpy[1] + k2 * rpy_rates_local[1] + k3 * attitude[2] |
| 67 | + k1, k2, k3 = SYS_ID_PARAMS["yaw_acc"] |
| 68 | + yaw_rate_deriv = k1 * rpy[2] + k2 * rpy_rates_local[2] + k3 * attitude[3] |
| 69 | + rpy_rates_deriv = jnp.array([roll_rate_deriv, pitch_rate_deriv, yaw_rate_deriv]) |
77 | 70 | # The identified dynamics model does not use forces or torques, because we assume no knowledge
|
78 | 71 | # of the drone's mass and inertia. However, to remain compatible with the physics pipeline, we
|
79 | 72 | # return surrogate forces and torques that result in the desired acceleration and rpy rates
|
80 | 73 | # derivative. When converting back to the state derivative, the mass and inertia will cancel
|
81 | 74 | # out, resulting in the correct acceleration and rpy rates derivative regardless of the model's
|
82 | 75 | # mass and inertia.
|
83 |
| - surrogate_torques = rot.apply(J @ rpy_rates_local_deriv) |
| 76 | + surrogate_torques = rot.apply(J @ rpy_rates_deriv) |
84 | 77 | surrogate_forces = acc * mass
|
85 | 78 | return surrogate_forces, surrogate_torques
|
86 | 79 |
|
|
0 commit comments