Skip to content

Commit cbc6e85

Browse files
committed
optimize spring rendering and add options
1 parent 25d64af commit cbc6e85

File tree

2 files changed

+41
-31
lines changed

2 files changed

+41
-31
lines changed

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)