def wallFollowerModel(K, T=0.1, V=0.1): multipliedResult = K * (T**2) * V num1 = poly.Polynomial([multipliedResult, 0, 0]) den1 = poly.Polynomial([1, -2, 1]) top = sf.SystemFunctional(num1, den1) return sf.FeedbackSubtract( top, sf.SystemFunctional(poly.Polynomial([1]), poly.Polynomial([1])))
def angleModel(Kp, Ka): T = 0.1 V = 0.1 plant1 = sf.SystemFunctional(poly.Polynomial([T, 0]), poly.Polynomial([-1, 1])) smallFeedbackNum = sf.Cascade(plant1, sf.Gain(Ka)) smallFeedbackDen = sf.Gain(1) smallFeedback = sf.FeedbackSubtract(smallFeedbackNum, smallFeedbackDen) firstCascade = sf.Cascade(sf.Gain(float(Kp) / Ka), smallFeedback) plant2 = sf.SystemFunctional(poly.Polynomial([T * V, 0]), poly.Polynomial([-1, 1])) secondCascade = sf.Cascade(firstCascade, plant2) return sf.FeedbackSubtract(secondCascade, sf.Gain(1))
def delayPlusPropModel(k1, k2): T = 0.1 V = 0.1 # Controller: your code here ## controller = sf.Sum(sf.Gain(k1), sf.Cascade(sf.Gain(k2), sf.R())) controller = sf.SystemFunction(poly.Polynomial([k2, k1]), poly.Polynomial([1])) # The plant is like the one for the proportional controller. Use # your definition from last week. plant1 = sf.Cascade(sf.Gain(0.1), sf.FeedbackAdd(sf.R(), sf.Gain(1))) plant2 = sf.Cascade(sf.Gain(0.1 * 0.1), sf.FeedbackAdd(sf.R(), sf.Gain(1))) # Combine the three parts sys = sf.FeedbackSubtract( sf.Cascade(controller, sf.Cascade(plant1, plant2)), sf.Gain(1)) return sys
def poles(self): # returns a list of the poles # the poles are the solutions to the poly in the denom # where z = 1/R coeffsInZ = self.denominator.coeffs[:] coeffsInZ = list(reversed(coeffsInZ)) polyInZ = poly.Polynomial(coeffsInZ) return polyInZ.roots()
def poles(self): """Returns a list of the poles of the system""" coeffsZ = self.denominator.coeffs[:] # Reverse so the coefficients are in ascending order coeffsZ = list(reversed(coeffsZ)) # Create a polynomial with these coefficients polyZ = poly.Polynomial(coeffsZ) # The roots of this polynomial are the poles return polyZ.roots()
import lib601.poly as poly import swLab04SignalDefinitions reload(swLab04SignalDefinitions ) # so changes you make in swLab04SignalDefinitions.py will be reloaded from swLab04SignalDefinitions import * ##StepSignal().plot(-10, 10) ##SummedSignal(ConstantSignal(3.0), StepSignal()).plot(-10, 10) ##ScaledSignal(UnitSampleSignal(), 3).plot(-3, 3) ##R(UnitSampleSignal()).plot(-5, 5) ##Rn(UnitSampleSignal(), 3).plot(-5, 5) polyR(UnitSampleSignal(), poly.Polynomial([3, 2, 1])).plot(-5, 5)
import lib601.poly as poly import sfSkeleton as sf reload(sf) import math import lib601.poly as poly import lib601.util as util # Part 1: Stable? s1 = sf.SystemFunction(poly.Polynomial([-1]), poly.Polynomial([1, 5. / 6., -1])) print "dominant pole magnitude :", s1.dominantPole() print "unstable, non oscillatory" s2 = sf.SystemFunction(poly.Polynomial([1]), poly.Polynomial([3. / 8., 5. / 4., 1])) print "dominant pole magnitude :", abs(s2.dominantPole()) print "stable, oscillatory" s3 = sf.SystemFunction(poly.Polynomial([1]), poly.Polynomial([9. / 8., 3. / 2., 1])) print "dominant pole magnitude :", abs(s3.dominantPole()) print "unstable, oscillatory" s4 = sf.SystemFunction(poly.Polynomial([1]), poly.Polynomial([1. / 2., 1, 1])) print "dominant pole magnitude :", abs(s4.dominantPole()) print "stable, oscillatory" # Part 2: DiffEq Behavior sA = sf.SystemFunction(poly.Polynomial([1]),
import math import lib601.poly as poly coeffs = [1, 2, 1] p = poly.Polynomial(coeffs) print p.roots()
import lib601.poly as poly import lib601.sig from lib601.sig import * ## You can evaluate expressions that use any of the classes or ## functions from the sig module (Signals class, etc.). You do not ## need to prefix them with "sig." s = UnitSampleSignal() #s.plot(-5, 5) import math cs = CosineSignal(math.pi / 8) # cs.plot(-10, 10) step_signal = MyStepSignal() sum_signal = MySummedSignal(step_signal, step_signal) # sum_signal.plot(-5, 5) p = poly.Polynomial([1, 2, 3]) a = myPolyR(s, p) a.plot(-5, 5)
import lib601.poly as poly import sfSkeleton as sf reload(sf) ###################################################################### ## Examples from handout on SystemFunction class ## You should comment out the parts that you don't want ###################################################################### s1 = sf.SystemFunction(poly.Polynomial([1]), poly.Polynomial([0.63, -1.6, 1])) print '----------------------------------------' print 's1:', s1 print 's1.poles():', s1.poles() print 's1.poleMagnitudes():', s1.poleMagnitudes() print 's1.dominantPole():', s1.dominantPole() s2 = sf.SystemFunction(poly.Polynomial([1]), poly.Polynomial([1.1, -1.9, 1])) print '----------------------------------------' print 's2:', s2 print 's2.poles():', s2.poles() print 's2.poleMagnitudes():', s2.poleMagnitudes() print 's2.dominantPole():', s2.dominantPole() T = 0.1 k = 2.0 controller = sf.SystemFunction(poly.Polynomial([-k]), poly.Polynomial([1])) plant = sf.SystemFunction(poly.Polynomial([-T, 0]), poly.Polynomial([-1, 1]))
def plant1(T): return sf.SystemFunction(poly.Polynomial([T, 0]), poly.Polynomial([-1, 1]))
import lib601.sig from lib601.sig import * from swLab04SignalDefinitions import * ## You can evaluate expressions that use any of the classes or ## functions from the sig module (Signals class, etc.). You do not ## need to prefix them with "sig." s = UnitSampleSignal() s.plot(-5, 5) def samplesInRange(signal, lo, hi): return [signal.sample(i) for i in range(lo, hi)] step1 = Rn(ScaledSignal(StepSignal(), 3), 3) #step1.plot(-5,5) print samplesInRange(step1, -5, 5) step2 = SummedSignal(Rn(step1, 5), ConstantSignal(-3)) #step2.plot(-10,10) print samplesInRange(step2, -10, 10) stepUpDown = SummedSignal(step1, SummedSignal(Rn(step1, 4), ConstantSignal(-3))) # stepUpDown.plot(-10,10) p = poly.Polynomial([5, 0, 3, 0, 1, 0]) stepUpDownPoly = polyR(UnitSampleSignal(), p) stepUpDownPoly1 = polyRRec(UnitSampleSignal(), p) stepUpDownPoly.plot(0, 10) print samplesInRange(stepUpDownPoly, 0, 10) print samplesInRange(stepUpDownPoly1, 0, 10)
def FeedbackSubtract(sf1, sf2=None): """ Args: sf1, sf2: instances of the SystemFunction class Returns: a new instance of the SystemFunction class that represents the feedback subtract composition of the input systems """ newNumerator = sf1.numerator * sf2.denominator newDenominator = (sf1.numerator * sf2.numerator + sf1.denominator * sf2.denominator) return SystemFunction(newNumerator, newDenominator) # Real poles sample output s1 = sf.SystemFunction(poly.Polynomial([1]), poly.Polynomial([0.63, -1.6, 1])) print(s1) # SF(1.000/0.630 R**2 + -1.600R + 1.000) s1.poles() # [0.90000000000000069, 0.69999999999999951] s1.poleMagnitudes() # [0.90000000000000069, 0.69999999999999951] s1.dominantPole() # 0.90000000000000069 # Complex poles sample output s2 = sf.SystemFunction(poly.Polynomial([1]), poly.Polynomial([1.1, -1.9, 1])) print(s2) # SF(1.000/1.100 R**2 + -1.900R + 1.000) s2.poles() # [(0.94999999999999996+0.44440972086577957j),
import math import lib601.poly as poly import lib601.sf as sf def wallFollowerModel(K, T=0.1, V=0.1): numerator = poly.polynomial([K * T * T * V, 0, 0]) denominator = poly.polynomial([K * T * T * V + 1, -2, 1]) result = sf.SystemFunctional(numerator, denominator) return result def periodOfPole(pole): real = pole.real imag = pole.imag if math.atan2(imag, real) == 0: return real else: return abs(2 * math.pi / math.atan2(imag, real)) def Pole(K): return (2 + math.sqrt(abs(4 - 4 * (1 + K * 0.1 * 0.1 * 0.1)))) / 2 for k in [0.2, 1, 10, 50, 100]: numerator = poly.Polynomial([k * 0.1 * 0.1 * 0.1, 0, 0]) denominator = poly.Polynomial([k * 0.1 * 0.1 * 0.1 + 1, -2, 1]) result = sf.SystemFunctional(numerator, denominator) print result.dominantPole(), periodOfPole(result.dominantPole())
import lib601.poly as poly import lib601.sig from lib601.sig import * ## You can evaluate expressions that use any of the classes or ## functions from the sig module (Signals class, etc.). You do not ## need to prefix them with "sig." step1 = ScaledSignal(Rn(StepSignal(), 3), 3.0) step1a = polyR(StepSignal(), poly.Polynomial([3, 0, 0, 0])) ##step1.plot(-10, 10) ##step1a.plot(-10, 10) step2 = ScaledSignal(Rn(StepSignal(), 7), -3.0) ##step2.plot(0, 20) stepUpDown = SummedSignal(step1, step2) ##stepUpDown.plot(0, 20) stepUpDownPoly = polyR(UnitSampleSignal(), poly.Polynomial([5.0, 0, 3.0, 0, 1.0, 0])) stepUpDownPoly.plot(0, 10)
def controller(k): return sf.SystemFunction(poly.Polynomial([k]), poly.Polynomial([1]))
def polyR(s, p): if len(p.coeffs) == 1: return p.coeffs[0] * s return p.coeffs[-1] * s + R(polyR(s, poly.Polynomial(p.coeffs[:-1])))
def plant2(T, V): return sf.SystemFunction(poly.Polynomial([T * V, 0]), poly.Polynomial([-1, 1]))
dominantPole = util.argmax(poles, abs) return dominantPole def __str__(self): return 'SF(' + self.numerator.__str__('R') + \ '/' + self.denominator.__str__('R') + ')' __repr__ = __str__ def Cascade(sf1, sf2): d1 = sf1.denominator n1 = sf1.numerator d2 = sf2.denominator n2 = sf2.numerator casD = d1 * d2 casN = n1 * n2 return SystemFunction(casN, casD) def FeedbackSubtract(sf1, sf2=None): # n1d2/(d1d2+n1n2) numerator = sf1.numerator * sf2.denominator denominator = sf1.numerator * sf2.numerator + sf1.denominator * sf2.denominator return SystemFunction(numerator, denominator) if __name__ == "__main__": polys = poly.Polynomial([64, 16 * 8, 63]) print polys.roots()
def makeSF(K): return sf.SystemFunctional(poly.Polynomial([K,0]),poly.Polynomial([K,-1,1]))
def poles(self): reverDe = self.denominator.coeffs[:] reverDe.reverse() new_poly = poly.Polynomial(reverDe) return new_poly.roots()
def makeSF(K): num = poly.Polynomial([K, 0]) den = poly.Polynomial([K, -1, 1]) return sf.SystemFunctional(num, den)
self.m = m self.pureMachine = self.m def sample(self, n): if n < 0: return 0 else: samples = samplesInRange(self.s, n, n + 1) return self.m.transduce(samples)[-1] # Part 2: Application polyList = [] for i in range(51): if i == 0 or i == 20 or i == 50: polyList.append(100) else: polyList.append(0) p = poly.Polynomial(polyList) inputSig = polyR(UnitSampleSignal(), p) bankLTISM = LTISM([1], [0.99], [], [0]) bankSig = TransducedSignal(inputSig, bankLTISM) balance = samplesInRange(bankSig, 0, 61) print "Value at time 10: ", balance[10] print "Value at time 20: ", balance[20] print "Value at time 30: ", balance[30] print "Value at time 40: ", balance[40] print "Value at time 50: ", balance[50] print "Value at time 60: ", balance[60]