Exemplo n.º 1
0
I3 = 1/2*M*R**2      # moment of inertia, I, of gyroscope about its own axis
I1 = M*r**2 + 1/2*I3 # I about a line through the support, perpendicular to axis
phi = psi = thetadot = 0
x = vector(theta, phi, psi) # Lagrangian coordinates
v = vector(thetadot, phidot, psidot)

# ############################################################ the scene
vp = Plotter(verbose=0, axes=3, interactive=0)

shaft = vp.cylinder([[0,0,0],         [Lshaft,0,0]], r=.03, c='dg')
rotor = vp.cylinder([[Lshaft/2.2,0,0],[Lshaft/1.8,0,0]], r=R, texture='marble')
base  = vp.sphere([     0, 0, 0], c='dg', r=.03)
tip   = vp.sphere([Lshaft, 0, 0], c='dg', r=.03)
gyro  = vp.makeAssembly([shaft, rotor, base, tip]) # group relevant actors

pedestal = vp.box([0,-0.63,0], height=.1, length=.1, width=1, texture='wood5')
pedbase  = vp.box([0,-1.13,0], height=.5, length=.5, width=.05, texture='wood5')
pedpin   = vp.pyramid([0,-.08,0], axis=[0,1,0], s=.05, height=.12, texture='wood5')
formulas = vp.load('data/images/gyro_formulas.png', alpha=.9).scale(.003).pos([-1,-1,-1.1])

# ############################################################ the physics
pb = ProgressBar(0, 4, dt, c='b')
for i, t in enumerate(pb.range()):
    st, ct, sp, cp = sin(x[0]), cos(x[0]), sin(x[1]), cos(x[1])

    thetadot, phidot, psidot = v # unpack
    atheta = st*ct*phidot**2 + (M*g*r*st-I3*(psidot+phidot*ct)*phidot*st)/I1
    aphi = (I3/I1)*(psidot+phidot*ct)*thetadot/st - 2*ct*thetadot*phidot/st
    apsi = phidot*thetadot*st - aphi*ct
    a = vector(atheta, aphi, apsi)
Exemplo n.º 2
0
l_rest = 0.1  # spring x position at rest
x0 = 0.85  # initial x-coordinate of the block
k = 25  # spring constant
m = 20  # block mass
b = 0.5  # viscosity friction (proportional to velocity)
dt = 0.1  # time step

#initial conditions
v = vector(0, 0, 0.2)
x = vector(x0, 0, 0)
xr = vector(l_rest, 0, 0)
sx0 = vector(-0.8, 0, 0)
offx = vector(0, 0.3, 0)

vp.box(pos=(0, -0.1, 0), length=2.0, width=0.02, height=0.5)  #surface
vp.box(pos=(-.82, .15, 0), length=.04, width=0.50, height=0.3)  #wall
block = vp.cube(pos=x, length=0.2, c='t')
spring = vp.helix(sx0, x, r=.06, thickness=.01, texture='metal1')

pb = ProgressBar(0, 500, c='r')
for i in pb.range():
    F = -k * (x - xr) - b * v  # Force and friction
    a = F / m  # acceleration
    v = v + a * dt  # velocity
    x = x + v * dt + 1 / 2 * a * dt**2  # position

    block.pos(x)  # update block position
    spring.stretch(sx0, x)  # stretch helix accordingly
    trace = vp.point(x + offx, c='r/0.5', r=3)  # leave a red trace
Exemplo n.º 3
0
gaxis = vector(0, 0, 1)   # initial orientation of gyroscope
gaxis = norm(gaxis)
I = 1/2*M*R**2            # moment of inertia of gyroscope
Lrot = I*omega*gaxis      # angular momentum
cm = gpos + 0.5*Ls*gaxis  # center of mass of shaft

# ############################################################ the scene
vp = Plotter(verbose=0, axes=0, interactive=0)

shaft = vp.cylinder([[0,0,0], Ls*gaxis], r=0.03, c='dg')
rotor = vp.cylinder([(Ls-0.55)*gaxis, (Ls-0.45)*gaxis], r=R, c='t')
bar   = vp.cylinder([Ls*gaxis/2-R*vector(0,1,0), Ls*gaxis/2+R*vector(0,1,0)], r=R/6, c='r')
gyro  = vp.Assembly([shaft, rotor, bar]) # group actors into a single one

