API

resonance/system.py

class resonance.system.System

This is the abstract base class for any single or multi degree of freedom system. It can be sub-classed to make a custom system or the necessary methods can be added dynamically.

add_measurement(name, func)

Creates a new measurement entry in the measurements attribute that uses the provided function to compute the measurement.

Parameters:
  • name (string) – This must be a valid Python variable name and it should not clash with any names in the constants or coordinates dictionary.
  • func (function) – This function must only have existing parameter, coordinate, or measurement names in the function signature. These can be a subset of the available choices and any order is permitted. The function must be able to operate on arrays, i.e. use NumPy vectorized functions inside. It should return a single variable, scalar or array, that gives the values of the measurement.

Examples

>>> import numpy as np
>>> def f(par2, meas4, par1, coord5):
          return par2 + meas4 + par1 + np.abs(coord5)
>>> f(1.0, 2.0, 3.0, -4.0):
10.0
>>> f(1.0, 2.0, 3.0, np.array([1.0, 2.0, -4.0]))
array([  7.,   8.,  10.])
>>> sys.add_measurement('meas5', f)
>>> sys.measurements['meas5']
10.0
animate_configuration(fps=30, **kwargs)

Returns a matplotlib animation function based on the configuration plot and the configuration plot update function.

Parameters:
  • fps (integer) – The frames per second that should be displayed in the animation. The latest trajectory will be resampled via linear interpolation to create the correct number of frames. Note that the frame rate will depend on the CPU speed of the computer. You’ll likely have to adjust this by trial and error to get something that matches well for your computer if you want the animation to run in real time.
  • **kwargs – Any extra keyword arguments will be passed to matplotlib.animation.FuncAnimation(). The interval keyword argument will be ignored.
config_plot_func

The configuration plot function arguments should be any of the system’s constants, coordinates, measurements, or ‘time’. No other arguments are valid. The function has to return the matplotlib figure as the first item but can be followed by any number of mutable matplotlib objects that you may want to change during an animation. Refer to the matplotlib documentation for tips on creating figures.

Examples

>>> sys = SingleDoFLinearSystem()
>>> sys.constants['radius'] = 5.0
>>> sys.constants['center_y'] = 10.0
>>> sys.coordinates['center_x'] = 0.0
>>> def plot(radius, center_x, center_y, time):
...     fig, ax = plt.subplots(1, 1)
...     circle = Circle((center_x, center_y), radius=radius)
...     ax.add_patch(circle)
...     ax.set_title(time)
...     return fig, circle, ax
...
>>> sys.config_plot_function = plot
>>> sys.plot_configuration()
config_plot_update_func

The configuration plot update function arguments should be any of the system’s constants, coordinates, measurements, or ‘time’ in any order with the returned values from the config_plot_func as the last arguments in the exact order as in the configuration plot return statement. No other arguments are valid. Nothing need be returned from the function. See the matplotlib animation documentation for tips on creating these update functions.

Examples

>>> sys = SingleDoFLinearSystem()
>>> sys.constants['radius'] = 5.0
>>> sys.constants['center_y'] = 10.0
>>> sys.coordinates['center_x'] = 0.0
>>> def plot(radius, center_x, center_y, time):
...     fig, ax = plt.subplots(1, 1)
...     circle = Circle((center_x, center_y), radius=radius)
...     ax.add_patch(circle)
...     ax.set_title(time)
...     return fig, circle, ax
...
>>> sys.config_plot_function = plot
>>> def update(center_y, center_x, time, circle, ax):
...     # NOTE : that circle and ax have to be the last arguments and be
...     # in the same order as returned from plot()
...     circle.set_xy((center_x, center_y))
...     ax.set_title(time)
...     fig.canvas.draw()
...
>>> sys.config_plot_update_func = update
>>> sys.animate_configuration()
constants

A dictionary containing the all of the system’s constants, i.e. parameters that do not vary with time.

Examples

>>> sys = System()
>>> sys.constants
{}
>>> sys.constants['mass'] = 5.0
>>> sys.constants
{'mass': 5.0}
>>> del sys.constants['mass']
>>> sys.constants
{}
>>> sys.constants['mass'] = 5.0
>>> sys.constants['length'] = 10.0
>>> sys.constants
{'mass': 5.0, 'length': 10.0}
coordinates

