forked from arindam1993/PyBioSim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Simulator.py
165 lines (131 loc) · 5.08 KB
/
Simulator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
'''
Created on Jan 16, 2015
@author: Arindam
'''
import numpy as np
import matplotlib.pyplot as plt
from numpy import *
from World import *
from Agent import Agent
from Obstacle import *
from pylab import *
from Ball import Ball
from LinearAlegebraUtils import distBetween
from RunAtBallBrain import RunAtBallBrain
from Team import Team
#Called once for initialization
'''
Usage guidelines:
1. Define globals required for the simulation in the __init__ constructor, here we define a bunch of waypoints for the ball
2. Initialize the globals in the setup() method.
'''
class Simulator(object):
def __init__(self, world, simTime, fps, imageDirName):
self.world = world
self.simTime = simTime
self.fps = fps
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])]
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
teamA = Team("A", '#ff99ff')
teamB = Team("B", '#ffcc99')
#Defining a couple of agents
ag1Pos = array([80, 50, -20])
ag1Rot = array([30, 0, 0])
ag1Brain = RunAtBallBrain()
agent1 = Agent(teamA, ag1Pos, ag1Rot, ag1Brain, 5, 5)
ag2Pos = array([-80, 0, 0])
ag2Rot = array([0, 0, 0])
ag2Brain = RunAtBallBrain()
agent2 = Agent(teamA, ag2Pos, ag2Rot, ag2Brain, 5, 5)
ag3Pos = array([70, 30, 50])
ag3Rot = array([0, 0, 0])
ag3Brain = RunAtBallBrain()
agent3 = Agent(teamB, ag3Pos, ag3Rot, ag3Brain, 5, 5)
ag4Pos = array([-80, 20, 60])
ag4Rot = array([0, 0, 0])
ag4Brain = RunAtBallBrain()
agent4 = Agent(teamB, ag4Pos, ag4Rot, ag4Brain, 5, 5)
#Add the agent to the world
self.world.agents.append(agent1)
self.world.agents.append(agent2)
self.world.agents.append(agent3)
self.world.agents.append(agent4)
#
#define a bunch of obstacles
ob1Pos = array([-50,-50,-50])
ob1 = Obstacle(ob1Pos, 30)
ob2Pos = array([80,-50,-50])
ob2 = Obstacle(ob2Pos, 20)
#add obstacles to the world
self.world.obstacles.append(ob1);
self.world.obstacles.append(ob2)
#define a ball
ball = Ball(array([0, 0, 0]))
#add the ball to the world
self.world.balls.append(ball)
#called at a fixed 30fps always
def fixedLoop(self):
for agent in self.world.agents:
agent.moveAgent(self.world)
for ball in self.world.balls:
if len(self.ballWPs) > 0:
ball.moveBall(self.ballWPs[0], 1)
if distBetween(ball.position, self.ballWPs[0]) < 0.5:
if len(self.ballWPs) > 0:
self.ballWPs.remove(self.ballWPs[0])
#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')
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()
#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()
'''
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.
'''