diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dbe9c82 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/ \ No newline at end of file diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..147f4e9 --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,60 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.8.2" +manifest_format = "2.0" +project_hash = "edef2709ca5ed93a887579907c4eb7045e5446ec" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "0.5.2+0" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.20+0" + +[[deps.Random]] +deps = ["SHA", "Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "Random", "StaticArraysCore", "Statistics"] +git-tree-sha1 = "f86b3a049e5d05227b10e15dbb315c5b90f14988" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.5.9" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "6b7ba252635a5eff6a0b0664a41ee140a1c9e72a" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl", "OpenBLAS_jll"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.1.1+0" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..937f3d7 --- /dev/null +++ b/Project.toml @@ -0,0 +1,8 @@ +name = "Inertia" +uuid = "58d22092-de16-4bdf-bc5b-1f5634c2cdd0" +authors = ["tom "] +version = "0.1.0" + +[deps] +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" diff --git a/src/Inertia.jl b/src/Inertia.jl new file mode 100644 index 0000000..fe25928 --- /dev/null +++ b/src/Inertia.jl @@ -0,0 +1,12 @@ +module Inertia + +using LinearAlgebra, StaticArrays + +include("solids.jl") +include("composite.jl") + +export Cuboid, Sphere, Cylinder +export centre_of_mass, calculate_inertia + + +end # module Inertia diff --git a/src/composite.jl b/src/composite.jl new file mode 100644 index 0000000..6e087c2 --- /dev/null +++ b/src/composite.jl @@ -0,0 +1,51 @@ +# calculate inertial properties for combinations of solids + +# inertia about axes rotated by R from axes inertia currently expressed in +rotated_inertia(I, R) = R * I * R' + +# parallel axis theorem for inertia tensor about a point p from CoM +function parallel_axis(I, m, p) + Ixx = I[1, 1] + m * (p[2]^2 + p[3]^2) + Iyy = I[2, 2] + m * (p[1]^2 + p[3]^2) + Izz = I[3, 3] + m * (p[1]^2 + p[2]^2) + Ixy = Iyx = I[1, 2] - m * p[1] * p[2] + Ixz = Izx = I[1, 3] - m * p[1] * p[3] + Iyz = Izy = I[2, 3] - m * p[2] * p[3] + + return [Ixx Ixy Ixz; Iyx Iyy Iyz; Izx Izy Izz] +end + +parallel_axis(solid::AbstractSolid, p) = parallel_axis(solid.moi, solid.mass, p) + +# sum inertia +sum_inertia(I...) = sum(I) + +# centre of mass +centre_of_mass(ms, rs) = reduce(+, ms .* rs) / sum(ms) + +centre_of_mass(solids::Vector{AbstractSolid}, rs) = centre_of_mass(getfield.(solids, :mass), rs) + +# calculate total inertia of collection of solids about a point p +function calculate_inertia(Is, Rs, ms, rs, p) + # total inertia about CoM + Itotal = zeros(3, 3) + + for (I, R, m, r) in zip(Is, Rs, ms, rs) + # inertia about axes parallel to global frame + I′ = R * I * R' + + # inertia about com + I′cm = parallel_axis(I′, m, p - r) + + Itotal += I′cm + end + + return Itotal +end + +# total inertia about CoM +calculate_inertia(Is, Rs, ms, rs) = calculate_inertia(Is, Rs, ms, rs, centre_of_mass(ms, rs)) + +calculate_inertia(solids::Vector{AbstractSolid}, Rs, rs, p) = begin + calculate_inertia(getfield.(solids, :moi), Rs, getfield.(solids, :mass), rs, p) +end diff --git a/src/solids.jl b/src/solids.jl new file mode 100644 index 0000000..5f668c5 --- /dev/null +++ b/src/solids.jl @@ -0,0 +1,53 @@ +# regular solids and their inertial properties +abstract type AbstractSolid end + +## cuboid +struct Cuboid{T} <: AbstractSolid + length::T + width::T + height::T + mass::T + moi::SMatrix{3,T} # principle inertia tensor + + # determine moment of inertia from dimensions and mass + function Cuboid{T}(l, w, h, m) where {T} + c = 1 / 12 * m + I = @SMatrix [c*(w^2+h^2) 0 0; 0 c*(l^2+h^2) 0; 0 0 c*(l^2+w^2)] + + return new{T}(l, w, h, m, I) + end +end + +## sphere +struct Sphere{T} <: AbstractSolid + radius::T + mass::T + moi::SMatrix{3,T} # principle inertia tensor + + # determine moment of inertia from dimensions and mass + function Sphere{T}(r, m) where {T} + c = 2 / 5 * m + I = @SMatrix [c*r^2 0 0; 0 c*r^2 0; 0 0 c*r^2] + + return new{T}(r, m, I) + end +end + +## cylinder +struct Cylinder{T} <: AbstractSolid + radius::T + length::T + mass::T + moi::SMatrix{3,T} # principle inertia tensor + + # determine moment of inertia from dimensions and mass + function Cylinder{T}(r, l, m) where {T} + c1 = 1 / 12 * m + c2 = 1 / 2 * m + I = @SMatrix [c2*r^2 0 0; 0 c1*(3r^2+l^2) 0; 0 0 c1*(3r^2+l^2)] + + return new{T}(r, l, m, I) + end +end + +