In [10]:
# import necessary packages
import numpy as np
from numpy import pi, sin, cos, sqrt, absolute, arcsin, arccos, arctan, sign
import matplotlib.pyplot as plt
%matplotlib inline
from matplotlib import animation, rc
from IPython.display import HTML
print(animation.writers.list())
In [11]:
# input parameters
r = 0.395 # crank radius
l = 4.27 # connecting rod length
rr = 1.15; # rocker radius
d = 4.03 # center-to-center distance
rot_num = 6 # number of crank rotations
increment = 0.1 # angle incremement
over = 1 # if over = 1 --> mechanism is on top, If over = -1, mechanism on bottom
s = over / absolute(over)
# create the angle array, where the last angle is the number of rotations*2*pi
angle_minus_last = np.arange(0, rot_num * 2 * pi, increment)
R_Angles = np.append(angle_minus_last, rot_num * 2 * pi)
# coordinates of the crank center point : Point 1
x1 = 0;
y1 = 0;
# Coordinates of the rocker center point: Point 4
x4 = d
y4 = 0
X2 = np.zeros(len(R_Angles)) # array of crank x-positions: Point 2
Y2 = np.zeros(len(R_Angles)) # array of crank y-positions: Point 2
RR_Angle = np.zeros(len(R_Angles)) # array of rocker arm angles
X3 = np.zeros(len(R_Angles)) # array of rocker x-positions: Point 3
Y3 = np.zeros(len(R_Angles)) # array of rocker y-positions: Point 3
# find the crank and connecting rod positions for each angle
for index, R_Angle in enumerate(R_Angles, start=0):
theta1 = R_Angle
x2 = r * cos(theta1) # x-cooridnate of the crank: Point 2
y2 = r * sin(theta1) # y-cooridnate of the crank: Point 2
e = sqrt((x2 - d) ** 2 + (y2 ** 2))
phi2 = arccos((e ** 2 + rr ** 2 - l ** 2) / (2 * e * rr))
phi1 = arctan(y2 / (x2 - d)) + (1 - sign(x2 - d)) * pi / 2
theta3 = phi1 - s * phi2
RR_Angle[index] = theta3
x3 = rr * cos(theta3) + d; # x cooridnate of the rocker moving point: Point 3
y3 = rr * sin(theta3); # y cooridnate of the rocker moving point: Point 3
theta2 = arctan((y3 - y2) / (x3 - x2)) + (1 - sign(x3 - x2)) * pi / 2;
X2[index] = x2 # grab the crankshaft x-position
Y2[index] = y2 # grab the crankshaft y-position
X3[index] = x3 # grab the connecting rod x-position
Y3[index] = y3 # grab the connecting rod y-position
# set up the figure and subplot
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(-2, 6), ylim=(-2, 3))
# add grid lines, title and take out the axis tick labels
ax.grid(alpha=0.5)
ax.set_title('Crank and Rocker Motion')
ax.set_xticklabels([])
ax.set_yticklabels([])
line, = ax.plot([], [], 'o-', lw=5, color='#2b8cbe') # color from: http://colorbrewer2.org/
# initialization function
def init():
line.set_data([], [])
return line,
# animation function
def animate(i):
x_points = [x1, X2[i], X3[i], x4]
y_points = [y1, Y2[i], Y3[i], y4]
line.set_data(x_points, y_points)
return line,
# call the animation
ani = animation.FuncAnimation(fig, animate, init_func=init, frames=len(X2), interval=40, blit=True, repeat=False)
## to save animation, uncomment the line below. Ensure ffmpeg is installed:
## ani.save('crank_and_rocker_motion_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
# show the animation
#plt.show()
In [12]:
HTML(ani.to_html5_video())
Out[12]:
In [13]:
# equivalent to rcParams['animation.html'] = 'html5'
rc('animation', html='html5')
ani
Out[13]:
In [ ]: