def test_timebaseEqual_deprecated(self, dt1, dt2, expected): """Test that timbaseEqual throws a warning and returns as documented""" sys1 = tf([1], [1, 2, 3], dt1) sys2 = tf([1], [1, 4, 5], dt2) print(sys1.dt) print(sys2.dt) with pytest.deprecated_call(): assert timebaseEqual(sys1, sys2) is expected # Make sure behaviour is symmetric with pytest.deprecated_call(): assert timebaseEqual(sys2, sys1) is expected
def testTimebaseEqual(self): self.assertEqual(timebaseEqual(self.siso_ss1, self.siso_tf1), True) self.assertEqual(timebaseEqual(self.siso_ss1, self.siso_ss1c), True) self.assertEqual(timebaseEqual(self.siso_ss1, self.siso_ss1d), True) self.assertEqual(timebaseEqual(self.siso_ss1d, self.siso_ss1c), False) self.assertEqual(timebaseEqual(self.siso_ss1d, self.siso_ss2d), False) self.assertEqual(timebaseEqual(self.siso_ss1d, self.siso_ss3d), False)
def feedback(self, other=1, sign=-1): """Feedback interconnection between two LTI systems.""" other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if ((self.inputs != other.outputs) or (self.outputs != other.inputs)): raise ValueError("State space systems don't have compatible \ inputs/outputs for feedback.") # Figure out the sampling time to use if (self.dt == None and other.dt != None): dt = other.dt # use dt from second argument elif (other.dt == None and self.dt != None) or \ timebaseEqual(self, other): dt = self.dt # use dt from first argument else: raise ValueError("Systems have different sampling times") A1 = self.A B1 = self.B C1 = self.C D1 = self.D A2 = other.A B2 = other.B C2 = other.C D2 = other.D F = eye(self.inputs) - sign * D2 * D1 if abs(det(F)) < 1.e-6: raise ValueError("I - sign * D2 * D1 is singular.") E = inv(F) T1 = eye(self.outputs) + sign * D1 * E * D2 T2 = eye(self.inputs) + sign * E * D2 * D1 A = concatenate( (concatenate( (A1 + sign * B1 * E * D2 * C1, sign * B1 * E * C2), axis=1), concatenate( (B2 * T1 * C1, A2 + sign * B2 * D1 * E * C2), axis=1)), axis=0) B = concatenate((B1 * T2, B2 * D1 * T2), axis=0) C = concatenate((T1 * C1, sign * D1 * E * C2), axis=1) D = D1 * T2 return StateSpace(A, B, C, D, dt)
def __add__(self, other): """Add two LTI objects (parallel connection).""" from control.statesp import StateSpace # Convert the second argument to a transfer function. if (isinstance(other, StateSpace)): other = _convertToTransferFunction(other) elif not isinstance(other, TransferFunction): other = _convertToTransferFunction(other, inputs=self.inputs, outputs=self.outputs) # Check that the input-output sizes are consistent. if self.inputs != other.inputs: raise ValueError("The first summand has %i input(s), but the \ second has %i." % (self.inputs, other.inputs)) if self.outputs != other.outputs: raise ValueError("The first summand has %i output(s), but the \ second has %i." % (self.outputs, other.outputs)) # Figure out the sampling time to use if (self.dt == None and other.dt != None): dt = other.dt # use dt from second argument elif (other.dt == None and self.dt != None) or \ (timebaseEqual(self, other)): dt = self.dt # use dt from first argument else: raise ValueError("Systems have different sampling times") # Preallocate the numerator and denominator of the sum. num = [[[] for j in range(self.inputs)] for i in range(self.outputs)] den = [[[] for j in range(self.inputs)] for i in range(self.outputs)] for i in range(self.outputs): for j in range(self.inputs): num[i][j], den[i][j] = _addSISO(self.num[i][j], self.den[i][j], other.num[i][j], other.den[i][j]) return TransferFunction(num, den, dt)
def __add__(self, other): """Add two LTI systems (parallel connection).""" # Check for a couple of special cases if (isinstance(other, (int, float, complex))): # Just adding a scalar; put it in the D matrix A, B, C = self.A, self.B, self.C D = self.D + other dt = self.dt else: other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if ((self.inputs != other.inputs) or (self.outputs != other.outputs)): raise ValueError("Systems have different shapes.") # Figure out the sampling time to use if (self.dt == None and other.dt != None): dt = other.dt # use dt from second argument elif (other.dt == None and self.dt != None) or \ (timebaseEqual(self, other)): dt = self.dt # use dt from first argument else: raise ValueError("Systems have different sampling times") # Concatenate the various arrays A = concatenate( (concatenate( (self.A, zeros((self.A.shape[0], other.A.shape[-1]))), axis=1), concatenate((zeros( (other.A.shape[0], self.A.shape[-1])), other.A), axis=1)), axis=0) B = concatenate((self.B, other.B), axis=0) C = concatenate((self.C, other.C), axis=1) D = self.D + other.D return StateSpace(A, B, C, D, dt)
def __add__(self, other): """Add two LTI systems (parallel connection).""" # Check for a couple of special cases if (isinstance(other, (int, float, complex))): # Just adding a scalar; put it in the D matrix A, B, C = self.A, self.B, self.C; D = self.D + other; dt = self.dt else: other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if ((self.inputs != other.inputs) or (self.outputs != other.outputs)): raise ValueError("Systems have different shapes.") # Figure out the sampling time to use if (self.dt == None and other.dt != None): dt = other.dt # use dt from second argument elif (other.dt == None and self.dt != None) or \ (timebaseEqual(self, other)): dt = self.dt # use dt from first argument else: raise ValueError("Systems have different sampling times") # Concatenate the various arrays A = concatenate(( concatenate((self.A, zeros((self.A.shape[0], other.A.shape[-1]))),axis=1), concatenate((zeros((other.A.shape[0], self.A.shape[-1])), other.A),axis=1) ),axis=0) B = concatenate((self.B, other.B), axis=0) C = concatenate((self.C, other.C), axis=1) D = self.D + other.D return StateSpace(A, B, C, D, dt)
def __mul__(self, other): """Multiply two LTI objects (serial connection).""" # Check for a couple of special cases if isinstance(other, (int, float, complex)): # Just multiplying by a scalar; change the output A, B = self.A, self.B C = self.C * other D = self.D * other dt = self.dt else: other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if self.inputs != other.outputs: raise ValueError("C = A * B: A has %i column(s) (input(s)), \ but B has %i row(s)\n(output(s))." % (self.inputs, other.outputs)) # Figure out the sampling time to use if (self.dt == None and other.dt != None): dt = other.dt # use dt from second argument elif (other.dt == None and self.dt != None) or \ (timebaseEqual(self, other)): dt = self.dt # use dt from first argument else: raise ValueError("Systems have different sampling times") # Concatenate the various arrays A = concatenate( (concatenate( (other.A, zeros((other.A.shape[0], self.A.shape[1]))), axis=1), concatenate((self.B * other.C, self.A), axis=1)), axis=0) B = concatenate((other.B, self.B * other.D), axis=0) C = concatenate((self.D * other.C, self.C), axis=1) D = self.D * other.D return StateSpace(A, B, C, D, dt)
def __mul__(self, other): """Multiply two LTI objects (serial connection).""" # Check for a couple of special cases if isinstance(other, (int, float, complex)): # Just multiplying by a scalar; change the output A, B = self.A, self.B C = self.C * other D = self.D * other dt = self.dt else: other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if self.inputs != other.outputs: raise ValueError("C = A * B: A has %i column(s) (input(s)), \ but B has %i row(s)\n(output(s))." % (self.inputs, other.outputs)) # Figure out the sampling time to use if (self.dt == None and other.dt != None): dt = other.dt # use dt from second argument elif (other.dt == None and self.dt != None) or \ (timebaseEqual(self, other)): dt = self.dt # use dt from first argument else: raise ValueError("Systems have different sampling times") # Concatenate the various arrays A = concatenate( (concatenate((other.A, zeros((other.A.shape[0], self.A.shape[1]))), axis=1), concatenate((self.B * other.C, self.A), axis=1)), axis=0) B = concatenate((other.B, self.B * other.D), axis=0) C = concatenate((self.D * other.C, self.C),axis=1) D = self.D * other.D return StateSpace(A, B, C, D, dt)