Skip to content

Commit 6990591

Browse files
committed
add performance optimization for sparse inertia matrices
1 parent 2e7a76d commit 6990591

File tree

5 files changed

+26
-11
lines changed

5 files changed

+26
-11
lines changed

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118"
1313
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
1414
ModelingToolkitStandardLibrary = "16a59e39-deab-5bd0-87e4-056b12336739"
1515
Rotations = "6038ab10-8711-5258-84ad-4b1120ba62dc"
16+
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1617
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1718

1819
[weakdeps]
@@ -31,6 +32,7 @@ MeshIO = "0.4"
3132
ModelingToolkit = "9"
3233
ModelingToolkitStandardLibrary = "2.7.2"
3334
Rotations = "1.4"
35+
SparseArrays = "1"
3436
StaticArrays = "1"
3537
julia = "1"
3638

src/Multibody.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ using ModelingToolkit
77
using JuliaSimCompiler
88
import ModelingToolkitStandardLibrary.Mechanical.Rotational
99
import ModelingToolkitStandardLibrary.Mechanical.TranslationalModelica as Translational
10+
using SparseArrays
1011
using StaticArrays
1112
export Rotational, Translational
1213

src/components.jl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,15 @@ To obtain an axis-angle representation of any rotation, see [Conversion between
207207
end
208208

209209
"""
210-
Body(; name, m = 1, r_cm, isroot = false, phi0 = zeros(3), phid0 = zeros(3), r_0=zeros(3), state_priority = 2, quat=false)
210+
Body(; name, m = 1, r_cm, isroot = false, phi0 = zeros(3), phid0 = zeros(3), r_0 = zeros(3), state_priority = 2, quat = false, sparse_I = false)
211211
212212
Representing a body with 3 translational and 3 rotational degrees-of-freedom.
213213
214214
This component has a single frame, `frame_a`. To represent bodies with more than one frame, see [`BodyShape`](@ref), [`BodyCylinder`](@ref), [`BodyBox`](@ref).
215215
216+
# Performance optimization
217+
- `sparse_I`: If `true`, the zero elements of the inerita matrix are considered "structurally zero", and this fact is used to optimize performance. When this option is enabled, the elements of the inertia matrix that were zero when the component was created cannot changed without reinstantiating the component. This performance optimization may be useful, e.g., when the inertia matrix is known to be diagonal.
218+
216219
# Parameters
217220
- `m`: Mass
218221
- `r_cm`: Vector from `frame_a` to center of mass, resolved in `frame_a`
@@ -221,7 +224,6 @@ This component has a single frame, `frame_a`. To represent bodies with more than
221224
- `phi0`: Initial orientation, only applicable if `isroot = true` and `quat = false`
222225
- `phid0`: Initial angular velocity
223226
224-
225227
# Variables
226228
- `r_0`: Position vector from origin of world frame to origin of `frame_a`
227229
- `v_0`: Absolute velocity of `frame_a`, resolved in world frame (= D(r_0))
@@ -239,6 +241,7 @@ This component has a single frame, `frame_a`. To represent bodies with more than
239241
I_21 = 0,
240242
I_31 = 0,
241243
I_32 = 0,
244+
sparse_I = false,
242245
isroot = false,
243246
state = false,
244247
sequence = [1,2,3],
@@ -295,6 +298,10 @@ This component has a single frame, `frame_a`. To represent bodies with more than
295298
@parameters render = render [description = "Render the component in animations"]
296299
# @parameters I[1:3, 1:3]=I [description="inertia tensor"]
297300

301+
if sparse_I
302+
Isparsity = sparse(.!isequal.(0, [I_11 I_21 I_31; I_21 I_22 I_32; I_31 I_32 I_33]))
303+
end
304+
298305
@parameters I_11=I_11 [description = "Element (1,1) of inertia tensor"]
299306
@parameters I_22=I_22 [description = "Element (2,2) of inertia tensor"]
300307
@parameters I_33=I_33 [description = "Element (3,3) of inertia tensor"]
@@ -303,6 +310,9 @@ This component has a single frame, `frame_a`. To represent bodies with more than
303310
@parameters I_32=I_32 [description = "Element (3,2) of inertia tensor"]
304311

305312
I = [I_11 I_21 I_31; I_21 I_22 I_32; I_31 I_32 I_33]
313+
if sparse_I
314+
I = I.*Isparsity
315+
end
306316

307317
r_0, v_0, a_0, g_0, w_a, z_a, r_cm = collect.((r_0, v_0, a_0, g_0, w_a, z_a, r_cm))
308318

@@ -691,7 +701,7 @@ Rigid body with cylinder shape. The mass properties of the body (mass, center of
691701
frame_a = Frame()
692702
frame_b = Frame()
693703
translation = FixedTranslation(r = r)
694-
body = Body(; m, r_cm, I_11 = I[1,1], I_22 = I[2,2], I_33 = I[3,3], I_21 = I[2,1], I_31 = I[3,1], I_32 = I[3,2], state, quat, isroot, sequence, neg_w)
704+
body = Body(; m, r_cm, I_11 = I[1,1], I_22 = I[2,2], I_33 = I[3,3], I_21 = I[2,1], I_31 = I[3,1], I_32 = I[3,2], state, quat, isroot, sequence, neg_w, sparse_I=true)
695705
end
696706

697707
@equations begin
@@ -821,7 +831,7 @@ Rigid body with box shape. The mass properties of the body (mass, center of mass
821831
frame_a = Frame()
822832
frame_b = Frame()
823833
translation = FixedTranslation(r = r)
824-
body = Body(; m, r_cm, I_11 = I[1,1], I_22 = I[2,2], I_33 = I[3,3], I_21 = I[2,1], I_31 = I[3,1], I_32 = I[3,2], state, quat, isroot)
834+
body = Body(; m, r_cm, I_11 = I[1,1], I_22 = I[2,2], I_33 = I[3,3], I_21 = I[2,1], I_31 = I[3,1], I_32 = I[3,2], state, quat, isroot, sparse_I = true)
825835
end
826836

827837
@equations begin

src/robot/robot_components.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ function MechanicalStructure(; name, mLoad = 15, rLoad = [0, 0.25, 0], g = 9.81)
454454
r4 = Revolute(n = [0, 1, 0], axisflange = true, isroot = false, radius=0.06, color=robot_orange)
455455
r5 = Revolute(n = [1, 0, 0], axisflange = true, isroot = false, radius=0.05, color=robot_orange)
456456
r6 = Revolute(n = [0, 1, 0], axisflange = true, isroot = false, radius=0.02, color=[0.5, 0.5, 0.5, 1])
457-
b0 = BodyShape(r = [0, 0.351, 0],
457+
b0 = BodyShape(sparse_I = true, r = [0, 0.351, 0],
458458
shapefile = joinpath(path, "../../examples/resources/b0.stl"),
459459
# r_shape = [0, 0, 0],
460460
# lengthDirection = [1, 0, 0],
@@ -465,7 +465,7 @@ function MechanicalStructure(; name, mLoad = 15, rLoad = [0, 0.25, 0], g = 9.81)
465465
radius = 0.3/2,
466466
color = [0.5, 0.5, 0.5, 1],
467467
m = 1)
468-
b1 = BodyShape(r = [0, 0.324, 0.3],
468+
b1 = BodyShape(sparse_I = true, r = [0, 0.324, 0.3],
469469
shapefile = joinpath(path, "../../examples/resources/b1.stl"),
470470
I_22 = 1.16,
471471
# lengthDirection = [1, 0, 0],
@@ -476,7 +476,7 @@ function MechanicalStructure(; name, mLoad = 15, rLoad = [0, 0.25, 0], g = 9.81)
476476
radius = 0.2/2,
477477
color = robot_orange,
478478
m = 1)
479-
b2 = BodyShape(r = [0, 0.65, 0],
479+
b2 = BodyShape(sparse_I = true, r = [0, 0.65, 0],
480480
shapefile = joinpath(path, "../../examples/resources/b2.stl"),
481481
r_cm = [0.172, 0.205, 0],
482482
m = 56.5,
@@ -492,7 +492,7 @@ function MechanicalStructure(; name, mLoad = 15, rLoad = [0, 0.25, 0], g = 9.81)
492492
radius = 0.2/2,
493493
color = robot_orange,
494494
)
495-
b3 = BodyShape(r = [0, 0.414, -0.155],
495+
b3 = BodyShape(sparse_I = true, r = [0, 0.414, -0.155],
496496
shapefile = joinpath(path, "../../examples/resources/b3.stl"),
497497
r_cm = [0.064, -0.034, 0],
498498
m = 26.4,
@@ -508,7 +508,7 @@ function MechanicalStructure(; name, mLoad = 15, rLoad = [0, 0.25, 0], g = 9.81)
508508
radius = 0.15/2,
509509
color = robot_orange,
510510
)
511-
b4 = BodyShape(r = [0, 0.186, 0],
511+
b4 = BodyShape(sparse_I = true, r = [0, 0.186, 0],
512512
shapefile = joinpath(path, "../../examples/resources/b4.stl"),
513513
m = 28.7,
514514
I_11 = 1.67,
@@ -522,7 +522,7 @@ function MechanicalStructure(; name, mLoad = 15, rLoad = [0, 0.25, 0], g = 9.81)
522522
radius = 0.1/2,
523523
color = robot_orange,
524524
)
525-
b5 = BodyShape(r = [0, 0.125, 0],
525+
b5 = BodyShape(sparse_I = true, r = [0, 0.125, 0],
526526
shapefile = joinpath(path, "../../examples/resources/b5.stl"),
527527
m = 5.2,
528528
I_11 = 1.25,
@@ -536,7 +536,7 @@ function MechanicalStructure(; name, mLoad = 15, rLoad = [0, 0.25, 0], g = 9.81)
536536
radius = 0.1/2,
537537
color = [0.5, 0.5, 0.5, 1],
538538
)
539-
b6 = BodyShape(r = [0, 0, 0],
539+
b6 = BodyShape(sparse_I = true, r = [0, 0, 0],
540540
shapefile = joinpath(path, "../../examples/resources/b6.stl"),
541541
r_cm = [0.05, 0.05, 0.05],
542542
m = 0.5,

src/wheels.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,12 +550,14 @@ function RollingWheelSet(;
550550
I_11 = I_long,
551551
I_22 = I_long,
552552
I_33 = I_axis,
553+
sparse_I = true,
553554
render = false)
554555
body1 = Body(r_cm = [0, 0, 0],
555556
m = m_wheel,
556557
I_11 = I_long,
557558
I_22 = I_long,
558559
I_33 = I_axis,
560+
sparse_I = true,
559561
render = false)
560562
axis1 = Rotational.Flange()
561563
axis2 = Rotational.Flange()

0 commit comments

Comments
 (0)