Skip to content

Commit

Permalink
improve language precision
Browse files Browse the repository at this point in the history
  • Loading branch information
baggepinnen committed Sep 28, 2023
1 parent fc4ddd0 commit 2a89155
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 23 deletions.
4 changes: 2 additions & 2 deletions docs/src/examples/free_motion.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Free motions
This example demonstrates how a free-floating [`Body`](@ref) can be simulated. The body is attached to the world through a [`FreeMotion`](@ref) joint, i.e., a joint that imposes no constraints. The joint is required to add the appropriate relative states between the world and the body. We choose `enforceStates = true` and `isroot = true` in the [`FreeMotion`](@ref) constructor.
This example demonstrates how a free-floating [`Body`](@ref) can be simulated. The body is attached to the world through a [`FreeMotion`](@ref) joint, i.e., a joint that imposes no constraints. The joint is required to add the appropriate relative state variables between the world and the body. We choose `enforceState = true` and `isroot = true` in the [`FreeMotion`](@ref) constructor.

```@example FREE_MOTION
using Multibody
Expand All @@ -12,7 +12,7 @@ t = Multibody.t
D = Differential(t)
world = Multibody.world
@named freeMotion = FreeMotion(enforceStates = true, isroot = true)
@named freeMotion = FreeMotion(enforceState = true, isroot = true)
@named body = Body(m = 1)
eqs = [connect(world.frame_b, freeMotion.frame_a)
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/pendulum.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Our simple pendulum will initially consist of a [`Body`](@ref) and a [`Revolute`
@named body = Body(; m = 1, isroot = false, r_cm = [0.5, 0, 0])
nothing # hide
```
The `n` argument to [`Revolute`](@ref) denotes the rotational axis of the joint, this vector must have `norm(n) == 1`. We also indicate that the revolute joint is the root of the kinematic tree, i.e., the potential states of the joint will serve as the state variables for the system.
The `n` argument to [`Revolute`](@ref) denotes the rotational axis of the joint, this vector must have `norm(n) == 1`. We also indicate that the revolute joint is the root of the kinematic tree, i.e., the potential state of the joint will serve as the state variables for the system.

The [`Body`](@ref) is constructed by providing its mass, `m`, and the vector `r_cm` from its first frame, `body.frame_a`, to the center of mass. Since the world by default has the gravity field pointing along the negative ``y`` axis, we place the center of mass along the ``x``-axis to make the pendulum swing back and forth. The body is not selected as the root of the kinematic tree, since we have a joint in this system, but if we had attached the body directly to, e.g., a spring, we could set the body to be the root and avoid having to introduce an "artificial joint".

Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/spherical_pendulum.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ D = Differential(t)
world = Multibody.world
systems = @named begin
joint = Spherical(enforceStates=true, isroot=true, phi = 1)
joint = Spherical(enforceState=true, isroot=true, phi = 1)
bar = FixedTranslation(r = [0, -1, 0])
body = Body(; m = 1, isroot = false)
end
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/spring_damper_system.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Welcome to the spring-damper system example, where we will show you the process of modeling and simulating a basic yet essential mechanical system using the powerful Multibody.jl package in JuliaSim. By understanding the underlying principles of spring-damper systems, you will gain valuable insights into the behavior of various real-world systems, such as suspension systems in vehicles, vibration isolation mechanisms, and biomechanical structures.

