@@ -515,7 +515,7 @@ def feedback(self, other=1, sign=-1, params=None):
515515 # Return the newly created system
516516 return newsys
517517
518- def linearize (self , x0 , u0 , t = 0 , params = None , eps = 1e-6 ,
518+ def linearize (self , x0 , u0 = None , t = 0 , params = None , eps = 1e-6 ,
519519 copy_names = False , ** kwargs ):
520520 """Linearize an input/output system at a given state and input.
521521
@@ -526,6 +526,14 @@ def linearize(self, x0, u0, t=0, params=None, eps=1e-6,
526526 """
527527 from .statesp import StateSpace
528528
529+ # Allow first argument to be an operating point
530+ if isinstance (x0 , OperatingPoint ):
531+ if u0 is None :
532+ u0 = x0 .inputs
533+ x0 = x0 .states
534+ elif u0 is None :
535+ u0 = 0
536+
529537 #
530538 # If the linearization is not defined by the subclass, perform a
531539 # numerical linearization use the `_rhs()` and `_out()` member
@@ -1673,19 +1681,19 @@ class OperatingPoint(object):
16731681
16741682 Attributes
16751683 ----------
1676- xop : array
1684+ states : array
16771685 State vector at the operating point.
1678- uop : array
1686+ inputs : array
16791687 Input vector at the operating point.
16801688 result : :class:`scipy.optimize.OptimizeResult`, optional
16811689 Result from the :func:`scipy.optimize.root` function, if available.
16821690
16831691 """
16841692 def __init__ (
1685- self , xop , uop = None , yop = None , result = None ,
1693+ self , states , inputs = None , yop = None , result = None ,
16861694 return_y = False , return_result = False ):
1687- self .xop = xop
1688- self .uop = uop
1695+ self .states = states
1696+ self .inputs = inputs
16891697
16901698 if yop is None and return_y and not return_result :
16911699 raise SystemError ("return_y specified by no y0 value" )
@@ -1700,13 +1708,13 @@ def __init__(
17001708 # Implement iter to allow assigning to a tuple
17011709 def __iter__ (self ):
17021710 if self .return_y and self .return_result :
1703- return iter ((self .xop , self .uop , self .yop , self .result ))
1711+ return iter ((self .states , self .inputs , self .yop , self .result ))
17041712 elif self .return_y :
1705- return iter ((self .xop , self .uop , self .yop ))
1713+ return iter ((self .states , self .inputs , self .yop ))
17061714 elif self .return_result :
1707- return iter ((self .xop , self .uop , self .result ))
1715+ return iter ((self .states , self .inputs , self .result ))
17081716 else :
1709- return iter ((self .xop , self .uop ))
1717+ return iter ((self .states , self .inputs ))
17101718
17111719 # Implement (thin) getitem to allow access via legacy indexing
17121720 def __getitem__ (self , index ):
@@ -1723,10 +1731,10 @@ def find_operating_point(
17231731 root_kwargs = None , return_y = False , return_result = False ):
17241732 """Find an operating point for an input/output system.
17251733
1726- An operating point for a nonlinear system is a state `xop` and input
1727- `uop` around which a nonlinear system operates. This point is most
1728- commonly an equilibrium point for the system, but in some cases a
1729- non-equilibrium operating point can be used.
1734+ An operating point for a nonlinear system is a state and input around
1735+ which a nonlinear system operates. This point is most commonly an
1736+ equilibrium point for the system, but in some cases a non-equilibrium
1737+ operating point can be used.
17301738
17311739 This function attempts to find an operating point given a specification
17321740 for the desired inputs, outputs, states, or state updates of the system.
@@ -1802,10 +1810,10 @@ def find_operating_point(
18021810
18031811 Returns
18041812 -------
1805- xop : array of states
1813+ states : array of states
18061814 Value of the states at the equilibrium point, or `None` if no
18071815 equilibrium point was found and `return_result` was False.
1808- uop : array of input values
1816+ inputs : array of input values
18091817 Value of the inputs at the equilibrium point, or `None` if no
18101818 equilibrium point was found and `return_result` was False.
18111819 yop : array of output values, optional
@@ -2034,12 +2042,13 @@ def linearize(sys, xeq, ueq=None, t=0, params=None, **kw):
20342042 ----------
20352043 sys : InputOutputSystem
20362044 The system to be linearized.
2037- xeq : array
2038- The state at which the linearization will be evaluated (does not need
2039- to be an equilibrium state).
2040- ueq : array
2045+ xeq : array or :class:`~control.OperatingPoint`
2046+ The state or operating point at which the linearization will be
2047+ evaluated (does not need to be an equilibrium state).
2048+ ueq : array, optional
20412049 The input at which the linearization will be evaluated (does not need
2042- to correspond to an equlibrium state).
2050+ to correspond to an equlibrium state). Can be omitted if `xeq` is
2051+ an :class:`~control.OperatingPoint`. Defaults to 0.
20432052 t : float, optional
20442053 The time at which the linearization will be computed (for time-varying
20452054 systems).
@@ -2074,6 +2083,7 @@ def linearize(sys, xeq, ueq=None, t=0, params=None, **kw):
20742083 Description of the system outputs. Same format as `inputs`.
20752084 states : int, list of str, or None, optional
20762085 Description of the system states. Same format as `inputs`.
2086+
20772087 """
20782088 if not isinstance (sys , InputOutputSystem ):
20792089 raise TypeError ("Can only linearize InputOutputSystem types" )
0 commit comments