VehicleDynamics Icon
Examples.VehicleDynamics
VehicleDynamics(; name, mass, g_acc, R, v0)Vehicle dynamics model for wheel slip and velocity calculations.
Parameters
mass: Vehicle mass in kg (default: 75)g_acc: Gravitational acceleration in m/s² (default: 9.81)R: Wheel radius in m (default: 1.25)v0: Initial velocity in m/s (default: 70)
Connectors
brake_torque: Input for brake torque commandwheel_slip: Output for computed wheel slip ratioTrueOmega: Output for actual wheel angular velocityNoSlipOmega: Output for theoretical no-slip angular velocity
Description
Models the continuous-time vehicle dynamics including:
- Friction force calculation from slip ratio via lookup table
- Vehicle longitudinal acceleration and velocity integration
- Wheel angular acceleration and velocity integration
- Slip ratio computation from vehicle and wheel velocities
- Saturation limiters to ensure physical constraints
Usage
PrimitiveComponents.Examples.VehicleDynamics(mass=75, g_acc=9.81, R=1.25, v0=70)
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
mass | kg | 75 | |
g_acc | m/s2 | 9.81 | |
R | m | 1.25 | |
v0 | m/s | 70 |
Connectors
brake_torque- This connector represents a real signal as an input to a component (RealInput)wheel_slip- This connector represents a real signal as an output from a component (RealOutput)TrueOmega- This connector represents a real signal as an output from a component (RealOutput)NoSlipOmega- This connector represents a real signal as an output from a component (RealOutput)
Behavior
Behavior of this component cannot be rendered because it includes path variables.
Source
"""
VehicleDynamics(; name, mass, g_acc, R, v0)
Vehicle dynamics model for wheel slip and velocity calculations.
# Parameters
- `mass`: Vehicle mass in kg (default: 75)
- `g_acc`: Gravitational acceleration in m/s² (default: 9.81)
- `R`: Wheel radius in m (default: 1.25)
- `v0`: Initial velocity in m/s (default: 70)
# Connectors
- `brake_torque`: Input for brake torque command
- `wheel_slip`: Output for computed wheel slip ratio
- `TrueOmega`: Output for actual wheel angular velocity
- `NoSlipOmega`: Output for theoretical no-slip angular velocity
# Description
Models the continuous-time vehicle dynamics including:
- Friction force calculation from slip ratio via lookup table
- Vehicle longitudinal acceleration and velocity integration
- Wheel angular acceleration and velocity integration
- Slip ratio computation from vehicle and wheel velocities
- Saturation limiters to ensure physical constraints
"""
component VehicleDynamics
brake_torque = Dyad.RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -60, "y1": 450, "x2": 40, "y2": 550, "rot": 0}
},
"tags": []
}
}
wheel_slip = Dyad.RealOutput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 960, "y1": 450, "x2": 1060, "y2": 550, "rot": 0}
},
"tags": []
}
}
TrueOmega = Dyad.RealOutput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 960, "y1": 70, "x2": 1060, "y2": 170, "rot": 0}
},
"tags": []
}
}
NoSlipOmega = Dyad.RealOutput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 960, "y1": 810, "x2": 1060, "y2": 910, "rot": 0}
},
"tags": []
}
}
mu_slip = MuVsSlipLookup() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 860, "y1": 953, "x2": 960, "y2": 1053, "rot": 0}
},
"tags": []
}
}
normal_force = BlockComponents.Gain(k = mass * g_acc / 4) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 630, "x2": 260, "y2": 730, "rot": 0}
},
"tags": []
}
}
wheel_radius = BlockComponents.Gain(k = R) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 510, "x2": 400, "y2": 610, "rot": 0}
},
"tags": []
}
}
gain2 = BlockComponents.Gain(k = -1.0 / mass) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 630, "x2": 400, "y2": 730, "rot": 0}
},
"tags": []
}
}
limiter1 = BlockComponents.Limiter(y_max = 1000, y_min = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 840, "x2": 400, "y2": 940, "rot": 0}
},
"tags": []
}
}
integrator1 = BlockComponents.Integrator(x0 = v0, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 630, "x2": 540, "y2": 730, "rot": 0}
},
"tags": []
}
}
gain3 = BlockComponents.Gain(k = 1 / R) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 840, "x2": 540, "y2": 940, "rot": 0}
},
"tags": []
}
}
integrator2 = BlockComponents.Integrator(x0 = 0, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 840, "x2": 690, "y2": 940, "rot": 0}
},
"tags": []
}
}
add = BlockComponents.Add(k1 = -1, k2 = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 480, "x2": 540, "y2": 580, "rot": 0}
},
"tags": []
}
}
integrator3 = BlockComponents.Integrator(x0 = v0 / R, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 70, "x2": 400, "y2": 170, "rot": 0}
},
"tags": []
}
}
limiter2 = BlockComponents.Limiter(y_max = 1000, y_min = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 70, "x2": 540, "y2": 170, "rot": 0}
},
"tags": []
}
}
rim_speed = BlockComponents.Gain(k = R) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 270, "x2": 260, "y2": 370, "rot": 0}
},
"tags": []
}
}
div = BlockComponents.Division() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 600, "x2": 690, "y2": 700, "rot": 0}
},
"tags": []
}
}
c1 = BlockComponents.Constant(k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 960, "x2": 690, "y2": 1060, "rot": 0}
},
"tags": []
}
}
sub2 = BlockComponents.Add(k1 = -1, k2 = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 730, "y1": 930, "x2": 830, "y2": 1030, "rot": 0}
},
"tags": []
}
}
integrator = BlockComponents.Integrator(x0 = 0, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 450, "x2": 260, "y2": 550, "rot": 0}
},
"tags": []
}
}
limiter = BlockComponents.Limiter(y_max = 1000, y_min = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 390, "x2": 400, "y2": 490, "rot": 0}
},
"tags": []
}
}
parameter mass::Mass = 75
parameter g_acc::Acceleration = 9.81
parameter R::Length = 1.25
parameter v0::Velocity = 70
relations
connect(mu_slip.y, normal_force.u) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 922, "y": 220}, {"x": 130, "y": 220}, {"x": 130, "y": 680}],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(normal_force.y, gain2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(normal_force.y, wheel_radius.u) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 280, "y": 560}], "E": 2}],
"junctions": [{"x": 280, "y": 680}],
"renderStyle": "standard"
}
}
connect(sub2.y, mu_slip.u, wheel_slip) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": 2},
{"S": -1, "M": [{"x": 850, "y": 500}], "E": 3}
],
"junctions": [{"x": 850, "y": 980}],
"renderStyle": "standard"
}
}
connect(rim_speed.y, div.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 560, "y": 320}, {"x": 560, "y": 620}], "E": 2}],
"renderStyle": "standard"
}
}
connect(c1.y, sub2.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(div.y, sub2.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 710, "y": 650}, {"x": 710, "y": 950}], "E": 2}],
"renderStyle": "standard"
}
}
connect(gain2.y, integrator1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(integrator1.y, div.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(limiter1.u, integrator1.y) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 280, "y": 890}, {"x": 280, "y": 790}, {"x": 560, "y": 790}],
"E": -1
},
{"S": -1, "M": [], "E": 2}
],
"junctions": [{"x": 560, "y": 680}],
"renderStyle": "standard"
}
}
connect(limiter1.y, gain3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(gain3.y, integrator2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(gain3.y, NoSlipOmega) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 570, "y": 860}], "E": 2}],
"junctions": [{"x": 570, "y": 890}],
"renderStyle": "standard"
}
}
connect(brake_torque, integrator.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(integrator.y, limiter.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 280, "y": 500}, {"x": 280, "y": 440}], "E": 2}],
"renderStyle": "standard"
}
}
connect(limiter.y, add.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 420, "y": 440}, {"x": 420, "y": 500}], "E": 2}],
"renderStyle": "standard"
}
}
connect(wheel_radius.y, add.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(integrator3.u, add.y) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [
{"x": 280, "y": 120},
{"x": 280, "y": 310},
{"x": 570, "y": 310},
{"x": 570, "y": 530}
],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(integrator3.y, limiter2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(rim_speed.u, integrator3.y) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 140, "y": 320}, {"x": 140, "y": 20}, {"x": 420, "y": 20}],
"E": -1
},
{"S": -1, "M": [], "E": 2}
],
"junctions": [{"x": 420, "y": 120}],
"renderStyle": "standard"
}
}
connect(limiter2.y, TrueOmega) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
"Dyad": {
"icons": {"default": "dyad://PrimitiveComponents/VehicleDynamics.svg"},
"doc": {"behavior": false}
}
}
end
Flattened Source
"""
VehicleDynamics(; name, mass, g_acc, R, v0)
Vehicle dynamics model for wheel slip and velocity calculations.
# Parameters
- `mass`: Vehicle mass in kg (default: 75)
- `g_acc`: Gravitational acceleration in m/s² (default: 9.81)
- `R`: Wheel radius in m (default: 1.25)
- `v0`: Initial velocity in m/s (default: 70)
# Connectors
- `brake_torque`: Input for brake torque command
- `wheel_slip`: Output for computed wheel slip ratio
- `TrueOmega`: Output for actual wheel angular velocity
- `NoSlipOmega`: Output for theoretical no-slip angular velocity
# Description
Models the continuous-time vehicle dynamics including:
- Friction force calculation from slip ratio via lookup table
- Vehicle longitudinal acceleration and velocity integration
- Wheel angular acceleration and velocity integration
- Slip ratio computation from vehicle and wheel velocities
- Saturation limiters to ensure physical constraints
"""
component VehicleDynamics
brake_torque = Dyad.RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -60, "y1": 450, "x2": 40, "y2": 550, "rot": 0}
},
"tags": []
}
}
wheel_slip = Dyad.RealOutput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 960, "y1": 450, "x2": 1060, "y2": 550, "rot": 0}
},
"tags": []
}
}
TrueOmega = Dyad.RealOutput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 960, "y1": 70, "x2": 1060, "y2": 170, "rot": 0}
},
"tags": []
}
}
NoSlipOmega = Dyad.RealOutput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 960, "y1": 810, "x2": 1060, "y2": 910, "rot": 0}
},
"tags": []
}
}
mu_slip = MuVsSlipLookup() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 860, "y1": 953, "x2": 960, "y2": 1053, "rot": 0}
},
"tags": []
}
}
normal_force = BlockComponents.Gain(k = mass * g_acc / 4) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 630, "x2": 260, "y2": 730, "rot": 0}
},
"tags": []
}
}
wheel_radius = BlockComponents.Gain(k = R) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 510, "x2": 400, "y2": 610, "rot": 0}
},
"tags": []
}
}
gain2 = BlockComponents.Gain(k = -1.0 / mass) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 630, "x2": 400, "y2": 730, "rot": 0}
},
"tags": []
}
}
limiter1 = BlockComponents.Limiter(y_max = 1000, y_min = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 840, "x2": 400, "y2": 940, "rot": 0}
},
"tags": []
}
}
integrator1 = BlockComponents.Integrator(x0 = v0, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 630, "x2": 540, "y2": 730, "rot": 0}
},
"tags": []
}
}
gain3 = BlockComponents.Gain(k = 1 / R) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 840, "x2": 540, "y2": 940, "rot": 0}
},
"tags": []
}
}
integrator2 = BlockComponents.Integrator(x0 = 0, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 840, "x2": 690, "y2": 940, "rot": 0}
},
"tags": []
}
}
add = BlockComponents.Add(k1 = -1, k2 = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 480, "x2": 540, "y2": 580, "rot": 0}
},
"tags": []
}
}
integrator3 = BlockComponents.Integrator(x0 = v0 / R, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 70, "x2": 400, "y2": 170, "rot": 0}
},
"tags": []
}
}
limiter2 = BlockComponents.Limiter(y_max = 1000, y_min = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 70, "x2": 540, "y2": 170, "rot": 0}
},
"tags": []
}
}
rim_speed = BlockComponents.Gain(k = R) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 270, "x2": 260, "y2": 370, "rot": 0}
},
"tags": []
}
}
div = BlockComponents.Division() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 600, "x2": 690, "y2": 700, "rot": 0}
},
"tags": []
}
}
c1 = BlockComponents.Constant(k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 960, "x2": 690, "y2": 1060, "rot": 0}
},
"tags": []
}
}
sub2 = BlockComponents.Add(k1 = -1, k2 = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 730, "y1": 930, "x2": 830, "y2": 1030, "rot": 0}
},
"tags": []
}
}
integrator = BlockComponents.Integrator(x0 = 0, k = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 450, "x2": 260, "y2": 550, "rot": 0}
},
"tags": []
}
}
limiter = BlockComponents.Limiter(y_max = 1000, y_min = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 300, "y1": 390, "x2": 400, "y2": 490, "rot": 0}
},
"tags": []
}
}
parameter mass::Mass = 75
parameter g_acc::Acceleration = 9.81
parameter R::Length = 1.25
parameter v0::Velocity = 70
relations
connect(mu_slip.y, normal_force.u) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 922, "y": 220}, {"x": 130, "y": 220}, {"x": 130, "y": 680}],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(normal_force.y, gain2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(normal_force.y, wheel_radius.u) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 280, "y": 560}], "E": 2}],
"junctions": [{"x": 280, "y": 680}],
"renderStyle": "standard"
}
}
connect(sub2.y, mu_slip.u, wheel_slip) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": 2},
{"S": -1, "M": [{"x": 850, "y": 500}], "E": 3}
],
"junctions": [{"x": 850, "y": 980}],
"renderStyle": "standard"
}
}
connect(rim_speed.y, div.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 560, "y": 320}, {"x": 560, "y": 620}], "E": 2}],
"renderStyle": "standard"
}
}
connect(c1.y, sub2.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(div.y, sub2.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 710, "y": 650}, {"x": 710, "y": 950}], "E": 2}],
"renderStyle": "standard"
}
}
connect(gain2.y, integrator1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(integrator1.y, div.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(limiter1.u, integrator1.y) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 280, "y": 890}, {"x": 280, "y": 790}, {"x": 560, "y": 790}],
"E": -1
},
{"S": -1, "M": [], "E": 2}
],
"junctions": [{"x": 560, "y": 680}],
"renderStyle": "standard"
}
}
connect(limiter1.y, gain3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(gain3.y, integrator2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(gain3.y, NoSlipOmega) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 570, "y": 860}], "E": 2}],
"junctions": [{"x": 570, "y": 890}],
"renderStyle": "standard"
}
}
connect(brake_torque, integrator.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(integrator.y, limiter.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 280, "y": 500}, {"x": 280, "y": 440}], "E": 2}],
"renderStyle": "standard"
}
}
connect(limiter.y, add.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 420, "y": 440}, {"x": 420, "y": 500}], "E": 2}],
"renderStyle": "standard"
}
}
connect(wheel_radius.y, add.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(integrator3.u, add.y) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [
{"x": 280, "y": 120},
{"x": 280, "y": 310},
{"x": 570, "y": 310},
{"x": 570, "y": 530}
],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(integrator3.y, limiter2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(rim_speed.u, integrator3.y) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 140, "y": 320}, {"x": 140, "y": 20}, {"x": 420, "y": 20}],
"E": -1
},
{"S": -1, "M": [], "E": 2}
],
"junctions": [{"x": 420, "y": 120}],
"renderStyle": "standard"
}
}
connect(limiter2.y, TrueOmega) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
"Dyad": {
"icons": {"default": "dyad://PrimitiveComponents/VehicleDynamics.svg"},
"doc": {"behavior": false}
}
}
endTest Cases
No test cases defined.
Related
- Examples
- Experiments
- Analyses