This tutorial mirrors that of the following Modelica tutorial [Spring damper system](https://doc.modelica.org/om/Modelica.Mechanics.MultiBody.Examples.Elementary.SpringDamperSystem.html) and demonstrates that a body can be freely moving without any connection to a joint. In this case body coordinates are used as states by setting the option `isroot=true` to the body.
This tutorial mirrors that of the following Modelica tutorial [Spring damper system](https://doc.modelica.org/om/Modelica.Mechanics.MultiBody.Examples.Elementary.SpringDamperSystem.html) and demonstrates that a body can be freely moving without any connection to a joint. In this case body coordinates are used as state by setting the option `isroot=true` to the body.

![Spring-damper system](https://doc.modelica.org/Modelica%203.2.3/Resources/Images/Mechanics/MultiBody/Examples/Elementary/SpringDamperSystem.png)

Expand Down
28 changes: 14 additions & 14 deletions src/joints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,14 @@ function Prismatic(; name, n = Float64[0, 0, 1], useAxisFlange = false,
end

"""
Spherical(; name, enforceStates = false, isroot = true, w_rel_a_fixed = false, z_rel_a_fixed = false, sequence_angleStates, phi = 0, phi_d = 0, phi_dd = 0)
Spherical(; name, enforceState = false, isroot = true, w_rel_a_fixed = false, z_rel_a_fixed = false, sequence_angleStates, phi = 0, phi_d = 0, phi_dd = 0)
Joint with 3 constraints that define that the origin of `frame_a` and the origin of `frame_b` coincide. By default this joint defines only the 3 constraints without any potential states. If parameter `enforceStates` is set to true, three states are introduced. The orientation of `frame_b` is computed by rotating `frame_a` along the axes defined in parameter vector `sequence_angleStates` (default = [1,2,3], i.e., the Cardan angle sequence) around the angles used as states. If angles are used as states there is the slight disadvantage that a singular configuration is present leading to a division by zero.
Joint with 3 constraints that define that the origin of `frame_a` and the origin of `frame_b` coincide. By default this joint defines only the 3 constraints without any potential state variables. If parameter `enforceState` is set to true, three states are introduced. The orientation of `frame_b` is computed by rotating `frame_a` along the axes defined in parameter vector `sequence_angleStates` (default = [1,2,3], i.e., the Cardan angle sequence) around the angles used as state. If angles are used as state there is the slight disadvantage that a singular configuration is present leading to a division by zero.
- `isroot`: Indicate that `frame_a` is the root, otherwise `frame_b` is the root. Only relevant if `enforceStates = true`.
- `isroot`: Indicate that `frame_a` is the root, otherwise `frame_b` is the root. Only relevant if `enforceState = true`.
- `sequence_angleStates`: Rotation sequence
"""
function Spherical(; name, enforceStates = false, isroot = true, w_rel_a_fixed = false,
function Spherical(; name, enforceState = false, isroot = true, w_rel_a_fixed = false,
z_rel_a_fixed = false, sequence_angleStates = [1, 2, 3], phi = 0,
phi_d = 0,
phi_dd = 0)
Expand All @@ -168,7 +168,7 @@ function Spherical(; name, enforceStates = false, isroot = true, w_rel_a_fixed =
zeros(3) .~ collect(frame_b.tau)
collect(frame_b.r_0) .~ collect(frame_a.r_0)]

if enforceStates
if enforceState
@variables begin
(phi(t)[1:3] = phi),
[state_priority = 10, description = "3 angles to rotate frame_a into frame_b"]
Expand All @@ -194,7 +194,7 @@ function Spherical(; name, enforceStates = false, isroot = true, w_rel_a_fixed =
end

else
# Spherical joint does not have states
# Spherical joint does not have state
append!(eqs,
#frame_b.r_0 ~ transpose(frame_b.R.T)*(frame_b.R.T*(transpose(frame_a.R.T)*(frame_a.R.T*frame_a.r_0)));
zeros(3) .~ collect(frame_a.f) +
Expand Down Expand Up @@ -606,19 +606,19 @@ function RollingWheel(; name, radius, m, I_axis, I_long, width = 0.035, x0, y0,
end

"""
FreeMotion(; name, enforceStates = true, sequence, isroot = true, w_rel_a_fixed = false, z_rel_a_fixed = false, phi = 0, phi_d = 0, phi_dd = 0, w_rel_b = 0, r_rel_a = 0, v_rel_a = 0, a_rel_a = 0)
FreeMotion(; name, enforceState = true, sequence, isroot = true, w_rel_a_fixed = false, z_rel_a_fixed = false, phi = 0, phi_d = 0, phi_dd = 0, w_rel_b = 0, r_rel_a = 0, v_rel_a = 0, a_rel_a = 0)
Joint which does not constrain the motion between `frame_a` and `frame_b`. Such a joint is only meaningful if the relative distance and orientation between `frame_a` and `frame_b`, and their derivatives, shall be used as states.
Joint which does not constrain the motion between `frame_a` and `frame_b`. Such a joint is only meaningful if the relative distance and orientation between `frame_a` and `frame_b`, and their derivatives, shall be used as state.
Note, that bodies such as [`Body`](@ref), [`BodyShape`](@ref), have potential states describing the distance and orientation, and their derivatives, between the world frame and a body fixed frame. Therefore, if these potential state variables are suited, a `FreeMotion` joint is not needed.
Note, that bodies such as [`Body`](@ref), [`BodyShape`](@ref), have potential state variables describing the distance and orientation, and their derivatives, between the world frame and a body fixed frame. Therefore, if these potential state variables are suited, a `FreeMotion` joint is not needed.
The states of the FreeMotion object are:
The state of the FreeMotion object consits of:
The relative position vector `r_rel_a` from the origin of `frame_a` to the origin of `frame_b`, resolved in `frame_a` and the relative velocity `v_rel_a` of the origin of `frame_b` with respect to the origin of `frame_a`, resolved in `frame_a (= der(r_rel_a))`.
# Arguments
- `enforceStates`: Enforce this joint having states, this is often desired and is the default choice.
- `enforceState`: Enforce this joint having state, this is often desired and is the default choice.
- `sequence`: Rotation sequence
- `w_rel_a_fixed`: = true, if `w_rel_a_start` are used as initial values, else as guess values
- `z_rel_a_fixed`: = true, if `z_rel_a_start` are used as initial values, else as guess values
Expand All @@ -632,7 +632,7 @@ The relative position vector `r_rel_a` from the origin of `frame_a` to the origi
- `v_rel_a`
- `a_rel_a`
"""
function FreeMotion(; name, enforceStates = true, sequence = [1, 2, 3], isroot = true,
function FreeMotion(; name, enforceState = true, sequence = [1, 2, 3], isroot = true,
w_rel_a_fixed = false, z_rel_a_fixed = false, phi = 0,
phi_d = 0,
phi_dd = 0,
Expand Down Expand Up @@ -681,7 +681,7 @@ function FreeMotion(; name, enforceStates = true, sequence = [1, 2, 3], isroot =
# Kinematic relationships
frame_b.r_0 .~ frame_a.r_0 .+ resolve1(frame_a, r_rel_a)]

if enforceStates
if enforceState
if isroot
append!(eqs,
ori(frame_b) ~ absoluteRotation(frame_a, R_rel))
Expand All @@ -698,7 +698,7 @@ function FreeMotion(; name, enforceStates = true, sequence = [1, 2, 3], isroot =
w_rel_b .~ angularVelocity2(R_rel)])

else
# Free motion joint does not have states
# Free motion joint does not have state
if w_rel_a_fixed || z_rel_a_fixed
append!(eqs,
w_rel_b .~ angularVelocity2(frame_b) - resolve2(frame_b.
Expand Down
8 changes: 4 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ssys = structural_simplify(model)
# ==============================================================================
#=
The multibody paper mentions this as an interesting example, figure 8:
"The non-standard feature to have potential states
"The non-standard feature to have potential state
both in joints and in bodies is especially useful for
inexperienced users, since they do not have to
introduce a “virtual” joint with 6 degrees of
Expand Down Expand Up @@ -594,7 +594,7 @@ D = Differential(t)
world = Multibody.world

@named begin
joint = Spherical(enforceStates = true, isroot = true, phi = 1)
joint = Spherical(enforceState = true, isroot = true, phi = 1)
bar = FixedTranslation(r = [0, -1, 0])
body = Body(; m = 1, isroot = false)
end
Expand Down Expand Up @@ -783,7 +783,7 @@ defs = [

# Model a free-falling body
world = Multibody.world
@named freeMotion = FreeMotion(enforceStates = true, isroot = true)
@named freeMotion = FreeMotion(enforceState = true, isroot = true)
@named body = Body(m = 1, isroot = false)

eqs = [connect(world.frame_b, freeMotion.frame_a)
Expand Down Expand Up @@ -812,7 +812,7 @@ y = sol(0:0.1:10, idxs = body.r_0[2])
## Dzhanibekov effect ==========================================================
# ==============================================================================
world = Multibody.world
@named freeMotion = FreeMotion(enforceStates = true, isroot = true)
@named freeMotion = FreeMotion(enforceState = true, isroot = true)
@named body = Body(m = 1, isroot = false, I_11 = 1, I_22 = 10, I_33 = 100)

eqs = [connect(world.frame_b, freeMotion.frame_a)
Expand Down

0 comments on commit 2a89155

Please sign in to comment.