Skip to content

Commit d2742fa

Browse files
committed
add rendering of several planar components
1 parent b51aa00 commit d2742fa

File tree

4 files changed

+119
-3
lines changed

4 files changed

+119
-3
lines changed

ext/Render.jl

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module Render
22
using Makie
33
using Multibody
44
import Multibody: render, render!, loop_render, encode, decode, get_rot, get_trans, get_frame
5+
import Multibody.PlanarMechanics as P
56
using Rotations
67
using LinearAlgebra
78
using ModelingToolkit
@@ -679,4 +680,103 @@ function rot_from_line(d)
679680
y = y ./ norm(y)
680681
RotMatrix{3}([x y d])
681682
end
683+
684+
# ==============================================================================
685+
## PlanarMechanics
686+
# ==============================================================================
687+
function get_rot_fun_2d(sol, frame)
688+
phifun = get_fun(sol, frame.phi)
689+
function (t)
690+
phi = phifun(t)
691+
[cos(phi) -sin(phi); sin(phi) cos(phi)]
692+
end
693+
end
694+
695+
function get_frame_fun_2d(sol, frame)
696+
R = get_rot_fun_2d(sol, frame)
697+
tr = get_fun(sol, [frame.x, frame.y])
698+
function (t)
699+
[R(t) tr(t); 0 0 1]
700+
end
701+
end
702+
703+
function render!(scene, ::typeof(P.Body), sys, sol, t)
704+
sol(sol.t[1], idxs=sys.render)==true || return true # yes, == true
705+
color = get_color(sys, sol, :purple)
706+
r_cm = get_fun(sol, collect(sys.r))
707+
framefun = get_frame_fun_2d(sol, sys.frame)
708+
radius = sol(sol.t[1], idxs=sys.radius) |> Float32
709+
thing = @lift begin # Sphere
710+
# Ta = framefun($t)
711+
# coords = (Ta*[0; 0; 1])[1:2] # r_cm($t)
712+
713+
coords = r_cm($t)
714+
point = Point3f(coords..., 0)
715+
Sphere(point, Float32(radius))
716+
end
717+
mesh!(scene, thing; color, specular = Vec3f(1.5), shininess=20f0, diffuse=Vec3f(1))
718+
false
719+
end
720+
721+
722+
function render!(scene, ::typeof(P.FixedTranslation), sys, sol, t)
723+
r_0a = get_fun(sol, [sys.frame_a.x, sys.frame_a.y])
724+
r_0b = get_fun(sol, [sys.frame_b.x, sys.frame_b.y])
725+
color = get_color(sys, sol, :purple)
726+
thing = @lift begin
727+
r1 = Point3f(r_0a($t)..., 0)
728+
r2 = Point3f(r_0b($t)..., 0)
729+
origin = r1#(r1+r2) ./ 2
730+
extremity = r2#-r1 # Double pendulum is a good test for this
731+
radius = 0.1f0#Float32(sol($t, idxs=sys.radius))
732+
Makie.GeometryBasics.Cylinder(origin, extremity, radius)
733+
end
734+
mesh!(scene, thing; color, specular = Vec3f(1.5), shininess=20f0, diffuse=Vec3f(1))
735+
true
736+
end
737+
738+
function render!(scene, ::typeof(P.Revolute), sys, sol, t)
739+
r_0 = get_fun(sol, [sys.frame_a.x, sys.frame_a.y])
740+
n = [0,0,1]
741+
color = get_color(sys, sol, :red)
742+
743+
rotfun = get_rot_fun_2d(sol, sys.frame_a)
744+
radius = try
745+
sol(sol.t[1], idxs=sys.radius)
746+
catch
747+
0.05f0
748+
end |> Float32
749+
length = try
750+
sol(sol.t[1], idxs=sys.length)
751+
catch
752+
radius
753+
end |> Float32
754+
thing = @lift begin
755+
O = [r_0($t)..., 0]
756+
R_w_a = cat(rotfun($t), 1, dims=(1,2))
757+
n_w = R_w_a*n # Rotate to the world frame
758+
p1 = Point3f(O + length*n_w)
759+
p2 = Point3f(O - length*n_w)
760+
Makie.GeometryBasics.Cylinder(p1, p2, radius)
761+
end
762+
mesh!(scene, thing; color, specular = Vec3f(1.5), shininess=20f0, diffuse=Vec3f(1))
763+
true
764+
end
765+
766+
function render!(scene, ::Union{typeof(P.Spring), typeof(P.SpringDamper)}, sys, sol, t)
767+
r_0a = get_fun(sol, [sys.frame_a.x, sys.frame_a.y])
768+
r_0b = get_fun(sol, [sys.frame_b.x, sys.frame_b.y])
769+
color = get_color(sys, sol, :blue)
770+
n_wind = sol(sol.t[1], idxs=sys.num_windings)
771+
radius = sol(sol.t[1], idxs=sys.radius) |> Float32
772+
N = sol(sol.t[1], idxs=sys.N) |> Int
773+
thing = @lift begin
774+
r1 = Point3f(r_0a($t)..., 0)
775+
r2 = Point3f(r_0b($t)..., 0)
776+
spring_mesh(r1,r2; n_wind, radius, N)
777+
end
778+
plot!(scene, thing; color)
779+
true
780+
end
781+
682782
end

