@@ -4,6 +4,7 @@ author: Fredrik Bagge Carlson
44---
55
66This is a Multibody.jl model of a 6-axis industrial robot with 6 revolute joints. The first three joints are modeled as flexible. The robot is tracking a smooth, predefined reference trajectory.
7+
78```julia
89cd(@__DIR__)
910using Pkg
@@ -16,58 +17,108 @@ using JuliaSimCompiler
1617using OrdinaryDiffEq
1718using CairoMakie
1819using Printf
20+ ```
21+
22+ ## Setup
1923
24+ ```julia
2025time_instantiate = @elapsed @named robot = Robot6DOF()
2126robot = complete(robot)
2227time_simplify = @elapsed ssys = structural_simplify(IRSystem(robot))
23- time_prob = @elapsed prob = ODEProblem(ssys, [
24- robot.mechanics.r1.phi => deg2rad(-60)
25- robot.mechanics.r2.phi => deg2rad(20)
26- robot.mechanics.r3.phi => deg2rad(90)
27- robot.mechanics.r4.phi => deg2rad(0)
28- robot.mechanics.r5.phi => deg2rad(-110)
29- robot.mechanics.r6.phi => deg2rad(0)
30- robot.axis1.motor.Jmotor.phi => deg2rad(-60) * (-105)
31- robot.axis2.motor.Jmotor.phi => deg2rad(20) * (210)
32- robot.axis3.motor.Jmotor.phi => deg2rad(90) * (60)
33- ], (0.0, 4.0))
34- time_solve = @elapsed sol = solve(prob, Rodas5P(autodiff=false)); # With autodiff=true this takes over 150 seconds
35-
36- tv = 0:0.01:4
37- time_extract_data = @elapsed data = sol(tv, idxs=[
38- robot.pathPlanning.controlBus.axisControlBus1.angle
39- robot.pathPlanning.controlBus.axisControlBus2.angle
40- robot.pathPlanning.controlBus.axisControlBus3.angle
41- robot.pathPlanning.controlBus.axisControlBus4.angle
42- robot.pathPlanning.controlBus.axisControlBus5.angle
43- robot.pathPlanning.controlBus.axisControlBus6.angle
44- robot.mechanics.r1.phi
45- robot.mechanics.r2.phi
46- robot.mechanics.r3.phi
47- robot.mechanics.r4.phi
48- robot.mechanics.r5.phi
49- robot.mechanics.r6.phi
50- robot.axis1.controller.feedback1.output.u
51- robot.axis2.controller.feedback1.output.u
52- robot.axis3.controller.feedback1.output.u
53- robot.axis4.controller.feedback1.output.u
54- robot.axis5.controller.feedback1.output.u
55- robot.axis6.controller.feedback1.output.u
56- ]);
57-
28+ const C = JuliaSimCompiler.CTarget();
29+ const LLVM = JuliaSimCompiler.llvm.LLVMTarget();
5830labels = ["Instantiate", "Simplify", "Problem creation", "Solve", "Extract data"]
59- timings = [time_instantiate, time_simplify, time_prob, time_solve, time_extract_data]
31+ const u0 = [
32+ robot.mechanics.r1.phi => deg2rad(-60)
33+ robot.mechanics.r2.phi => deg2rad(20)
34+ robot.mechanics.r3.phi => deg2rad(90)
35+ robot.mechanics.r4.phi => deg2rad(0)
36+ robot.mechanics.r5.phi => deg2rad(-110)
37+ robot.mechanics.r6.phi => deg2rad(0)
38+ robot.axis1.motor.Jmotor.phi => deg2rad(-60) * (-105)
39+ robot.axis2.motor.Jmotor.phi => deg2rad(20) * (210)
40+ robot.axis3.motor.Jmotor.phi => deg2rad(90) * (60)
41+ ]
42+ const tspan = (0.0, 4.0)
43+ ```
44+
45+ ## Backend Benchmark Definition
46+
47+ ```julia
48+ function julia_multibody_timings(ssys, target)
49+ time_prob = @elapsed prob = if target === JuliaSimCompiler.JuliaTarget()
50+ ODEProblem(ssys, u0, tspan)
51+ else
52+ ODEProblem(ssys, target, u0, tspan)
53+ end
54+ time_solve = @elapsed sol = solve(prob, Rodas5P(autodiff=false)); # With autodiff=true this takes over 150 seconds
55+
56+ tv = 0:0.01:4
57+ time_extract_data = @elapsed data = sol(tv, idxs=[
58+ robot.pathPlanning.controlBus.axisControlBus1.angle
59+ robot.pathPlanning.controlBus.axisControlBus2.angle
60+ robot.pathPlanning.controlBus.axisControlBus3.angle
61+ robot.pathPlanning.controlBus.axisControlBus4.angle
62+ robot.pathPlanning.controlBus.axisControlBus5.angle
63+ robot.pathPlanning.controlBus.axisControlBus6.angle
64+ robot.mechanics.r1.phi
65+ robot.mechanics.r2.phi
66+ robot.mechanics.r3.phi
67+ robot.mechanics.r4.phi
68+ robot.mechanics.r5.phi
69+ robot.mechanics.r6.phi
70+ robot.axis1.controller.feedback1.output.u
71+ robot.axis2.controller.feedback1.output.u
72+ robot.axis3.controller.feedback1.output.u
73+ robot.axis4.controller.feedback1.output.u
74+ robot.axis5.controller.feedback1.output.u
75+ robot.axis6.controller.feedback1.output.u
76+ ]);
77+ timings = [time_instantiate, time_simplify, time_prob, time_solve, time_extract_data]
78+ end
79+ ```
80+
81+ ```julia
82+ julia_timings = julia_multibody_timings(ssys, JuliaSimCompiler.JuliaTarget())
83+
6084f = Figure()
6185xs = 1:length(labels)
62- points = Makie.Point.(xs .- 0.25, timings .+ 1)
63- anns = [@sprintf("%3.3g", t) for t in timings]
64- barplot(f[1,1], timings, axis=(; title="Timings", xticks = (xs, labels), limits = (nothing, (0, maximum(timings)*1.2 + 2))))
86+ points = Makie.Point.(xs .- 0.25, julia_timings .+ 1)
87+ anns = [@sprintf("%3.3g", t) for t in julia_timings]
88+ barplot(f[1,1], julia_timings, axis=(; title="Julia Backend Timings", xticks = (xs, labels), limits = (nothing, (0, maximum(julia_timings)*1.2 + 2))))
89+ annotations!(f[1,1], anns, points)
90+ barplot(f[2,1], julia_timings, axis=(; title="Log Timings", xticks = (xs, labels), yscale=log10))
91+ f
92+ ```
6593
94+ ```julia
95+ llvm_timings = julia_multibody_timings(ssys, LLVM)
96+
97+ f = Figure()
98+ xs = 1:length(labels)
99+ points = Makie.Point.(xs .- 0.25, llvm_timings .+ 1)
100+ anns = [@sprintf("%3.3g", t) for t in llvm_timings]
101+ barplot(f[1,1], llvm_timings, axis=(; title="LLVM Backend Timings", xticks = (xs, labels), limits = (nothing, (0, maximum(llvm_timings)*1.2 + 2))))
102+ annotations!(f[1,1], anns, points)
103+ barplot(f[2,1], llvm_timings, axis=(; title="Log Timings", xticks = (xs, labels), yscale=log10))
104+ f
105+ ```
106+
107+ ```julia
108+ c_timings = julia_multibody_timings(ssys, C)
109+
110+ f = Figure()
111+ xs = 1:length(labels)
112+ points = Makie.Point.(xs .- 0.25, c_timings .+ 1)
113+ anns = [@sprintf("%3.3g", t) for t in c_timings]
114+ barplot(f[1,1], c_timings, axis=(; title="C Backend Timings", xticks = (xs, labels), limits = (nothing, (0, maximum(c_timings)*1.2 + 2))))
66115annotations!(f[1,1], anns, points)
67- barplot(f[2,1], timings , axis=(; title="Log Timings", xticks = (xs, labels), yscale=log10))
116+ barplot(f[2,1], c_timings , axis=(; title="Log Timings", xticks = (xs, labels), yscale=log10))
68117f
69118```
70119
120+ Since the C backend currently errors, it's omitted from the total timings.
121+
71122## OpenModelica
72123
73124```julia
@@ -91,26 +142,37 @@ OMJulia.quit(mod)
91142```julia
92143colors = Makie.wong_colors()
93144labels = ["Build", "Simulate", "Total"]
94- julia_build = time_instantiate + time_simplify + time_prob
95- julia_sim = time_solve + time_extract_data
145+ julia_build = sum(julia_timings[1:3])
146+ julia_sim = sum(julia_timings[4:5])
96147julia_total = julia_build + julia_sim
148+
149+ llvm_build = sum(llvm_timings[1:3])
150+ llvm_sim = sum(llvm_timings[4:5])
151+ llvm_total = llvm_build + llvm_sim
152+
153+ # c_build = sum(c_timings[1:3])
154+ # c_sim = sum(c_timings[4:5])
155+ # c_total = c_build + c_sim
156+
97157dymola_build = sum([5.075, 3.912, 4.024])/3
98158dymola_total = sum([5.267, 4.112, 4.255])/3
99159dymola_sim = dymola_total - dymola_build
100160
101161data = [
102162 julia_build julia_sim julia_total
163+ llvm_build llvm_sim llvm_total
164+ # c_build c_sim c_total
103165 om_build om_sim om_total
104166 dymola_build dymola_sim dymola_total
105167]
106168
107- xs = repeat(1:length(labels), inner=3 )
108- group = repeat([1,2,3], outer=3)
169+ xs = repeat(1:length(labels), inner=4 )
170+ group = repeat([1,2,3,4 ], outer=3)
109171fig = Figure()
110172barplot(fig[1,1], xs, vec(data), dodge=group, color=colors[group], axis=(; title="Timings", xticks = ([1,2,3], labels)))
111173
112174# Legend
113- legendentries = ["Julia", "OpenModelica", "Dymola"]
175+ legendentries = ["Julia Backend", "LLVM Backend", #= "C Backend", =# "OpenModelica", "Dymola"]
114176elements = [PolyElement(polycolor = colors[i]) for i in 1:length(legendentries)]
115177title = "Contestants"
116178
0 commit comments