Skip to content

Commit 5a9e770

Browse files
committed
add Cylindrical
1 parent 38abc92 commit 5a9e770

File tree

3 files changed

+80
-5
lines changed

3 files changed

+80
-5
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/joints.jl

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

test/runtests.jl

+24-1
Original file line numberDiff line numberDiff line change
@@ -1285,4 +1285,27 @@ 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=1)
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+
end
1302+
end
1303+
@named model = CylinderTest()
1304+
model = complete(model)
1305+
ssys = structural_simplify(IRSystem(model))
1306+
prob = ODEProblem(ssys, [
1307+
model.body.v_0[1] => 1
1308+
model.body.r_0[1] => 0.1
1309+
], (0, 1))
1310+
sol = solve(prob, Rodas4())
1311+
plot(sol)

0 commit comments

Comments
 (0)