spring= vp.helix(top, gpos, r=0.06, thickness=0.01, c='gray')
vp.box(top, length=0.2, width=0.02, height=0.2, c='gray')
vp.box(pos=(0,.5,0), length=2.2, width=3, height=2.2, c='gray', wire=1, alpha=.2)

# ############################################################ the physics
pb = ProgressBar(0, 5, dt, c='b')
for t in pb.range():
    Fspring = -ks*norm(gpos-top)*(mag(gpos-top)-Lrest)
    torque  = cross(-1/2*Ls*norm(Lrot), Fspring) # torque about center of mass
    Lrot    += torque*dt
    precess += (Fgrav+Fspring)*dt  # momentum of center of mass
    cm      += (precess/M)*dt
    gpos    = cm - 1/2*Ls*norm(Lrot)

    # set orientation along gaxis and rotate it around its axis by omega*t degrees
    gyro.orientation(Lrot, rotation=omega*t*57.3).pos(gpos)
    spring.stretch(top, gpos)
Exemplo n.º 4
0
gaxis = vector(0, 0, 1)   # initial orientation of gyroscope
gaxis = norm(gaxis)
I = 1/2*M*R**2            # moment of inertia of gyroscope
Lrot = I*omega*gaxis      # angular momentum
cm = gpos + 0.5*Ls*gaxis  # center of mass of shaft

# ############################################################ the scene
vp = Plotter(verbose=0, axes=3, interactive=0)

shaft = vp.cylinder([[0,0,0], Ls*gaxis], r=0.03, c='dg')
rotor = vp.cylinder([(Ls-0.55)*gaxis, (Ls-0.45)*gaxis], r=R, c='t')
bar   = vp.cylinder([Ls*gaxis/2-R*vector(0,1,0), Ls*gaxis/2+R*vector(0,1,0)], r=R/6, c='r')
gyro  = vp.makeAssembly([shaft, rotor, bar]) # group actors into a single one

spring= vp.helix(top, gpos, r=0.06, thickness=0.01, c='gray')
box   = vp.box(top, length=0.2, width=0.02, height=0.2, c='gray')

# ############################################################ the physics
pb = ProgressBar(0, 5, dt, c='b')
for t in pb.range():
    Fspring = -ks*norm(gpos-top)*(mag(gpos-top)-Lrest)
    torque  = cross(-1/2*Ls*norm(Lrot), Fspring) # torque about center of mass
    Lrot    += torque*dt
    precess += (Fgrav+Fspring)*dt  # momentum of center of mass
    cm      += (precess/M)*dt
    gpos    = cm - 1/2*Ls*norm(Lrot)

    # set orientation along gaxis and rotate it around its axis by omega*t degrees
    gyro.orientation(Lrot, rotation=omega*t*57.3).pos(gpos)
    spring.stretch(top, gpos)
    vp.point(gpos + Ls*norm(Lrot), r=1, c='g') # add trace point to show in the end
