LIBRARY
examples.suspension.HalfCar
Half-car model with two rolling wheels: two ExcitedWheelAssembly suspensions (right mirror=false, left mirror=true) mounted on a chassis BodyShape, attached to the world through a vertical Prismatic and a roll Revolute.
Usage
MultibodyComponents.examples.suspension.HalfCar(wheel_base=1, ms=1500, rod_radius=0.02)
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
wheel_angular_state | Keep wheel Cardan-angle orientation states. When false (default), each wheel's orientation is taken from its rooted mounting axis (no orientation loop, matching FullCar and upstream Multibody.jl's choice for multi-wheel vehicles). Set true (together with wheel_iscut) to keep the wheel Cardan-angle states. | – | false |
wheel_iscut | Cut the wheel orientation loop. When false (default), no orientation loop is introduced. Set true (together with wheel_angular_state) to use a 3-residue orientation cut. | – | false |
wheel_base | Distance between the left and right wheels [m] | – | 1 |
ms | Mass of the car [kg] | kg | 1500 |
rod_radius | Radius of the rods | – | 0.02 |
Behavior
Source
dyad
"""
Half-car model with two rolling wheels: two `ExcitedWheelAssembly` suspensions
(right `mirror=false`, left `mirror=true`) mounted on a chassis `BodyShape`,
attached to the world through a vertical `Prismatic` and a roll `Revolute`.
"""
component HalfCar
world = MultibodyComponents.World() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 170, "x2": 120, "y2": 270, "rot": 0}
},
"tags": []
}
}
mass = MultibodyComponents.BodyShape(m = ms, r = [0, 0, -wheel_base], radius = 0.1, color = [0.4, 0.4, 0.4, 0.3]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 400, "y1": 170, "x2": 500, "y2": 270, "rot": 270}
},
"tags": []
}
}
excited_suspension_r = ExcitedWheelAssembly(mirror = false, rod_radius = rod_radius, amplitude = 0.015, freq = 3, angular_state = wheel_angular_state, iscut = wheel_iscut) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 540, "y1": 270, "x2": 640, "y2": 370, "rot": 0}
},
"tags": []
}
}
excited_suspension_l = ExcitedWheelAssembly(mirror = true, rod_radius = rod_radius, amplitude = 0.015, freq = 2.9, angular_state = wheel_angular_state, iscut = wheel_iscut) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 540, "y1": 70, "x2": 640, "y2": 170, "rot": 0}
},
"tags": []
}
}
body_upright = MultibodyComponents.Prismatic(n = [0, 1, 0], render = false, statePriority = 2000) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 150, "y1": 170, "x2": 250, "y2": 270, "rot": 0}
},
"tags": []
}
}
body_upright2 = MultibodyComponents.Revolute(n = [1, 0, 0], n_nonzero = [true, false, false], render = false, statePriority = 2000, phi(initial = 0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 280, "y1": 170, "x2": 380, "y2": 270, "rot": 0}
},
"tags": []
}
}
"""
Keep wheel Cardan-angle orientation states. When false (default), each wheel's
orientation is taken from its rooted mounting axis (no orientation loop, matching
FullCar and upstream Multibody.jl's choice for multi-wheel vehicles). Set true
(together with `wheel_iscut`) to keep the wheel Cardan-angle states.
"""
structural parameter wheel_angular_state::Boolean = false
"""
Cut the wheel orientation loop. When false (default), no orientation loop is
introduced. Set true (together with `wheel_angular_state`) to use a 3-residue
orientation cut.
"""
structural parameter wheel_iscut::Boolean = false
"Distance between the left and right wheels [m]"
parameter wheel_base::Real = 1
"Mass of the car [kg]"
parameter ms::Mass = 1500
"Radius of the rods"
parameter rod_radius::Real = 0.02
relations
connect(world.frame_b, body_upright.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(body_upright.frame_b, body_upright2.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(body_upright2.frame_b, mass.frame_cm) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(mass.frame_b, excited_suspension_l.chassis_frame) {
"Dyad": {
"renderStyle": "standard",
"edges": [{"S": 1, "M": [{"x": 450, "y": 120}], "E": 2}]
}
}
connect(excited_suspension_r.chassis_frame, mass.frame_a) {
"Dyad": {
"renderStyle": "standard",
"edges": [{"S": 1, "M": [{"x": 450, "y": 320}], "E": 2}]
}
}
metadata {"Dyad": {"icons": {"default": "dyad://MultibodyComponents/HalfCar.svg"}}}
endFlattened Source
dyad
"""
Half-car model with two rolling wheels: two `ExcitedWheelAssembly` suspensions
(right `mirror=false`, left `mirror=true`) mounted on a chassis `BodyShape`,
attached to the world through a vertical `Prismatic` and a roll `Revolute`.
"""
component HalfCar
world = MultibodyComponents.World() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 170, "x2": 120, "y2": 270, "rot": 0}
},
"tags": []
}
}
mass = MultibodyComponents.BodyShape(m = ms, r = [0, 0, -wheel_base], radius = 0.1, color = [0.4, 0.4, 0.4, 0.3]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 400, "y1": 170, "x2": 500, "y2": 270, "rot": 270}
},
"tags": []
}
}
excited_suspension_r = ExcitedWheelAssembly(mirror = false, rod_radius = rod_radius, amplitude = 0.015, freq = 3, angular_state = wheel_angular_state, iscut = wheel_iscut) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 540, "y1": 270, "x2": 640, "y2": 370, "rot": 0}
},
"tags": []
}
}
excited_suspension_l = ExcitedWheelAssembly(mirror = true, rod_radius = rod_radius, amplitude = 0.015, freq = 2.9, angular_state = wheel_angular_state, iscut = wheel_iscut) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 540, "y1": 70, "x2": 640, "y2": 170, "rot": 0}
},
"tags": []
}
}
body_upright = MultibodyComponents.Prismatic(n = [0, 1, 0], render = false, statePriority = 2000) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 150, "y1": 170, "x2": 250, "y2": 270, "rot": 0}
},
"tags": []
}
}
body_upright2 = MultibodyComponents.Revolute(n = [1, 0, 0], n_nonzero = [true, false, false], render = false, statePriority = 2000, phi(initial = 0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 280, "y1": 170, "x2": 380, "y2": 270, "rot": 0}
},
"tags": []
}
}
"""
Keep wheel Cardan-angle orientation states. When false (default), each wheel's
orientation is taken from its rooted mounting axis (no orientation loop, matching
FullCar and upstream Multibody.jl's choice for multi-wheel vehicles). Set true
(together with `wheel_iscut`) to keep the wheel Cardan-angle states.
"""
structural parameter wheel_angular_state::Boolean = false
"""
Cut the wheel orientation loop. When false (default), no orientation loop is
introduced. Set true (together with `wheel_angular_state`) to use a 3-residue
orientation cut.
"""
structural parameter wheel_iscut::Boolean = false
"Distance between the left and right wheels [m]"
parameter wheel_base::Real = 1
"Mass of the car [kg]"
parameter ms::Mass = 1500
"Radius of the rods"
parameter rod_radius::Real = 0.02
relations
connect(world.frame_b, body_upright.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(body_upright.frame_b, body_upright2.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(body_upright2.frame_b, mass.frame_cm) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(mass.frame_b, excited_suspension_l.chassis_frame) {
"Dyad": {
"renderStyle": "standard",
"edges": [{"S": 1, "M": [{"x": 450, "y": 120}], "E": 2}]
}
}
connect(excited_suspension_r.chassis_frame, mass.frame_a) {
"Dyad": {
"renderStyle": "standard",
"edges": [{"S": 1, "M": [{"x": 450, "y": 320}], "E": 2}]
}
}
metadata {"Dyad": {"icons": {"default": "dyad://MultibodyComponents/HalfCar.svg"}}}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses