Python-控制-步进系统
Python-control - step system
当我使用 python-control 包创建系统时:
import control
H = control.tf([1], [1])
然后想迭代模拟那个系统,我该怎么做?
我知道我能做到:
T = np.arange(0, 10, 0.01)
u = np.sin(T)
y, t, x = control.lsim(H, u, T)
但我想做的是:
Tstart = get_current_time() # returns a scalar
T = get_current_time()
x = None
while T - Tstart < 100:
u = get_next_input() # returns a scalar
T = get_current_time()
y, x = control.step_system(H, u, T, x)
do_something_with_output(y)
有什么方法可以做到这一点吗?您还应该如何使用使用控制包开发的系统来控制某些东西?
这是一个很好的问题。我自己对此很感兴趣,不久前在 Mathworks 论坛上问了一个 similar question,目前在 MATLAB 中还不可能。
好消息是,您现在可以使用 iosys module and the input_output_response
功能在 Python 控件中完成。
对于您示例中的线性系统,您使用 LinearIOSystem
class
这是我的模拟示例:
import time
import numpy as np
import matplotlib.pyplot as plt
import control
from control import input_output_response
from control.iosys import LinearIOSystem
# Define system
# Continuous-time transfer function
G = control.tf([1], [2, 1])
# Convert to state-space representation
Gss = control.ss(G)
# Construct IO system
sys = LinearIOSystem(Gss, inputs='u', outputs='y')
def get_next_input(u, avg_time=0.5):
"""Function to simulate data acquisition"""
t0 = time.time()
wait_time = avg_time*(0.5 + np.random.rand())
while time.time() - t0 < wait_time:
pass
if np.random.rand() > 0.8:
u = u + np.random.randn()
return u
# Simulate system in response to irregular inputs
t0 = time.time()
t = 0
y0 = 0
u = 0
x = np.zeros(sys.nstates)
np.random.seed(1)
sim_results = [[0, u, y0]]
print(sim_results[-1])
while t < 10:
u_new, t_new = get_next_input(u), time.time() - t0
# Simulation of system up to current time
T_sim = [t, t_new]
T_sim, Y_sim, X_sim = input_output_response(sys, T_sim, u, X0=x,
return_x=True)
sim_results.append([T_sim[-1], u_new, Y_sim[-1]])
print(sim_results[-1])
# Set current state and outputs to end of simulation period
x = X_sim[0, -1]
u = u_new
t = t_new
sim_results = np.array(sim_results)
t = sim_results[:, 0]
u = sim_results[:, 1]
y = sim_results[:, 2]
# Plot inputs and outputs
plt.subplot(2, 1, 1)
plt.plot(t, y, 'o-')
plt.xlabel('t')
plt.ylabel('y(t)')
plt.grid()
plt.subplot(2, 1, 2)
plt.step(t, u, where='post')
plt.xlabel('t')
plt.ylabel('u(t)')
plt.grid()
plt.show()
最后一个问题的回答:
How else are you supposed to use a system developed with the control package to, you know, control something?"
我认为像 MATLAB 控制模块和 python-control 这样的工具旨在用于控制系统的分析、设计和仿真,而不一定用于它们的实现。根据您的应用,通常最终的控制系统实现是在专用硬件 and/or 软件上完成的,或者可能是用 C 等低级语言手工编码的。像 MATLAB 和 Python 这样的高级语言可以说是太不可靠和难以 maintain/upgrade 使它们成为任何严肃的过程控制或现实世界机器人应用程序中有吸引力的解决方案。但对于爱好者和实验室实验来说,它们是理想的,所以我同意这种功能很有用。
当我使用 python-control 包创建系统时:
import control
H = control.tf([1], [1])
然后想迭代模拟那个系统,我该怎么做?
我知道我能做到:
T = np.arange(0, 10, 0.01)
u = np.sin(T)
y, t, x = control.lsim(H, u, T)
但我想做的是:
Tstart = get_current_time() # returns a scalar
T = get_current_time()
x = None
while T - Tstart < 100:
u = get_next_input() # returns a scalar
T = get_current_time()
y, x = control.step_system(H, u, T, x)
do_something_with_output(y)
有什么方法可以做到这一点吗?您还应该如何使用使用控制包开发的系统来控制某些东西?
这是一个很好的问题。我自己对此很感兴趣,不久前在 Mathworks 论坛上问了一个 similar question,目前在 MATLAB 中还不可能。
好消息是,您现在可以使用 iosys module and the input_output_response
功能在 Python 控件中完成。
对于您示例中的线性系统,您使用 LinearIOSystem
class
这是我的模拟示例:
import time
import numpy as np
import matplotlib.pyplot as plt
import control
from control import input_output_response
from control.iosys import LinearIOSystem
# Define system
# Continuous-time transfer function
G = control.tf([1], [2, 1])
# Convert to state-space representation
Gss = control.ss(G)
# Construct IO system
sys = LinearIOSystem(Gss, inputs='u', outputs='y')
def get_next_input(u, avg_time=0.5):
"""Function to simulate data acquisition"""
t0 = time.time()
wait_time = avg_time*(0.5 + np.random.rand())
while time.time() - t0 < wait_time:
pass
if np.random.rand() > 0.8:
u = u + np.random.randn()
return u
# Simulate system in response to irregular inputs
t0 = time.time()
t = 0
y0 = 0
u = 0
x = np.zeros(sys.nstates)
np.random.seed(1)
sim_results = [[0, u, y0]]
print(sim_results[-1])
while t < 10:
u_new, t_new = get_next_input(u), time.time() - t0
# Simulation of system up to current time
T_sim = [t, t_new]
T_sim, Y_sim, X_sim = input_output_response(sys, T_sim, u, X0=x,
return_x=True)
sim_results.append([T_sim[-1], u_new, Y_sim[-1]])
print(sim_results[-1])
# Set current state and outputs to end of simulation period
x = X_sim[0, -1]
u = u_new
t = t_new
sim_results = np.array(sim_results)
t = sim_results[:, 0]
u = sim_results[:, 1]
y = sim_results[:, 2]
# Plot inputs and outputs
plt.subplot(2, 1, 1)
plt.plot(t, y, 'o-')
plt.xlabel('t')
plt.ylabel('y(t)')
plt.grid()
plt.subplot(2, 1, 2)
plt.step(t, u, where='post')
plt.xlabel('t')
plt.ylabel('u(t)')
plt.grid()
plt.show()
最后一个问题的回答:
How else are you supposed to use a system developed with the control package to, you know, control something?"
我认为像 MATLAB 控制模块和 python-control 这样的工具旨在用于控制系统的分析、设计和仿真,而不一定用于它们的实现。根据您的应用,通常最终的控制系统实现是在专用硬件 and/or 软件上完成的,或者可能是用 C 等低级语言手工编码的。像 MATLAB 和 Python 这样的高级语言可以说是太不可靠和难以 maintain/upgrade 使它们成为任何严肃的过程控制或现实世界机器人应用程序中有吸引力的解决方案。但对于爱好者和实验室实验来说,它们是理想的,所以我同意这种功能很有用。