Skip to content

Commit

Permalink
Merge pull request #106 from ModiaSim/improve_cut_joint_message
Browse files Browse the repository at this point in the history
Improve corner cases and error messages
  • Loading branch information
MartinOtter authored Mar 26, 2022
2 parents 1223fbb + 044e432 commit 4f32004
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 30 deletions.
4 changes: 2 additions & 2 deletions src/Composition/dynamics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ function getJointsAndForceElementsAndObject3DsWithoutParents!(evaluatedParameter
if typeof(value.feature) <: Scene
push!(object3DWithoutParents, value)
else
error("\n", value.path, " is an Object3D that has no parent, but no feature=Scene(..)!\n")
error("\n", value.path, " is an Object3D that has no parent, but no feature=Scene(..)!\nThis means no Scene is defined (exactly one Object3D must have feature=Scene(..))!")
end
elseif typeof(value.feature) <: Scene
error("\n", value.path, " is an Object3D that has feature=Scene(..) and has a parent (= ", value.parent.path, ")!\n")
error("\n", value.path, " is an Object3D that has feature=Scene(..) and has a parent (= ", value.parent.path, ")!\nThe Object3D with feature=Scene(..) is not allowed to have a parent!")
end

elseif typeof(value) <: Modia3D.Composition.Revolute
Expand Down
6 changes: 1 addition & 5 deletions src/Composition/joints/Fix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ struct Fix{F <: Modia3D.VarFloatType}
translation::AbstractVector = Modia3D.ZeroVector3D(F),
rotation::AbstractVector = Modia3D.ZeroVector3D(F)) where F <: Modia3D.VarFloatType

(parent, child, cutJoint) = attach(obj1, obj2)
if cutJoint
error("\nError from Fix joint connecting ", Modia3D.fullName(obj1), " with ", Modia3D.fullName(obj2), ":",
"\nThis joint is a cut-joint which is not allowed.")
end
(parent, child, cutJoint) = attach(obj1, obj2, name = "Fix joint") # an error is triggered if cutJoint=true

r_rel = Modia3D.convertAndStripUnit(SVector{3,F}, u"m", translation)
rot = Modia3D.convertAndStripUnit(SVector{3,F}, u"rad", rotation)
Expand Down
8 changes: 2 additions & 6 deletions src/Composition/joints/Prismatic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ get_eAxis(::Type{F}, axis::Int) where F <: Modia3D.VarFloatType = axis== 1 ? SV
error("Modia3D.Composition.Prismatic: axis = ", axis, " but must be 1, 2, 3, -1, -2, or -3.")

"""
joint = Prismatic(; obj1, obj2, path="", axis=1, s=0, v=0, canCollide=true)
joint = Prismatic(; obj1, obj2, axis=1, s=0, v=0, canCollide=true)
Return a `joint` that translates `obj2::`[`Object3D`](@ref) with respect to
`obj1::`[`Object3D`](@ref) along coordinate axis `axis` (`axis = 1,2,3,-1,-2,-3`)
Expand Down Expand Up @@ -52,11 +52,7 @@ mutable struct Prismatic{F <: Modia3D.VarFloatType} <: Modia3D.AbstractJoint
v::Real = F(0.0),
canCollide::Bool = true) where F <: Modia3D.VarFloatType

(parent,obj,cutJoint) = attach(obj1, obj2)
if cutJoint
error("\nError from Prismatic joint connecting ", Modia3D.fullName(obj1), " with ", Modia3D.fullName(obj2), ":\n",
" This joint is a cut-joint which is currently not supported.!")
end
(parent,obj,cutJoint) = attach(obj1, obj2, name = "Prismatic joint") # an error is triggered if cutJoint=true

if !(1 <= abs(axis) <= 3)
error("\nError from Prismatic joint connecting ", Modia3D.fullName(obj1), " with ", Modia3D.fullName(obj2), ":\n",
Expand Down
8 changes: 2 additions & 6 deletions src/Composition/joints/Revolute.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Modia3D.Frames


"""
joint = Revolute(;obj1, obj2, path="", axis=3, phi=0, w=0, canCollide=false)
joint = Revolute(;obj1, obj2, axis=3, phi=0, w=0, canCollide=false)
Return a Revolute `joint` that rotates `obj1::`[`Object3D`](@ref) into
`obj2::`[`Object3D`](@ref) along the axis `axis` of `obj1` (`axis = 1,2,3,-1,-2,-3`).
Expand Down Expand Up @@ -43,11 +43,7 @@ mutable struct Revolute{F <: Modia3D.VarFloatType} <: Modia3D.AbstractJoint
w::Real = F(0.0),
canCollide::Bool = false) where F <: Modia3D.VarFloatType

