Skip to content

Commit b5741d6

Browse files
authored
add Cylindrical (#115)
* add Cylindrical * wip * add test * update default state priorities
1 parent c957819 commit b5741d6

File tree

4 files changed

+87
-9
lines changed

4 files changed

+87
-9
lines changed

src/Multibody.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export World, world, Mounting1D, Fixed, FixedTranslation, FixedRotation, Body, B
155155
include("components.jl")
156156

157157
export Revolute, Prismatic, Planar, Spherical, Universal,
158-
GearConstraint, RollingWheelJoint, RollingWheel, FreeMotion, RevolutePlanarLoopConstraint
158+
GearConstraint, RollingWheelJoint, RollingWheel, FreeMotion, RevolutePlanarLoopConstraint, Cylindrical
159159
include("joints.jl")
160160

161161
export SphericalSpherical, UniversalSpherical, JointUSR, JointRRR

src/components.jl

+1-2
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,11 @@ This component has a single frame, `frame_a`. To represent bodies with more than
266266
description = "Absolute velocity of frame_a, resolved in world frame (= D(r_0))",
267267
]
268268
@variables a_0(t)[1:3] [guess = 0,
269-
state_priority = state_priority+isroot,
270269
description = "Absolute acceleration of frame_a resolved in world frame (= D(v_0))",
271270
]
272271
@variables g_0(t)[1:3] [guess = 0, description = "gravity acceleration"]
273272
@variables w_a(t)[1:3]=w_a [guess = 0,
274-
state_priority = state_priority-1+2quat*state,
273+
state_priority = isroot ? quat ? state_priority : -1 : 0,
275274
description = "Absolute angular velocity of frame_a resolved in frame_a",
276275
]
277276
@variables z_a(t)[1:3] [guess = 0,

src/joints.jl

+56-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ If `axisflange`, flange connectors for ModelicaStandardLibrary.Mechanics.Rotatio
2424
"""
2525
@component function Revolute(; name, phi0 = 0, w0 = 0, n = Float64[0, 0, 1], axisflange = false,
2626
isroot = true, iscut = false, radius = 0.05, length = radius, color = [0.5019608f0,0.0f0,0.5019608f0,1.0f0], state_priority = 3.0)
27-
if !(eltype(n) <: Num)
27+
if !(eltype(n) <: Num) && !isa(n, Symbolics.Arr{Num, 1})
2828
norm(n) 1 || error("Axis of rotation must be a unit vector")
2929
end
3030
@named frame_a = Frame()
@@ -37,7 +37,7 @@ If `axisflange`, flange connectors for ModelicaStandardLibrary.Mechanics.Rotatio
3737
end
3838
@variables tau(t)=0 [
3939
connect = Flow,
40-
state_priority = 2,
40+
# state_priority = 2,
4141
description = "Driving torque in direction of axis of rotation",
4242
]
4343
@variables phi(t)=phi0 [
@@ -102,8 +102,8 @@ If `axisflange`, flange connectors for ModelicaStandardLibrary.Mechanics.Transla
102102
The function returns an ODESystem representing the prismatic joint.
103103
"""
104104
@component function Prismatic(; name, n = Float64[0, 0, 1], axisflange = false,
105-
s0 = 0, v0 = 0, radius = 0.05, color = [0,0.8,1,1], state_priority=10, iscut=false)
106-
if !(eltype(n) <: Num)
105+
s0 = 0, v0 = 0, radius = 0.05, color = [0,0.8,1,1], state_priority=10, iscut=false, render=true)
106+
if !(eltype(n) <: Num) && !isa(n, Symbolics.Arr{Num, 1})
107107
norm(n) 1 || error("Prismatic axis of motion must be a unit vector, got norm(n) = $(norm(n))")
108108
end
109109
@named frame_a = Frame()
@@ -114,6 +114,7 @@ The function returns an ODESystem representing the prismatic joint.
114114
pars = @parameters begin
115115
radius = radius, [description = "radius of the joint in animations"]
116116
color[1:4] = color, [description = "color of the joint in animations (RGBA)"]
117+
render = render, [description = "render the joint in animations"]
117118
end
118119