Exemplo n.º 5
0
class VirtualKeyboard:

    def __init__(self, songname=''):
                         
        self.KB = dict()
        self.vp = None
        self.rightHand = None
        self.leftHand  = None
        self.vpRH = None
        self.vpLH = None
        self.playsounds = True
        self.verbose = True
        self.songname = songname
        self.t0 = 0 # keep track of how many seconds to play
        self.dt = 0.1
        self.speedfactor = 1
        self.engagedfingersR = [False]*6 # element 0 is dummy
        self.engagedfingersL = [False]*6 
        self.engagedkeysR    = []
        self.engagedkeysL    = []

        self.build_keyboard() 

    #######################################################
    def makeHandActor(self, f=1):
        a1, a2, a3, c = (10*f,0,0), (0,7*f,0), (0,0,3*f), (.7,0.3,0.3)
        palm = ellipsoid(pos=(0,-3,0), axis1=a1, axis2=a2, axis3=a3, alpha=0.6, c=c)
        wrist= box(pos=(0,-9,0), length=6*f, width=5, height=2, alpha=0.4, c=c)
        arm  = makeAssembly([palm,wrist])
        self.vp.actors.append(arm) # add actor to internal list
        f1 = self.vp.cylinder((-2, 1.5,0), axis=(0,1,0), height=5, r=.8*f, c=c)
        f2 = self.vp.cylinder((-1, 3  ,0), axis=(0,1,0), height=6, r=.7*f, c=c)
        f3 = self.vp.cylinder(( 0, 4  ,0), axis=(0,1,0), height=6.2, r=.75*f, c=c)
        f4 = self.vp.cylinder(( 1, 3.5,0), axis=(0,1,0), height=6.1, r=.7*f, c=c)
        f5 = self.vp.cylinder(( 2, 2  ,0), axis=(0,1,0), height=5, r=.6*f, c=c)
        return [arm, f1,f2,f3,f4,f5]

    def build_RH(self, hand):    
        if self.verbose: print('Building Right Hand..')
        self.rightHand = hand
        f = utils.handSizeFactor(hand.size)
        self.vpRH = self.makeHandActor(f)
        for limb in self.vpRH: # initial x positions are superseded later
            limb.x( limb.x()* 2.5 )
            limb.addpos([16.5*5+1, -7.5, 3] )

    def build_LH(self, hand): #########################
        if self.verbose: print('Building Left Hand..')
        self.leftHand = hand
        f = utils.handSizeFactor(hand.size)
        self.vpLH = self.makeHandActor(f)
        for limb in self.vpLH: 
            limb.x( limb.x()* -2.5 ) #flip
            limb.addpos([16.5*3+1, -7.5, 3] )
               

    #######################################################
    def build_keyboard(self):
        
        if self.verbose: print('Building Keyboard..')
        nts = ("C","D","E","F","G","A","B")
        tol = 0.12
        keybsize = 16.5 # in cm, span of one octave
        wb = keybsize/7
        nr_octaves = 7
        span = nr_octaves*wb*7
    
        self.vp = Plotter(title='PianoPlayer '+__version__, axes=0, size=(1400,700), bg='lb', verbose=0)

        #wooden top and base
        self.vp.box(pos=(span/2+keybsize, 6,  1), length=span+1, height=3, width= 5, texture='wood5') #top
        self.vp.box(pos=(span/2+keybsize, 0, -1), length=span+1, height=1, width=17, texture='wood5')
        self.vp.text('PianoPlayer '+__version__, pos=(18, 5.5, 2), depth=.7)
        self.vp.text('https://github.com/marcomusy/pianoplayer', pos=(105,4.8,2), depth=.7, s=.8)
        leggio = self.vp.box(pos=(span/1.55,8,10), length=span/2, height=span/8, width=0.08, c=(1,1,0.9))
        leggio.rotateX(-20)
        self.vp.text('Playing\n\n'+self.songname, s=1.2).rotateX(70).pos([49,11,9])

        for ioct in range(nr_octaves):
            for ik in range(7):              #white keys
                x  = ik * wb + (ioct+1)*keybsize +wb/2
                tb = self.vp.box(pos=(x,-2,0), length=wb-tol, height=1, width=12, c='white')
                self.KB.update({nts[ik]+str(ioct+1) : tb})
                if not nts[ik] in ("E","B"): #black keys
                    tn=self.vp.box(pos=(x+wb/2,0,1), length=wb*.6, height=1, width=8, c='black')
                    self.KB.update({nts[ik]+"#"+str(ioct+1) : tn})
        self.vp.show(interactive=0)
        self.vp.camera.Azimuth(4)
        self.vp.camera.Elevation(-30)


    #####################################################################
    def play(self):
        printc('Press [0-9] to proceed by one note or for more seconds',1)
        printc('Press Esc to exit.',1)
        self.vp.keyPressFunction = runTime    # enable observer

        if self.rightHand:
            self.engagedkeysR    = [False]*len(self.rightHand.noteseq)
            self.engagedfingersR = [False]*6  # element 0 is dummy
        if self.leftHand:           
            self.engagedkeysL    = [False]*len(self.leftHand.noteseq)
            self.engagedfingersL = [False]*6        

        t=0.0
        while True:
            if self.rightHand: self._moveHand( 1, t)
            if self.leftHand:  self._moveHand(-1, t)
            if t > 1000: break                                         
            t += self.dt                      # absolute time flows
        
        if self.verbose: printc('End of note sequence reached.')
        self.vp.keyPressFunction = None       # disable observer

    ###################################################################
    def _moveHand(self, side, t):############# runs inside play() loop
        if side == 1: 
            c1,c2 = 'tomato', 'orange'
            engagedkeys    = self.engagedkeysR
            engagedfingers = self.engagedfingersR
            H              = self.rightHand
            vpH            = self.vpRH
        else:               
            c1,c2 = 'purple', 'mediumpurple'
            engagedkeys    = self.engagedkeysL
            engagedfingers = self.engagedfingersL
            H              = self.leftHand
            vpH            = self.vpLH

        for i, n in enumerate(H.noteseq):##################### 
            start, stop, f = n.time, n.time+n.duration, n.fingering
            if isinstance(f, str): continue
            if f and stop <= t <= stop+self.dt and engagedkeys[i]: #release key
                engagedkeys[i]    = False
                engagedfingers[f] = False
                name = nameof(n)
                krelease(self.KB[name])
                frelease(vpH[f])
                self.vp.interactor.Render()

        for i, n in enumerate(H.noteseq):##################### 
            start, stop, f = n.time, n.time+n.duration, n.fingering   
            if isinstance(f, str):
                print('Warning: cannot understand lyrics:',f, 'skip note',i)
                continue
            if f and start <= t < stop and not engagedkeys[i] and not engagedfingers[f]: #press key
                if i >= len(H.fingerseq): return                    
                engagedkeys[i]    = True
                engagedfingers[f] = True
                name = nameof(n)
                
                if t> self.t0 + self.vp.clock: 
                    self.t0 = t
                    self.vp.show(zoom=2, interactive=True)

                for g in [1,2,3,4,5]: 
                    vpH[g].x( side * H.fingerseq[i][g] ) 
                vpH[0].x(vpH[3].x()) # index 0 is arm, put it where middle finger is
                
                fpress(vpH[f],  c1)
                kpress(self.KB[name], c2)
                self.vp.show(zoom=2, interactive=False)

                if self.verbose:
                    msg = 'meas.'+str(n.measure)+' t='+str(round(t,2))
                    if side==1: printc((msg,'\t\t\t\tRH.finger', f, 'hit', name), 'b')
                    else:       printc((msg,      '\tLH.finger', f, 'hit', name), 'm')

                if self.playsounds: 
                    playSound(n, self.speedfactor)
                else: 
                    time.sleep(n.duration*self.speedfactor)
