예제 9.1 풀이
import sympy
from sympy import solve
from scipy.optimize import fsolve
import control as ct
import numpy as np
import matplotlib.pyplot as plt
zeta = 0.174
theta = np.arcsin(0.174)
radian_ = np.pi/2 - theta
np.rad2deg(radian_)
79.97953045136717
tan_factor = np.tan(np.pi/2 - theta)
tan_factor
5.659457772645189
wd/σ = 5.66
wd = 5.66 * σ
import scipy.optimize as opt
import numpy as np
def equation(x):
return -np.arctan(tan_factor*x/(10+x)) - np.arctan(tan_factor*x/(2+x))\
- np.arctan(tan_factor*x/(1+x)) - np.radians(180)
# Initial guess for x
initial_guess = 0.01
# Solve the equation numerically
solution = opt.fsolve(equation, initial_guess)
print("real number:", solution[0])
print("imaginary number:{}i".format(solution[0]*tan_factor))
real number: -0.6936132551253392 imaginary number:-3.925474927928832i
from sympy import I
s0 = solution[0]+I*solution[0]*tan_factor
print("s0 is {}".format(s0))
K_notcompansated = abs(s0+10)*abs(s0+2)*abs(s0+1)
K_notcompansated
s0 is -0.693613255125339 - 3.92547492792883*I
from sympy import I, atan2, im, re, Abs
# Function to calculate the angle of a complex number in radians
def complex_angle(expr):
return atan2(im(expr), re(expr))
# Calculate the angles
angle1 = complex_angle(s0 + 10)
angle2 = complex_angle(s0 + 2)
angle3 = complex_angle(s0 + 1)
# Sum of angles
total_angle = angle1 + angle2 + angle3
print("Total angle in radians:", total_angle)
# If you want to convert the angle to degrees
total_angle_degrees = total_angle * 180 / sympy.pi
print("Total angle in degrees:", total_angle_degrees)
Total angle in radians: -3.14159265358979 Total angle in degrees: -565.486677646163/pi
K = K_notcompansated
s = sympy.Symbol('s')
G = 1/((s+10)*(s+1)*(s+2))
CLTF = K * G /(1+K*G)
CLTF = sympy.cancel(CLTF)
OLTF = K*G
#유리식을 약분
#cancle이 없으면 약분하지 않음.
#3차식이 6차식으로 바뀜.
#sympy.cancel(CLTF)
num, den = [[float(i) for i in sympy.Poly(i, s).all_coeffs()] for i in CLTF.as_numer_denom()]
num_ol, den_ol = [[float(i) for i in sympy.Poly(i, s).all_coeffs()] for i in OLTF.as_numer_denom()]
CLTF_system = ct.TransferFunction(num, den)
OLTF_system = ct.TransferFunction(num_ol, den_ol)
CLTF_system
OLTF_system
wn, zetas, poles = ct.damp(CLTF_system)
Eigenvalue (pole) Damping Frequency -11.61 1 11.61 -10 1 10 -0.6936 +3.925j 0.174 3.986 -0.6936 -3.925j 0.174 3.986 -2 1 2 -1 1 1
ct.root_locus(CLTF_system, plot = True)
# Customize the plot (optional)
plt.title('Root Locus Plot')
plt.xlabel('Real Axis')
plt.ylabel('Imaginary Axis')
plt.grid(True)
plt.show()
# Time vector
time, response = ct.step_response(CLTF_system)
# Plot the step response
plt.plot(time, response)
plt.title('Step Response')
plt.xlabel('Time (seconds)')
plt.ylabel('Amplitude')
plt.grid(True)
# Set x-axis limits
plt.xlim(0, 10) # x-axis will range from 0 to 10
plt.show()
ct.step_info(CLTF_system)
{'RiseTime': 0.32087752924572477, 'SettlingTime': 5.1459248208666235, 'SettlingMin': 0.6149955074584611, 'SettlingMax': 1.3734915686374334, 'Overshoot': 54.04487150851232, 'Undershoot': 0, 'Peak': 1.3734915686374334, 'PeakTime': 0.8913264701270133, 'SteadyStateValue': 0.8916178482199818}
compensator = K(s+0.1)/s
s0는 compensator를 추가하기 전에 구했음.
s0
## compansated system의 gain
K_compansated = abs(s0+10)*abs(s0+2)*abs(s0+1)*abs(s0+0.1) /abs(s0)
print("compansated system의 새로운 gain은 {}".format(K_compansated))
compansated system의 새로운 gain은 163.864466237033
from sympy import I, atan2, im, re, Abs
import sympy
# Function to calculate the angle of a complex number in radians
def complex_angle(expr):
return atan2(im(expr), re(expr))
# Calculate the angles
angle1 = complex_angle(s0 + 10)
angle2 = complex_angle(s0 + 2)
angle3 = complex_angle(s0 + 1)
angle4 = complex_angle(s0)
angle5 = complex_angle(s0+0.1)
# Sum of angles
total_angle = angle1 + angle2 + angle3 + angle4 -angle5
print("Total angle in radians:", total_angle)
# If you want to convert the angle to degrees
total_angle_degrees = total_angle * 180 / sympy.pi
print("Total angle in degrees:", total_angle_degrees)
Total angle in radians: -3.16639922089135 Total angle in degrees: -569.951859760442/pi
ideal_compensator = (s+0.1)/(s)
ideal_compensator
K2 = K_compansated
CLTF_compensated = K2 * G * ideal_compensator /(1 + K2 * G * ideal_compensator)
CLTF_compensated = sympy.cancel(CLTF_compensated)
num_com, den_com = [[float(i) for i in sympy.Poly(i, s).all_coeffs()] for i in CLTF_compensated.as_numer_denom()]
CLTF_compensated_system = ct.TransferFunction(num_com, den_com)
CLTF_compensated
wn_com, zeta_com, poles_com = ct.damp(CLTF_compensated_system)
Eigenvalue (pole) Damping Frequency -11.6 1 11.6 -10 1 10 -0.6561 +3.897j 0.166 3.951 -0.6561 -3.897j 0.166 3.951 -2 1 2 -1 1 1 -0.0905 1 0.0905
damping_ratio = 0.166
#compansated system
# Time vector
time, response = ct.step_response(CLTF_compensated_system)
# Plot the step response
plt.plot(time, response)
plt.title('Step Response')
plt.xlabel('Time (seconds)')
plt.ylabel('Amplitude')
plt.grid(True)
# Set x-axis limits
plt.xlim(0, 10) # x-axis will range from 0 to 10
#uncompansated system
# Time vector
time, response = ct.step_response(CLTF_system)
# Plot the step response
plt.plot(time, response)
plt.title('Step Response')
plt.xlabel('Time (seconds)')
plt.ylabel('Amplitude')
plt.grid(True)
# Set x-axis limits
plt.xlim(0, 10) # x-axis will range from 0 to 10
plt.show()
ct.step_info(CLTF_compensated_system)
{'RiseTime': 0.3359298355175059, 'SettlingTime': 17.39200375701996, 'SettlingMin': 0.6214103019543759, 'SettlingMax': 1.4131621197095117, 'Overshoot': 41.316211970951166, 'Undershoot': 0, 'Peak': 1.4131621197095117, 'PeakTime': 0.9009027407060384, 'SteadyStateValue': 1.0}