119120
@variables s(t)=s0 [
@@ -125,7 +126,6 @@ The function returns an ODESystem representing the prismatic joint.
125126
description = "Relative velocity between frame_a and frame_b",
126127
]
127128
@variables a(t)=0 [
128-
state_priority = state_priority,
129129
description = "Relative acceleration between frame_a and frame_b",
130130
]
131131
@variables f(t)=0 [
@@ -987,3 +987,54 @@ s_y=prismatic_y.s=0` and `phi=revolute.phi=0`.
987987
connect(revolute.frame_b, frame_b)
988988
end
989989
end
990+
991+
@mtkmodel Cylindrical begin
992+
begin
993+
n_def = [1, 0, 0] # Workaround for mtkmodel bug
994+
cylinder_color_def = [1, 0, 1, 1]
995+
end
996+
997+
@structural_parameters begin
998+
# _state_priority = 2 # mtkmodel bug prevents this from being any form of parameter at all :/
999+
cylinder_color = [1, 0, 1, 1]#, [description = "Color of cylinder"]
1000+
end
1001+
1002+
@parameters begin
1003+
n[1:3] = n_def, [description = "Cylinder axis resolved in frame_a (= same as in frame_b)"]
1004+
cylinder_diameter = 0.05, [description = "Diameter of cylinder"]
1005+
render = true, [description = "Enable rendering of the joint in animations"]
1006+
end
1007+
begin
1008+
n = collect(n)
1009+
cylinder_color = collect(cylinder_color)
1010+
end
1011+
1012+
@components begin
1013+
frame_a = Frame()
1014+
frame_b = Frame()
1015+
prismatic = Prismatic(; n, state_priority=1, render = false)
1016+
revolute = Revolute(; n, state_priority=1, color = cylinder_color, radius = cylinder_diameter/2)
1017+
end
1018+
1019+
@variables begin
1020+
(s(t) = 0), [state_priority = 200, description = "Relative distance between frame_a and frame_b"]
1021+
(phi(t) = 0), [state_priority = 200, description = "Relative rotation angle from frame_a to frame_b"]
1022+
(v(t) = 0), [state_priority = 200, description = "First derivative of s (relative velocity)"]
1023+
(w(t) = 0), [state_priority = 200, description = "First derivative of angle phi (relative angular velocity)"]
1024+
(a(t) = 0), [description = "Second derivative of s (relative acceleration)"]
1025+
(wd(t) = 0), [description = "Second derivative of angle phi (relative angular acceleration)"]
1026+
end
1027+
1028+
@equations begin
1029+
phi ~ revolute.phi
1030+
w ~ D(phi)
1031+
wd ~ D(w)
1032+
s ~ prismatic.s
1033+
v ~ D(s)
1034+
a ~ D(v)
1035+
connect(frame_a, prismatic.frame_a)
1036+
connect(prismatic.frame_b, revolute.frame_a)
1037+
connect(revolute.frame_b, frame_b)
1038+
end
1039+
1040+
end

test/runtests.jl

+29-1
Original file line numberDiff line numberDiff line change
@@ -1285,4 +1285,32 @@ sol = solve(prob, Rodas4())
12851285
include("test_fourbar.jl")
12861286
end
12871287

1288-
## =============================================================================
1288+
## =============================================================================
1289+
# using Plots
1290+
# Test cylindrical joint
1291+
@mtkmodel CylinderTest begin
1292+
@components begin
1293+
world = W()
1294+
cyl = Cylindrical(n = [0, 1, 0])
1295+
# spring = Spring(c = 1)
1296+
body = Body(state_priority=0)
1297+
end
1298+
@equations begin
1299+
# connect(world.frame_b, cyl.frame_a, spring.frame_a)
1300+
# connect(cyl.frame_b, spring.frame_b, body.frame_a)
1301+
1302+
connect(world.frame_b, cyl.frame_a)
1303+
connect(cyl.frame_b, body.frame_a)
1304+
end
1305+
end
1306+
@named model = CylinderTest()
1307+
model = complete(model)
1308+
ssys = structural_simplify(IRSystem(model))
1309+
prob = ODEProblem(ssys, [
1310+
model.cyl.revolute.w => 1
1311+
], (0, 1))
1312+
sol = solve(prob, Rodas4())
1313+
# plot(sol)
1314+
@test sol[model.cyl.v][end] -9.81 atol=0.01
1315+
@test sol[model.cyl.phi][end] 1 atol=0.01
1316+

0 commit comments

Comments
 (0)