A dictionary containing the system’s generalized coordinates, i.e. coordinate parameters that vary with time. These values will be used as initial conditions in simulations.

Examples

>>> sys = System()
>>> sys.coordinates['angle'] = 0.0
>>> sys.coordinates
{'angle': 0.0}
free_response(final_time, initial_time=0.0, sample_rate=100, **kwargs)

Returns a data frame with monotonic time values as the index and columns for each coordinate and measurement at the time value for that row. Note that this data frame is stored on the system as the variable result until this method is called again, which will overwrite it.

Parameters:
  • final_time (float) – A value of time in seconds corresponding to the end of the simulation.
  • initial_time (float, optional) – A value of time in seconds corresponding to the start of the simulation.
  • sample_rate (integer, optional) – The sample rate of the simulation in Hertz (samples per second). The time values will be reported at the initial time and final time, i.e. inclusive, along with times space equally based on the sample rate.
Returns:

df – A data frame indexed by time with all of the coordinates and measurements as columns.

Return type:

pandas.DataFrame

measurements

A dictionary containing the all of the system’s measurements, i.e. parameters that are functions of the constants, coordinates, speeds, and other measurements.

plot_configuration()

Returns a matplotlib figure generated by the function assigned to the config_plot_func attribute. You may need to call matplotlib.pyplot.show() to display the figure.

Returns:
  • fig (matplotlib.figure.Figure) – The first returned object is always a figure.
  • *args (matplotlib objects) – Any matplotlib objects can be returned after the figure.
speeds

A dictionary containing the system’s generalized speeds, i.e. speed parameters that vary with time. These values will be used as initial conditions in simulations.

Examples

>>> sys = System()
>>> sys.speeds['angle_vel'] = 0.0
>>> sys.speeds
{'angle_vel': 0.0}
states

An ordered dictionary containing the system’s state variables and values. The coordinates are always ordered before the speeds and the individual order of the values depends on the order they were added to coordinates and speeds.

Examples

>>> sys = System()
>>> sys.coordinates['angle'] = 0.2
>>> sys.speeds['angle_vel'] = 0.1
>>> sys.states
{'angle': 0.2, 'angle_vel': 0.1}
>>> list(sys.states.keys())
['angle', 'angle_vel']
>>> list(sys.states.values())
[0.2, 0.1]

resonance/linear_systems.py

class resonance.linear_systems.BaseExcitationSystem

Bases: resonance.linear_systems.SingleDoFLinearSystem

This system represents a mass connected to a moving massless base via a spring and damper in parallel. The motion of the mass is subject to viscous damping. The system is described by:

constants
mass, m [kg]
The suspended mass.
damping, c [kg / s]
The viscous linear damping coefficient which represents any energy dissipation from things like air resistance, friction, etc.
stiffness, k [N / m]
The linear elastic stiffness of the spring.
coordinates
position, x [m]
The absolute position of the mass.
speeds
velocity, x_dot [m / s]
The absolute velocity of the mass.
periodic_base_displacing_response(twice_avg, cos_coeffs, sin_coeffs, frequency, final_time, initial_time=0.0, sample_rate=100, force_col_name='forcing_function', displace_col_name='displacing_function')

Returns the trajectory of the system’s coordinates, speeds, accelerations, and measurements if a periodic function defined by a Fourier series is applied as displacement of the base in the same direction as the system’s coordinate. The displacing function is defined as:

                 N
y(t)  = a0 / 2 + ∑ (an * cos(n*ω*t) + bn * sin(n*ω*t))
                n=1

Where a0, a1...an, and b1...bn are the Fourier coefficients. If N=∞ then the Fourier series can describe any periodic function with a period (2*π)/ω.

