
根轨迹法是分析和设计线性定常控制系统的一种图解方法,它是根据系统开环传递函数的零极点分布,研究当系统某一参数(通常是开环增益)从零变化到无穷大时,闭环系统特征方程的根在复平面上变化的轨迹。
对于一个负反馈控制系统,其闭环传递函数为:

其中,G(s)是前向通道传递函数,H(s)是反馈通道传递函数,G(s)H(s)是开环传递函数。闭环系统的特征方程为:1 + G(s)H(s) = 0
即: G(s)H(s) = -1
这一方程可以分解为幅值条件和相角条件:

根轨迹上的点必须同时满足这两个条件。
Python 实现示例
下面我们使用 Python 的control库来绘制一个简单系统的根轨迹:
import control
import matplotlib.pyplot as plt
import numpy as np
import warnings
# 忽略特定警告
warnings.filterwarnings("ignore", category=FutureWarning)
# 解决字体问题 - 使用通用字体
plt.rcParams["font.sans-serif"] = ["SimHei", "Arial", "sans-serif"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义开环传递函数
# G(s) = K / (s(s+1)(s+2))
num = [1] # 分子多项式系数
den = [1, 3, 2, 0] # 分母多项式系数
sys = control.TransferFunction(num, den)
# 绘制根轨迹 - 使用 rlocus 函数
plt.figure(figsize=(10, 6))
# 使用 rlocus 并处理返回值
rlist, klist = control.rlocus(sys, plot=False) # 不自动绘制
# 手动绘制根轨迹
for i in range(rlist.shape[1]):
plt.plot(rlist[:, i].real, rlist[:, i].imag, 'b-', linewidth=1.5)
# 添加坐标轴
plt.axhline(0, color='k', linestyle='--', linewidth=0.8) # 实轴
plt.axvline(0, color='k', linestyle='--', linewidth=0.8) # 虚轴
# 添加标题和标签
plt.title('系统根轨迹图')
plt.xlabel('实部')
plt.ylabel('虚部')
plt.grid(True)
plt.show()
# 分析特定增益下的闭环极点
K = 10 # 设定增益值
closed_loop_sys = control.feedback(K * sys, 1)
# 使用正确的函数名获取极点
try:
# 新版本使用 poles()
poles = closed_loop_sys.poles()
except AttributeError:
try:
# 旧版本使用 pole()
poles = control.pole(closed_loop_sys)
except AttributeError:
# 最后尝试使用 poles 属性
poles = closed_loop_sys.poles
print(f"当增益K={K}时,闭环极点为: {poles}")
# 纯英文版本(如果中文显示仍有问题)
plt.figure(figsize=(10, 6))
for i in range(rlist.shape[1]):
plt.plot(rlist[:, i].real, rlist[:, i].imag, 'b-', linewidth=1.5)
plt.axhline(0, color='k', linestyle='--', linewidth=0.8)
plt.axvline(0, color='k', linestyle='--', linewidth=0.8)
plt.title('System Root Locus')
plt.xlabel('Real Axis')
plt.ylabel('Imaginary Axis')
plt.grid(True)
plt.show()
这个示例展示了如何使用 Python 的control库绘制系统

的根轨迹,并分析特定增益下的闭环极点位置。
根轨迹的绘制可以依据一些基本法则来进行,这些法则可以帮助我们快速准确地画出根轨迹的大致形状。以下是一些主要的根轨迹绘制法则:


求得,其中 K 是开环增益。
Python 实现示例
下面我们使用 Python 实现一个更复杂系统的根轨迹绘制,并标注出分离点和与虚轴的交点:
import control
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import fsolve
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 定义开环传递函数
num = [1, 2] # 分子多项式系数
den = [1, 4, 3, 0] # 分母多项式系数
sys = control.TransferFunction(num, den)
# 绘制根轨迹
plt.figure(figsize=(10, 6))
rlist, klist = control.rlocus(sys)
# 绘制根轨迹点
for i in range(len(klist)):
plt.plot(np.real(rlist[i]), np.imag(rlist[i]), 'b-', alpha=0.7)
# 计算渐近线
poles = control.pole(sys)
zeros = control.zero(sys)
n = len(poles)
m = len(zeros)
sigma_a = (np.sum(poles) - np.sum(zeros)) / (n - m)
theta_a = [(2*k + 1) * 180 / (n - m) for k in range(n - m)]
# 绘制渐近线
x_asymptote = np.linspace(-10, 10, 100)
for angle in theta_a:
angle_rad = np.radians(angle)
y_asymptote = (x_asymptote - sigma_a) * np.tan(angle_rad)
plt.plot(x_asymptote, y_asymptote, 'g--', alpha=0.5)
# 计算分离点
def equation(s):
return 3*s**2 + 10*s + 8
s_points = fsolve(equation, [-2, -1])
for s in s_points:
plt.plot(s, 0, 'ro', markersize=8)
print(f"分离点/会合点: s = {s:.4f}")
# 计算与虚轴的交点
def imaginary_intersection(omega):
return omega**2 - 6
omega = np.sqrt(fsolve(imaginary_intersection, 2))[0]
K = 2 * omega**2
plt.plot(0, omega, 'mo', markersize=8)
plt.plot(0, -omega, 'mo', markersize=8)
print(f"与虚轴的交点: s = ±j{omega:.4f}, 对应的增益 K = {K:.4f}")
plt.title('系统根轨迹图(含渐近线、分离点和虚轴交点)')
plt.xlabel('实部')
plt.ylabel('虚部')
plt.grid(True)
plt.axis('equal')
plt.legend(['根轨迹', '渐近线', '分离点/会合点', '虚轴交点'])
plt.show()
这个示例展示了如何绘制系统

的根轨迹,并标注出渐近线、分离点和与虚轴的交点,帮助我们更全面地分析系统特性。
广义根轨迹是指除了开环增益 K 以外的其他参数变化时的根轨迹。常见的广义根轨迹包括参量根轨迹和零度根轨迹。
参量根轨迹是指系统中除开环增益以外的其他参数(如时间常数、反馈系数等)变化时的根轨迹。绘制参量根轨迹的方法与绘制常规根轨迹类似,只需将特征方程变形为关于参量的标准形式。
零度根轨迹是指相角条件为 0° 的根轨迹,常见于正反馈系统或非最小相位系统。零度根轨迹的幅值条件与常规根轨迹相同,但相角条件变为:

Python 实现示例
下面我们使用 Python 实现参量根轨迹和零度根轨迹的绘制:
import control
import matplotlib.pyplot as plt
import numpy as np
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 参量根轨迹示例: G(s) = K/(s^3 + 3s^2 + 2s + K)
# 改写特征方程为: 1 + K/(s^3 + 3s^2 + 2s) = 0
# 令G_param(s) = 1/(s^3 + 3s^2 + 2s)
num_param = [1]
den_param = [1, 3, 2, 0]
sys_param = control.TransferFunction(num_param, den_param)
plt.figure(figsize=(10, 6))
rlist_param, klist_param = control.rlocus(sys_param)
plt.title('参量根轨迹示例')
plt.xlabel('实部')
plt.ylabel('虚部')
plt.grid(True)
plt.show()
# 零度根轨迹示例: 正反馈系统
# G(s) = K/(s(s+1)(s+2)), 正反馈
# 特征方程: 1 - G(s) = 0 -> G(s) = 1
# 幅值条件: |G(s)| = 1, 相角条件: ∠G(s) = 0°
# 可以通过修改rlocus函数的参数来绘制零度根轨迹
# 定义开环传递函数
num_pos = [1]
den_pos = [1, 3, 2, 0]
sys_pos = control.TransferFunction(num_pos, den_pos)
plt.figure(figsize=(10, 6))
# 为了绘制零度根轨迹,我们需要自定义角度计算
sys_neg = control.TransferFunction(num_pos, den_pos)
rlist_pos, klist_pos = control.rlocus(sys_neg)
plt.title('零度根轨迹示例(正反馈系统)')
plt.xlabel('实部')
plt.ylabel('虚部')
plt.grid(True)
plt.show()

这个示例展示了如何绘制参量根轨迹和零度根轨迹。参量根轨迹通过将特征方程变形为关于参量的标准形式来实现,而零度根轨迹则通过修改系统的符号来模拟正反馈系统。
根轨迹图可以直观地反映系统参数变化时闭环极点的分布情况,从而帮助我们分析系统的性能。主要从以下几个方面进行分析:
Python 实现示例
下面我们使用 Python 分析根轨迹与系统性能之间的关系:
import control
import matplotlib.pyplot as plt
import numpy as np
# 设置中文显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义开环传递函数
# G(s) = K / (s(s+1)(s+5))
num = [1]
den = [1, 6, 5, 0]
sys = control.TransferFunction(num, den)
# 绘制根轨迹
plt.figure(figsize=(12, 10))
plt.subplot(2, 2, 1)
rlist, klist = control.rlocus(sys)
plt.title('系统根轨迹图')
plt.xlabel('实部')
plt.ylabel('虚部')
plt.grid(True)
# 分析不同增益下的系统性能
gains = [0.5, 5, 25]
plt.subplot(2, 2, 2)
for K in gains:
# 计算闭环传递函数
closed_loop_sys = control.feedback(K * sys, 1)
# 计算阶跃响应
t, y = control.step_response(closed_loop_sys)
# 绘制阶跃响应曲线
plt.plot(t, y, label=f'K={K}')
# 分析系统性能
poles = control.pole(closed_loop_sys)
print(f"增益 K={K} 时:")
print(f" 闭环极点: {poles}")
# 计算阻尼比和自然频率(对于主导极点)
if np.max(np.real(poles)) < 0: # 确保系统稳定
dominant_pole = poles[np.argmax(np.abs(np.imag(poles)))]
sigma = np.real(dominant_pole)
omega = np.abs(dominant_pole)
zeta = -sigma / omega
print(f" 主导极点: {dominant_pole}")
print(f" 阻尼比: ζ = {zeta:.4f}")
print(f" 自然频率: ωn = {omega:.4f} rad/s")
# 计算性能指标
overshoot = np.exp(-zeta * np.pi / np.sqrt(1 - zeta**2)) * 100
settling_time = 4.6 / (zeta * omega) # 2%误差带
print(f" 超调量: {overshoot:.2f}%")
print(f" 调节时间: {settling_time:.4f}s")
print("-" * 40)
plt.title('不同增益下的阶跃响应')
plt.xlabel('时间 (s)')
plt.ylabel('输出')
plt.legend()
plt.grid(True)
# 绘制阻尼比线
plt.subplot(2, 2, 1)
zetas = [0.2, 0.4, 0.6, 0.8]
omega_n = 5
for zeta in zetas:
theta = np.arccos(zeta)
x = np.linspace(-omega_n, 0, 100)
y = x * np.tan(theta)
plt.plot(x, y, 'g--', alpha=0.5)
plt.plot(x, -y, 'g--', alpha=0.5)
plt.text(-2, -2*np.tan(theta), f'ζ={zeta}')
plt.show()

这个示例展示了如何通过根轨迹分析系统性能。我们绘制了不同增益下的阶跃响应曲线,并计算了相应的性能指标(如超调量、调节时间等)。同时,在根轨迹图上添加了阻尼比线,帮助我们直观地了解阻尼比与极点位置的关系。
控制系统的复域设计是指利用根轨迹法在复平面上设计控制器,使系统满足给定的性能指标。常见的复域设计方法包括增益调整、串联校正和反馈校正等。
增益调整是最简单的控制系统设计方法,通过选择合适的开环增益,使闭环极点位于复平面上满足性能指标的区域。
串联校正是指在系统前向通道中串联一个校正装置,以改善系统的性能。常见的串联校正装置有:
Python 实现示例
下面我们使用 Python 实现一个控制系统的复域设计:
import control
import matplotlib.pyplot as plt
import numpy as np
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 原系统开环传递函数
# G(s) = 1 / (s(s+1)(s+5))
num_original = [1]
den_original = [1, 6, 5, 0]
sys_original = control.TransferFunction(num_original, den_original)
# 设计要求: 阻尼比 ζ = 0.5, 自然频率 ωn ≥ 2 rad/s
# 期望的主导极点位置: s = -ζωn ± jωn√(1-ζ²)
zeta = 0.5
omega_n = 2.5
s_desired = complex(-zeta*omega_n, omega_n*np.sqrt(1-zeta**2))
print(f"期望的主导极点位置: {s_desired}")
# 计算满足主导极点的增益
angle_G = np.angle(control.evalfr(sys_original, s_desired), deg=True)
print(f"原系统在期望极点处的相角: {angle_G:.2f}°")
# 需要补偿的相角
angle_needed = 180 - angle_G
print(f"需要补偿的相角: {angle_needed:.2f}°")
# 设计超前校正器
# 超前校正器传递函数: Gc(s) = (s+z)/(s+p), p > z
# 最大相角补偿: φm = arcsin((α-1)/(α+1)), α = p/z
alpha = (1 + np.sin(np.radians(angle_needed))) / (1 - np.sin(np.radians(angle_needed)))
print(f"超前校正器参数 α = {alpha:.4f}")
# 选择校正器零点位置
z_c = omega_n / 2 # 选择零点位置为期望极点实部的一半
p_c = z_c * alpha
print(f"校正器零点: z = {z_c:.4f}")
print(f"校正器极点: p = {p_c:.4f}")
# 超前校正器传递函数
num_c = [1, z_c]
den_c = [1, p_c]
sys_c = control.TransferFunction(num_c, den_c)
# 校正后系统开环传递函数
sys_compensated = sys_c * sys_original
# 计算满足期望极点的增益
K = 1 / abs(control.evalfr(sys_compensated, s_desired))
print(f"需要的增益: K = {K:.4f}")
# 绘制根轨迹
plt.figure(figsize=(12, 10))
# 原系统根轨迹
plt.subplot(2, 2, 1)
rlist_original, klist_original = control.rlocus(sys_original)
plt.plot(np.real(s_desired), np.imag(s_desired), 'ro', markersize=8)
plt.title('原系统根轨迹')
plt.xlabel('实部')
plt.ylabel('虚部')
plt.grid(True)
# 校正后系统根轨迹
plt.subplot(2, 2, 2)
rlist_compensated, klist_compensated = control.rlocus(sys_compensated)
plt.plot(np.real(s_desired), np.imag(s_desired), 'ro', markersize=8)
plt.title('校正后系统根轨迹')
plt.xlabel('实部')
plt.ylabel('虚部')
plt.grid(True)
# 比较原系统和校正后系统的阶跃响应
plt.subplot(2, 2, 3)
# 获取原系统的阶跃响应
t_original, y_original = control.step_response(control.feedback(1 * sys_original, 1))
# 获取校正后系统的阶跃响应
t_compensated, y_compensated = control.step_response(control.feedback(K * sys_compensated, 1))
# 确保时间向量和响应向量长度一致
min_len = min(len(t_original), len(y_original))
plt.plot(t_original[:min_len], y_original[:min_len], 'b-', label='原系统')
min_len = min(len(t_compensated), len(y_compensated))
plt.plot(t_compensated[:min_len], y_compensated[:min_len], 'r-', label='校正后系统')
plt.title('阶跃响应比较')
plt.xlabel('时间 (s)')
plt.ylabel('输出')
plt.legend()
plt.grid(True)
# 比较原系统和校正后系统的Bode图
plt.subplot(2, 2, 4)
control.bode_plot([sys_original, K * sys_compensated], dB=True, deg=True, omega_limits=(0.1, 100))
plt.legend(['原系统', '校正后系统'])
plt.tight_layout()
plt.show()
# 分析系统性能
print("\n原系统性能分析:")
poles_original = control.pole(control.feedback(1 * sys_original, 1))
print(f" 闭环极点: {poles_original}")
print(f" 稳态值: {y_original[-1]:.4f}")
print("\n校正后系统性能分析:")
poles_compensated = control.pole(control.feedback(K * sys_compensated, 1))
print(f" 闭环极点: {poles_compensated}")
print(f" 稳态值: {y_compensated[-1]:.4f}")
# 计算超调量
def calculate_overshoot(y):
max_value = np.max(y)
steady_state = y[-1]
return (max_value - steady_state) / steady_state * 100
print(f" 原系统超调量: {calculate_overshoot(y_original):.2f}%")
print(f" 校正后系统超调量: {calculate_overshoot(y_compensated):.2f}%")
# 计算调节时间(2%误差带)
def calculate_settling_time(t, y):
steady_state = y[-1]
for i in range(len(y)):
if np.all(np.abs(y[i:] - steady_state) <= 0.02 * steady_state):
return t[i]
return t[-1]
print(f" 原系统调节时间: {calculate_settling_time(t_original, y_original):.2f}s")
print(f" 校正后系统调节时间: {calculate_settling_time(t_compensated, y_compensated):.2f}s")
这个示例展示了如何使用根轨迹法进行控制系统的复域设计。我们首先确定了期望的主导极点位置,然后设计了一个超前校正器来补偿系统的相角不足,最后比较了校正前后系统的性能。通过复域设计,我们可以显著改善系统的动态性能。
根轨迹法是分析和设计线性控制系统的重要工具,它通过图解的方式直观地展示了系统参数变化时闭环极点的运动轨迹。通过根轨迹,我们可以分析系统的稳定性、动态性能和稳态性能,并进行控制系统的设计。本章详细介绍了根轨迹法的基本概念、绘制法则、广义根轨迹、系统性能分析以及控制系统的复域设计方法,并通过 Python 代码实现了相关的分析和设计过程。
希望本文能够帮助你理解和掌握自动控制原理中的根轨迹法,为进一步学习和应用控制系统理论打下坚实的基础。