Skip to content

Commit 0c0f15b

Browse files
committed
new version
1 parent 3a2c927 commit 0c0f15b

File tree

19 files changed

+545
-483
lines changed

19 files changed

+545
-483
lines changed

examples/1_example.py

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,79 @@
11
import numpy as np
22
import matplotlib.pyplot as plt
3-
import control as ctl
3+
import scipy.signal as scipysig
44
from vrft import *
55

66
def generateNoise(t):
77
omega = 2*np.pi*100
88
xi = 0.9
9+
dt = t[1] - t[0]
910
noise = np.random.normal(0,0.1,t.size)
11+
tf = scipysig.TransferFunction([10*omega**2], [1, 2*xi*omega, omega**2])
1012
# Second order system
11-
yn,t,x = ctl.lsim(ctl.tf([10*omega**2], [1, 2*xi*omega, omega**2]), \
12-
noise, t)
13+
_, yn, _ = scipysig.lsim(tf, noise, t)
1314
return yn
1415

1516
#Generate time and u(t) signals
1617
t_start = 0
1718
t_end = 10
1819
t_step = 1e-2
1920
t = np.arange(t_start, t_end, t_step)
20-
u = np.ones(len(t)).tolist()
21+
u = np.ones(len(t))
2122
u[200:400] = np.zeros(200)
2223
u[600:800] = np.zeros(200)
2324

2425
#Experiment
2526
num = [0.5]
2627
den = [1, -0.9]
27-
sys = ctl.tf(num, den, t_step)
28-
y,t,x= ctl.lsim(sys, u, t)
28+
sys = ExtendedTF(num, den, dt=t_step)
29+
t, y = scipysig.dlsim(sys, u, t)
30+
y = y[:, 0]
2931
y += generateNoise(t)
30-
data = vrft.iddata(y[0],u,t_step,[0])
32+
data = iddata(y, u, t_step, [0])
33+
3134

3235
#Reference Model
33-
refModel = ctl.tf([0.6], [1, -0.4], t_step)
36+
refModel = ExtendedTF([0.6], [1, -0.4], dt=t_step)
3437

3538
#PI Controller
36-
base = [ctl.tf([1], [1],t_step),
37-
ctl.tf([1, 0], [1, -1],t_step)]
39+
base = [ExtendedTF([1], [1, -1], dt=t_step),
40+
ExtendedTF([1, 0], [1, -1], dt=t_step)]
3841

3942
#Experiment filter
40-
omega = 2*np.pi*0.1
41-
L = ctl.tf([1], [1/omega, 1])
42-
L = ctl.sample_system(L, 0.01)
43-
43+
L = refModel * (1 - refModel)
4444
#VRFT
45-
C, theta, r = vrft.vrftAlgorithm(data, refModel, base, L)
45+
theta, r, _, _, C = compute_vrft(data, refModel, base, L)
4646

4747
#Obtained controller
48-
print "Controller:", C
49-
L = C*sys
50-
L = L/(1+L)
48+
print("Controller: {}".format(C))
5149

52-
L = L.minreal()
53-
#this is due to a bug in the control library
54-
L = ctl.tf(L.num, L.den, t_step)
50+
L = C * sys
51+
L = feedback(L)
5552

56-
print "Theta:", theta
53+
print("Theta: {}".format(theta))
5754

5855
#Analysis
59-
yr,t = ctl.step(refModel, t)
60-
yc,t = ctl.step(L, t)
61-
ys,t = ctl.step(sys, t)
62-
63-
56+
t = t[:len(r)]
57+
u = np.ones(len(t))
58+
_, yr = scipysig.dlsim(refModel, u, t)
59+
_, yc = scipysig.dlsim(L, u, t)
60+
_, ys = scipysig.dlsim(sys, u, t)
61+
62+
yr = np.array(yr).flatten()
63+
ys = np.array(ys).flatten()
64+
yc = np.array(yc).flatten()
6465
fig, ax = plt.subplots(4, sharex=True)
65-
ax[0].plot(t,yr[0],label='Ref System')
66-
ax[0].plot(t,yc[0], label='CL System')
66+
ax[0].plot(t, yr,label='Ref System')
67+
ax[0].plot(t, yc, label='CL System')
6768
ax[0].set_title('Systems response')
6869
ax[0].grid(True)
69-
ax[1].plot(t,ys[0], label='OL System')
70+
ax[1].plot(t, ys, label='OL System')
7071
ax[1].set_title('OL Systems response')
7172
ax[1].grid(True)
72-
ax[2].plot(t,y[0])
73+
ax[2].plot(t, y[:len(r)])
7374
ax[2].grid(True)
7475
ax[2].set_title('Experiment data')
75-
ax[3].plot(t,r)
76+
ax[3].plot(t, r)
7677
ax[3].grid(True)
7778
ax[3].set_title('Virtual Reference')
7879

setup.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
from setuptools import setup
22