Parameters:
  • twice_avg (float) – Twice the average value over one cycle, a0.
  • cos_coeffs (float or sequence of floats) – The N cosine Fourier coefficients: a1, ..., aN.
  • sin_coeffs (float or sequence of floats) – The N sine Fourier coefficients: b1, ..., bN.
  • frequency (float) – The frequency, ω, in radians per second corresponding to one full cycle of the function.
  • final_time (float) – A value of time in seconds corresponding to the end of the simulation.
  • initial_time (float, optional) – A value of time in seconds corresponding to the start of the simulation.
  • sample_rate (integer, optional) – The sample rate of the simulation in Hertz (samples per second). The time values will be reported at the initial time and final time, i.e. inclusive, along with times space equally based on the sample rate.
  • force_col_name (string, optional) – A valid Python identifier that will be used as the column name for the forcing function trajectory in the returned data frame.
  • displace_col_name (string, optional) – A valid Python identifier that will be used as the column name for the forcing function trajectory in the returned data frame.
Returns:

A data frame indexed by time with all of the coordinates, speeds, measurements, and forcing/displacing functions as columns.

Return type:

pandas.DataFrame

sinusoidal_base_displacing_response(amplitude, frequency, final_time, initial_time=0.0, sample_rate=100, force_col_name='forcing_function', displace_col_name='displacing_function')

Returns the trajectory of the system’s coordinates, speeds, accelerations, and measurements if a sinusoidal displacement function described by:

y(t) = Y * sin(ω*t)

is specified for the movement of the base in the direction of the system’s coordinate.

Parameters:
  • amplitude (float) – The amplitude of the displacement function, Y, in meters.
  • frequency (float) – The frequency, ω, in radians per second of the sinusoidal displacement.
  • final_time (float) – A value of time in seconds corresponding to the end of the simulation.
  • initial_time (float, optional) – A value of time in seconds corresponding to the start of the simulation.
  • sample_rate (integer, optional) – The sample rate of the simulation in Hertz (samples per second). The time values will be reported at the initial time and final time, i.e. inclusive, along with times space equally based on the sample rate.
  • force_col_name (string, optional) – A valid Python identifier that will be used as the column name for the forcing function trajectory in the returned data frame.
  • displace_col_name (string, optional) – A valid Python identifier that will be used as the column name for the forcing function trajectory in the returned data frame.
Returns:

A data frame indexed by time with all of the coordinates and measurements as columns.

Return type:

pandas.DataFrame

class resonance.linear_systems.BookOnCupSystem

Bases: resonance.linear_systems.SingleDoFLinearSystem

This system represents dynamics of a typical engineering textbook set atop a cylinder (a coffee cup) such that the book can vibrate without slip on the curvature of the cup. It is described by:

constants
thickness, t [meters]
the thickness of the book
length, l [meters]
the length of the edge of the book which is tangent to the cup’s surface
mass, m [kilograms]
the mass of the book
radius, r [meters]
the outer radius of the cup
coordinates
book_angle, theta [radians]
the angle of the book with respect to the gravity vector
speeds
book_angle_vel, theta [radians]
the angular rate of the book with respect to the gravity vector
class resonance.linear_systems.ClockPendulumSystem

Bases: resonance.linear_systems.SingleDoFLinearSystem

This system represents dynamics of a simple compound pendulum in which a rigid body is attached via a revolute joint to a fixed point. Gravity acts on the pendulum to bring it to an equilibrium state and there is no friction in the joint. It is described by:

constants
pendulum_mass, m [kg]
The mass of the compound pendulum.
inertia_about_joint, i [kg m**2]
The moment of inertia of the compound pendulum about the revolute joint.
joint_to_mass_center, l [m]
The distance from the revolute joint to the mass center of the compound pendulum.
acc_due_to_gravity, g [m/s**2]
The acceleration due to gravity.
coordinates
angle, theta [rad]
The angle of the pendulum relative to the direction of gravity. When theta is zero the pendulum is hanging down in it’s equilibrium state.
speeds
angle_vel, theta_dot [rad / s]
The angular velocity of the pendulum about the revolute joint axis.
class resonance.linear_systems.CompoundPendulumSystem

Bases: resonance.linear_systems.SingleDoFLinearSystem

This system represents dynamics of a simple compound pendulum in which a rigid body is attached via a revolute joint to a fixed point. Gravity acts on the pendulum to bring it to an equilibrium state and there is no friction in the joint. It is described by:

