Skip to content

Commit be4fb4a

Browse files
committed
autotune: resample using linear interpolation
1 parent 6011414 commit be4fb4a

2 files changed

Lines changed: 40 additions & 47 deletions

File tree

autotune/autotune.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
from pid_design import computePidGmvc
5050
from system_identification import SystemIdentification
5151
import control as ctrl
52-
from scipy.signal import resample, detrend
52+
from scipy.signal import detrend
5353

5454
from data_selection_window import DataSelectionWindow
5555

@@ -715,13 +715,15 @@ def refreshInputOutputData(self):
715715

716716
def resampleData(self, dt):
717717
self.dt = dt
718-
self.t = np.arange(0, self.t[-1]+self.dt, self.dt)
719-
self.u = resample(self.u, len(self.t))
720-
self.y = resample(self.y, len(self.t))
721-
self.input = resample(self.input, len(self.t))
718+
t_new = np.arange(0, self.t[-1]+self.dt, self.dt)
719+
self.u = resample_interp(self.t, self.u, t_new)
720+
self.y = resample_interp(self.t, self.y, t_new)
721+
self.input = resample_interp(self.t, self.input, t_new)
722722

723723
if len(self.true_airspeed) > 0:
724-
self.true_airspeed = resample(self.true_airspeed, len(self.t))
724+
self.true_airspeed = resample_interp(self.t, self.true_airspeed, t_new)
725+
726+
self.t = t_new
725727

726728
class DoubleSlider(QSlider):
727729

autotune/data_extractor.py

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import numpy as np
4040
from scipy import signal
4141
from pyulog import ULog
42-
from scipy.signal import resample
42+
from scipy.interpolate import make_interp_spline
4343

4444
def getInputOutputData(logfile, axis, t_start=0.0, t_stop=0.0, instance=0):
4545
log = ULog(logfile)
@@ -85,57 +85,48 @@ def get_delta_mean(data_list):
8585
dx = dx/(length-1)
8686
return dx
8787

88+
def resample_interp(t, u, t_new):
89+
interp = make_interp_spline(t, u, k=1)
90+
return interp(t_new)
91+
8892
def extract_identification_data(log, t_u_data, u_data, t_y_data, y_data, axis, t_v_data, v_data, t_start, t_stop):
89-
status_data = get_data(log, 'autotune_attitude_control_status', 'state')
90-
t_status = us2s(get_data(log, 'autotune_attitude_control_status', 'timestamp'))
91-
92-
len_y = len(t_y_data)
93-
len_s = len(t_status)
94-
len_v = len(t_v_data)
95-
i_y = 0
96-
i_s = 0
97-
i_v = 0
98-
u_aligned = []
99-
y_aligned = []
100-
v_aligned = []
101-
t_aligned = []
102-
axis_to_state = [2, 4, 6] # roll, pitch, yaw states
93+
if t_start == 0.0 and t_stop == 0.0:
94+
# Find autotune sequence
95+
status_data = get_data(log, 'autotune_attitude_control_status', 'state')
96+
t_status = us2s(get_data(log, 'autotune_attitude_control_status', 'timestamp'))
97+
axis_to_state = [2, 4, 6] # roll, pitch, yaw states
10398

104-
if t_start == 0.0:
105-
t_start = t_u_data[0]
99+
status_prev = 0
106100

107-
if t_stop == 0.0:
108-
t_stop = t_u_data[-1]
101+
for i_s in range(len(t_status)):
102+
if status_data[i_s] == axis_to_state[axis]:
103+
if status_prev != axis_to_state[axis]:
104+
t_start = t_status[i_s]
109105

110-
for i_u in range(len(t_u_data)):
111-
t_u = t_u_data[i_u]
112-
while t_y_data[i_y] <= t_u and i_y < len_y-1:
113-
i_y += 1
106+
else:
107+
if status_prev == axis_to_state[axis]:
108+
t_stop = t_status[i_s]
109+
break
114110

115-
while i_v < len_v-1 and t_v_data[i_v] <= t_u:
116-
i_v += 1
111+
status_prev = status_data[i_s]
117112

118-
if len_s > 0:
119-
while t_status[i_s] <= t_u and i_s < len_s-1:
120-
i_s += 1
113+
if t_start == 0.0:
114+
t_start = t_u_data[0]
121115

122-
status_aligned = status_data[i_s-1]
116+
if t_stop == 0.0:
117+
t_stop = t_u_data[-1]
123118

124-
if status_aligned == axis_to_state[axis] and t_u >= t_start and t_u <= t_stop:
125-
u_aligned.append(u_data[i_u])
126-
y_aligned.append(y_data[i_y-1])
127-
t_aligned.append(t_u)
119+
dt = get_delta_mean(t_y_data)
120+
t_aligned = np.arange(t_start, t_stop, dt)
128121

129-
if i_v > 0:
130-
v_aligned.append(v_data[i_v-1])
122+
# Resample series to the common index
123+
u_aligned = resample_interp(t_u_data, u_data, t_aligned)
124+
y_aligned = resample_interp(t_y_data, y_data, t_aligned)
131125

132-
elif t_u >= t_start and t_u <= t_stop:
133-
u_aligned.append(u_data[i_u])
134-
y_aligned.append(y_data[i_y-1])
135-
t_aligned.append(t_u)
126+
v_aligned = []
136127

137-
if i_v > 0:
138-
v_aligned.append(v_data[i_v-1])
128+
if len(v_data) > 0:
129+
v_aligned = resample_interp(t_v_data, v_data, t_aligned)
139130

140131
return (t_aligned, u_aligned, y_aligned, v_aligned)
141132

0 commit comments

Comments
 (0)