src/PlanarMechanics/PlanarMechanics.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ using ModelingToolkit: t_nounits as t, D_nounits as D
1010
using ModelingToolkit
1111
using ...Blocks: RealInput, RealOutput
1212
import ...@symcheck
13+
import ..Multibody
1314

1415
export Frame, FrameResolve, PartialTwoFrames, ZeroPosition
1516
include("utils.jl")

src/PlanarMechanics/components.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,15 @@ Body component with mass and inertia
6363
6464
https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b708391461cbe2523/PlanarMechanics/Parts/Body.mo
6565
"""
66-
@component function Body(; name, m, I, rx = 0, ry = 0, phi = 0, gy = -9.807)
66+
@component function Body(; name, m, I, rx = 0, ry = 0, phi = 0, gy = -9.807, radius=0.1, render=true, color=Multibody.purple)
6767
@named frame = Frame()
6868
pars = @parameters begin
6969
m = m
7070
I = I
7171
gy = gy
72+
radius = radius, [description = "Radius of the body in animations"]
73+
render = render, [description = "Render the body in animations"]
74+
color[1:4] = color, [description = "Color of the body in animations"]
7275
end
7376

7477
vars = @variables begin
@@ -96,7 +99,7 @@ https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b70839146
9699
I * α ~ frame.j
97100
]
98101

99-
return compose(ODESystem(eqs, t; name),
102+
return compose(ODESystem(eqs, t, vars, pars; name),
100103
frame)
101104
end
102105

@@ -125,6 +128,8 @@ https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b70839146
125128
[
126129
description = "Fixed x,y-length of the rod resolved w.r.t to body frame_a at phi = 0"
127130
]
131+
radius = 0.1, [description = "Radius of the rod in animations"]
132+
render = true, [description = "Render the rod in animations"]
128133
end
129134
begin
130135
r = collect(r)
@@ -185,6 +190,11 @@ https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b70839146
185190
[
186191
description = "Prevent zero-division if distance between frame_a and frame_b is zero"
187192
]
193+
num_windings = 6, [description = "Number of windings of the coil when rendered"]
194+
color[1:4] = [0, 0.0, 1, 1], [description = "Color of the spring in animations"]
195+
render = true, [description = "Render the spring in animations"]
196+
radius = 0.1, [description = "Radius of spring when rendered"]
197+
N = 200, [description = "Number of points in mesh when rendered"]
188198
end
189199

190200
@variables begin
@@ -325,6 +335,11 @@ https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b70839146
325335
[
326336
description = "Prevent zero-division if distance between frame_a and frame_b is zero"
327337
]
338+
num_windings = 6, [description = "Number of windings of the coil when rendered"]
339+
color[1:4] = [0, 0.0, 1, 1], [description = "Color of the spring in animations"]
340+
render = true, [description = "Render the spring in animations"]
341+
radius = 0.1, [description = "Radius of spring when rendered"]
342+
N = 200, [description = "Number of points in mesh when rendered"]
328343
end
329344

330345
@variables begin

test/test_PlanarMechanics.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ end
302302
c_x = 5,
303303
d_x = 1,
304304
c_phi = 0)
305-
@named body = Planar.Body(; I = 0.1, m = 0.5, rx = 1, ry = 1)
305+
@named body = Planar.Body(; I = 0.1, m = 0.5, rx = 1, ry = 1, color=[0,1,0,1])
306306
@named fixed = Planar.Fixed()
307307
@named fixed_translation = Planar.FixedTranslation(; r = [-1, 0])
308308

0 commit comments

Comments
 (0)