Skip to content

Commit 5f669c4

Browse files
committed
add feedforward calculation
1 parent 185aae8 commit 5f669c4

1 file changed

Lines changed: 27 additions & 5 deletions

File tree

autotune/autotune.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33
"""
4-
Copyright (c) 2021 PX4 Development Team
4+
Copyright (c) 2021-2024 PX4 Development Team
55
Redistribution and use in source and binary forms, with or without
66
modification, are permitted provided that the following conditions
77
are met:
@@ -72,6 +72,7 @@ def __init__(self, parent=None):
7272
self.kc = 0.0
7373
self.ki = 0.0
7474
self.kd = 0.0
75+
self.kff = 0.0
7576
self.figure = plt.figure(1)
7677
self.figure.subplots_adjust(hspace=0.5, wspace=1.0)
7778
self.num = []
@@ -110,7 +111,7 @@ def __init__(self, parent=None):
110111
pz_group.addRow(QLabel("Poles"), self.line_edit_poles)
111112
self.line_edit_delays = QSpinBox()
112113
self.line_edit_delays.setValue(self.sys_id_delays)
113-
self.line_edit_delays.setRange(1, 1000)
114+
self.line_edit_delays.setRange(0, 1000)
114115
self.line_edit_delays.valueChanged.connect(self.onDelaysChanged)
115116
pz_group.addRow(QLabel("Delays"), self.line_edit_delays)
116117
self.btn_run_sys_id = QPushButton("Run identification")
@@ -270,14 +271,25 @@ def createPidLayout(self):
270271
layout_d = QHBoxLayout()
271272
self.slider_d = DoubleSlider(Qt.Horizontal)
272273
self.slider_d.setMinimum(0.0)
273-
self.slider_d.setMaximum(0.05)
274+
self.slider_d.setMaximum(0.2)
274275
self.slider_d.setInterval(0.001)
275276
self.lbl_d = QLabel("{:.3f}".format(self.kd))
276277
layout_d.addWidget(self.slider_d)
277278
layout_d.addWidget(self.lbl_d)
278279
self.slider_d.valueChanged.connect(self.updateLabelD)
279280
layout_pid.addRow(QLabel("D"), layout_d)
280281

282+
layout_ff = QHBoxLayout()
283+
self.slider_ff = DoubleSlider(Qt.Horizontal)
284+
self.slider_ff.setMinimum(0.0)
285+
self.slider_ff.setMaximum(1.0)
286+
self.slider_ff.setInterval(0.01)
287+
self.lbl_ff = QLabel("{:.3f}".format(self.kff))
288+
layout_ff.addWidget(self.slider_ff)
289+
layout_ff.addWidget(self.lbl_ff)
290+
self.slider_ff.valueChanged.connect(self.updateLabelFF)
291+
layout_pid.addRow(QLabel("FF"), layout_ff)
292+
281293
return layout_pid
282294

283295
def updateLabelK(self):
@@ -298,6 +310,12 @@ def updateLabelD(self):
298310
if self.slider_d.isSliderDown():
299311
self.updateClosedLoop()
300312

313+
def updateLabelFF(self):
314+
self.kff = self.slider_ff.value()
315+
self.lbl_ff.setText("{:.3f}".format(self.kff))
316+
if self.slider_ff.isSliderDown():
317+
self.updateClosedLoop()
318+
301319
def createGmvcLayout(self):
302320
layout_gmvc = QFormLayout()
303321

@@ -412,7 +430,7 @@ def replayInputData(self):
412430
return
413431
d = self.sysid.d
414432
u_detrended = detrend(self.u)
415-
u_delayed = np.concatenate(([0 for k in range(d)], u_detrended[0:-d]))
433+
u_delayed = np.concatenate(([0 for k in range(d)], u_detrended[0:(len(u_detrended)-d)]))
416434
self.t_est, self.y_est = ctrl.forced_response(self.Gz, T=self.t, U=u_delayed)
417435
if len(self.t_est) > len(self.y_est):
418436
self.t_est = self.t_est[0:len(self.y_est - 1)]
@@ -494,6 +512,8 @@ def computeController(self):
494512
(self.kc, self.ki, self.kd) = computePidGmvc(self.num, self.den, self.dt, sigma, delta, lbda)
495513
#TODO:find a better solution
496514
self.ki /= 5.0
515+
static_gain = sum(self.num) / sum(self.den)
516+
self.kff = 1 / static_gain
497517
# (self.kc, self.ki, self.kd) = computePidDahlin(self.num, self.den, self.dt, sigma)
498518

499519
self.updateKIDSliders()
@@ -503,6 +523,7 @@ def updateKIDSliders(self):
503523
self.slider_k.setValue(self.kc)
504524
self.slider_i.setValue(self.ki)
505525
self.slider_d.setValue(self.kd)
526+
self.slider_ff.setValue(self.kff)
506527

507528
def updateClosedLoop(self):
508529
if not self.is_system_identified:
@@ -514,11 +535,12 @@ def updateClosedLoop(self):
514535
kc = self.kc
515536
ki = self.ki
516537
kd = self.kd
538+
kff = self.kff
517539
Gd = ctrl.TransferFunction([1], np.append([1], np.zeros(self.sys_id_delays)), dt)
518540
Gz2 = ctrl.TransferFunction(num, den, dt)
519541
(pid_num, pid_den) = gainsToNumDen(kc, ki, kd, dt)
520542
PID = ctrl.TransferFunction(pid_num, pid_den, dt)
521-
Gcl = ctrl.feedback(PID * Gd * Gz2, 1)
543+
Gcl = (kff * Gd * Gz2 + PID * Gd * Gz2) / (1 + PID * Gd * Gz2)
522544
t_out,y_out = ctrl.step_response(Gcl, T=np.arange(0,1,dt))
523545
self.plotClosedLoop(t_out, y_out)
524546
w = np.logspace(-1, 3, 40).tolist()

0 commit comments

Comments
 (0)