jeudi 23 juin 2016

How to animate the position and orientation of an image on a Matplotlib plot?


Problem I am trying to simulate the landing of an upright rocket. I can plot the point representation of the dynamics easily; however, in order to make this simulation look cool I would like to add a picture representation of the rocket. Basically all I want to do is refresh an image of the rocket, with a height of L, a width of W, a position of (x,y), and an orientation of ϕ, where (x,y) and ϕ are determined from the rocket's data point. What is currently happening is that the .png image is being plotted at every time step and not refreshing. My problem can easily be understood by the animation I have so far in this video. Please take a look at the animation portion of my Python code below. Any help is appreciated. Python Code # Initial and global vars Earth = Environment('Earth') Falcon = Lander(Earth) dt = 1. / 30. # 30 fps #/////////////////////////////////////////////////////////////////////////// # set up figure and animation fig = plt.figure() ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(0,150), ylim=(0,100)) ax.grid() line, = ax.plot([], 'o-', lw=2) status = ax.text(0.02, 0.50, '', transform=ax.transAxes) im_fname = os.path.dirname(os.path.realpath(__file__)) + '/falcon9.png' im = img.imread(im_fname) def init(): """initialize animation""" line.set_data([], []) status.set_text('') return line, status def animate(i): """perform animation step""" global Falcon, dt; Falcon.step(dt) x, y, vx, vy, theta, omega, mass = Falcon.state L, W, Isp = Falcon.params # Length and width of rocket line.set_data([Falcon.state[0], Falcon.state[1]]) t = Falcon.time_elapsed aax, aay = Falcon.Drag()/mass theta = np.degrees(theta)%360 v = np.linalg.norm([vx, vy]) status.set_text('$Time = %.2f$n' % t + '$a_D = (%.2f, %.2f)$n' % (aax, aay) + '$v = %.2f$n' % v + '$angle = %.2f$n' % theta + '$mass = %.4f$n' % mass) # Show Falcon9 image x_hat, y_hat = Falcon.Orientation() # in this orientation left, right = x-W/2., x+W/2. # perimeter of object down, up = y-L/2., y+L/2. ax.imshow(np.zeros((100, 100)), aspect='auto', extent=(left, right, down, up)) return line, status # Interval based on dt and time to animate one step from time import time t0 = time() animate(0) t1 = time() interval = 1000 * dt - (t1 - t0) ani = animation.FuncAnimation(fig, animate, frames=300, interval=interval, blit=True, init_func=init) ani.save('falcon9.mp4', fps=30, extra_args=['-vcodec', 'libx264']) plt.show()

Aucun commentaire:

Enregistrer un commentaire