def testSignal(simTime = 1.0): nsteps = int(simTime/simulate.Tsim) print __name__, 'nsteps ', nsteps ninter = nsteps/2 return (nsteps, sig.ListSignal(ninter*[{'pot1':0.0}]+\ ninter*[{'pot1':0.1}]))
def simpleSignal2(dist=1.0, simTime=3.0): nsteps = int(simTime / simulate.Tsim) return (nsteps, sig.ListSignal(nsteps * [{ 'lightAngle': 3 * math.pi / 4, 'lightDist': dist }]))
def testSignal(simTime=2.5): nsteps = int(simTime / simulate.Tsim) print __name__, 'nsteps ', nsteps ninter = nsteps / 3 return (nsteps, sig.ListSignal(ninter*[{'pot1':.25}]+\ ninter*[{'pot1':.5}]+\ ninter*[{'pot1':.75}]))
def testSignal(dist = 3.0, simTime = 3.0): nsteps = int(simTime/simulate.Tsim) print __name__, 'nsteps ', nsteps ninter=nsteps/4 return (nsteps, sig.ListSignal(ninter*[{'lightAngle':1.57, 'lightDist':dist}]+\ ninter*[{'lightAngle':3.14, 'lightDist':dist}]+\ ninter*[{'lightAngle':1.57, 'lightDist':dist}]+\ ninter*[{'lightAngle':3.14, 'lightDist':dist}]))
def testSignal(simTime=2.5): nsteps = int(simTime / simulate.Tsim) print __name__, 'nsteps ', nsteps ninter = math.pi / nsteps return (nsteps, sig.ListSignal([{ 'motorAngle': 3 * math.pi / 4, 'lightAngle': (5 * math.pi / 4) - (i * ninter), 'lightDist': 3 } for i in range(nsteps + 1)]))
def testSignal(simTime = 3.0): nsteps = int(simTime/simulate.Tsim) print __name__, 'nsteps ', nsteps return (nsteps, sig.ListSignal(nsteps*[{}]))
def simpleSignal(dist = 3.0, simTime = 3.0): nsteps = int(simTime/simulate.Tsim) return (nsteps, sig.ListSignal(nsteps*[{'lightAngle':1.57, 'lightDist':dist}]))
def solve(lines, potAlphaSignals, lampAngleSignals, lampDistanceSignals, potLabels, lampLabels, headMotorLabels, motorLabels, nSamples=100, deltaT=0.02): global nodes, N def makeGMatrix(): gMatrix = [[0.0 for x in range(N)] for y in range(N)] for c in resistors + pots + motorPots + heads + motors + probes + opAmps + vsources + isources: if c.connected(): c.addConductance(gMatrix) return gMatrix def makeVoltages(): vArray = [0.0 for i in range(N)] vKnown = [False for i in range(N)] iArray = [0.0 for i in range(N)] for c in vsources: c.setVoltage(vArray, vKnown) for c in isources: c.setCurrent(iArray) for c in opAmps: c.initial(vArray, vKnown) return (vArray, vKnown, iArray) (nodes, N) = makeNodes(lines) (resistors, pots, motorPots, heads, motors, vsources, isources, opAmps, probes) = parseComponents(lines) assert len(pots) == len(potAlphaSignals) == len(potLabels) assert len(heads) == len(lampAngleSignals) == len( lampDistanceSignals) == len(lampLabels) == len(headMotorLabels) assert len(motors) == len(motorLabels) nodePins = [] for i in range(N): msg = '' if nodes[201] == i: msg += ' top-' if nodes[202] == i: msg += ' top+' if nodes[203] == i: msg += ' bottom-' if nodes[204] == i: msg += ' bottom+' for c in range(1, 64): if nodes[300 + c] == i: msg += ' ' + str(c) + 'J' if nodes[400 + c] == i: msg += ' ' + str(c) + 'A' nodePins.append(msg) for i in range(N): warn('node ' + chr(97 + i) + ':' + nodePins[i]) for c in resistors: warn(str(c)) for c in pots: warn(str(c)) for c in motorPots: warn(str(c)) for c in heads: warn(str(c)) for c in motors: warn(str(c)) for c in vsources: warn(str(c)) for c in isources: warn(str(c)) for c in opAmps: warn(str(c)) for c in probes: warn(str(c)) for h in heads: h.phi = h.lampAngleSample(0) * 2. * math.pi h.distance = h.lampDistanceSample(0) # h.updatePhotoResistors() h.updatePhotoDiodes() h.updatePot() for p in pots: p.alpha = p.alphaSample(0) gMatrix = makeGMatrix() (vArray, vKnown, iArray) = makeVoltages() j = 0 for i in range(N): if gMatrix[i][i] == 0.0: warn( 'Floating node at{0:s} must be connected - it is possible you have not connected the inputs of an opamp.' .format(nodePins[i])) j += 1 if j > 0: raise SingularMatrix('Floating nodes must be connected') for i, pot in enumerate(pots): pot.alphaSample = potAlphaSignals[i].sample #if potAlphaSignal: # if len(pots)<1: # warn('Simulation file specifies input signal for nonexistent pot') # raise NonexistentPart('No pot in this circuit!') # else: # pots[0].alphaSample = potAlphaSignal.sample # warning = 'potAlphaSignal:' # for n in range(nSamples): # warning +='{0:5.2f}'.format(potAlphaSignal.sample(n)) # warn(warning) for i, head in enumerate(heads): head.lampAngleSample = lampAngleSignals[i].sample head.lampDistanceSample = lampDistanceSignals[i].sample #if lampAngleSignal: # if len(heads)<1: # warn('Simulation file specifies lamp angle input signal for nonexistent head') # raise NonexistentPart('No head in this circuit!') # else: # heads[0].lampAngleSample = lampAngleSignal.sample # warning = 'lampAngleSignal:' # for n in range(nSamples): # warning += '{0:5.2f}'.format(lampAngleSignal.sample(n)) # warn(warning) #if lampDistanceSignal: # if len(heads)<1: # warn('Simulation file specifies lamp angle input signal for nonexistent head') # raise NonexistentPart('No head in this circuit!') # else: # heads[0].lampDistanceSample = lampDistanceSignal.sample # warning = 'lampDistanceSignal:' # for n in range(nSamples): # warning += '{0:5.2f}'.format(lampDistanceSignal.sample(n)) # warn(warning) for h in heads + motors: h.thetaOutput = [] h.omegaOutput = [] for p in probes: p.outputs = [] for n in range(nSamples): for h in heads: h.phi = h.lampAngleSample(n) * 2. * math.pi h.distance = h.lampDistanceSample(n) # h.updatePhotoResistors() h.updatePhotoDiodes() h.updatePot() for p in pots: p.alpha = p.alphaSample(n) gMatrix = makeGMatrix() (vArray, vKnown, iArray) = makeVoltages() # print '---' # for i in range(N): # print i,vArray[i],vKnown[i] # print '---' # for i in range(N): # for j in range(N): # if gMatrix[i][j]!=0: # print 'gMatrix[{0:d}][{1:d}]={2:f}'.format(i,j,gMatrix[i][j]) # exit() for o in opAmps: gain = 0 if not vKnown[o.vP]: gain += gMatrix[o.vP][o.vO] / gMatrix[o.vP][o.vP] if not vKnown[o.vM]: gain -= gMatrix[o.vM][o.vO] / gMatrix[o.vM][o.vM] if gain != 0: o.alpha = 1. / gain / o.K else: o.alpha = 1. / o.K vArray0 = vArray[:] for j in range(1000): for nn in range(N): if not vKnown[nn]: vArray[nn] = 0 vArray[nn] = (-iArray[nn] - sum( [gMatrix[nn][k] * vArray[k] for k in range(N)])) / gMatrix[nn][nn] for c in opAmps: c.update(vArray, vKnown) if j % 10 == 0: error = math.sqrt( sum([(vArray[i] - vArray0[i])**2 for i in range(len(vArray))]) / len(vArray)) if error < max([abs(v) for v in vArray]) / 1000.: break vArray0 = vArray[:] # print j,error for h in heads + motors: h.update(vArray, deltaT) h.thetaOutput.append(h.theta) h.omegaOutput.append(h.omega) for p in probes: p.outputs.append(vArray[p.n1]) pos = [] neg = [] for p in probes: if p.sign == '+': pos.append(p) else: neg.append(p) def myPlot(s, title, y0, y1): if nSamples > 1: samps = [s.sample(x) for x in xrange(nSamples)] yy0 = min(samps) yy1 = max(samps) if float(yy1 - y0) / float(y1 - y0 + .001) > 0.9: y1 = yy1 if float(y1 - yy0) / float(y1 - y0 + .001) > 0.9: y0 = yy0 p = PlotWindow(title) p.stem(range(nSamples), samps) p.axis([0, nSamples, y0, y1]) add_window(p) warning = str(title) + ':' for nn in range(nSamples): warning += '{0:6.2f}'.format(s.sample(nn)) warn(warning) w = 0 for i in range(min(len(pos), len(neg))): myPlot( sig.ListSignal( [a - b for (a, b) in zip(pos[i].outputs, neg[i].outputs)]), 'probe', 0, .01) w += 1 for i, label in enumerate(headMotorLabels): myPlot(sig.ListSignal(heads[i].thetaOutput), 'Motor %s Angle' % label, 0, 0) myPlot(sig.ListSignal(heads[i].omegaOutput), 'Motor %s Velocity' % label, 0, 0) w += 1 for i, label in enumerate(motorLabels): myPlot(sig.ListSignal(motors[i].thetaOutput), 'Motor %s Angle' % label, 0, 0) myPlot(sig.ListSignal(motors[i].omegaOutput), 'Motor %s Velocity' % label, 0, 0) w += 1 #for h in heads+motors: # myPlot(sig.ListSignal(h.thetaOutput),'Motor Angle',0,0) # myPlot(sig.ListSignal(h.omegaOutput),'Motor Velocity',0,0) # w += 1 for i, label in enumerate(lampLabels): if label: myPlot(lampDistanceSignals[i], 'Lamp %s Distance Signal' % label, 0, 1) myPlot(lampAngleSignals[i], 'Lamp %s Angle Signal' % label, -1. / 8, 1. / 8) w += 2 #if lampDistanceSignal: # myPlot(lampDistanceSignal,'Lamp Distance Signal',0,1) # w += 1 #if lampAngleSignal: # myPlot(lampAngleSignal,'Lamp Angle Signal',-1./8.,1./8.) # w += 1 for i, label in enumerate(potLabels): myPlot(potAlphaSignals[i], 'Pot %s Alpha Signal' % label, 0, 1) w += 1 #if potAlphaSignal: # myPlot(potAlphaSignal,'Pot Alpha Signal',0,1) # w += 1 #elif len(pots)>0: # myPlot(sig.ListSignal([pots[0].alphaSample(n) for n in range(nSamples)]),'Pot Alpha Signal',0,1) # w += 1 if w == 0: warn('No output signals are specified. Do you want to add a Probe?')