(based on Example 3-1)
Calculate the net magetic field produced by a three-phase stator (adapted for 50Hz).
Import the PyLab namespace (provides set of useful commands and constants like $\pi$):
In [1]:
%pylab inline
Set up the basic conditions:
In [2]:
bmax = 1 # Normalize bmax to 1
freq = 50 # [Hz]
w = 2*pi*freq # [rad/s] angluar velocity
First, generate the three component magnetic fields
In [3]:
t = linspace(0, 1./50, 100) # 100 values for one period
wt = w*t # we are going to use this quite often
# amplitudes (changed them to see effect of unsymmetry):
B_amp = [[1.0], [1.0], [1.0]]
# time variants
B_time = array([sin(wt),
sin(wt-2*pi/3),
sin(wt+2*pi/3)])
# vectorial shifts
B_shift = [[cos(0) + 1j*sin(0)],
[cos(2*pi/3) + 1j*sin(2*pi/3)],
[cos(-2*pi/3) + 1j*sin(-2*pi/3)]]
# all combined
B_ph = B_amp * B_time
B = B_ph * B_shift
Calculate total flux vector Btot
:
In [4]:
Btot = B[0] + B[1] + B[2]
Calculate a circle representing the expected maximum value of Btot
:
In [5]:
circle = 1.5 * (cos(wt) + 1j*sin(wt))
Generating the animation:
In [6]:
# First set up the figure, the axis, and the plot element we want to animate
from matplotlib import animation
fig = figure()
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)
ax1.set_title('Space vectors in motion')
ax1.set_xlabel('Real')
ax1.set_ylabel('Imag')
ax1.set_xlim(-1.6, 1.6)
ax1.set_ylim(-1.6, 1.6)
ax1.set_aspect('equal')
ax2.set_title('Sinusoidal three-phase')
ax2.set_xlabel('wt [rad]')
ax2.set_xlim(0, 2*pi)
ax2.set_ylim(-1.6, 1.6)
# set up the different line colours
la, lb, lc, ltot, circ = ax1.plot([], [], 'red',
[], [], 'green',
[], [], 'blue',
[], [], 'magenta',
[], [], 'magenta',
lw=2)
# set up the moving dots
da, db, dc = ax2.plot([], [], 'ro',
[], [], 'go',
[], [], 'bo',
lw=2)
tight_layout() # sometimes useful when sub-plots get a bit crowded
# initialization function: plot the background of each frame
def init():
ax1.plot(real(circle), imag(circle), 'black');
ax2.plot(wt, B_ph[0,], 'red',
wt, B_ph[1,], 'green',
wt, B_ph[2,], 'blue',
lw=1);
return
# animation function. This is called sequentially
def animate(i):
re = [real(B[0,i]), real(B[1,i]), real(B[2,i])]
im = [imag(B[0,i]), imag(B[1,i]), imag(B[2,i])]
la.set_data([0, re[0]], [0, im[0]])
lb.set_data([re[0], re[0]+re[1]], [im[0], im[0]+im[1]])
lc.set_data([re[0]+re[1], re[0]+re[1]+re[2]], [im[0]+im[1], im[0]+im[1]+im[2]])
ltot.set_data([0, real(Btot[i])], [0, imag(Btot[i])])
circ.set_data(real(Btot[:i]),imag(Btot[:i]))
da.set_data(wt[i], B_ph[0,i])
db.set_data(wt[i], B_ph[1,i])
dc.set_data(wt[i], B_ph[2,i])
return la, lb, lc, ltot, da, db, dc
# call the animator:
anim = animation.FuncAnimation(fig, animate, init_func=init, interval=50)
If run "normally" (and not in "inline" mode like we are doing here) the command above would have opened a window with the animation running. On the server we can only run "inline" mode but there is a solution to simply generate the animation as a video and embed it right here:
In [7]:
from IPython.display import HTML
HTML(anim.to_html5_video())
Out[7]: