Skip to content
LIBRARY
examples.suspension.HalfCar.md

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:

NameDescriptionUnitsDefault value
wheel_angular_stateKeep 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_iscutCut 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_baseDistance between the left and right wheels [m]1
msMass of the car [kg]kg1500
rod_radiusRadius of the rods0.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"}}}
end
Flattened 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"}}}
end


Test Cases

No test cases defined.

  • Examples

  • Experiments

  • Analyses