constants
pendulum_mass, m [kg]
The mass of the compound pendulum.
inertia_about_joint, i [kg m**2]
The moment of inertia of the compound pendulum about the revolute joint.
joint_to_mass_center, l [m]
The distance from the revolute joint to the mass center of the compound pendulum.
acc_due_to_gravity, g [m/s**2]
The acceleration due to gravity.
coordinates
angle, theta [rad]
The angle of the pendulum relative to the direction of gravity. When theta is zero the pendulum is hanging down in it’s equilibrium state.
speeds
angle_vel, theta_dot [rad / s]
The angular velocity of the pendulum about the revolute joint axis.
class resonance.linear_systems.MassSpringDamperSystem

Bases: resonance.linear_systems.SingleDoFLinearSystem

This system represents dynamics of a mass connected to a spring and damper (dashpot). The mass moves horizontally without friction and is acted on horizontally by the spring and damper in parallel. The system is described by:

constants
mass, M [kg]
The system mass.
damping, C [kg / s]
The viscous linear damping coefficient which represents any energy dissipation from things like air resistance, slip, etc.
stiffness, K [N / m]
The linear elastic stiffness of the spring.
coordinates

position, x [m]

speeds

velocity, x_dot [m / s]

class resonance.linear_systems.SimplePendulumSystem

Bases: resonance.linear_systems.SingleDoFLinearSystem

This system represents dynamics of a simple pendulum in which a point mass is fixed on a massless pendulum arm of some length to a revolute joint. Gravity acts on the pendulum to bring it to an equilibrium state and there is no friction in the joint. It is described by:

constants
pendulum_mass, m [kg]
The mass of the compound pendulum.
pendulum_length, l [m]
The distance from the revolute joint to the point mass location.
acc_due_to_gravity, g [m/s**2]
The acceleration due to gravity.
coordinates
angle, theta [rad]
The angle of the pendulum relative to the direction of gravity. When theta is zero the pendulum is hanging down in it’s equilibrium state.
speeds
angle_vel, theta_dot [rad / s]
The angular velocity of the pendulum about the revolute joint axis.
class resonance.linear_systems.SimpleQuarterCarSystem

Bases: resonance.linear_systems.BaseExcitationSystem

This system represents a mass connected to a moving massless base via a spring and damper in parallel. The motion of the mass is subject to viscous damping. The system is described by:

constants
mass, m [kg]
The suspended mass.
damping, c [kg / s]
The viscous linear damping coefficient which represents any energy dissipation from things like air resistance, friction, etc.
stiffness, k [N / m]
The linear elastic stiffness of the spring.
coordinates
position, x [m]
The absolute position of the mass.
speeds
velocity, x_dot [m / s]
The absolute velocity of the mass.
class resonance.linear_systems.SingleDoFLinearSystem

Bases: resonance.system.System

This is the abstract base class for any single degree of freedom linear system. It can be sub-classed to make a custom system or the necessary methods can be added dynamically.

canonical_coeffs_func

A function that returns the three linear coefficients of the left hand side of a canonical second order ordinary differential equation. This equation looks like the following for linear motion:

mv’ + cv + kx = F(t)

and like the following for angular motion:

Iω’ + cω + kθ = T(t)

where:

  • m: mass of the moving particle
  • I: moment of inertia of a rigid body
  • c: viscous damping coefficient (linear or angular)
  • k: spring stiffness (linear or angular)
  • x: the positional coordinate of the mass
  • v: the positional speed of the mass
  • θ: the angular coordinate of the body
  • ω: the angular speed of the body

The coefficients (m, c, k, I) must be defined in terms of the system’s constants.

Example

>>> sys = SingleDoFLinearSystem()
>>> sys.constants['gravity'] = 9.8  # m/s**2
>>> sys.constants['length'] = 1.0  # m
>>> sys.constnats['mass'] = 0.5  # kg
>>> sys.coordinates['theta'] = 0.3  # rad
>>> sys.speeds['omega'] = 0.0  # rad/s
>>> def coeffs(gravity, length, mass):
>>>     # Represents a linear model of a simple pendulum:
...     #  m * l**2 ω' + m * g * l * θ = 0
...     I = mass * length**2
...     c = 0.0
...     k = mass * gravity * length
...     return I, c, k
>>> sys.canonical_coeffs_func = coeffs
frequency_response(frequencies, amplitude)

