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.

NeuralLyapunovProblemLibrary.Pendulum — Function
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)NeuralLyapunovProblemLibrary.control_pendulum — Function
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)NeuralLyapunovProblemLibrary.get_pendulum_state_symbols — Function
get_pendulum_state_symbols(pend)Get the state variable symbols of the given pendulum pend as a vector: [θ, ω], where $ω = \dot{θ}$.
NeuralLyapunovProblemLibrary.get_pendulum_param_symbols — Function
get_pendulum_param_symbols(pend)Get the parameter symbols of the given pendulum pend as a vector: [ζ, ω_0].
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)
Plotting the Pendulum
NeuralLyapunovProblemLibrary.plot_pendulum — Function
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θandt, useslength(t); defaults to 500 when usingsol.angle_symbol: The symbol of the angle insol; defaults to:θ.