LIBRARY
Examples.EKFPendulumExample ​
Damped pendulum driven by a sinusoidal torque, observed by an EKFObserver that estimates the angle and the angular velocity from the sampled angle alone. The observer's prediction model is the plant component itself (dynamics = plant, inputs = ["tau"]), and it starts from a wrong initial estimate (the pendulum starts at 45°, the observer at rest) to show the convergence of the estimate. jacobian_backend selects the symbolic (Symbolic) or the automatic (ForwardDiff) Jacobians of the observer.
Usage ​
MPCComponents.Examples.EKFPendulumExample()
Parameters: ​
| Name | Description | Units | Default value |
|---|---|---|---|
jacobian_backend | How the observer obtains the Jacobians of the model on the Julia backend | – | MPCComponen....Symbolic() |
backend | Backend of the observer | – | MPCComponen...kend.Auto() |
Variables ​
| Name | Description | Units |
|---|---|---|
theta | Angle of the pendulum | – |
omega | Angular velocity of the pendulum | – |
theta_hat | Estimated angle | – |
omega_hat | Estimated angular velocity | – |
Behavior ​
Behavior of this component cannot be rendered because it includes path variables.
Source ​
dyad
"""
Damped pendulum driven by a sinusoidal torque, observed by an `EKFObserver` that estimates the angle
and the angular velocity from the sampled angle alone. The observer's prediction model is the plant
component itself (`dynamics = plant, inputs = ["tau"]`), and it starts from a wrong initial estimate
(the pendulum starts at 45°, the observer at rest) to show the convergence of the estimate.
`jacobian_backend` selects the symbolic (Symbolic) or the automatic (ForwardDiff) Jacobians of the
observer.
"""
example component EKFPendulumExample
periodicclock = DiscreteComponents.PeriodicClock(dt = 0.05) {
"Dyad": {"placement": {"diagram": {"x1": 500, "y1": 640, "x2": 600, "y2": 740}}}
}
plant = MPCComponents.Examples.ACADOSPendulumPlant(theta0 = 0.7853981633974483) {
"Dyad": {"placement": {"diagram": {"x1": 700, "y1": 300, "x2": 800, "y2": 400}}}
}
torque = BlockComponents.Sources.Sine(amplitude = 2.0, frequency = 0.5) {
"Dyad": {"placement": {"diagram": {"x1": 100, "y1": 300, "x2": 200, "y2": 400}}}
}
su = DiscreteComponents.Sampler() {
"Dyad": {"placement": {"diagram": {"x1": 300, "y1": 300, "x2": 400, "y2": 400}}}
}
sy = DiscreteComponents.Sampler() {
"Dyad": {
"placement": {"diagram": {"x1": 580, "y1": 490, "x2": 680, "y2": 590, "rot": 180}}
}
}
zoh = DiscreteComponents.ZeroOrderHold() {
"Dyad": {"placement": {"diagram": {"x1": 500, "y1": 300, "x2": 600, "y2": 400}}}
}
ekf = MPCComponents.EKFObserver(dynamics = plant, inputs = ["tau"], outputs = ["theta"], state_variables = ["th", "om"], Ts = 0.05, R1 = diagonal([1e-4, 1e-4]), R2 = diagonal([1e-3]), x0 = [0.0, 0.0], R0 = diagonal([1.0, 1.0]), final jacobian_backend = jacobian_backend, final backend = backend) {
"Dyad": {"placement": {"diagram": {"x1": 430, "y1": 470, "x2": 330, "y2": 570}}}
}
"How the observer obtains the Jacobians of the model on the Julia backend"
structural parameter jacobian_backend::MPCComponents.ACADOSJacobianBackend = MPCComponents.ACADOSJacobianBackend.Symbolic()
"Backend of the observer"
structural parameter backend::MPCComponents.Backend = MPCComponents.Backend.Auto()
"Angle of the pendulum"
variable theta::Real
"Angular velocity of the pendulum"
variable omega::Real
"Estimated angle"
variable theta_hat::Real
"Estimated angular velocity"
variable omega_hat::Real
relations
theta = plant.theta
omega = plant.omega
theta_hat = ekf.xhat[1]
omega_hat = ekf.xhat[2]
connect(torque.y, su.u)
connect(su.y, zoh.u)
connect(zoh.y, plant.tau)
connect(su.y, ekf.u[1]) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 460, "y": 350}, {"x": 460, "y": 495}], "E": 2}],
"path": {}
}
}
connect(plant.theta, sy.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 860, "y": 335}, {"x": 860, "y": 540}], "E": 2}],
"path": {}
}
}
connect(sy.y, ekf.y[1], periodicclock.y) {
"Dyad": {
"edges": [
{"S": 1, "M": [{"x": 475, "y": 540}, {"x": 475, "y": 545}], "E": 2},
{"S": 2, "M": [{"x": 435, "y": 690}], "E": 3}
],
"path": {}
}
}
metadata {"Dyad": {"tests": {"case1": {"stop": 6}}, "doc": {"behavior": false}}}
endFlattened Source
dyad
"""
Damped pendulum driven by a sinusoidal torque, observed by an `EKFObserver` that estimates the angle
and the angular velocity from the sampled angle alone. The observer's prediction model is the plant
component itself (`dynamics = plant, inputs = ["tau"]`), and it starts from a wrong initial estimate
(the pendulum starts at 45°, the observer at rest) to show the convergence of the estimate.
`jacobian_backend` selects the symbolic (Symbolic) or the automatic (ForwardDiff) Jacobians of the
observer.
"""
example component EKFPendulumExample
periodicclock = DiscreteComponents.PeriodicClock(dt = 0.05) {
"Dyad": {"placement": {"diagram": {"x1": 500, "y1": 640, "x2": 600, "y2": 740}}}
}
plant = MPCComponents.Examples.ACADOSPendulumPlant(theta0 = 0.7853981633974483) {
"Dyad": {"placement": {"diagram": {"x1": 700, "y1": 300, "x2": 800, "y2": 400}}}
}
torque = BlockComponents.Sources.Sine(amplitude = 2.0, frequency = 0.5) {
"Dyad": {"placement": {"diagram": {"x1": 100, "y1": 300, "x2": 200, "y2": 400}}}
}
su = DiscreteComponents.Sampler() {
"Dyad": {"placement": {"diagram": {"x1": 300, "y1": 300, "x2": 400, "y2": 400}}}
}
sy = DiscreteComponents.Sampler() {
"Dyad": {
"placement": {"diagram": {"x1": 580, "y1": 490, "x2": 680, "y2": 590, "rot": 180}}
}
}
zoh = DiscreteComponents.ZeroOrderHold() {
"Dyad": {"placement": {"diagram": {"x1": 500, "y1": 300, "x2": 600, "y2": 400}}}
}
ekf = MPCComponents.EKFObserver(dynamics = plant, inputs = ["tau"], outputs = ["theta"], state_variables = ["th", "om"], Ts = 0.05, R1 = diagonal([1e-4, 1e-4]), R2 = diagonal([1e-3]), x0 = [0.0, 0.0], R0 = diagonal([1.0, 1.0]), final jacobian_backend = jacobian_backend, final backend = backend) {
"Dyad": {"placement": {"diagram": {"x1": 430, "y1": 470, "x2": 330, "y2": 570}}}
}
"How the observer obtains the Jacobians of the model on the Julia backend"
structural parameter jacobian_backend::MPCComponents.ACADOSJacobianBackend = MPCComponents.ACADOSJacobianBackend.Symbolic()
"Backend of the observer"
structural parameter backend::MPCComponents.Backend = MPCComponents.Backend.Auto()
"Angle of the pendulum"
variable theta::Real
"Angular velocity of the pendulum"
variable omega::Real
"Estimated angle"
variable theta_hat::Real
"Estimated angular velocity"
variable omega_hat::Real
relations
theta = plant.theta
omega = plant.omega
theta_hat = ekf.xhat[1]
omega_hat = ekf.xhat[2]
connect(torque.y, su.u)
connect(su.y, zoh.u)
connect(zoh.y, plant.tau)
connect(su.y, ekf.u[1]) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 460, "y": 350}, {"x": 460, "y": 495}], "E": 2}],
"path": {}
}
}
connect(plant.theta, sy.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 860, "y": 335}, {"x": 860, "y": 540}], "E": 2}],
"path": {}
}
}
connect(sy.y, ekf.y[1], periodicclock.y) {
"Dyad": {
"edges": [
{"S": 1, "M": [{"x": 475, "y": 540}, {"x": 475, "y": 545}], "E": 2},
{"S": 2, "M": [{"x": 435, "y": 690}], "E": 3}
],
"path": {}
}
}
metadata {"Dyad": {"tests": {"case1": {"stop": 6}}, "doc": {"behavior": false}}}
endTest Cases ​
Test Case case1 ​
Related ​
Examples
Experiments
Analyses