Exemplo n.º 6
0
L = 0.1   # spring x position at rest
x0 = 0.85 # initial x-coordinate of the block
k = 25    # spring constant
m = 20    # block mass
b = 0.5   # viscosity friction (proportional to velocity)
dt= 0.15  # time step

#initial conditions
v = vector(0, 0, 0.2)
x = vector(x0, 0, 0)
xr = vector(L, 0, 0)
sx0 = vector(-0.8, 0, 0)
offx= vector(0, 0.3, 0)

vp.box(pos=(0, -0.1, 0), length=2.0, width=0.02, height=0.5) #surface
vp.box(pos=(-.82,.15,0), length=.04, width=0.50, height=0.3) #wall
block = vp.cube(pos=x, length=0.2, c='tomato')
block.addTrail(offset=[0,0.2,0], alpha=0.6, lw=2, n=500) 
spring= vp.helix(sx0, x, r=.06, thickness=.01, texture='metal1')

pb = ProgressBar(0,300, c='r')
for i in pb.range(): 
    F = -k*(x-xr) - b*v             # Force and friction
    a = F/m                         # acceleration
    v = v + a * dt                  # velocity
    x = x + v*dt + 1/2 * a * dt**2  # position
    
    block.pos(x)                    # update block position and trail
    spring.stretch(sx0, x)          # stretch helix accordingly
    
Exemplo n.º 7
0
# Create the initial positions and velocitites (0,0) of the bobs
bob_x = [0]
bob_y = [0]
x_dot = [0] * (N + 1)  #velocities
y_dot = [0] * (N + 1)

for k in range(1, N + 1):
    alpha = np.pi / 5 * k / 10
    bob_x.append(bob_x[k - 1] + np.cos(alpha) + np.random.normal(0, .1))
    bob_y.append(bob_y[k - 1] + np.sin(alpha) + np.random.normal(0, .1))

# Create the bobs
vp = Plotter(title="Multiple Pendulum", axes=0, verbose=0)
vp.box(pos=(bob_x[0], bob_y[0], 0),
       length=12,
       width=12,
       height=.7,
       c='k',
       wire=1)
bob = [vp.sphere(pos=(bob_x[0], bob_y[0], 0), r=R / 2, c='gray')]
for k in range(1, N + 1):
    bob.append(vp.cylinder(pos=(bob_x[k], bob_y[k], 0), r=R, height=.3, c=k))

# Create the springs out of N links
link = [0] * N
for k in range(N):
    p0 = bob[k].pos()
    p1 = bob[k + 1].pos()
    link[k] = vp.helix(p0, p1, thickness=.015, r=R / 3, c='gray')

# Create some auxiliary variables
x_dot_m = [0] * (N + 1)