Simulation and Modeling (CSCI 3010U)
Faculty of Science, Ontario Tech University
http://vclab.science.ontariotechu.ca
Check Canvas for Due Date
The goal of this lab is to set up Pygame and Matplotlib python packages on your machines, and get some experience with these packages.
The following steps assumes that you are using Ubuntu linux distribution. To see if you have Python3 installed, use the following command:
$ python3 --versionIf Python3 is not found, you can install it as follows:
$ sudo apt-get update
$ sudo apt-get install python3Next you will need pip3 to install the packages needed for this course. You can see if pip3 is already installed by using the following command:
$ command -v pip3If pip3 is not installed, you can install it using the following command:
$ sudo apt-get install python3-pipIn any case, it is a good idea to upgrade pip3 to the latest version. This can be done using the following command:
$ python3 -m pip install --upgrade pipNow that pip3 is installed, you need to install the packages needed
for this course. You can do so by using the
requirements.txt file available here. You will use the following command to
install the packages:
$ pip3 install -r requirements.txtIf everything goes according to plan, you should be ab le to run the
lab1.py file without a hitch. You can run this file using
the following command:
$ python lab1.pyCheck out the following code that simulates a ball falling under gravity. Friction due to air is missing. The simulation also collects position data and plots position vs. time once the simulation is completed.
"""
author: Faisal Qureshi
email: faisal.qureshi@uoit.ca
website: http://www.vclab.ca
license: BSD
"""
import pygame, sys
import matplotlib.pyplot as plt
import numpy as np
# set up the colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# clock object that ensure that animation has the same
# on all machines, regardless of the actual machine speed.
clock = pygame.time.Clock()
def load_image(name):
image = pygame.image.load(name)
return image
class MyCircle(pygame.sprite.Sprite):
def __init__(self, color, width, height):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.rect = self.image.get_rect()
self.image.fill(WHITE)
cx = self.rect.centerx
cy = self.rect.centery
pygame.draw.circle(self.image, color, (width//2, height//2), cx, cy)
self.rect = self.image.get_rect()
def update(self):
pass
class Simulation:
def __init__(self):
self.y = 0
self.vy = 0
self.mass = 0
self.g = -9.8 # gravity acts downwards
self.dt = 0.033 # 33 millisecond, which corresponds to 30 fps
self.cur_time = 0
self.paused = True # starting in paused mode
def setup(self, y, vy, mass):
self.y = y
self.vy = vy
self.mass = mass
self.times = [self.cur_time*1000]
self.positions = [self.y]
def step(self):
self.y += self.vy
self.vy += (self.g * self.dt / self.mass)
self.cur_time += self.dt
self.times.append(self.cur_time * 1000)
self.positions.append(self.y)
def pause(self):
self.paused = True
def resume(self):
self.paused = False
def sim_to_screen_y(win_height, y):
'''flipping y, since we want our y to increase as we move up'''
return win_height - y
def main():
# initializing pygame
pygame.init()
# top left corner is (0,0) top right (640,0) bottom left (0,480)
# and bottom right is (640,480).
win_width = 640
win_height = 480
screen = pygame.display.set_mode((win_width, win_height))
pygame.display.set_caption('1D Ball in Free Fall')
# setting up a sprite group, which will be drawn on the
# screen
my_sprite = MyCircle(RED, 30, 30)
my_group = pygame.sprite.Group(my_sprite)
# setting up simulation
sim = Simulation()
sim.setup(460, 0, 1)
print ('--------------------------------')
print ('Usage:')
print ('Press (r) to start/resume simulation')
print ('Press (p) to pause simulation')
print ('Press (space) to step forward simulation when paused')
print ('--------------------------------')
while True:
# 30 fps
clock.tick(30)
# update sprite x, y position using values
# returned from the simulation
my_sprite.rect.x = win_width/2
my_sprite.rect.y = sim_to_screen_y(win_height, sim.y)
event = pygame.event.poll()
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(0)
if event.type == pygame.KEYDOWN and event.key == pygame.K_p:
sim.pause()
continue
elif event.type == pygame.KEYDOWN and event.key == pygame.K_r:
sim.resume()
continue
else:
pass
# clear the background, and draw the sprites
screen.fill(WHITE)
my_group.update()
my_group.draw(screen)
pygame.display.flip()
if sim_to_screen_y(win_height, sim.y) > win_height:
pygame.quit()
break
# update simulation
if not sim.paused:
sim.step()
else:
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
sim.step()
# Lets move our lists to numpy array
# first row contains times, second row contains positions
pos_vs_times = np.vstack([sim.times, sim.positions])
# Using matplotlib to plot simulation data
plt.figure(1)
plt.plot(pos_vs_times[0,:], pos_vs_times[1,:])
plt.xlabel('Time (ms)')
plt.ylabel('y position')
plt.title('Height vs. Time')
plt.show()
if __name__ == '__main__':
main()The code is available at lab1.py
You are asked to complete the following tasks:
Via Canvas.
The requirements.txt file is provided here and whose contents are listed
below:
imageio
jupyterlab
matplotlib
notebook
numpy
scipy
opencv-contrib-python
pygame