33
setup(name = 'vrft',
4-
version = '0.0.2',
4+
version = '0.0.3',
55
description = 'VRFT Python Library',
66
long_description = 'VRFT Python Library',
77
keywords = 'VRFT Virtual Reference Feedback Tuning Adaptive Control',
88
url = 'https://github.com/rssalessio/PythonVRFT/',
99
author = 'Alessio Russo',
10-
author_email = 'alessio.russo@rapyuta-robotics.com',
10+
author_email = 'alessior@kth.se',
1111
license='GPL3',
12-
packages=['vrft', 'vrft.tests', 'vrft.utilities', 'vrft.vrft'],
12+
packages=['vrft', 'test', 'vrft.utilities', 'vrft.vrft'],
1313
zip_safe=False,
1414
install_requires = [
1515
'scipy',
1616
'numpy',
17-
'control',
1817
],
1918
test_suite = 'nose.collector',
2019
test_requires = ['nose']

test/__init__.py

Whitespace-only changes.

test/test_iddata.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from unittest import TestCase
2+
from vrft.utilities.iddata import iddata
3+
import numpy as np
4+
5+
class TestIDData(TestCase):
6+
def test_type(self):
7+
a = iddata(0.0, 0.0, 0.0)
8+
with self.assertRaises(ValueError):
9+
a.checkData()
10+
11+
a = iddata(0.0, [1], 0.0)
12+
with self.assertRaises(ValueError):
13+
a.checkData()
14+
15+
a = iddata(np.zeros(10), 1, 0.0)
16+
with self.assertRaises(ValueError):
17+
a.checkData()
18+
19+
a = iddata([0 for i in range(10)], [0 for i in range(10)], 1.0)
20+
self.assertTrue(a.checkData())
21+
22+
a = iddata(np.zeros(10), np.zeros(10), 1.0)
23+
self.assertTrue(a.checkData())
24+
25+
def test_size(self):
26+
a = iddata(np.zeros(10), np.zeros(10), 0.0)
27+
self.assertEqual(len(a.y), 10)
28+
self.assertEqual(len(a.u), 10)
29+
self.assertEqual(len(a.y), len(a.u))
30+
31+
a = iddata([0 for i in range(10)], [1 for i in range(0,10)], 0.0)
32+
self.assertEqual(len(a.y), 10)
33+
self.assertEqual(len(a.u), 10)
34+
self.assertEqual(len(a.y), len(a.u))
35+
36+
a = iddata(np.zeros(10), np.zeros(9), 0.0)
37+
with self.assertRaises(ValueError):
38+
a.checkData()
39+
40+
a = iddata(np.zeros(8), np.zeros(9), 0.0)
41+
with self.assertRaises(ValueError):
42+
a.checkData()
43+
44+
45+
def test_sampling_time(self):
46+
a = iddata(np.zeros(10), np.zeros(10), 0.0)
47+
with self.assertRaises(ValueError):
48+
a.checkData()
49+
50+
a = iddata(np.zeros(10), np.zeros(10), 1e-9)
51+
with self.assertRaises(ValueError):
52+
a.checkData()
53+
54+
a = iddata(np.zeros(10), np.zeros(10), -0.1)
55+
with self.assertRaises(ValueError):
56+
a.checkData()
57+
58+
a = iddata(np.zeros(10), np.zeros(10), 0.1)
59+
self.assertTrue(a.checkData())
60+

test/test_reference.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from unittest import TestCase
2+
from vrft.utilities.iddata import *
3+
from vrft.utilities.utils import *
4+
from vrft.vrft.vrft_algo import *
5+
import numpy as np
6+
import scipy.signal as scipysig
7+
8+
class TestReference(TestCase):
9+
def test_virtualReference(self):
10+
# wrong system
11+
with self.assertRaises(ValueError):
12+
virtualReference(1, 1, 0)
13+
14+
# cant be constant the system
15+
with self.assertRaises(ValueError):
16+
virtualReference([1],[1], 0)
17+
18+
# cant be constant the system
19+
with self.assertRaises(ValueError):
20+
virtualReference(np.array(2), np.array(3), 0)
21+
22+
# wrong data
23+
with self.assertRaises(ValueError):
24+
virtualReference([1], [1, 1], 0)
25+
26+
t_start = 0
27+
t_end = 10
28+
t_step = 1e-2
29+
t = np.arange(t_start, t_end, t_step)
30+
u = np.ones(len(t)).tolist()
31+
32+
num = [0.1]
33+
den = [1, -0.9]
34+
sys = scipysig.TransferFunction(num, den, dt=t_step)
35+
t,y = scipysig.dlsim(sys, u, t)
36+
y = y[:,0]
37+
data = iddata(y,u,t_step,[0,0])
38+
#wrong initial conditions
39+
with self.assertRaises(ValueError):
40+
virtualReference(data, num, den)
41+
42+
#wrong initial conditions
43+
data = iddata(y,u,t_step,[0,0,0])
44+
with self.assertRaises(ValueError):
45+
virtualReference(data, num, den)
46+
47+
#test good data, first order
48+
data = iddata(y,u,t_step,[0])
49+
50+
r, _ = virtualReference(data, num, den)
51+
52+
for i in range(len(r)):
53+
self.assertTrue(np.isclose(r[i], u[i]))
54+
55+
56+
num = [0, 1-1.6+0.63]
57+
den = [1, -1.6, 0.63]
58+
sys = scipysig.TransferFunction(num, den, dt=t_step)
59+
t, y = scipysig.dlsim(sys, u, t)
60+
y = y[:,0]
61+
data = iddata(y,u,t_step,[0,0])
62+
#test second order
63+
r, _ = virtualReference(data, num, den)
64+
for i in range(len(r)):
65+
self.assertTrue(np.isclose(r[i], u[i]))

test/test_tf.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from unittest import TestCase
2+
from vrft.utilities.utils import *
3+
import numpy as np
4+
5+
class TestTF(TestCase):
6+
def test_checkSystem(self):
7+
a = [1, 0, 1]
8+
b = [1, 0, 2]
9+
self.assertTrue(checkSystem(a,b))
10+
11+
b = [1, 0, 2, 4]
12+
self.assertTrue(checkSystem(a,b))
13+
14+
a = [1]
15+
self.assertTrue(checkSystem(a,b))
16+
17+
a = [1, 0, 1]
18+
b = [1,0]
19+
with self.assertRaises(ValueError):
20+
checkSystem(a,b)
21+
22+
b = [1]
23+
with self.assertRaises(ValueError):
24+
checkSystem(a,b)
25+
26+
def test_systemOrder(self):
27+
with self.assertRaises(ValueError):
28+
systemOrder(0, 0)
29+
30+
with self.assertRaises(ValueError):
31+
systemOrder(1, 0)
32+
33+
with self.assertRaises(ValueError):
34+
systemOrder([0], 0)
35+
36+
with self.assertRaises(ValueError):
37+
systemOrder([0], [0])
38+
39+
with self.assertRaises(ValueError):
40+
systemOrder([0, 0], [0, 0])
41+
42+
with self.assertRaises(ValueError):
43+
systemOrder([0], [0, 0])
44+
45+
46+
self.assertEqual(systemOrder([1],[1]), (0, 0))
47+
self.assertEqual(systemOrder([1, 1],[1, 1]), (1,1))
48+
self.assertEqual(systemOrder([1, 1, 3],[1, 1]), (2,1))
49+
self.assertEqual(systemOrder([1, 1, 3],[1]), (2,0))
50+
self.assertEqual(systemOrder([1, 1],[1, 1, 1]), (1,2))
51+
self.assertEqual(systemOrder([1],[1, 1, 1]), (0,2))
52+
self.assertEqual(systemOrder([0, 1],[1, 1, 1]), (0,2))
53+
self.assertEqual(systemOrder([0,0,1],[1, 1, 1]), (0,2))
54+
self.assertEqual(systemOrder([0,0,1],[0, 1, 1, 1]), (0,2))
55+
self.assertEqual(systemOrder([0,0,1],[0, 0, 1, 1, 1]), (0,2))

test/test_vrft.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from unittest import TestCase
2+
from vrft.utilities.iddata import *
3+
from vrft.vrft.vrft_algo import *
4+
from vrft.utilities.utils import ExtendedTF
5+
import numpy as np
6+
import scipy.signal as scipysig
7+
8+
class TestVRFT(TestCase):
9+
def test_vrft(self):
10+
t_start = 0
11+
t_end = 10
12+
t_step = 1e-2
13+
t = np.arange(t_start, t_end, t_step)
14+
u = np.ones(len(t)).tolist()
15+
16+
num = [0.1]
17+
den = [1, -0.9]
18+
sys = scipysig.TransferFunction(num, den, dt=t_step)
19+
t, y = scipysig.dlsim(sys, u, t)
20+
y = y[:,0]
21+
data = iddata(y,u,t_step,[0])
22+
23+
refModel = ExtendedTF([0.2], [1, -0.8], dt=t_step)
24+
25+
control = [ExtendedTF([1], [1,0], dt=t_step),
26+
ExtendedTF([1], [1,0,0], dt=t_step),
27+
ExtendedTF([1], [1,0,0,0], dt=t_step),
28+
ExtendedTF([1, 0], [1,1], dt=t_step)]
29+
30+
theta, _, _, loss, _ = compute_vrft(data, refModel, control, refModel * (1-refModel))
31+
32+
33+

vrft/__init__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import utilities
2-
from utilities import *
3-
import vrft
4-
from vrft import *
1+
2+
from .utilities import *
3+
from .vrft import *

0 commit comments

Comments
 (0)