PlanarMechanics.RelativeForce
Relative force and torque acting between frame_a and frame_b, defined by input signals.
Applies the input force to frame_b and the reaction (equal and opposite) to frame_a. The force inputs (force_x, force_y) and torque input are resolved in the frame selected by the structural parameter resolve_in_frame (world, frame_a, or frame_b).
This component extends from MultibodyComponents.Renderable
Usage
MultibodyComponents.PlanarMechanics.RelativeForce(render=true, color=[0, 1, 0, 0.5], specular_coefficient=0.7, scale=0.1, arrow_diameter=0.05, z_position=0)
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
resolve_in_frame | – | MultibodyComponents.ResolveInFrame.FrameA() | |
render | – | true | |
color | – | [0, 1, 0, 0.5] | |
specular_coefficient | – | 0.7 | |
scale | Scale factor for force visualization (length = force * scale) | – | 0.1 |
arrow_diameter | Diameter of the force arrow shaft | – | 0.05 |
z_position | z-position of the arrow in animations | – | 0 |
Connectors
frame_a- Coordinate system (2-dim.) fixed to the component with one cut-force and cut-torque.
All variables are resolved in the planar world frame. (Frame2D)
frame_b- Coordinate system (2-dim.) fixed to the component with one cut-force and cut-torque.
All variables are resolved in the planar world frame. (Frame2D)
force_x- This connector represents a real signal as an input to a component (RealInput)force_y- This connector represents a real signal as an input to a component (RealInput)torque- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
phi | Angle of resolution frame | rad |
Behavior
Dict{MIME{Symbol("text/plain")}, String} with 1 entry: MIME type text/plain => "Error displaying result"
Source
"""
Relative force and torque acting between frame_a and frame_b, defined by input signals.
Applies the input force to frame_b and the reaction (equal and opposite) to frame_a.
The force inputs (force_x, force_y) and torque input are resolved in the frame
selected by the structural parameter `resolve_in_frame` (world, frame_a, or frame_b).
"""
component RelativeForce
extends MultibodyComponents.Renderable(color = [0, 1, 0, 0.5])
frame_a = Frame2D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame_b = Frame2D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
},
"tags": []
}
}
force_x = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 90, "y1": -50, "x2": 190, "y2": 50, "rot": 90}
},
"tags": []
}
}
force_y = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": -50, "x2": 550, "y2": 50, "rot": 90}
},
"tags": []
}
}
torque = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 810, "y1": -50, "x2": 910, "y2": 50, "rot": 90}
},
"tags": []
}
}
"Force arrow visualization at frame_b"
force_arrow = MultibodyComponents.ArrowShape(render = render, color = color, head_at_origin = true, diameter = arrow_diameter)
structural parameter resolve_in_frame::MultibodyComponents.ResolveInFrame = MultibodyComponents.ResolveInFrame.FrameA()
"Scale factor for force visualization (length = force * scale)"
parameter scale::Real = 0.1
"Diameter of the force arrow shaft"
parameter arrow_diameter::Real = 0.05
"z-position of the arrow in animations"
parameter z_position::Real = 0
"Angle of resolution frame"
variable phi::Angle
relations
if resolve_in_frame == MultibodyComponents.ResolveInFrame.World()
phi = 0
end
if resolve_in_frame == MultibodyComponents.ResolveInFrame.FrameA()
phi = frame_a.phi
end
if resolve_in_frame == MultibodyComponents.ResolveInFrame.FrameB()
phi = frame_b.phi
end
# Apply rotated force to frame_b
frame_b.fx + cos(phi) * force_x - sin(phi) * force_y = 0
frame_b.fy + sin(phi) * force_x + cos(phi) * force_y = 0
frame_b.tau + torque = 0
# Reaction forces on frame_a (equal and opposite)
frame_a.fx + frame_b.fx = 0
frame_a.fy + frame_b.fy = 0
frame_a.tau + frame_b.tau = 0
# Force arrow: display the applied force vector at frame_b
force_arrow.r = [frame_b.x, frame_b.y, z_position]
force_arrow.R = (MultibodyComponents.planar_rotation([0, 0, 1], phi, 0))
force_arrow.r_shape = [0, 0, 0]
force_arrow.length_direction = [force_x, force_y, 0]
force_arrow.width_direction = [0, 0, 1]
force_arrow.length = sqrt(force_x ^ 2 + force_y ^ 2) * scale
force_arrow.width = arrow_diameter
force_arrow.height = arrow_diameter
metadata {"Dyad": {"icons": {"default": "dyad://MultibodyComponents/RelativeForce.svg"}}}
endFlattened Source
"""
Relative force and torque acting between frame_a and frame_b, defined by input signals.
Applies the input force to frame_b and the reaction (equal and opposite) to frame_a.
The force inputs (force_x, force_y) and torque input are resolved in the frame
selected by the structural parameter `resolve_in_frame` (world, frame_a, or frame_b).
"""
component RelativeForce
parameter render::Boolean = true
parameter color::Real[4] = [0.5, 0.5, 0.5, 1.0]
parameter specular_coefficient::Real = 0.7
frame_a = Frame2D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame_b = Frame2D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
},
"tags": []
}
}
force_x = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 90, "y1": -50, "x2": 190, "y2": 50, "rot": 90}
},
"tags": []
}
}
force_y = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": -50, "x2": 550, "y2": 50, "rot": 90}
},
"tags": []
}
}
torque = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 810, "y1": -50, "x2": 910, "y2": 50, "rot": 90}
},
"tags": []
}
}
"Force arrow visualization at frame_b"
force_arrow = MultibodyComponents.ArrowShape(render = render, color = color, head_at_origin = true, diameter = arrow_diameter)
structural parameter resolve_in_frame::MultibodyComponents.ResolveInFrame = MultibodyComponents.ResolveInFrame.FrameA()
"Scale factor for force visualization (length = force * scale)"
parameter scale::Real = 0.1
"Diameter of the force arrow shaft"
parameter arrow_diameter::Real = 0.05
"z-position of the arrow in animations"
parameter z_position::Real = 0
"Angle of resolution frame"
variable phi::Angle
relations
if resolve_in_frame == MultibodyComponents.ResolveInFrame.World()
phi = 0
end
if resolve_in_frame == MultibodyComponents.ResolveInFrame.FrameA()
phi = frame_a.phi
end
if resolve_in_frame == MultibodyComponents.ResolveInFrame.FrameB()
phi = frame_b.phi
end
# Apply rotated force to frame_b
frame_b.fx + cos(phi) * force_x - sin(phi) * force_y = 0
frame_b.fy + sin(phi) * force_x + cos(phi) * force_y = 0
frame_b.tau + torque = 0
# Reaction forces on frame_a (equal and opposite)
frame_a.fx + frame_b.fx = 0
frame_a.fy + frame_b.fy = 0
frame_a.tau + frame_b.tau = 0
# Force arrow: display the applied force vector at frame_b
force_arrow.r = [frame_b.x, frame_b.y, z_position]
force_arrow.R = (MultibodyComponents.planar_rotation([0, 0, 1], phi, 0))
force_arrow.r_shape = [0, 0, 0]
force_arrow.length_direction = [force_x, force_y, 0]
force_arrow.width_direction = [0, 0, 1]
force_arrow.length = sqrt(force_x ^ 2 + force_y ^ 2) * scale
force_arrow.width = arrow_diameter
force_arrow.height = arrow_diameter
metadata {"Dyad": {"icons": {"default": "dyad://MultibodyComponents/RelativeForce.svg"}}}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses
Tests