Pendulum Model

A simple damped pendulum can be constructed using the Pendulum function, as shown below. Additionally, when also using the Plots.jl package, the convenience plotting function plot_pendulum is provided.

Pendulum animation

NeuralLyapunovProblemLibrary.PendulumFunction
Pendulum(; driven = true, name, defaults)

Create an System representing a damped, driven or undriven pendulum, depending on the value of driven (defaults to true, i.e., driven pendulum).

The equation used in this model is $\ddot{θ} + 2 ζ ω_0 \dot{θ} + ω_0^2 \sin(θ) = τ,$ where $θ$ is the angle counter-clockwise from the downward equilibrium, $ζ$ is the damping parameter, $ω_0$ is the resonant angular frequency, and $τ$ is the input torque divided by the moment of inertia of the pendulum around the pivot (driven = false sets $τ ≡ 0$).

The name of the System is name.

Users may optionally provide default values of the parameters through defaults: a vector of the default values for [ζ, ω_0].

Example

@named pendulum = Pendulum(driven = false)
pendulum = mtkcompile(pendulum)

x0 = [2.0, 0.0]
p = ones(2)
t_end = 10
x = get_pendulum_state_symbols(pendulum)
params = get_pendulum_param_symbols(pendulum)

op = Dict(vcat(x, params) .=> vcat(x0, p))
prob = ODEProblem(pendulum, op, t_end)
source
NeuralLyapunovProblemLibrary.control_pendulumFunction
control_pendulum(pend, controller; name)

Control the given driven pendulum pend using the provided controller function.

The controller function should have the signature controller(x, p, t), where x is the state vector [θ, ω], p is the parameter vector [ζ, ω_0], and t is time. The function should return the torque τ to be applied to the pendulum. The resulting controlled pendulum system will have the name name.

Example

# Define a simple feedback cancellation controller
π_cancellation(x, p, t) = 2 * p[2]^2 * sin(x[1])

# Create driven pendulum system, apply controller, and simplify
@named pendulum = Pendulum(driven = true)
@named pendulum_feedback_cancellation = control_pendulum(pendulum, π_cancellation)
pendulum_feedback_cancellation = mtkcompile(pendulum_feedback_cancellation)

# Construct ODE problem
x0 = zeros(2)
p = ones(2)
t_end = 10
x = get_pendulum_state_symbols(pendulum)
params = get_pendulum_param_symbols(pendulum)

op = Dict(vcat(x, params) .=> vcat(x0, p))
prob = ODEProblem(pendulum_feedback_cancellation, op, t_end)
source

Copy-Pastable Code

using ModelingToolkit, NeuralLyapunovProblemLibrary, Plots, OrdinaryDiffEq

x0 = [π * rand(), -π * rand()]
p = [0.5, 1]

@mtkcompile pendulum = Pendulum(driven = false)
prob = ODEProblem(pendulum, x0, 15, p)
sol = solve(prob, Tsit5())

gif(plot_pendulum(sol); fps=50)
Example block output

Plotting the Pendulum

NeuralLyapunovProblemLibrary.plot_pendulumFunction
plot_pendulum(θ, t; title)
plot_pendulum(sol; title, N, angle_symbol)

Plot the pendulum's trajectory.

Arguments

  • θ: The angle of the pendulum at each time step.
  • t: The time steps.
  • sol: The solution to the ODE problem.

Keyword arguments

  • title: The title of the plot; defaults to no title (i.e., title="").
  • N: The number of points to plot; when using θ and t, uses length(t); defaults to 500 when using sol.
  • angle_symbol: The symbol of the angle in sol; defaults to .
source