Skip to content

Commit 30baabe

Browse files
committed
Update identification pipeline and add tests
1 parent 6948a61 commit 30baabe

4 files changed

Lines changed: 259 additions & 148 deletions

File tree

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,19 @@
1919
logger = logging.getLogger(__name__)
2020

2121

22-
def preprocessing(data: dict[str, Array], constants: dict[str, float]) -> dict[str, Array]:
23-
"""TODO."""
22+
def preprocessing(data: dict[str, Array]) -> dict[str, Array]:
23+
"""Applies preprocessing to collected data.
24+
25+
The preprocessing includes
26+
outlier detection and interpolation,
27+
normalizing orientation (assuming hover at start),
28+
calculating rpy from quaternions,
29+
and calculating rotational error
30+
31+
Args:
32+
data: The raw data dictionary containing
33+
time [s], pos [m], quat, cmd_rpy [rad], cmd_f [N].
34+
"""
2435
data["dt"] = np.diff(data["time"])
2536
data["time"] -= data["time"][0]
2637
### Outlier detection + interpolation
@@ -53,30 +64,22 @@ def preprocessing(data: dict[str, Array], constants: dict[str, float]) -> dict[s
5364
data["rpy"] = rot.as_euler("xyz")
5465
data["z_axis"] = rot.inv().as_matrix()[..., -1, :]
5566

56-
### Force clipping and vectorization
57-
data["cmd_f"] = data["cmd_pwm"] / constants["PWM_MAX"] * constants["THRUST_MAX"] * 4
58-
data["cmd_f"] = np.clip(data["cmd_f"], 0, constants["THRUST_MAX"] * 4)
59-
data["cmd_pwm"] = np.clip(data["cmd_pwm"], constants["PWM_MIN"], constants["PWM_MAX"])
60-
rot = R.from_quat(data["quat"])
61-
zeros = np.zeros_like(data["cmd_f"])
62-
f_cmd_vec = np.stack((zeros, zeros, data["cmd_f"]), axis=-1)
63-
data["cmd_f_vec"] = rot.apply(f_cmd_vec)
64-
6567
### Rotational error
68+
rot = R.from_quat(data["quat"])
6669
R_act = rot.as_matrix()
67-
R_des = R.from_euler("xyz", data["cmd_rpy"], degrees=True).as_matrix()
70+
R_des = R.from_euler("xyz", data["cmd_rpy"], degrees=False).as_matrix()
6871
eRM = np.matmul(np.swapaxes(R_des, -1, -2), R_act) - np.matmul(
6972
np.swapaxes(R_act, -1, -2), R_des
7073
)
7174
data["eR"] = np.stack(
7275
(eRM[..., 2, 1], eRM[..., 0, 2], eRM[..., 1, 0]), axis=-1
7376
) # vee operator (SO3 to R3)
74-
data["eR_vec"] = (rot.inv() * R.from_euler("xyz", data["cmd_rpy"], degrees=True)).as_rotvec()
77+
data["eR_vec"] = (rot.inv() * R.from_euler("xyz", data["cmd_rpy"], degrees=False)).as_rotvec()
7578

7679
return data
7780

7881

79-
def derivatives_svf(data: dict[str, Array], constants: dict[str, float]) -> dict[str, Array]:
82+
def derivatives_svf(data: dict[str, Array]) -> dict[str, Array]:
8083
"""Calculate derivatives with State Variable Filter."""
8184
# Important: Don't mix with unfiltered signals (also for input!)
8285
if data is None:
@@ -100,15 +103,13 @@ def derivatives_svf(data: dict[str, Array], constants: dict[str, float]) -> dict
100103
data["SVF_ang_acc"] = rpy_rates2ang_vel(data["SVF_quat"], data["SVF_ddrpy"])
101104
data["SVF_ang_jerk"] = rpy_rates2ang_vel(data["SVF_quat"], data["SVF_dddrpy"])
102105

103-
svf_input_pwm = state_variable_filter(data["cmd_pwm"], data["time"], f_c=6, N_deriv=3)
104-
data["SVF_cmd_pwm"] = svf_input_pwm[0]
105-
data["SVF_cmd_f"] = data["SVF_cmd_pwm"] / constants["PWM_MAX"] * constants["THRUST_MAX"] * 4
106-
106+
svf_input_f = state_variable_filter(data["cmd_f"], data["time"], f_c=6, N_deriv=3)
107+
data["SVF_cmd_f"] = svf_input_f[0]
107108
svf_input_rpy = state_variable_filter(data["cmd_rpy"].T, data["time"], f_c=8, N_deriv=3)
108109
data["SVF_cmd_rpy"] = svf_input_rpy[:, 0].T
109110

110111
R_act = rot.as_matrix()
111-
rot_cmd = R.from_euler("xyz", data["SVF_cmd_rpy"], degrees=True)
112+
rot_cmd = R.from_euler("xyz", data["SVF_cmd_rpy"])
112113
R_des = rot_cmd.as_matrix()
113114
eRM = np.matmul(np.swapaxes(R_des, -1, -2), R_act) - np.matmul(
114115
np.swapaxes(R_act, -1, -2), R_des
@@ -118,10 +119,6 @@ def derivatives_svf(data: dict[str, Array], constants: dict[str, float]) -> dict
118119
) # vee operator (SO3 to R3)
119120
data["SVF_eR_vec"] = (rot.inv() * rot_cmd).as_rotvec()
120121

121-
zeros = np.zeros_like(data["cmd_f"])
122-
f_cmd_vec = np.stack((zeros, zeros, data["cmd_f"]), axis=-1)
123-
data["SVF_cmd_f_vec"] = rot.apply(f_cmd_vec)
124-
125122
return data
126123

127124

0 commit comments

Comments
 (0)