Skip to content

Commit 83b0e2e

Browse files
authored
Merge pull request #130 from JuliaComputing/planarmechanics
add PlanarMechanics module
2 parents 49d14ac + 4c312f7 commit 83b0e2e

File tree

9 files changed

+1971
-0
lines changed

9 files changed

+1971
-0
lines changed

ext/Render.jl

+103
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,106 @@ 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, ::Union{typeof(P.FixedTranslation), typeof(P.BodyShape)}, sys, sol, t)
723+
sol(sol.t[1], idxs=sys.render)==true || return true # yes, == true
724+
r_0a = get_fun(sol, [sys.frame_a.x, sys.frame_a.y])
725+
r_0b = get_fun(sol, [sys.frame_b.x, sys.frame_b.y])
726+
color = get_color(sys, sol, :purple)
727+
thing = @lift begin
728+
r1 = Point3f(r_0a($t)..., 0)
729+
r2 = Point3f(r_0b($t)..., 0)
730+
origin = r1#(r1+r2) ./ 2
731+
extremity = r2#-r1 # Double pendulum is a good test for this
732+
radius = Float32(sol($t, idxs=sys.radius))
733+
Makie.GeometryBasics.Cylinder(origin, extremity, radius)
734+
end
735+
mesh!(scene, thing; color, specular = Vec3f(1.5), shininess=20f0, diffuse=Vec3f(1))
736+
true
737+
end
738+
739+
function render!(scene, ::typeof(P.Revolute), sys, sol, t)
740+
sol(sol.t[1], idxs=sys.render)==true || return true # yes, == true
741+
r_0 = get_fun(sol, [sys.frame_a.x, sys.frame_a.y])
742+
n = [0,0,1]
743+
color = get_color(sys, sol, :red)
744+
745+
rotfun = get_rot_fun_2d(sol, sys.frame_a)
746+
radius = try
747+
sol(sol.t[1], idxs=sys.radius)
748+
catch
749+
0.05f0
750+
end |> Float32
751+
length = try
752+
sol(sol.t[1], idxs=sys.length)
753+
catch
754+
radius
755+
end |> Float32
756+
thing = @lift begin
757+
O = [r_0($t)..., 0]
758+
R_w_a = cat(rotfun($t), 1, dims=(1,2))
759+
n_w = R_w_a*n # Rotate to the world frame
760+
p1 = Point3f(O + length*n_w)
761+
p2 = Point3f(O - length*n_w)
762+
Makie.GeometryBasics.Cylinder(p1, p2, radius)
763+
end
764+
mesh!(scene, thing; color, specular = Vec3f(1.5), shininess=20f0, diffuse=Vec3f(1))
765+
true
766+
end
767+
768+
function render!(scene, ::Union{typeof(P.Spring), typeof(P.SpringDamper)}, sys, sol, t)
769+
sol(sol.t[1], idxs=sys.render)==true || return true # yes, == true
770+
r_0a = get_fun(sol, [sys.frame_a.x, sys.frame_a.y])
771+
r_0b = get_fun(sol, [sys.frame_b.x, sys.frame_b.y])
772+
color = get_color(sys, sol, :blue)
773+
n_wind = sol(sol.t[1], idxs=sys.num_windings)
774+
radius = sol(sol.t[1], idxs=sys.radius) |> Float32
775+
N = sol(sol.t[1], idxs=sys.N) |> Int
776+
thing = @lift begin
777+
r1 = Point3f(r_0a($t)..., 0)
778+
r2 = Point3f(r_0b($t)..., 0)
779+
spring_mesh(r1,r2; n_wind, radius, N)
780+
end
781+
plot!(scene, thing; color)
782+
true
783+
end
784+
682785
end

src/Multibody.jl

+2
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,7 @@ include("robot/robot_components.jl")
210210
include("robot/FullRobot.jl")
211211

212212

213+
export PlanarMechanics
214+
include("PlanarMechanics/PlanarMechanics.jl")
213215

214216
end
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
Library to model planar mechanical multi-body systems inspired by https://github.com/dzimmer/PlanarMechanics
3+
"""
4+
5+
module PlanarMechanics
6+
7+
import ModelingToolkitStandardLibrary.Mechanical.Rotational
8+
import ModelingToolkitStandardLibrary.Mechanical.TranslationalModelica
9+
using ModelingToolkit: t_nounits as t, D_nounits as D
10+
using ModelingToolkit
11+
using ...Blocks: RealInput, RealOutput
12+
import ...@symcheck
13+
import ..Multibody
14+
15+
export Frame, FrameResolve, PartialTwoFrames, ZeroPosition
16+
include("utils.jl")
17+
18+
export Fixed, Body, FixedTranslation, Spring, Damper, SpringDamper
19+
include("components.jl")
20+
21+
export Revolute, Prismatic
22+
include("joints.jl")
23+
24+
export AbsolutePosition,
25+
RelativePosition, AbsoluteVelocity, RelativeVelocity, AbsoluteAcceleration,
26+
RelativeAcceleration, connect_sensor
27+
include("sensors.jl")
28+
end

0 commit comments

Comments
 (0)