mirror of
https://github.com/gabrielkheisa/control-system.git
synced 2024-11-23 20:03:22 +07:00
Add new assignment
This commit is contained in:
parent
335927a157
commit
1366d8014b
134
Assignment 3 - Routh Table/README.md
Normal file
134
Assignment 3 - Routh Table/README.md
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
# routh_table
|
||||||
|
This dir is belong to Control System class contains with Automated Routh Table Calculator based on Python. This code 100% original made by my hand :), please leave some notes if you're going to use it. Thanks!
|
||||||
|
|
||||||
|
## Libraries
|
||||||
|
Libraries that used in this program is ```numpy``` and ```pandas```. ```numpy``` works to define and perform array while ```pandas``` is the final form after ```numpy.array``` to simplify the presentation. They imported by write..
|
||||||
|
```
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
```
|
||||||
|
|
||||||
|
## RouthStability Class
|
||||||
|
This class contains lots of procedures to simplify our Routh Stability Table Generator process.
|
||||||
|
```
|
||||||
|
def __init__(self, den):
|
||||||
|
self.den = np.array([float(item) for item in den.split()])
|
||||||
|
self.deg = len(self.den)
|
||||||
|
```
|
||||||
|
The constructor ```__init__``` takes string of coefficiens from polynomial, extract the number, and load into class variable. It also define ```self.deg``` variable to save array's length, reducing number to calling ```len()``` function
|
||||||
|
|
||||||
|
```
|
||||||
|
def set_k(self, k):
|
||||||
|
self.den = np.append(self.den, float(k))
|
||||||
|
self.deg += 1
|
||||||
|
```
|
||||||
|
This function only takes one number from user and append it to ```self.den``` which defined as gain (constant). Also ```self.deg``` will increase by one
|
||||||
|
|
||||||
|
```
|
||||||
|
def calc_routh(self):
|
||||||
|
height = (self.deg+1)//2
|
||||||
|
arr = np.zeros((height + 2,height))
|
||||||
|
for index in range(self.deg):
|
||||||
|
if index % 2 == 0:
|
||||||
|
arr[0][index//2] = self.den[index]
|
||||||
|
else:
|
||||||
|
arr[1][(index-1)//2] = self.den[index]
|
||||||
|
|
||||||
|
for i in range(2, height+2):
|
||||||
|
for j in range(height-1):
|
||||||
|
arr[i][j] = (arr[i-1][0]*arr[i-2][j+1] - arr[i-2][0]*arr[i-1][j+1])/arr[i-1][0]
|
||||||
|
arr[i][j] += 0
|
||||||
|
|
||||||
|
self.df = pd.DataFrame(arr)
|
||||||
|
self.show_tab()
|
||||||
|
if self.is_stable() == True:
|
||||||
|
print("SYSTEM IS STABLE")
|
||||||
|
else:
|
||||||
|
print("SYSTEM IS UNSTABLE")
|
||||||
|
```
|
||||||
|
```calc_routh(self)``` as the core process of this class contains initialization and process about Routh Stability Process. Firstly, it define an empty zero (basically it filled with zeros) and iteratively being inserted by ```self.den``` (refering to Routh Table principle). After that, each cell will be updated by calculating Routh Table formula. Routh Table defined as ```numpy.ndarray``` and converted to ```pandas.DataFrame``` to simplify the presentation of table. ```self.show_tab()``` is called to print the Routh Table and ```self.is_stable()``` to check system's stability.
|
||||||
|
|
||||||
|
```
|
||||||
|
def show_tab(self):
|
||||||
|
print(self.df)
|
||||||
|
```
|
||||||
|
This function print the Routh Table, should be called only if Routh Table is generated by ```calc_routh```
|
||||||
|
|
||||||
|
```
|
||||||
|
def get_table(self):
|
||||||
|
return self.df
|
||||||
|
```
|
||||||
|
This function return ```pandas.DataFrame``` contained by Routh Table
|
||||||
|
|
||||||
|
```
|
||||||
|
def is_stable(self):
|
||||||
|
flag = True
|
||||||
|
for item in self.df[0]:
|
||||||
|
if item < 0: flag = False
|
||||||
|
return flag
|
||||||
|
```
|
||||||
|
This function check the first column's value from Routh Table. The system is define as stable if and only if all the value is positive, else it's unstable
|
||||||
|
|
||||||
|
```
|
||||||
|
def get_poly(self, x):
|
||||||
|
total = 0
|
||||||
|
for i in range(self.deg):
|
||||||
|
total += self.den[self.deg-i-1]*(x**i)
|
||||||
|
print(total)
|
||||||
|
return total
|
||||||
|
```
|
||||||
|
This function initialize ```x``` value as variable on ```self.den``` polynomial and return the total
|
||||||
|
|
||||||
|
## Testing 1
|
||||||
|
The testing can follow below example:
|
||||||
|
```
|
||||||
|
# First Testing
|
||||||
|
den = input("Enter your polynomial: ")
|
||||||
|
k_in = input("Enter your K: ")
|
||||||
|
|
||||||
|
rs = RouthStability(den)
|
||||||
|
rs.set_k(k_in)
|
||||||
|
rs.calc_routh()
|
||||||
|
```
|
||||||
|
It takes coefficient of polynomial and K from user, insert it into ```RouthStability``` class as constructor parameter, insert the K value, and generate Routh Table. The result can be found below:
|
||||||
|
```
|
||||||
|
Enter your polynomial: 1 3 5 7
|
||||||
|
Enter your K: 9
|
||||||
|
0 1 2
|
||||||
|
0 1.000000 5.0 9.0
|
||||||
|
1 3.000000 7.0 0.0
|
||||||
|
2 2.666667 9.0 0.0
|
||||||
|
3 -3.125000 0.0 0.0
|
||||||
|
4 9.000000 -0.0 0.0
|
||||||
|
SYSTEM IS UNSTABLE
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing 2
|
||||||
|
```
|
||||||
|
Enter your polynomial: 11 15 19 21
|
||||||
|
Enter your K: 29
|
||||||
|
0 1 2
|
||||||
|
0 11.000000 19.0 29.0
|
||||||
|
1 15.000000 21.0 0.0
|
||||||
|
2 3.600000 29.0 0.0
|
||||||
|
3 -99.833333 0.0 0.0
|
||||||
|
4 29.000000 -0.0 0.0
|
||||||
|
SYSTEM IS UNSTABLE
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing 3
|
||||||
|
```
|
||||||
|
Enter your polynomial: 1.2 6.78 11.11
|
||||||
|
Enter your K: 3.141
|
||||||
|
0 1
|
||||||
|
0 1.200000 11.110
|
||||||
|
1 6.780000 3.141
|
||||||
|
2 10.554071 0.000
|
||||||
|
3 3.141000 0.000
|
||||||
|
SYSTEM IS STABLE
|
||||||
|
```
|
||||||
|
### Notes
|
||||||
|
Contact nanda.r.d@mail.ugm.ac.id for more information
|
||||||
|
### Links
|
||||||
|
You can access the source code here
|
||||||
|
[github.com/nandard/routh_table.git](https://github.com/nandard/routh_table.git)
|
69
Assignment 4 - PI/README.md
Normal file
69
Assignment 4 - PI/README.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Integral Effect on Control System
|
||||||
|
This dir is belong to Control System class contains with Integral Effect on Control System. This code 100% original made by my hand :), please leave some notes if you're going to use it. Thanks!
|
||||||
|
|
||||||
|
## Software
|
||||||
|
This program run in Matlab
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
`s = tf('s');` defines s as 'frequency domain' for transfer function and will be used further.
|
||||||
|
```
|
||||||
|
J = 0.01;
|
||||||
|
b = 0.1;
|
||||||
|
K = 0.01;
|
||||||
|
R = 1;
|
||||||
|
L = 0.5;
|
||||||
|
```
|
||||||
|
Those variable comes from BLDC control system.
|
||||||
|
```
|
||||||
|
Kp = 1;
|
||||||
|
% Ki = 1;
|
||||||
|
% Ki = 3;
|
||||||
|
% Ki = 5;
|
||||||
|
Ki = 7;
|
||||||
|
% Ki = 9;
|
||||||
|
```
|
||||||
|
Variable above is the constant from PI control, we're trying to varies the constant to analyze integral effect on control system
|
||||||
|
|
||||||
|
## Process
|
||||||
|
The BLDC motor control system should be defined as transfer function by initialize its numerator-denumerator and *tf()* function.
|
||||||
|
```
|
||||||
|
num_motor = [K];
|
||||||
|
den_motor = [J*L J*R+b*L R*b+K*K];
|
||||||
|
|
||||||
|
motor = tf(num_motor,den_motor)
|
||||||
|
```
|
||||||
|
Besides the plant function, the PI-control system defined by `C = tf([Kp Ki],[1 0])`. The vector is set according to PI formula which `PI = Kp * Ki/s`. After that, both of system are multiplied each others without feedback by `complete = feedback(motor*C,1);`
|
||||||
|
|
||||||
|
That system will be test with step, ramp, and impulse input by call below lines
|
||||||
|
```
|
||||||
|
subplot(311), impulse(complete); % Impulse reponse
|
||||||
|
subplot(312), step(complete); % Step Response
|
||||||
|
subplot(313), step(complete / s); % Ramp response
|
||||||
|
stepinfo(complete)
|
||||||
|
```
|
||||||
|
|
||||||
|
Since Matlab doesn't provide any steady-state error calculation, we process it by call below lines
|
||||||
|
```
|
||||||
|
[y,t] = step(complete); % Calculate Steady-State error
|
||||||
|
sse = abs(1 - y(end))
|
||||||
|
```
|
||||||
|
Last line works to limit the graph
|
||||||
|
```
|
||||||
|
xlim([0 50])
|
||||||
|
ylim([0 3])
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
| Kp = 1 | Ki = 1 | Ki = 3 | Ki = 5 | Ki = 7 | Ki = 9 |
|
||||||
|
|--- |--- |--- |--- |--- |--- |
|
||||||
|
| Rise Time | 22.7723 | 6.7782 | 3.5914 | 2.3175 | 2.3175 |
|
||||||
|
| Settling Time | 40.3716 | 12.1907 | 6.3158 | 3.6779 | 3.6779 |
|
||||||
|
| Overshoot | 0 | 0 | 0 | 0.3523 | 0 |
|
||||||
|
| SSE | 1.7396e-06 | 0.0034 | 0.0033 | 0.0034 | 6.6536e-05 |
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
Contact nanda.r.d@mail.ugm.ac.id for more information
|
||||||
|
### Links
|
||||||
|
You can access the source code here
|
||||||
|
[github.com/nandard/routh_table.git](https://github.com/nandard/routh_table.git)
|
35
Assignment 4 - PI/integral_tf.m
Normal file
35
Assignment 4 - PI/integral_tf.m
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
% Variable
|
||||||
|
s = tf('s');
|
||||||
|
J = 0.01;
|
||||||
|
b = 0.1;
|
||||||
|
K = 0.01;
|
||||||
|
R = 1;
|
||||||
|
L = 0.5;
|
||||||
|
|
||||||
|
Kp = 1;
|
||||||
|
% Ki = 1;
|
||||||
|
% Ki = 3;
|
||||||
|
% Ki = 5;
|
||||||
|
Ki = 7;
|
||||||
|
% Ki = 9;
|
||||||
|
|
||||||
|
% Define Transfer Function
|
||||||
|
num_motor = [K];
|
||||||
|
den_motor = [J*L J*R+b*L R*b+K*K];
|
||||||
|
|
||||||
|
motor = tf(num_motor,den_motor)
|
||||||
|
% Define Control Function
|
||||||
|
C = tf([Kp Ki],[1 0])
|
||||||
|
% Define Closed-Loop function
|
||||||
|
complete = feedback(motor*C,1);
|
||||||
|
% Process system responses
|
||||||
|
subplot(311), impulse(complete); % Impulse reponse
|
||||||
|
subplot(312), step(complete); % Step Response
|
||||||
|
subplot(313), step(complete / s); % Ramp response
|
||||||
|
stepinfo(complete)
|
||||||
|
% Calculate the Stead-State Error
|
||||||
|
[y,t] = step(complete); % Calculate Steady-State error
|
||||||
|
sse = abs(1 - y(end))
|
||||||
|
% Limit the graph
|
||||||
|
xlim([0 50])
|
||||||
|
ylim([0 3])
|
128
README.md
128
README.md
@ -1,132 +1,6 @@
|
|||||||
# routh_table
|
# routh_table
|
||||||
This repo is belong to Control System class contains with Automated Routh Table Calculator based on Python. This code 100% original made by my hand :), please leave some notes if you're going to use it. Thanks!
|
This repo is belong to Control System class and Mr. Muhammad Auzan as lecturer. This code 100% original made by my hand :), please leave some notes if you're going to use it. Thanks!
|
||||||
|
|
||||||
## Libraries
|
|
||||||
Libraries that used in this program is ```numpy``` and ```pandas```. ```numpy``` works to define and perform array while ```pandas``` is the final form after ```numpy.array``` to simplify the presentation. They imported by write..
|
|
||||||
```
|
|
||||||
import numpy as np
|
|
||||||
import pandas as pd
|
|
||||||
```
|
|
||||||
|
|
||||||
## RouthStability Class
|
|
||||||
This class contains lots of procedures to simplify our Routh Stability Table Generator process.
|
|
||||||
```
|
|
||||||
def __init__(self, den):
|
|
||||||
self.den = np.array([float(item) for item in den.split()])
|
|
||||||
self.deg = len(self.den)
|
|
||||||
```
|
|
||||||
The constructor ```__init__``` takes string of coefficiens from polynomial, extract the number, and load into class variable. It also define ```self.deg``` variable to save array's length, reducing number to calling ```len()``` function
|
|
||||||
|
|
||||||
```
|
|
||||||
def set_k(self, k):
|
|
||||||
self.den = np.append(self.den, float(k))
|
|
||||||
self.deg += 1
|
|
||||||
```
|
|
||||||
This function only takes one number from user and append it to ```self.den``` which defined as gain (constant). Also ```self.deg``` will increase by one
|
|
||||||
|
|
||||||
```
|
|
||||||
def calc_routh(self):
|
|
||||||
height = (self.deg+1)//2
|
|
||||||
arr = np.zeros((height + 2,height))
|
|
||||||
for index in range(self.deg):
|
|
||||||
if index % 2 == 0:
|
|
||||||
arr[0][index//2] = self.den[index]
|
|
||||||
else:
|
|
||||||
arr[1][(index-1)//2] = self.den[index]
|
|
||||||
|
|
||||||
for i in range(2, height+2):
|
|
||||||
for j in range(height-1):
|
|
||||||
arr[i][j] = (arr[i-1][0]*arr[i-2][j+1] - arr[i-2][0]*arr[i-1][j+1])/arr[i-1][0]
|
|
||||||
arr[i][j] += 0
|
|
||||||
|
|
||||||
self.df = pd.DataFrame(arr)
|
|
||||||
self.show_tab()
|
|
||||||
if self.is_stable() == True:
|
|
||||||
print("SYSTEM IS STABLE")
|
|
||||||
else:
|
|
||||||
print("SYSTEM IS UNSTABLE")
|
|
||||||
```
|
|
||||||
```calc_routh(self)``` as the core process of this class contains initialization and process about Routh Stability Process. Firstly, it define an empty zero (basically it filled with zeros) and iteratively being inserted by ```self.den``` (refering to Routh Table principle). After that, each cell will be updated by calculating Routh Table formula. Routh Table defined as ```numpy.ndarray``` and converted to ```pandas.DataFrame``` to simplify the presentation of table. ```self.show_tab()``` is called to print the Routh Table and ```self.is_stable()``` to check system's stability.
|
|
||||||
|
|
||||||
```
|
|
||||||
def show_tab(self):
|
|
||||||
print(self.df)
|
|
||||||
```
|
|
||||||
This function print the Routh Table, should be called only if Routh Table is generated by ```calc_routh```
|
|
||||||
|
|
||||||
```
|
|
||||||
def get_table(self):
|
|
||||||
return self.df
|
|
||||||
```
|
|
||||||
This function return ```pandas.DataFrame``` contained by Routh Table
|
|
||||||
|
|
||||||
```
|
|
||||||
def is_stable(self):
|
|
||||||
flag = True
|
|
||||||
for item in self.df[0]:
|
|
||||||
if item < 0: flag = False
|
|
||||||
return flag
|
|
||||||
```
|
|
||||||
This function check the first column's value from Routh Table. The system is define as stable if and only if all the value is positive, else it's unstable
|
|
||||||
|
|
||||||
```
|
|
||||||
def get_poly(self, x):
|
|
||||||
total = 0
|
|
||||||
for i in range(self.deg):
|
|
||||||
total += self.den[self.deg-i-1]*(x**i)
|
|
||||||
print(total)
|
|
||||||
return total
|
|
||||||
```
|
|
||||||
This function initialize ```x``` value as variable on ```self.den``` polynomial and return the total
|
|
||||||
|
|
||||||
## Testing 1
|
|
||||||
The testing can follow below example:
|
|
||||||
```
|
|
||||||
# First Testing
|
|
||||||
den = input("Enter your polynomial: ")
|
|
||||||
k_in = input("Enter your K: ")
|
|
||||||
|
|
||||||
rs = RouthStability(den)
|
|
||||||
rs.set_k(k_in)
|
|
||||||
rs.calc_routh()
|
|
||||||
```
|
|
||||||
It takes coefficient of polynomial and K from user, insert it into ```RouthStability``` class as constructor parameter, insert the K value, and generate Routh Table. The result can be found below:
|
|
||||||
```
|
|
||||||
Enter your polynomial: 1 3 5 7
|
|
||||||
Enter your K: 9
|
|
||||||
0 1 2
|
|
||||||
0 1.000000 5.0 9.0
|
|
||||||
1 3.000000 7.0 0.0
|
|
||||||
2 2.666667 9.0 0.0
|
|
||||||
3 -3.125000 0.0 0.0
|
|
||||||
4 9.000000 -0.0 0.0
|
|
||||||
SYSTEM IS UNSTABLE
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing 2
|
|
||||||
```
|
|
||||||
Enter your polynomial: 11 15 19 21
|
|
||||||
Enter your K: 29
|
|
||||||
0 1 2
|
|
||||||
0 11.000000 19.0 29.0
|
|
||||||
1 15.000000 21.0 0.0
|
|
||||||
2 3.600000 29.0 0.0
|
|
||||||
3 -99.833333 0.0 0.0
|
|
||||||
4 29.000000 -0.0 0.0
|
|
||||||
SYSTEM IS UNSTABLE
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing 3
|
|
||||||
```
|
|
||||||
Enter your polynomial: 1.2 6.78 11.11
|
|
||||||
Enter your K: 3.141
|
|
||||||
0 1
|
|
||||||
0 1.200000 11.110
|
|
||||||
1 6.780000 3.141
|
|
||||||
2 10.554071 0.000
|
|
||||||
3 3.141000 0.000
|
|
||||||
SYSTEM IS STABLE
|
|
||||||
```
|
|
||||||
### Notes
|
### Notes
|
||||||
Contact nanda.r.d@mail.ugm.ac.id for more information
|
Contact nanda.r.d@mail.ugm.ac.id for more information
|
||||||
### Links
|
### Links
|
||||||
|
Loading…
Reference in New Issue
Block a user