Skip to content

Commit bf469a3

Browse files
authored
Merge pull request #84 from JuliaComputing/gifgrid
add a grid of animations to doc front page
2 parents 25d64af + a47011d commit bf469a3

File tree

5 files changed

+118
-34
lines changed

5 files changed

+118
-34
lines changed

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ makedocs(;
1212
sitename = "Multibody.jl",
1313
warnonly = [:missing_docs, :cross_references, :docs_block],
1414
pagesonly = true,
15+
# draft = true,
1516
format = Documenter.HTML(;
1617
prettyurls = get(ENV, "CI", nothing) == "true",
1718
edit_link = nothing),

docs/src/examples/three_springs.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ systems = @named begin
2424
bar1 = FixedTranslation(r = [0.3, 0, 0])
2525
bar2 = FixedTranslation(r = [0, 0, 0.3])
2626
spring1 = Multibody.Spring(c = 20, m = 0, s_unstretched = 0.1, fixed_rotation_at_frame_b=true,
27-
r_rel_0 = [-0.2, -0.2, 0.2])
28-
spring2 = Multibody.Spring(c = 40, m = 0, s_unstretched = 0.1)
29-
spring3 = Multibody.Spring(c = 20, m = 0, s_unstretched = 0.1, fixed_rotation_at_frame_a=false)
27+
r_rel_0 = [-0.2, -0.2, 0.2], radius=0.05, num_windings=10)
28+
spring2 = Multibody.Spring(c = 40, m = 0, s_unstretched = 0.1, color=[0,0,0.3,1])
29+
spring3 = Multibody.Spring(c = 20, m = 0, s_unstretched = 0.1, radius=0.05, num_windings=10)
3030
end
3131
eqs = [connect(world.frame_b, bar1.frame_a)
3232
connect(world.frame_b, bar2.frame_a)

docs/src/index.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,79 @@ Built on top of the Julia language and the JuliaSim suite of tools for modeling,
7979

8080
In this documentation, you will find everything you need to get started with Multibody.jl, from basic component descriptions to detailed examples showcasing the package's capabilities. As you explore this documentation, you'll learn how to create complex models, work with forces and torques, simulate various types of motions, and visualize your results in both 2D and 3D. Whether you are a seasoned researcher or a newcomer to the field, Multibody.jl will empower you to bring your ideas to life and unlock new possibilities in the fascinating world of multibody dynamics.
8181

82+
## Example overview
83+
The following animations give a quick overview of simple mechanisms that can be modeled using Multibody.jl. The examples are ordered from simple at the top, to more advanced at the bottom. Please browse the examples for even more examples!
84+
```@raw html
85+
<!DOCTYPE html>
86+
<html lang="en">
87+
<head>
88+
<meta charset="UTF-8">
89+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
90+
<title>GIF Grid</title>
91+
<style>
92+
.grid-container {
93+
display: grid;
94+
grid-template-columns: repeat(3, 1fr);
95+
grid-template-rows: repeat(4, auto);
96+
gap: 10px;
97+
padding: 20px;
98+
}
99+
.grid-item {
100+
width: 100%;
101+
height: auto;
102+
}
103+
.grid-item img {
104+
width: 100%;
105+
height: auto;
106+
display: block;
107+
}
108+
</style>
109+
</head>
110+
<body>
111+
112+
<div class="grid-container">
113+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/pendulum/">
114+
<img src="https://help.juliahub.com/multibody/dev/examples/furuta.gif" alt="Furuta">
115+
</a>
116+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/spring_damper_system/">
117+
<img src="https://help.juliahub.com/multibody/dev/examples/springdamper.gif" alt="springdamper">
118+
</a>
119+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/spherical_pendulum/">
120+
<img src="https://help.juliahub.com/multibody/dev/examples/spherical.gif" alt="spherical">
121+
</a>
122+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/three_springs/">
123+
<img src="https://help.juliahub.com/multibody/dev/examples/three_springs.gif" alt="three_springs">
124+
</a>
125+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/space/">
126+
<img src="https://help.juliahub.com/multibody/dev/examples/space.gif" alt="space">
127+
</a>
128+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/free_motion/#Body-suspended-in-springs">
129+
<img src="https://help.juliahub.com/multibody/dev/examples/free_body.gif" alt="free_body">
130+
</a>
131+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/ropes_and_cables/">
132+
<img src="https://help.juliahub.com/multibody/dev/examples/flexible_rope.gif" alt="flexible_rope">
133+
</a>
134+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/ropes_and_cables/">
135+
<img src="https://help.juliahub.com/multibody/dev/examples/mounted_chain.gif" alt="mounted_chain">
136+
</a>
137+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/ropes_and_cables/">
138+
<img src="https://help.juliahub.com/multibody/dev/examples/stiff_rope.gif" alt="stiff_rope">
139+
</a>
140+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/kinematic_loops/">
141+
<img src="https://help.juliahub.com/multibody/dev/examples/fourbar2.gif" alt="fourbar2">
142+
</a>
143+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/kinematic_loops/">
144+
<img src="https://help.juliahub.com/multibody/dev/examples/fourbar.gif" alt="fourbar">
145+
</a>
146+
<a class="grid-item" href="https://help.juliahub.com/multibody/dev/examples/robot/">
147+
<img src="https://help.juliahub.com/multibody/dev/examples/robot.gif" alt="robot">
148+
</a>
149+
</div>
150+
151+
</body>
152+
</html>
153+
```
154+
82155

83156

84157

ext/Render.jl

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -385,16 +385,18 @@ function render!(scene, ::typeof(Spring), sys, sol, t)
385385
r_0a = get_fun(sol, collect(sys.frame_a.r_0))
386386
r_0b = get_fun(sol, collect(sys.frame_b.r_0))
387387
color = get_color(sys, sol, :blue)
388+
n_wind = sol(sol.t[1], idxs=sys.num_windings)
389+
radius = sol(sol.t[1], idxs=sys.radius) |> Float32
390+
N = sol(sol.t[1], idxs=sys.N) |> Int
388391
thing = @lift begin
389392
r1 = Point3f(r_0a($t))
390393
r2 = Point3f(r_0b($t))
391-
spring_mesh(r1,r2)
394+
spring_mesh(r1,r2; n_wind, radius, N)
392395
end
393396
plot!(scene, thing; color)
394397
true
395398
end
396399

397-
398400
function render!(scene, ::Function, sys, sol, t, args...) # Fallback for systems that have at least two frames
399401
count(ModelingToolkit.isframe, sys.systems) == 2 || return false
400402
r_0a = get_fun(sol, collect(sys.frame_a.r_0))
@@ -422,24 +424,19 @@ function render!(scene, ::Function, sys, sol, t, args...) # Fallback for systems
422424
end
423425

424426
function spring_mesh(p1, p2; n_wind=6, radius=0.1f0, N=200)
425-
phi = range(0, n_wind*2π, length=N)
426-
427+
phis = range(0, n_wind*2π, length=N)
427428
d = p2 - p1
428-
429-
x = radius*cos.(phi)
430-
y = radius*sin.(phi)
431429
z = range(0, norm(d), length=N) # Correct length
432-
points = Point3f.(x, y, z)
430+
dn = d ./ norm(d)
431+
R = rot_from_line(dn)
433432

434-
d = d ./ norm(d)
435-
436-
# Rotate
437-
R = rot_from_line(d)
438-
points = Ref(R) .* points
439-
440-
# Translate
441-
points = points .+ p1
433+
points = map(enumerate(phis)) do (i,phi)
434+
x = radius*cos(phi)
435+
y = radius*sin(phi)
436+
pᵢ = Point3f(x, y, z[i])
442437

438+
R * pᵢ + p1
439+
end
443440

444441
Makie.GeometryBasics.LineString(points)
445442
end

src/forces.jl

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ function LineForceBase(; name, length = 0, s_small = 1e-10, fixed_rotation_at_fr
181181
compose(ODESystem(eqs, t; name), frame_a, frame_b)
182182
end
183183

184-
function LineForceWithMass(; name, length = 0, m = 1.0, lengthFraction = 0.5, kwargs...)
184+
function LineForceWithMass(; name, length = 0, m = 1.0, lengthfraction = 0.5, kwargs...)
185185
m0 = m
186186
@named lfb = LineForceBase(; length, kwargs...)
187187
@unpack length, s, r_rel_0, e_rel_0, frame_a, frame_b = lfb
@@ -195,7 +195,7 @@ function LineForceWithMass(; name, length = 0, m = 1.0, lengthFraction = 0.5, kw
195195
]
196196
@variables v_CM_0(t)[1:3]=zeros(3) [description = "First derivative of r_CM_0"]
197197
@variables ag_CM_0(t)[1:3]=zeros(3) [description = "D(v_CM_0) - gravityAcceleration"]
198-
@parameters lengthFraction=lengthFraction [
198+
@parameters lengthfraction=lengthfraction [
199199
description = "Location of point mass with respect to frame_a as a fraction of the distance from frame_a to frame_b",
200200
bounds = (0, 1),
201201
]
@@ -214,13 +214,13 @@ function LineForceWithMass(; name, length = 0, m = 1.0, lengthFraction = 0.5, kw
214214
# NOTE, both frames are assumed to be connected, while modelica has special handling if they aren't
215215
if m0 > 0
216216
eqs = [eqs
217-
collect(r_CM_0 .~ frame_a.r_0 + r_rel_0 * lengthFraction)
217+
collect(r_CM_0 .~ frame_a.r_0 + r_rel_0 * lengthfraction)
218218
v_CM_0 .~ D.(r_CM_0)
219219
ag_CM_0 .~ D.(v_CM_0) - gravity_acceleration(r_CM_0)
220220
frame_a.f .~ resolve2(ori(frame_a),
221-
(m * (1 - lengthFraction)) * ag_CM_0 - e_rel_0 * fa)
221+
(m * (1 - lengthfraction)) * ag_CM_0 - e_rel_0 * fa)
222222
frame_b.f .~ resolve2(ori(frame_b),
223-
(m * lengthFraction) * ag_CM_0 - e_rel_0 * fb)]
223+
(m * lengthfraction) * ag_CM_0 - e_rel_0 * fb)]
224224
else
225225
eqs = [eqs
226226
r_CM_0 .~ zeros(3)
@@ -264,7 +264,7 @@ function PartialLineForce(; name, kwargs...)
264264
end
265265

266266
"""
267-
Spring(; c, name, m = 0, lengthFraction = 0.5, s_unstretched = 0, kwargs)
267+
Spring(; c, name, m = 0, lengthfraction = 0.5, s_unstretched = 0, kwargs)
268268
269269
Linear spring acting as line force between `frame_a` and `frame_b`.
270270
A force `f` is exerted on the origin of `frame_b` and with opposite sign
@@ -284,23 +284,35 @@ additional equations to handle the mass are removed.
284284
# Arguments:
285285
- `c`: Spring stiffness
286286
- `m`: Mass of the spring (can be zero)
287-
- `lengthFraction`: Location of spring mass with respect to `frame_a` as a fraction of the distance from `frame_a` to `frame_b` (=0: at `frame_a`; =1: at `frame_b`)
287+
- `lengthfraction`: Location of spring mass with respect to `frame_a` as a fraction of the distance from `frame_a` to `frame_b` (=0: at `frame_a`; =1: at `frame_b`)
288288
- `s_unstretched`: Length of the spring when it is unstretched
289289
- `kwargs`: are passed to `LineForceWithMass`
290290
291+
# Rendering
292+
- `num_windings = 6`
293+
- `color = [0,0,1,1]`
294+
- `radius = 0.1`
295+
- `N = 200`
296+
291297
See also [`SpringDamperParallel`](@ref)
292298
"""
293-
@component function Spring(; c, name, m = 0, lengthFraction = 0.5, s_unstretched = 0, kwargs...)
299+
@component function Spring(; c, name, m = 0, lengthfraction = 0.5, s_unstretched = 0, num_windings=6, color=[0,0,1,1], radius=0.1, N=200, kwargs...)
294300
@named ptf = PartialTwoFrames()
295301
@unpack frame_a, frame_b = ptf
296-
@named lineforce = LineForceWithMass(; length = s_unstretched, m, lengthFraction,
302+
pars = @parameters begin
303+
# c=c, [description = "spring constant", bounds = (0, Inf)]
304+
# s_unstretched=s_unstretched, [
305+
# description = "unstretched length of spring",
306+
# bounds = (0, Inf),
307+
# ] # Bug in MTK where parameters only passed to sub components are ignored
308+
num_windings = num_windings, [description = "Number of windings of the coil when rendered"]
309+
color[1:4] = color
310+
radius = radius, [description = "Radius of spring when rendered"]
311+
N = N, [description = "Number of points in mesh when rendered"]
312+
end
313+
@named lineforce = LineForceWithMass(; length = s_unstretched, m, lengthfraction,
297314
kwargs...)
298315

299-
# @parameters c=c [description = "spring constant", bounds = (0, Inf)]
300-
# @parameters s_unstretched=s_unstretched [
301-
# description = "unstretched length of spring",
302-
# bounds = (0, Inf),
303-
# ] # Bug in MTK where parameters only passed to sub components are ignored
304316
@named spring2d = TP.Spring(; c, s_rel0 = s_unstretched)
305317

306318
@variables r_rel_a(t)[1:3]=0 [
@@ -341,7 +353,8 @@ See also [`SpringDamperParallel`](@ref)
341353
connect(spring2d.flange_b, lineforce.flange_b)
342354
connect(spring2d.flange_a, lineforce.flange_a)]
343355

344-
extend(ODESystem(eqs, t; name, systems = [lineforce, spring2d]), ptf)
356+
sys = extend(ODESystem(eqs, t; name=:nothing, systems = [lineforce, spring2d]), ptf)
357+
add_params(sys, pars; name)
345358
end
346359

347360
"""

0 commit comments

Comments
 (0)