Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitff960c3

Browse files
committed
enhance step_info to MIMO
1 parentb41574f commitff960c3

File tree

1 file changed

+100
-88
lines changed

1 file changed

+100
-88
lines changed

‎control/timeresp.py

Lines changed: 100 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -746,36 +746,43 @@ def step_info(sys, T=None, T_num=None, SettlingTimeThreshold=0.02,
746746
747747
Parameters
748748
----------
749-
sys : SISO dynamic system model. Dynamic systems that you can use include:
750-
StateSpace or TransferFunction
751-
LTI system to simulate
752-
749+
sys : LTI system
753750
T : array_like or float, optional
754751
Time vector, or simulation time duration if a number (time vector is
755752
autocomputed if not given, see :func:`step_response` for more detail)
756-
757753
T_num : int, optional
758754
Number of time steps to use in simulation if T is not provided as an
759755
array (autocomputed if not given); ignored if sys is discrete-time.
760-
761756
SettlingTimeThreshold : float value, optional
762757
Defines the error to compute settling time (default = 0.02)
763-
764758
RiseTimeLimits : tuple (lower_threshold, upper_theshold)
765759
Defines the lower and upper threshold for RiseTime computation
766760
767761
Returns
768762
-------
769-
S: a dictionary containing:
770-
RiseTime: Time from 10% to 90% of the steady-state value.
771-
SettlingTime: Time to enter inside a default error of 2%
772-
SettlingMin: Minimum value after RiseTime
773-
SettlingMax: Maximum value after RiseTime
774-
Overshoot: Percentage of the Peak relative to steady value
775-
Undershoot: Percentage of undershoot
776-
Peak: Absolute peak value
777-
PeakTime: time of the Peak
778-
SteadyStateValue: Steady-state value
763+
S : dict or list of list of dict
764+
If `sys` is a SISO system, S is a dictionary containing:
765+
766+
RiseTime:
767+
Time from 10% to 90% of the steady-state value.
768+
SettlingTime:
769+
Time to enter inside a default error of 2%
770+
SettlingMin:
771+
Minimum value after RiseTime
772+
SettlingMax:
773+
Maximum value after RiseTime
774+
Overshoot:
775+
Percentage of the Peak relative to steady value
776+
Undershoot:
777+
Percentage of undershoot
778+
Peak:
779+
Absolute peak value
780+
PeakTime:
781+
time of the Peak
782+
SteadyStateValue:
783+
Steady-state value
784+
785+
If `sys` is a MIMO system, S is a 2D-List of dicts.
779786
780787
781788
See Also
@@ -786,81 +793,86 @@ def step_info(sys, T=None, T_num=None, SettlingTimeThreshold=0.02,
786793
--------
787794
>>> info = step_info(sys, T)
788795
'''
789-
790-
ifnotsys.issiso():
791-
sys=_mimo2siso(sys,0,0)
792-
warnings.warn(" Internal conversion from a MIMO system to a SISO system,"
793-
" the first input and the first output were used (u1 -> y1);"
794-
" it may not be the result you are looking for")
796+
795797

796798
ifTisNoneornp.asarray(T).size==1:
797799
T=_default_time_vector(sys,N=T_num,tfinal=T,is_step=True)
798800

799-
T,yout=step_response(sys,T)
800-
801-
# Steady state value
802-
InfValue=sys.dcgain().real
803-
804-
# TODO: this could be a function step_info4data(t,y,yfinal)
805-
rise_time:float=np.NaN
806-
settling_time:float=np.NaN
807-
settling_min:float=np.NaN
808-
settling_max:float=np.NaN
809-
peak_value:float=np.Inf
810-
peak_time:float=np.Inf
811-
undershoot:float=np.NaN
812-
overshoot:float=np.NaN
813-
steady_state_value:float=np.NaN
814-
815-
ifnotnp.isnan(InfValue)andnotnp.isinf(InfValue):
816-
# SteadyStateValue
817-
steady_state_value=InfValue
818-
# Peak
819-
peak_index=np.abs(yout).argmax()
820-
peak_value=np.abs(yout[peak_index])
821-
peak_time=T[peak_index]
822-
823-
sup_margin= (1.+SettlingTimeThreshold)*InfValue
824-
inf_margin= (1.-SettlingTimeThreshold)*InfValue
825-
826-
# RiseTime
827-
tr_lower_index= (np.where(np.sign(InfValue.real)* (yout-RiseTimeLimits[0]*InfValue)>=0 )[0])[0]
828-
tr_upper_index= (np.where(np.sign(InfValue.real)*yout>=np.sign(InfValue.real)*RiseTimeLimits[1]*InfValue)[0])[0]
829-
830-
# SettlingTime
831-
settling_time=T[np.where(np.abs(yout-InfValue)>=np.abs(SettlingTimeThreshold*InfValue))[0][-1]+1]
832-
# Overshoot and Undershoot
833-
y_os= (np.sign(InfValue.real)*yout).max()
834-
dy_os=np.abs(y_os)-np.abs(InfValue)
835-
ifdy_os>0:
836-
overshoot=np.abs(100.*dy_os/InfValue)
837-
else:
838-
overshoot=0
839-
840-
y_us= (np.sign(InfValue.real)*yout).min()
841-
dy_us=np.abs(y_us)
842-
ifdy_us>0:
843-
undershoot=np.abs(100.*dy_us/InfValue)
844-
else:
845-
undershoot=0
846-
847-
# RiseTime
848-
rise_time=T[tr_upper_index]-T[tr_lower_index]
849-
850-
settling_max= (yout[tr_upper_index:]).max()
851-
settling_min= (yout[tr_upper_index:]).min()
852-
853-
return {
854-
'RiseTime':rise_time,
855-
'SettlingTime':settling_time,
856-
'SettlingMin':settling_min,
857-
'SettlingMax':settling_max,
858-
'Overshoot':overshoot,
859-
'Undershoot':undershoot,
860-
'Peak':peak_value,
861-
'PeakTime':peak_time,
862-
'SteadyStateValue':steady_state_value
863-
}
801+
ret= [[None]*sys.ninputs]*sys.noutputs
802+
foriinrange(sys.noutputs):
803+
forjinrange(sys.ninputs):
804+
sys_siso=sys[i,j]
805+
T,yout=step_response(sys_siso,T)
806+
807+
# Steady state value
808+
InfValue=sys_siso.dcgain()
809+
sgnInf=np.sign(InfValue.real)
810+
811+
rise_time:float=np.NaN
812+
settling_time:float=np.NaN
813+
settling_min:float=np.NaN
814+
settling_max:float=np.NaN
815+
peak_value:float=np.Inf
816+
peak_time:float=np.Inf
817+
undershoot:float=np.NaN
818+
overshoot:float=np.NaN
819+
steady_state_value:complex=np.NaN
820+
821+
ifnotnp.isnan(InfValue)andnotnp.isinf(InfValue):
822+
# RiseTime
823+
tr_lower_index=np.where(
824+
sgnInf* (yout-RiseTimeLimits[0]*InfValue)>=0
825+
)[0][0]
826+
tr_upper_index=np.where(
827+
sgnInf* (yout-RiseTimeLimits[1]*InfValue)>=0
828+
)[0][0]
829+
rise_time=T[tr_upper_index]-T[tr_lower_index]
830+
831+
# SettlingTime
832+
settling_th=np.abs(SettlingTimeThreshold*InfValue)
833+
not_settled=np.where(np.abs(yout-InfValue)>=settling_th)
834+
settling_time=T[not_settled[0][-1]+1]
835+
836+
settling_min= (yout[tr_upper_index:]).min()
837+
settling_max= (yout[tr_upper_index:]).max()
838+
839+
# Overshoot
840+
y_os= (sgnInf*yout).max()
841+
dy_os=np.abs(y_os)-np.abs(InfValue)
842+
ifdy_os>0:
843+
overshoot=np.abs(100.*dy_os/InfValue)
844+
else:
845+
overshoot=0
846+
847+
# Undershoot
848+
y_us= (sgnInf*yout).min()
849+
dy_us=np.abs(y_us)
850+
ifdy_us>0:
851+
undershoot=np.abs(100.*dy_us/InfValue)
852+
else:
853+
undershoot=0
854+
855+
# Peak
856+
peak_index=np.abs(yout).argmax()
857+
peak_value=np.abs(yout[peak_index])
858+
peak_time=T[peak_index]
859+
860+
# SteadyStateValue
861+
steady_state_value=InfValue
862+
863+
ret[i][j]= {
864+
'RiseTime':rise_time,
865+
'SettlingTime':settling_time,
866+
'SettlingMin':settling_min,
867+
'SettlingMax':settling_max,
868+
'Overshoot':overshoot,
869+
'Undershoot':undershoot,
870+
'Peak':peak_value,
871+
'PeakTime':peak_time,
872+
'SteadyStateValue':steady_state_value
873+
}
874+
875+
returnret[0][0]ifsys.issiso()elseret
864876

865877
definitial_response(sys,T=None,X0=0.,input=0,output=None,T_num=None,
866878
transpose=False,return_x=False,squeeze=None):

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp