diff --git a/Simulator.py b/Simulator.py index ad28c6d..80bd54e 100644 --- a/Simulator.py +++ b/Simulator.py @@ -5,6 +5,8 @@ ''' import numpy as np +import matplotlib +matplotlib.use("Agg") import matplotlib.pyplot as plt from numpy import * from World import * @@ -15,7 +17,7 @@ from LinearAlegebraUtils import distBetween from RunAtBallBrain import RunAtBallBrain from Team import Team - +from matplotlib import animation #Called once for initialization @@ -33,17 +35,11 @@ def __init__(self, world, simTime, fps, imageDirName): self.imageDirName = imageDirName self.currWP = 0 self.ballWPs = [array([50.0, -100.0, 0.0]), array([0.0, 100.0, -70.0]), array([50.0, 20.0, 100.0]),array([-30.0, 50.0, -100.0]), array([80.0, -50.0, 50.0]), array([80.0, -50.0, -50.0]), array([-65.0, 20.0, 50.0]), array([-50.0, 20.0, -60.0])] + self.fig = plt.figure(figsize=(16,12)) - def setup(self): - #setup directory to save the images - self.imageDirName = 'images' - try: - os.mkdir(self.imageDirName) - except: - print self.imageDirName + " subdirectory already exists. OK." - - #define teams which the agents can be a part of + def setup(self): + #define teams which the agents can be a part of teamA = Team("A", '#ff99ff') teamB = Team("B", '#ffcc99') #Defining a couple of agents @@ -74,7 +70,6 @@ def setup(self): self.world.agents.append(agent3) self.world.agents.append(agent4) -# #define a bunch of obstacles ob1Pos = array([-50,-50,-50]) ob1 = Obstacle(ob1Pos, 30) @@ -83,7 +78,7 @@ def setup(self): ob2 = Obstacle(ob2Pos, 20) #add obstacles to the world - self.world.obstacles.append(ob1); + self.world.obstacles.append(ob1) self.world.obstacles.append(ob2) #define a ball @@ -93,7 +88,8 @@ def setup(self): #add the ball to the world self.world.balls.append(ball) -#called at a fixed 30fps always + # called at a fixed 30fps always + # physics simulation def fixedLoop(self): for agent in self.world.agents: agent.moveAgent(self.world) @@ -106,60 +102,36 @@ def fixedLoop(self): self.ballWPs.remove(self.ballWPs[0]) -#Called at specifed fps + #Called at specifed fps def loop(self, ax): self.world.draw(ax) - - - def run(self): - #Run setup once - self.setup() - - #Setup loop - timeStep = 1/double(30) - frameProb = double(self.fps) / 30 - currTime = double(0) - drawIndex = 0 - physicsIndex = 0 - while(currTime < self.simTime): - self.fixedLoop() - currProb = double(drawIndex)/double(physicsIndex+1) - if currProb < frameProb: - self.drawFrame(drawIndex) - drawIndex+=1 - physicsIndex+=1 - currTime+=double(timeStep) - - print "Physics ran for "+str(physicsIndex)+" steps" - print "Drawing ran for "+str(drawIndex)+" steps" - - def drawFrame(self, loopIndex): - fig = plt.figure(figsize=(16,12)) - ax = fig.add_subplot(111, projection='3d') + + # advances simulation 1 tick, returns the current world state plot + def tick(self): + self.fixedLoop() + + self.fig.clf() + ax = self.fig.add_subplot(111, projection='3d') ax.view_init(elev = 30) ax.set_xlabel("X") ax.set_ylabel("Y") - ax.set_zlabel("Z") - fname = self.imageDirName + '/' + str(int(100000000+loopIndex)) + '.png' # name the file - self.loop(ax) - plt.gca().set_ylim(ax.get_ylim()[::-1]) - savefig(fname, format='png', bbox_inches='tight') - print 'Written Frame No.'+ str(loopIndex)+' to '+ fname - plt.close() + ax.set_zlabel("Z") + + return self.loop(ax), plt.gca().set_ylim(ax.get_ylim()[::-1]) +def tick(i): + return sim.tick() + +# simulator assumes its physics simulation is running at dt = 1/30 s +# would have to recalculate the true animation framerate (to get physically accurate speeds, etc) +# if you change the raw sample rate of the animator function (which accepts arguments in ms) +FPS = 30 # hardcoded into simulation assumptions +simlen = 10 # sec +frames = FPS * simlen -#Simulation runs here -#set the size of the world world = World(100, 100) -#specify which world to simulate, total simulation time, and frammerate for video -sim = Simulator(world, 60, 30, "images") -#run the simulation -sim.run() +sim = Simulator(world, simlen, FPS, "images") -''' -To create a video using the image sequence, execute the following command in command line. ->ffmpeg -f image2 -i "1%08d.png" -r 30 outPut.mp4 -Make sure to set your current working directory to /images and have ffmpeg in your path. -''' +ani = animation.FuncAnimation(sim.fig, tick, frames=frames, blit=True, init_func=sim.setup) - +ani.save('output.mp4', fps=FPS, extra_args=['-vcodec', 'libx264'])