Returns the amplitude and phase shift for simple sinusoidal forcing of the system. The first holds the plot of the coordinate’s amplitude as a function of forcing frequency and the second holds a plot of the coordinate’s phase shift with respect to the forcing function.

Parameters:
  • frequencies (array_like, shape(n,)) –
  • amplitude (float) – The value of the forcing amplitude.
Returns:

  • amp_curve (ndarray, shape(n,)) – The amplitude values of the coordinate at different frequencies.
  • phase_curve (ndarray, shape(n,)) – The phase shift values in radians of the coordinate relative to the forcing.

frequency_response_plot(amplitude, log=False, axes=None)

Returns an array of two matplotlib axes. The first holds the plot of the coordinate’s amplitude as a function of forcing frequency and the second holds a plot of the coordinate’s phase shift with respect to the forcing function.

Parameters:
  • amplitude (float) – The value of the forcing amplitude.
  • log (boolean, optional) – If True, the amplitude will be plotted on a semi-log Y plot.
period()

Returns the (damped) period of oscillation of the coordinate in seconds.

periodic_forcing_response(twice_avg, cos_coeffs, sin_coeffs, frequency, final_time, initial_time=0.0, sample_rate=100, col_name='forcing_function')

Returns the trajectory of the system’s coordinates, speeds, accelerations, and measurements if a periodic forcing function defined by a Fourier series is applied as a force or torque in the same direction as the system’s coordinate. The forcing function is defined as:

                        N
F(t) or T(t) = a0 / 2 + ∑ (an * cos(n*ω*t) + bn * sin(n*ω*t))
                       n=1

Where a0, a1...an, and b1...bn are the Fourier coefficients. If N=∞ then the Fourier series can describe any periodic function with a period (2*π)/ω.

Parameters:
  • twice_avg (float) – Twice the average value over one cycle, a0.
  • cos_coeffs (float or sequence of floats) – The N cosine Fourier coefficients: a1, ..., aN.
  • sin_coeffs (float or sequence of floats) – The N sine Fourier coefficients: b1, ..., bN.
  • frequency (float) – The frequency, ω, in radians per second corresponding to one full cycle of the function.
  • final_time (float) – A value of time in seconds corresponding to the end of the simulation.
  • initial_time (float, optional) – A value of time in seconds corresponding to the start of the simulation.
  • sample_rate (integer, optional) – The sample rate of the simulation in Hertz (samples per second). The time values will be reported at the initial time and final time, i.e. inclusive, along with times space equally based on the sample rate.
  • col_name (string, optional) – A valid Python identifier that will be used as the column name for the forcing function trajectory in the returned data frame.
Returns:

A data frame indexed by time with all of the coordinates and measurements as columns.

Return type:

pandas.DataFrame

sinusoidal_forcing_response(amplitude, frequency, final_time, initial_time=0.0, sample_rate=100, col_name='forcing_function')

Returns the trajectory of the system’s coordinates, speeds, accelerations, and measurements if a sinusoidal forcing (or torquing) function defined by:

F(t) = Fo * cos(ω * t)

or

T(t) = To * cos(ω * t)

is applied to the moving body in the direction of the system’s coordinate.

Parameters:
  • amplitude (float) – The amplitude of the forcing/torquing function, Fo or To, in Newtons or Newton-Meters.
  • frequency (float) – The frequency, ω, in radians per second of the sinusoidal forcing.
  • final_time (float) – A value of time in seconds corresponding to the end of the simulation.
  • initial_time (float, optional) – A value of time in seconds corresponding to the start of the simulation.
  • sample_rate (integer, optional) – The sample rate of the simulation in Hertz (samples per second). The time values will be reported at the initial time and final time, i.e. inclusive, along with times space equally based on the sample rate.
  • col_name (string, optional) – A valid Python identifier that will be used as the column name for the forcing function trajectory in the returned data frame.
Returns:

A data frame indexed by time with all of the coordinates and measurements as columns.

Return type:

pandas.DataFrame

class resonance.linear_systems.TorsionalPendulumSystem

Bases: resonance.linear_systems.SingleDoFLinearSystem

