Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F94121142
fallingobjects.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Dec 4, 02:07
Size
8 KB
Mime Type
text/x-python
Expires
Fri, Dec 6, 02:07 (2 d)
Engine
blob
Format
Raw Data
Handle
22740151
Attached To
rNOTOPOCNB noto-poc-notebooks
fallingobjects.py
View Options
import
numpy
as
np
import
pandas
from
ipywidgets
import
interact
,
interactive
,
fixed
,
interact_manual
from
ipywidgets
import
HBox
,
VBox
,
Label
,
Layout
import
ipywidgets
as
widgets
from
IPython.display
import
set_matplotlib_formats
set_matplotlib_formats
(
'svg'
)
import
matplotlib.pyplot
as
plt
plt
.
style
.
use
(
'seaborn-whitegrid'
)
# global style for plotting
###--- Functions representing the equations of the movement as functions of time and the problem parameters
def
accel_time
(
g
,
h_0
,
v_0
,
m
,
t
):
'''
Computes the acceleration of the object as a function of time
a(t) = -g
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:m: mass of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for acceleration at each point of the time scale
'''
return
[
-
g
]
*
t
.
size
# returning a list of same length as the time interval filled with -g
def
veloc_time
(
g
,
h_0
,
v_0
,
m
,
t
):
'''
Computes the velocity of the object as a function of time
v(t) = -g.t + v_0
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:m: mass of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for velocity at each point of the time scale
'''
return
-
g
*
t
+
v_0
def
height_time
(
g
,
h_0
,
v_0
,
m
,
t
):
'''
Computes the height of the object as a function of time
h(t) = -1/2.g.t^2 + v_0.t + h_0
:g: gravitational acceleration constant
:h_0: initial height of the object
:v_0: initial velocity of the object
:m: mass of the object
:t: time scale (array of time points at which to compute the equation)
:returns: array of values for height at each point of the time scale
'''
return
-
0.5
*
g
*
(
t
**
2
)
+
v_0
*
t
+
h_0
###--- Static list of objects with which we can experiment.
# Objects come with a name, a mass (in kg) and a color for identifying them in the graphical display.
objects
=
[{
'name'
:
'Bowling ball'
,
'mass'
:
5.0
,
'color'
:
'#DC143C'
},{
'name'
:
'Tennis ball'
,
'mass'
:
0.05
,
'color'
:
'#2E8B57'
},{
'name'
:
'Ostrich feather'
,
'mass'
:
0.005
,
'color'
:
'#483D8B'
}]
class
FallingObjectsLab
:
"""
This class embeds all the necessary code to create a virtual lab to study the movement of objects falling vertically in vacuum.
"""
def
__init__
(
self
,
g
=
9.81
,
h_0
=
5
,
v_0
=
0
,
t
=
np
.
linspace
(
0
,
3
,
25
),
objects
=
objects
,
accel_time
=
accel_time
,
veloc_time
=
veloc_time
,
height_time
=
height_time
,
show_v_0
=
False
):
'''
Initiates and displays the virtual lab on falling objects.
:g: gravitational acceleration constant
:h_0: initial height of the objects
:v_0: initial velocity of the objects
:t: time scale (array of time points at which to compute the equation)
:objects: nested dictionnary with the objects to display, which should come with a name, a mass (in kg) and a color (hex code)
:accel_time: function to compute the acceleration of the objects as a function of time -- a(g, h_0, v_0, m, t)
:veloc_time: function to compute the velocity of the objects as a function of time -- v(g, h_0, v_0, m, t)
:height_time: function to compute the height of the objects as a function of time -- h(g, h_0, v_0, m, t)
:show_v_0: when True, a slider to change the initial velocity of objects is displayed in the interface
'''
###--- We define the parameters of our problem:
# The standard acceleration due to gravity
self
.
g
=
g
# gravity in m/s2
# The initial conditions of our problem
self
.
h_0
=
h_0
# initial height in m
self
.
v_0
=
v_0
# initial velocity in m/s
# To plot the movement of our objects in time we need to define a time scale.
self
.
t
=
t
# time interval from 0 to x seconds, with n points in the interval
# Functions to compute movement equations
self
.
accel_time
=
accel_time
self
.
veloc_time
=
veloc_time
self
.
height_time
=
height_time
# Create indexed list of objects
self
.
objects_list
=
pandas
.
DataFrame
(
objects
)
self
.
objects_list
.
set_index
(
'name'
,
inplace
=
True
)
# We index objects by their name to find them easily after
# Initialize list of currently selected objects with first element of the list
self
.
objs
=
[
self
.
objects_list
.
index
[
0
],]
###--- Then we define the elements of the ihm:
# parameters for sliders
self
.
h_min
=
0
self
.
h_max
=
10
self
.
v_min
=
0
self
.
v_max
=
5
# IHM input elements
input_layout
=
Layout
(
margin
=
'5px 10px'
)
self
.
h_label
=
Label
(
'Initial height ($m$):'
,
layout
=
input_layout
)
self
.
h_widget
=
widgets
.
FloatSlider
(
min
=
self
.
h_min
,
max
=
self
.
h_max
,
step
=
1
,
value
=
self
.
h_0
,
layout
=
input_layout
)
self
.
h_input
=
HBox
([
self
.
h_label
,
self
.
h_widget
])
self
.
v_label
=
Label
(
'Initial velocity ($m.s^{-1}$):'
,
layout
=
input_layout
)
self
.
v_widget
=
widgets
.
FloatSlider
(
min
=
self
.
v_min
,
max
=
self
.
v_max
,
step
=
1
,
value
=
self
.
v_0
,
layout
=
input_layout
)
self
.
v_input
=
HBox
([
self
.
v_label
,
self
.
v_widget
])
self
.
obj_m_label
=
Label
(
'Choice of object(s):'
,
layout
=
input_layout
)
self
.
obj_m_widget
=
widgets
.
SelectMultiple
(
options
=
self
.
objects_list
.
index
,
value
=
self
.
objs
,
disabled
=
False
,
layout
=
input_layout
)
self
.
obj_m_input
=
HBox
([
self
.
obj_m_label
,
self
.
obj_m_widget
])
# IHM output elements
self
.
obj_m_output
=
widgets
.
Output
(
layout
=
input_layout
)
self
.
graph_output
=
widgets
.
Output
(
layout
=
input_layout
)
# Linking widgets to handlers
self
.
h_widget
.
observe
(
self
.
h_event_handler
,
names
=
'value'
)
self
.
v_widget
.
observe
(
self
.
v_event_handler
,
names
=
'value'
)
self
.
obj_m_widget
.
observe
(
self
.
obj_m_event_handler
,
names
=
'value'
)
# Organize layout
self
.
ihm
=
VBox
([
self
.
graph_output
,
HBox
([
VBox
([
self
.
obj_m_input
,
self
.
obj_m_output
]),
VBox
([
self
.
h_input
,
self
.
v_input
])
if
show_v_0
else
VBox
([
self
.
h_input
])
])
])
###--- Finally, we display the whole interface and we update it right away so that it plots the graph with current values
display
(
self
.
ihm
);
self
.
update_lab
()
# Event handlers
def
h_event_handler
(
self
,
change
):
self
.
h_0
=
change
.
new
self
.
update_lab
()
def
v_event_handler
(
self
,
change
):
self
.
v_0
=
change
.
new
self
.
update_lab
()
def
obj_m_event_handler
(
self
,
change
):
self
.
objs
=
change
.
new
self
.
update_lab
()
# Display updated output function
def
update_lab
(
self
):
# Clear outputs
self
.
graph_output
.
clear_output
(
wait
=
True
)
self
.
obj_m_output
.
clear_output
(
wait
=
True
)
# Create the figure
fig
,
ax
=
plt
.
subplots
(
1
,
3
,
sharex
=
'col'
,
figsize
=
(
16
,
4
))
# for each object currently selected
for
o
in
self
.
objs
:
# get mass
m
=
self
.
objects_list
.
at
[
o
,
'mass'
]
# get color
c
=
self
.
objects_list
.
at
[
o
,
'color'
]
# Recompute equations with parameters set by the user
h_t
=
self
.
height_time
(
self
.
g
,
self
.
h_0
,
self
.
v_0
,
m
,
self
.
t
)
v_t
=
self
.
veloc_time
(
self
.
g
,
self
.
h_0
,
self
.
v_0
,
m
,
self
.
t
)
a_t
=
self
.
accel_time
(
self
.
g
,
self
.
h_0
,
self
.
v_0
,
m
,
self
.
t
)
# Plot equations
ax
[
0
]
.
set_title
(
'Height ($m$)'
)
ax
[
0
]
.
plot
(
self
.
t
,
h_t
,
color
=
c
,
label
=
o
)
ax
[
0
]
.
set_ylim
(
bottom
=
0
,
top
=
self
.
h_max
+
(
self
.
v_max
/
2
if
self
.
v_0
>
0
else
1
))
ax
[
1
]
.
set_title
(
'Velocity ($m.s^{-1}$)'
)
ax
[
1
]
.
plot
(
self
.
t
,
v_t
,
color
=
c
,
label
=
o
)
ax
[
1
]
.
set_ylim
(
top
=
self
.
v_max
+
1
)
ax
[
2
]
.
set_title
(
'Acceleration ($m.s^{-2}$)'
)
ax
[
2
]
.
plot
(
self
.
t
,
a_t
,
color
=
c
,
label
=
o
)
ax
[
2
]
.
set_ylim
(
top
=
0
)
# Display weight of object selected
with
self
.
obj_m_output
:
print
(
"Mass of the selected object (kg): "
,
m
)
# Add time axis and legend
for
a
in
ax
:
a
.
set_xlabel
(
'Time (s)'
)
a
.
legend
()
fig
.
tight_layout
()
# Display graph
with
self
.
graph_output
:
plt
.
show
();
# EOF
Event Timeline
Log In to Comment