(parent,obj,cutJoint) = attach(obj1, obj2)
if cutJoint
error("\nError from Revolute joint connecting ", Modia3D.fullName(obj1), " with ", Modia3D.fullName(obj2), ":\n",
" This joint is a cut-joint which is currently not supported.!")
end
(parent,obj,cutJoint) = attach(obj1, obj2, name = "Revolute joint") # an error is triggered if cutJoint=true

if !(1 <= abs(axis) <= 3)
error("\nError from Revolute joint connecting ", Modia3D.fullName(obj1), " with ", Modia3D.fullName(obj2), ":\n",
Expand Down
14 changes: 13 additions & 1 deletion src/Composition/joints/joints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ function attachAndReverseParents(newParent::Object3D{F}, obj::Object3D{F})::Noth
end


getParents(obj,rootPath) = "\"" * Modia3D.fullName(obj) * "\" has " * (length(rootPath) == 0 ? "no parents" : "parents: $rootPath")

"""
(obj1, obj2, cutJoint) = attach(frame_a, frame_b)
Expand All @@ -128,7 +130,7 @@ and cutJoint = false is returned.
If they have the same root, the tree is not modified and cutJoint=true is returned.
"""
function attach(obj1::Object3D, obj2::Object3D)
function attach(obj1::Object3D, obj2::Object3D; name = "")
root1 = rootObject3D(obj1)
root2 = rootObject3D(obj2)
#println("attach: obj1 = ", Modia3D.fullName(obj1), ", root = ", Modia3D.fullName(root1))
Expand All @@ -137,6 +139,16 @@ function attach(obj1::Object3D, obj2::Object3D)
if root1 root2
# Compute absolute positions
# updatePosition!(root1)

if name != ""
# Collect all objects that form a loop
rootPath1 = rootObject3DPath(obj1)
rootPath2 = rootObject3DPath(obj2)
error("\nError from $name connecting \"", Modia3D.fullName(obj1), "\" with \"", Modia3D.fullName(obj2), "\":\n",
" ", getParents(obj1,rootPath1), "\n",
" ", getParents(obj2,rootPath2), "\n",
" Therefore, a closed kinematic loop is defined, which is currently not supported.")
end
return (obj1,obj2,true)
end

Expand Down
2 changes: 1 addition & 1 deletion src/Composition/joints/object3DMotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ end


"""
joint = FreeMotion(; obj1, obj2, path="", r, rot, v, w)
joint = FreeMotion(; obj1, obj2, r, rot, v, w)
Return a `joint` that describes the free movement of `obj2::`[`Object3D`](@ref)
with respect to `obj1::`[`Object3D`](@ref). The initial position is `r`
Expand Down
2 changes: 1 addition & 1 deletion src/Composition/massPropertiesComputation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function addOrSubtractMassPropertiesOfChildToRoot!(obj_root::Object3D{F}, obj_ch
m = m_root + m_child

# common center of mass (parent + child)
@assert(m > 0.0)
@assert(m >= 0.0)
rCM = (m_root * rCM_root + m_child * rCM_child_new)/m

# I: substract new common mass multiplied with skew matrices of
Expand Down
12 changes: 12 additions & 0 deletions src/Composition/object3D.jl
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,18 @@ function rootObject3D(obj::Object3D{F}) where F <: Modia3D.VarFloatType
end


""" path = rootObject3DPath(obj) - returns a vector of Object3D names of all objects from obj to root"""
function rootObject3DPath(obj::Object3D{F}) where F <: Modia3D.VarFloatType
path = String[]
obj1 = obj
while hasParent(obj1)
obj1 = obj1.parent
push!(path, obj1.path)
end
return path
end


""" removeChild!(obj, child) - Remove child from obj.children"""
function removeChild!(obj::Object3D{F}, child::Object3D{F})::Nothing where F <: Modia3D.VarFloatType
children = obj.children
Expand Down
5 changes: 5 additions & 0 deletions src/ModiaInterface/buildModia3D.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ function buildModia3D!(model::AbstractDict, FloatType::Type, TimeType::Type,
jointStatesFreeMotion_isrot123 = Expr[]
freeMotionIndices = OrderedCollections.OrderedDict{String,Int}()

println("modelPath = $modelPath")

modelPathAsString = isnothing(modelPath) ? "" : string(modelPath)

i=1
Expand Down Expand Up @@ -243,6 +245,9 @@ function buildModia3D!(model::AbstractDict, FloatType::Type, TimeType::Type,
else
@error "Error should not occur (buildOption = $buildOption)"
end
else
# ndofTotal == 0
mbsCode = mbs_variables | Model(equations = :[$(mbs_equations...)])
end

# Store info in buildDict
Expand Down
2 changes: 1 addition & 1 deletion src/Shapes/massProperties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct MassProperties{F <: Modia3D.VarFloatType} <: Modia3D.AbstractMassProperti
#---------------- different constructors for MassProperties -----------------
# Constructor 0: takes mass, centerOfMass and inertiaMatrix as input values
function MassProperties{F}(mass::Number, centerOfMass::AbstractVector, inertiaMatrix::AbstractMatrix) where F <: Modia3D.VarFloatType
@assert(mass > 0.0)
@assert(mass >= 0.0)
new(mass, centerOfMass, inertiaMatrix)
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/Shapes/palettes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Read the palettes for which a file name is given and store them as global palett
If `log=true`, log the reading of the files.
When Modia3D is used the first time, it reads the palettes automatically from
`"Modia3D/palettes/*.sjon"`. The `loadPalettes` function overwrites this default setting.
`"Modia3D/palettes/*.json"`. The `loadPalettes` function overwrites this default setting.
# Examples
Expand Down
16 changes: 11 additions & 5 deletions src/Shapes/solid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Generate a [Solid](@ref) with physical behavior of a rigid body with mass, visua
computed from `shape` and `solidMaterial`. It is also possible to define only the mass of the solid and compute the
center of mass and inertia tensor from `shape` (e.g. `MassPropertiesFromShapeAndMass(mass=4.5)`) or explicitly
define all mass properties (e.g. `MassProperties(mass=4.5, centerOfMass=[1.0,2.0,3.0], Ixx=4.0, Iyy=5.0, Izz=6.0,
Ixy=4.5, Ixz=4.6, Iyz=5.5)`).
Ixy=4.5, Ixz=4.6, Iyz=5.5)`).
- `collision`: Defines if the solid is considered in [Collision Handling](@ref). `collision=true` requires definition
of `shape`, mass properties (defined by `solidMaterial` or `massProperties`) and contact material (defined by
Expand Down Expand Up @@ -88,7 +88,7 @@ struct Solid{F <: Modia3D.VarFloatType} <: Modia3D.AbstractObject3DFeature
collisionSmoothingRadius=F(0.001),
visualMaterial::Union{Shapes.VisualMaterial,AbstractString,Nothing} = Shapes.VisualMaterial(),
visualMaterialConvexDecomposition::Union{Shapes.VisualMaterial,AbstractString,Nothing} = Shapes.VisualMaterial(),
contactSphereRadius::Union{Nothing, F} = nothing) where F <: Modia3D.VarFloatType
contactSphereRadius::Union{Nothing, Number} = nothing) where F <: Modia3D.VarFloatType

if collision && isnothing(shape)
error("For collision/gripping simulations, a shape must be defined.")
Expand All @@ -105,20 +105,26 @@ struct Solid{F <: Modia3D.VarFloatType} <: Modia3D.AbstractObject3DFeature
contactMaterial = ""
end

if typeof(solidMaterial) == String && solidMaterial == ""
solidMaterial = nothing
end

if typeof(solidMaterial) == String
solidMaterial = solidMaterialPalette[1][solidMaterial]
end

if typeof(visualMaterial) == String
visualMaterial = Shapes.visualMaterialPalette[visualMaterial]
if typeof(visualMaterial) == String
visualMaterial = visualMaterial == "" ? Shapes.VisualMaterial() : Shapes.visualMaterialPalette[visualMaterial]
end

if typeof(shape) == FileMesh
(shape.centroid, shape.shortestEdge, shape.longestEdge, shape.objPoints, shape.facesIndizes) = getMeshInfos(shape.filename, shape.scaleFactor)
(shape.volume, shape.centroidAlgo, shape.inertia) = computeMassProperties(shape.objPoints, shape.facesIndizes; bodyCoords=false)
end

massProperties = createMassProperties(F, massProperties, shape, solidMaterial)
massProperties = isnothing(massProperties) && isnothing(solidMaterial) ? MassProperties{F}() : createMassProperties(F, massProperties, shape, solidMaterial)

contactSphereRadius::Union{Nothing,F} = isnothing(contactSphereRadius) || F(contactSphereRadius) <= F(0) ? nothing : F(contactSphereRadius)
(isFlat, contactSphereRadius) = setContactSphereRadius(shape, contactSphereRadius, F)
new(shape, solidMaterial, massProperties, collision, contactMaterial, setCollisionSmoothingRadius(shape, F(collisionSmoothingRadius)), visualMaterial, isFlat, contactSphereRadius)
end
Expand Down
3 changes: 2 additions & 1 deletion src/Shapes/visual.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
convertStringToVisualMaterial(visualMaterial::Shapes.VisualMaterial) = visualMaterial

convertStringToVisualMaterial(visualMaterial::AbstractString) = Shapes.visualMaterialPalette[visualMaterial]
convertStringToVisualMaterial(visualMaterial::AbstractString) = visualMaterial == "" ? Shapes.VisualMaterial() : Shapes.visualMaterialPalette[visualMaterial]


"""
Visual(;
Expand Down

0 comments on commit 4f32004

Please sign in to comment.