Exemplo n.º 1
0
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}]))
Exemplo n.º 2
0
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
            }]))
Exemplo n.º 3
0
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}]))
Exemplo n.º 4
0
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}]))
Exemplo n.º 5
0
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)]))
Exemplo n.º 6
0
def testSignal(simTime = 3.0):
   nsteps = int(simTime/simulate.Tsim)
   print __name__, 'nsteps ', nsteps
   return (nsteps,
           sig.ListSignal(nsteps*[{}]))
Exemplo n.º 7
0
def simpleSignal(dist = 3.0, simTime = 3.0):
   nsteps = int(simTime/simulate.Tsim)
   return (nsteps,
           sig.ListSignal(nsteps*[{'lightAngle':1.57, 'lightDist':dist}]))
Exemplo n.º 8
0
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?')