This system represents dynamics of a simple torsional pendulum in which the torsionally elastic member’s axis is aligned with gravity and the axis of the torsion member passes through the mass center of an object attached to it’s lower end. The top of the torsion rod is rigidly attached to the “ceiling”. It is described by:

constants
rotational_inertia, I [kg m**2]
The moment of inertia of the object attached to the pendulum.
torsional_damping, C [N s / m]
The viscous linear damping coefficient which represents any energy dissipation from things like air resistance, slip, etc.
torsional_stiffness, K [N / m]
The linear elastic stiffness coefficient of the torsion member, typically a round slender rod.
coordinates

torsional_angle, theta [rad]

speeds

torsional_angle_vel, theta_dot [rad / s]

resonance/nonlinear_systems.py

class resonance.nonlinear_systems.ClockPendulumSystem

Bases: resonance.nonlinear_systems.SingleDoFNonLinearSystem

This system represents dynamics of a compound pendulum representing a clock pendulum. It is made up of a thin long cylindrical rod with a thin disc bob on the end. Gravity acts on the pendulum to bring it to an equilibrium state and there is option Coulomb friction in the joint. It is described by:

constants
bob_mass, m_b [kg]
The mass of the bob (a thin disc) on the end of the pendulum.
bob_radius, r [m]
The radius of the bob (a thin disc) on the end of the pendulum.
rod_mass, m_r [kg]
The mass of the then cylindrical rod.
rod_length, l [m]
The length of the rod which connects the pivot joint to the center of the bob.
coeff_of_friction, mu [unitless]
The Coulomb coefficient of friction between the materials of the pivot joint.
joint_friction_radius, R [m]
The radius of the contact disc at the pivot joint. The joint is assumed to be two flat discs pressed together.
joint_clamp_force, F_N [N]
The clamping force pressing the two flat discs together at the pivot joint.
acc_due_to_gravity, g [m/s**2]
The acceleration due to gravity.
coordinates
angle, theta [rad]
The angle of the pendulum relative to the direction of gravity. When theta is zero the pendulum is hanging down in it’s equilibrium state.
speeds
angle_vel, theta_dot [rad / s]
The angular velocity of the pendulum about the revolute joint axis.
class resonance.nonlinear_systems.MultiDoFNonLinearSystem

Bases: resonance.system.System

This is the abstract base class for any single degree of freedom nonlinear system. It can be sub-classed to make a custom system or the necessary methods can be added dynamically.

diff_eq_func

A function that returns the time derivatives of the coordinate and speed, i.e. computes the right hand side of the two order differential equations. This equation looks like the following for linear motion:

dy – = f(t, q1, ..., qn, u1, ..., un, p1, p2, ..., pO) dt

where:

  • t: a time value
  • q: the coordinates
  • u: the speeds
  • p: any number of constants or measurements, O is the number of constants.

Notes

Your function should be able to operate on 1d arrays as inputs, i.e. use numpy math functions in your function, e.g. numpy.sin instead of math.sin.

The function has to return the derivatives of the states in the order of the state attribute.

Example

>>> sys = SingleDoFNonLinearSystem()
>>> sys.constants['gravity'] = 9.8  # m/s**2
>>> sys.constants['length'] = 1.0  # m
>>> sys.constants['mass'] = 0.5  # kg
>>> sys.coordinates['theta'] = 0.3  # rad
>>> sys.speeds['omega'] = 0.0  # rad/s
>>> def rhs(theta, omega, gravity, length, mass):
>>>     # Represents a linear model of a simple pendulum:
...     #  m * l**2 ω' + m * g * l * sin(θ) = 0
...     thetad = omega
...     omegad = (-m*g*l*np.sin(theta)) / m / l**2
...     return thetad, omegad  # in order of sys.states
>>> sys.diff_eq_func = rhs
class resonance.nonlinear_systems.SingleDoFNonLinearSystem

Bases: resonance.nonlinear_systems.MultiDoFNonLinearSystem

resonance/functions.py

resonance.functions.estimate_period(time, signal)

Computes the period of oscillation based on the given periodic signal.

Parameters:
  • time (array_like, shape(n,)) – An array of monotonically increasing time values.
  • signal (array_like, shape(n,)) – An array of values for the periodic signal at each time in t.
Returns:

period – An estimate of the period of oscillation.

Return type:

float