Skip to content

Commit 504a0bd

Browse files
Introduce basic result element infrastructure
- Add abstract type AbstractResultElement. - Generate list of result element objects during MBS initialization stored in scene. - Call basic result element functions: * initializeResultElement(model, result) once before simulation. * evaluateResultElement(model, scene, result, time) in every communication point evaluation. * terminateResultElement(result) once after simulation.
1 parent e93763b commit 504a0bd

File tree

3 files changed

+48
-21
lines changed

3 files changed

+48
-21
lines changed

src/Composition/dynamics.jl

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
function getJointsAndForceElementsAndObject3DsWithoutParents!(evaluatedParameters::AbstractDict,
2-
object3DWithoutParents::Vector{Object3D{F}},
3-
revoluteObjects::Vector{Object3D{F}},
4-
prismaticObjects::Vector{Object3D{F}},
5-
freeMotionObjects::Vector{Object3D{F}},
6-
hiddenJointObjects::Vector{Object3D{F}},
7-
forceElements::Vector{Modia3D.AbstractForceElement},
8-
path::String)::Nothing where F <: Modia3D.VarFloatType
1+
function getJointsAndForceElementsAndResultElementsAndObject3DsWithoutParents!(evaluatedParameters::AbstractDict,
2+
object3DWithoutParents::Vector{Object3D{F}},
3+
revoluteObjects::Vector{Object3D{F}},
4+
prismaticObjects::Vector{Object3D{F}},
5+
freeMotionObjects::Vector{Object3D{F}},
6+
hiddenJointObjects::Vector{Object3D{F}},
7+
forceElements::Vector{Modia3D.AbstractForceElement},
8+
resultElements::Vector{Modia3D.AbstractResultElement},
9+
path::String)::Nothing where F <: Modia3D.VarFloatType
910
for (key,value) in evaluatedParameters
1011
#println("$path.$key = $value")
1112
if typeof(value) <: Object3D
@@ -34,10 +35,14 @@ function getJointsAndForceElementsAndObject3DsWithoutParents!(evaluatedParameter
3435
elseif typeof(value) <: Modia3D.AbstractForceElement
3536
push!(forceElements, value)
3637

38+
elseif typeof(value) <: Modia3D.AbstractResultElement
39+
push!(resultElements, value)
40+
3741
elseif typeof(value) <: OrderedDict
3842
value1::OrderedDict = value
39-
getJointsAndForceElementsAndObject3DsWithoutParents!(value1, object3DWithoutParents, revoluteObjects, prismaticObjects,
40-
freeMotionObjects, hiddenJointObjects, forceElements, path*"."*string(key))
43+
getJointsAndForceElementsAndResultElementsAndObject3DsWithoutParents!(value1, object3DWithoutParents, revoluteObjects, prismaticObjects,
44+
freeMotionObjects, hiddenJointObjects, forceElements, resultElements,
45+
path*"."*string(key))
4146
end
4247
end
4348
return nothing
@@ -57,15 +62,17 @@ Recursively traverse model mbsRoot and perform the following actions:
5762
- Check that only `world` has a `feature` entry that is a SceneOption.
5863
- Return (world, revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects, forceElements)
5964
"""
60-
function checkMultibodySystemAndGetWorldAndJointsAndForceElements(instantiatedModelName, mbsRoot, mbsPath::String, FloatType::Type)
65+
function checkMultibodySystemAndGetWorldAndJointsAndForceElementsAndResultElements(instantiatedModelName, mbsRoot, mbsPath::String, FloatType::Type)
6166
object3DWithoutParents = Object3D{FloatType}[]
6267
revoluteObjects = Object3D{FloatType}[]
6368
prismaticObjects = Object3D{FloatType}[]
6469
freeMotionObjects = Object3D{FloatType}[]
6570
hiddenJointObjects = Object3D{FloatType}[]
6671
forceElements = Modia3D.AbstractForceElement[]
67-
getJointsAndForceElementsAndObject3DsWithoutParents!(mbsRoot, object3DWithoutParents, revoluteObjects, prismaticObjects,
68-
freeMotionObjects, hiddenJointObjects, forceElements, mbsPath)
72+
resultElements = Modia3D.AbstractResultElement[]
73+
getJointsAndForceElementsAndResultElementsAndObject3DsWithoutParents!(mbsRoot, object3DWithoutParents, revoluteObjects, prismaticObjects,
74+
freeMotionObjects, hiddenJointObjects, forceElements, resultElements,
75+
mbsPath)
6976

7077
if length(object3DWithoutParents) == 0
7178
error("\n", multiBodyName(instantiatedModelName, mbsPath), ": There is either no Object3D or all of them have a parent!\n",
@@ -79,7 +86,7 @@ function checkMultibodySystemAndGetWorldAndJointsAndForceElements(instantiatedMo
7986
"(note, there must be exactly one Object3D that has no parent and feature=Scene(..)):\n", object3DNames, "\n")
8087
end
8188
world = object3DWithoutParents[1]
82-
return (world, revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects, forceElements)
89+
return (world, revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects, forceElements, resultElements)
8390
end
8491

8592

@@ -122,7 +129,7 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
122129

123130
if isnothing(mbsBuild.mbs) || partiallyInstantiatedModel.nsegments == 1
124131
firstSegment = true
125-
(world, revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects, forceElements) = checkMultibodySystemAndGetWorldAndJointsAndForceElements(partiallyInstantiatedModel.modelName, parameters, modelPath, F)
132+
(world, revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects, forceElements, resultElements) = checkMultibodySystemAndGetWorldAndJointsAndForceElementsAndResultElements(partiallyInstantiatedModel.modelName, parameters, modelPath, F)
126133

127134
# Set timer in scene (so that timer is easily available in Modia3D functions)
128135

@@ -132,7 +139,7 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
132139
end
133140

134141
# Construct MultibodyData
135-
scene = initAnalysis2!(world,partiallyInstantiatedModel.timer)
142+
scene = initAnalysis2!(world, partiallyInstantiatedModel.timer)
136143
else
137144
firstSegment = false
138145
world::Object3D{F} = mbsBuild.mbs.world
@@ -146,7 +153,7 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
146153
# printWarnGrip(robotOrDepot, movableObj, waitingPeriod)
147154
end
148155

149-
(worldDummy, revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects, forceElements) = checkMultibodySystemAndGetWorldAndJointsAndForceElements(partiallyInstantiatedModel.modelName, parameters, modelPath, F)
156+
(worldDummy, revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects, forceElements, resultElements) = checkMultibodySystemAndGetWorldAndJointsAndForceElementsAndResultElements(partiallyInstantiatedModel.modelName, parameters, modelPath, F)
150157

151158
# Set timer in scene (so that timer is easily available in Modia3D functions)
152159

@@ -164,7 +171,13 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
164171
end
165172
end
166173

174+
# Initialize result elements
175+
for result in resultElements
176+
initializeResultElement(partiallyInstantiatedModel, result)
177+
end
178+
167179
scene.forceElements = forceElements
180+
scene.resultElements = resultElements
168181
if scene.options.enableContactDetection && scene.collide
169182
nz = 2
170183
zStartIndex = Modia.new_z_segmented_variable!(partiallyInstantiatedModel, nz)
@@ -183,10 +196,10 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
183196
objIndices[i,2] = 0
184197
else
185198
objIndices[i,1] = Modia.new_w_segmented_variable!(partiallyInstantiatedModel, obj.path*".r_abs", Modia3D.ZeroVector3D(F), "m")
186-
objIndices[i,2] = Modia.new_w_segmented_variable!(partiallyInstantiatedModel, obj.path*".R_abs", Modia3D.NullRotation(F), "")
199+
objIndices[i,2] = Modia.new_w_segmented_variable!(partiallyInstantiatedModel, obj.path*".R_abs", Modia3D.NullRotation(F), "")
187200
end
188-
end
189-
201+
end
202+
190203
mbsBuild.mbs = MultibodyData{F,TimeType}(partiallyInstantiatedModel, modelPath, world, scene,
191204
revoluteObjects, prismaticObjects, freeMotionObjects, hiddenJointObjects,
192205
mbsBuild.revoluteIndices, mbsBuild.prismaticIndices, mbsBuild.freeMotionIndices,
@@ -420,6 +433,7 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
420433

421434
tree = scene.treeForComputation
422435
forceElements = scene.forceElements
436+
resultElements = scene.resultElements
423437
visualize = scene.visualize # && sim.model.visualiz
424438
exportAnimation = scene.exportAnimation
425439
provideAnimationData = scene.provideAnimationData
@@ -429,6 +443,9 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
429443
for force in forceElements
430444
terminateForceElement(force)
431445
end
446+
for result in resultElements
447+
terminateResultElement(result)
448+
end
432449
if exportAnimation
433450
TimerOutputs.@timeit instantiatedModel.timer "Modia3D_4b exportAnimation" Modia3D.exportAnimation(scene)
434451
end
@@ -537,7 +554,7 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
537554
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,1], obj.r_abs)
538555
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,2], obj.R_abs)
539556
end
540-
557+
541558
# is executed only if an internal Object3D called
542559
if length( obj.visualizationFrame ) == 1
543560
obj.visualizationFrame[1].r_abs = obj.r_abs
@@ -550,6 +567,13 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
550567
end
551568
end
552569

570+
if storeResult && !isTerminalOfAllSegments
571+
# evaluate result elements
572+
for result in resultElements
573+
evaluateResultElement(instantiatedModel, scene, result, time)
574+
end
575+
end
576+
553577
if storeResult && !isTerminalOfAllSegments && (visualize || provideAnimationData)
554578
if abs(instantiatedModel.options.startTimeFirstSegment + scene.outputCounter*instantiatedModel.options.interval - time) < 1.0e-6*(abs(time) + 1.0)
555579
# Visualize at a communication point

src/Composition/scene.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ mutable struct Scene{F <: Modia3D.VarFloatType} <: Modia3D.AbstractScene
420420
AABB::Vector{Vector{Basics.BoundingBox{F}}} # Bounding boxes of elements that can collide
421421
zStartIndex::Int # start index of collision zero crossing functions
422422
forceElements::Vector{Modia3D.AbstractForceElement}
423+
resultElements::Vector{Modia3D.AbstractResultElement}
423424
provideAnimationData::Bool # = true, if animation data shall be provided
424425
exportAnimation::Bool # animation file export is enabled
425426
animation::Vector{animationStep} # animation data of visible Object3Ds
@@ -516,6 +517,7 @@ mutable struct Scene{F <: Modia3D.VarFloatType} <: Modia3D.AbstractScene
516517
Vector{Vector{Basics.BoundingBox{F}}}[],
517518
1,
518519
Vector{Modia3D.AbstractForceElement}[],
520+
Vector{Modia3D.AbstractResultElement}[],
519521
provideAnimationData,
520522
exportAnimation,
521523
Vector{animationStep}[],

src/Modia3D.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ abstract type AbstractObject3D end
2222
abstract type AbstractTwoObject3DObject <: AbstractObject3D end # Object related to two Object3Ds
2323
abstract type AbstractJoint <: AbstractTwoObject3DObject end # Constraint between two Object3Ds
2424
abstract type AbstractForceElement <: AbstractObject3D end
25+
abstract type AbstractResultElement <: AbstractObject3D end
2526

2627
abstract type AbstractScene end
2728
abstract type AbstractMassProperties end

0 commit comments

Comments
 (0)