Skip to content

Commit fcd38b3

Browse files
Fix position/orientation results
- Enable position and orientation result signals for all user-defined Object3Ds, independently of visualisation/animation configuration - Replace orientation result matrix R_abs -> Cardan angles rot123_abs
1 parent 8f22b8f commit fcd38b3

File tree

20 files changed

+164
-192
lines changed

20 files changed

+164
-192
lines changed

docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ julia -JModia3D_sysimage.so (otherwise)
9999
- Add Result Element infrastructure and Result Element ContactResult
100100
- Bugfix: Correct parent Object3D torque calculation for Fix Joint with non-zero rotation
101101
- Bugfix: Enable AnimationExport in case of no renderer available
102+
- Bugfix: Enable position/orientation result signals independent of visualization/animation configuration
102103

103104

104105
### Version 0.12.1

docs/src/internal/Profiling.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ see next section.
6363
## logTiming
6464

6565
Function `simulate!(..., logTiming=true, ...)` has keyword argument `logTiming`. When set to true,
66-
the result of the `@timeit` macro of the [TimerOutputs](https://github.com/KristofferC/TimerOutputs.jl) package is shown. Function `simulate!(..)` and `Modia3D` are instrumented with this timer.
66+
the result of the `@timeit` macro of the [TimerOutputs](https://github.com/KristofferC/TimerOutputs.jl) package is shown. Function `simulate!(..)` and `Modia3D` are instrumented with this timer.
6767
Example:
6868

6969
```julia
@@ -164,16 +164,16 @@ is the following:
164164

165165
1. `1.363270 seconds` is the time for the first evaluation of `getDerivatives!`.
166166
This time is nearly completely used for compilation of this function
167-
167+
168168
2. `0.002773 seconds` is the time for the second evaluation of `getDerivatives!`.
169169
This time is nearly irrelevant for the timing of `@instantiateModel.`
170-
170+
171171
3. `2.540190` seconds is the total time spent in `@instantiateModel`, including the
172172
two calls of `getDerivatives!`. This time, together with (1.) shows the following:
173173
- `0.47*2.5 = 1.1` seconds are used to process the model, generate `getDerivatives!` and
174174
process `getDerivatives!` twice.
175175
- `0.53*2.5 = 1.32` seconds are used to compile `getDerivatives!`.
176-
176+
177177

178178
The meaning of column `Section` is the following:
179179

@@ -208,8 +208,8 @@ The meaning of column `Section` is the following:
208208
| `Modia3D_2 computeKinematics!` | Time to compute accelerations with qdd = unit vector. |
209209
| `Modia3D_2 computeForcesAndResiduals` | Time to compute forces/torques/residuals for M(q)*qdd. |
210210
| `Modia3D_3` | Time of `leq_mode == -1`. |
211-
| `Modia3D_3 visualize!` | Time of `for obj in updateVisuElements ... visualize(..)`. |
212-
| `Modia3D_3 exportAnimation` | Time of `for obj in allVisuElements ... push!(objectData, dat)` |
211+
| `Modia3D_3 visualize!` | Time of `for obj in visualObject3Ds ... visualize(..)`. |
212+
| `Modia3D_3 exportAnimation` | Time of `for obj in visualObject3Ds ... push!(objectData, dat)` |
213213
| `Modia3D_4 isTerminal` | Time of `exportAnimation` and `closeVisualization` during termination. |
214214

215215

src/AnimationExport/exportAnimation.jl

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,8 @@ end
436436

437437

438438
function exportAnimation(scene)
439-
allVisuElements = scene.allVisuElements
440-
if scene.exportAnimation && length(allVisuElements) > 0
439+
visualObject3Ds = scene.visualObject3Ds
440+
if scene.exportAnimation && length(visualObject3Ds) > 0
441441
animationFile = scene.options.animationFile
442442
(head,ext) = splitext(animationFile)
443443
if ext != ".json"
@@ -467,7 +467,7 @@ function exportAnimation(scene)
467467
if !isnothing(animation) && length(animation) != 0
468468
iobj = 0
469469
tracks = []
470-
for obj in allVisuElements
470+
for obj in visualObject3Ds
471471
iobj = iobj + 1
472472
(r_obj, R_obj) = printObjectToJSON(object, elements, obj, initPos=animation[1].objectData[iobj].position, initRot=Modia3D.from_q(animation[1].objectData[iobj].quaternion))
473473
if !isnothing(R_obj)
@@ -478,7 +478,7 @@ function exportAnimation(scene)
478478
animations = [(; name="Simulation", uuid=uuid, tracks)]
479479
scene = (; metadata, elements.geometries, elements.materials, elements.shapes, object, animations)
480480
else
481-
for obj in allVisuElements
481+
for obj in visualObject3Ds
482482
(r_obj, R_obj) = printObjectToJSON(object, elements, obj)
483483
end
484484
scene = (; metadata, elements.geometries, elements.materials, elements.shapes, object)
@@ -491,12 +491,3 @@ function exportAnimation(scene)
491491
println("done.")
492492
end
493493
end
494-
495-
496-
function Composition.isVisible(feature::Shapes.Solid{F}, exportAnimation::Bool) where F <: Modia3D.VarFloatType
497-
return exportAnimation && !isnothing(feature.shape) && !isnothing(feature.visualMaterial)
498-
end
499-
500-
function Composition.isVisible(feature::Shapes.Visual, exportAnimation::Bool)
501-
return exportAnimation && !isnothing(feature.visualMaterial) && !isnothing(feature.shape)
502-
end

src/Composition/assignObjects.jl

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
assignObj(scene, superObjType, obj, actPos) = nothing
22

3+
# assign obj to superObjType.superObj in case it can collide
34
function assignObj(scene::Scene{F}, superObjType::SuperObjCollision{F}, obj::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
45
if canCollide(obj)
56
push!(superObjType.superObj, obj)
67
end
78
return nothing
89
end
910

11+
# assign obj to superObjType.superObj in case it has mass
1012
function assignObj(scene::Scene{F}, superObjType::SuperObjMass{F}, obj::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
1113
if featureHasMass(obj)
1214
push!(superObjType.superObj, obj)
1315
end
1416
return nothing
1517
end
1618

19+
# assign obj to superObjType.superObj in case it can be moved
1720
function assignObj(scene::Scene{F}, superObjType::SuperObjMovable{F}, obj::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
1821
if isMovable(obj)
1922
push!(superObjType.superObj, obj)
@@ -26,56 +29,56 @@ function assignObj(scene::Scene{F}, superObjType::SuperObjMovable{F}, obj::Objec
2629
return nothing
2730
end
2831

32+
# assign obj to superObjType.superObj in case it can apply force/torque
2933
function assignObj(scene::Scene{F}, superObjType::SuperObjForce{F}, obj::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
3034
if canCollide(obj) || hasJoint(obj) || hasForceElement(obj)
3135
push!(superObjType.superObj, obj)
3236
end
3337
return nothing
3438
end
3539

36-
function assignObj(scene::Scene{F}, superObjType::SuperObjVisu{F}, obj::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
37-
renderer = Modia3D.renderer[1]
38-
if ( isVisible(obj, renderer) || isVisible(obj, scene.exportAnimation) || !isnothing(obj.visualizationFrame) ) && !hasJoint(obj) && !canCollide(obj) && !hasForceElement(obj) && !hasChildJoint(obj) #&& !hasCutJoint(obj) && !featureHasMass(obj)
39-
# if an Object3D is for visualization/animation export only it is stored in updateVisuElements
40-
if !(obj in scene.updateVisuElements)
41-
push!(scene.updateVisuElements, obj)
40+
# assign obj to scene.pureResultObject3Ds in case it is pure result or visualization
41+
function assignObj(scene::Scene{F}, superObjType::SuperObjResult{F}, obj::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
42+
if ( isUserDefined(obj) || isVisible(obj) || length(obj.visualizationFrame) > 0 ) && !hasJoint(obj) && !canCollide(obj) && !hasForceElement(obj) && !hasChildJoint(obj) #&& !hasCutJoint(obj) && !featureHasMass(obj)
43+
if !(obj in scene.pureResultObject3Ds)
44+
push!(scene.pureResultObject3Ds, obj)
4245
end
4346
end
4447
return nothing
4548
end
4649

47-
50+
# assign obj to field vectors of superObj
4851
function assignAll(scene::Scene{F}, superObj::SuperObjsRow{F}, obj::Object3D{F}, world::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
4952
names = fieldnames(typeof(superObj))
5053
for val in names
51-
tmp = getfield(superObj,val)
54+
tmp = getfield(superObj, val)
5255
obj.interactionManner.originPos = actPos
53-
assignObj(scene,tmp,obj,actPos)
56+
assignObj(scene, tmp, obj, actPos)
5457
end
5558
return nothing
5659
end
5760

5861

5962
function fillVisuElements!(scene::Scene{F}, obj::Object3D{F}, world::Object3D{F})::Nothing where F <: Modia3D.VarFloatType
60-
if scene.options.enableVisualization || scene.provideAnimationData
61-
if isNotCoordinateSystem(obj) && obj.visualizeFrame != Modia3D.False &&
62-
((scene.options.visualizeFrames && obj.visualizeFrame == Modia3D.Inherited) || obj.visualizeFrame == Modia3D.True)
63-
name = Symbol(obj.path, ".", "visualizationFrame")
64-
if obj != world
65-
addObject3DVisualizationFrame!(obj, scene.autoCoordsys, name)
66-
else
67-
addObject3DVisualizationFrame!(obj, Shapes.CoordinateSystem(length=2*scene.options.defaultFrameLength), name)
68-
end
69-
append!(scene.allVisuElements, obj.visualizationFrame)
70-
# if an Object3D is for visualization only it is stored in updateVisuElements
71-
if !(obj in scene.updateVisuElements)
72-
push!(scene.updateVisuElements, obj)
73-
end
63+
if isNotCoordinateSystem(obj) && obj.visualizeFrame != Modia3D.False &&
64+
((scene.options.visualizeFrames && obj.visualizeFrame == Modia3D.Inherited) || obj.visualizeFrame == Modia3D.True)
65+
name = Symbol(obj.path, ".", "visualizationFrame")
66+
if obj != world
67+
addObject3DVisualizationFrame!(obj, scene.autoCoordsys, name)
68+
else
69+
addObject3DVisualizationFrame!(obj, Shapes.CoordinateSystem(length=2*scene.options.defaultFrameLength), name)
7470
end
75-
if isVisible(obj, Modia3D.renderer[1]) || isVisible(obj, scene.exportAnimation) # visible in visualization or animation export
76-
push!(scene.allVisuElements, obj)
71+
append!(scene.visualObject3Ds, obj.visualizationFrame)
72+
if !(obj in scene.pureResultObject3Ds)
73+
push!(scene.pureResultObject3Ds, obj)
7774
end
7875
end
76+
if isVisible(obj)
77+
push!(scene.visualObject3Ds, obj)
78+
end
79+
if isUserDefined(obj)
80+
push!(scene.userDefinedObject3Ds, obj)
81+
end
7982
return nothing
8083
end
8184

src/Composition/dynamics.jl

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,13 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
202202
zStartIndex = 0
203203
end
204204

205+
# add r_abs and rot123_abs of all user-defined Object3Ds to results
205206
# objIndices[i,1]: Index of r_abs of Object3D i
206-
# [i,2]: Index of R_abs of Object3D i
207-
objIndices = Matrix{Int}(undef, length(scene.updateVisuElements), 2)
208-
for (i,obj) in enumerate(scene.updateVisuElements)
209-
if typeof(obj.feature) == Modia3D.Composition.EmptyObject3DFeature
210-
objIndices[i,1] = 0
211-
objIndices[i,2] = 0
212-
else
213-
objIndices[i,1] = Modia.new_w_segmented_variable!(partiallyInstantiatedModel, obj.path*".r_abs", Modia3D.ZeroVector3D(F), "m")
214-
objIndices[i,2] = Modia.new_w_segmented_variable!(partiallyInstantiatedModel, obj.path*".R_abs", Modia3D.NullRotation(F), "")
215-
end
207+
# [i,2]: Index of rot123_abs of Object3D i
208+
objIndices = Matrix{Int}(undef, length(scene.userDefinedObject3Ds), 2)
209+
for (i,obj) in enumerate(scene.userDefinedObject3Ds)
210+
objIndices[i,1] = Modia.new_w_segmented_variable!(partiallyInstantiatedModel, obj.path*".r_abs", Modia3D.ZeroVector3D(F), "m")
211+
objIndices[i,2] = Modia.new_w_segmented_variable!(partiallyInstantiatedModel, obj.path*".rot123_abs", Modia3D.ZeroVector3D(F), "rad")
216212
end
217213

218214
mbsBuild.mbs = MultibodyData{F,TimeType}(partiallyInstantiatedModel, modelPath, world, scene,
@@ -233,7 +229,7 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
233229
if scene.visualize && firstSegment
234230
TimerOutputs.@timeit partiallyInstantiatedModel.timer "Modia3D_0 initializeVisualization" Modia3D.Composition.initializeVisualization(Modia3D.renderer[1], scene)
235231
if partiallyInstantiatedModel.options.log
236-
println( " Modia3D: nVisualShapes = ", length(scene.allVisuElements))
232+
println( " Modia3D: nVisualShapes = ", length(scene.visualObject3Ds))
237233
if scene.options.enableContactDetection
238234
println(" mprTolerance = ", scene.options.contactDetection.tol_rel)
239235
println(" contact_eps = ", scene.options.contactDetection.contact_eps)
@@ -557,19 +553,13 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
557553
elseif leq_mode == -2
558554
# Compute only terms needed at a communication point (currently: Only visualization + export animation)
559555
TimerOutputs.@timeit instantiatedModel.timer "Modia3D_3" begin
560-
# objects can have interactionManner (need to rename updateVisuElements)
556+
# objects can have interactionManner
561557
if scene.options.useOptimizedStructure
562-
objIndices = mbs.objIndices
563-
for (i,obj) in enumerate(scene.updateVisuElements)
558+
for obj in scene.pureResultObject3Ds
564559
parent = obj.parent
565560
obj.r_abs = obj.r_rel Modia3D.ZeroVector3D(F) ? parent.r_abs : parent.r_abs + parent.R_abs'*obj.r_rel
566561
obj.R_abs = obj.R_rel Modia3D.NullRotation(F) ? parent.R_abs : obj.R_rel*parent.R_abs
567562

568-
if objIndices[i,1] > 0
569-
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,1], obj.r_abs)
570-
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,2], obj.R_abs)
571-
end
572-
573563
# is executed only if an internal Object3D called
574564
if length( obj.visualizationFrame ) == 1
575565
obj.visualizationFrame[1].r_abs = obj.r_abs
@@ -583,6 +573,15 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
583573
end
584574

585575
if storeResult && !isTerminalOfAllSegments
576+
# copy r_abs and rot123_abs of all user-defined Object3Ds to results
577+
objIndices = mbs.objIndices
578+
for (i, obj) in enumerate(scene.userDefinedObject3Ds)
579+
if objIndices[i,1] > 0
580+
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,1], obj.r_abs)
581+
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,2], Modia3D.rot123fromR(obj.R_abs))
582+
end
583+
end
584+
586585
# evaluate result elements
587586
for result in resultElements
588587
evaluateResultElement(instantiatedModel, scene, result, time)
@@ -606,7 +605,7 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
606605
if provideAnimationData
607606
TimerOutputs.@timeit instantiatedModel.timer "Modia3D_3 provideAnimationData" begin
608607
objectData = []
609-
for obj in scene.allVisuElements
608+
for obj in scene.visualObject3Ds
610609
pos = Modia3D.convertToFloat64(obj.r_abs)
611610
ori = Modia3D.from_R(Modia3D.convertToFloat64(obj.R_abs))
612611
dat = animationData(pos, ori)

src/Composition/handler.jl

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77

88

99
function build_tree!(scene::Scene{F}, world::Object3D{F})::Nothing where F <: Modia3D.VarFloatType
10-
tree = scene.tree
11-
stack = scene.stack
10+
tree = scene.tree
11+
stack = scene.stack
1212
allCollisionElements = scene.allCollisionElements
1313
empty!(tree)
1414
empty!(stack)
15-
empty!(scene.allVisuElements)
15+
empty!(scene.userDefinedObject3Ds)
16+
empty!(scene.visualObject3Ds)
17+
empty!(scene.pureResultObject3Ds)
1618
empty!(allCollisionElements)
1719

1820
fillVisuElements!(scene, world, world)
@@ -186,8 +188,10 @@ function build_superObjs!(scene::Scene{F}, world::Object3D{F})::Nothing where F
186188
treeAccVelo = scene.treeAccVelo
187189
empty!(stack)
188190
empty!(buffer)
189-
empty!(scene.allVisuElements)
190191
empty!(treeAccVelo)
192+
empty!(scene.userDefinedObject3Ds)
193+
empty!(scene.visualObject3Ds)
194+
empty!(scene.pureResultObject3Ds)
191195

192196
world.computeAcceleration = true
193197
world.isRootObj = true # all objs stored in buffer are root objs
@@ -434,19 +438,19 @@ function chooseAndBuildUpTree(world::Object3D{F}, scene::Scene{F}) where F <: Mo
434438
if scene.options.enableContactDetection && scene.collide
435439
initializeContactDetection!(world, scene)
436440
if length(world.contactVisuObj1) > 0
437-
append!(scene.allVisuElements, world.contactVisuObj1)
438-
append!(scene.allVisuElements, world.contactVisuObj2)
441+
append!(scene.visualObject3Ds, world.contactVisuObj1)
442+
append!(scene.visualObject3Ds, world.contactVisuObj2)
439443
end
440444
if length(world.supportVisuObj1A) > 0
441-
append!(scene.allVisuElements, world.supportVisuObj1A)
442-
append!(scene.allVisuElements, world.supportVisuObj2A)
443-
append!(scene.allVisuElements, world.supportVisuObj3A)
444-
append!(scene.allVisuElements, world.supportVisuObj1B)
445-
append!(scene.allVisuElements, world.supportVisuObj2B)
446-
append!(scene.allVisuElements, world.supportVisuObj3B)
445+
append!(scene.visualObject3Ds, world.supportVisuObj1A)
446+
append!(scene.visualObject3Ds, world.supportVisuObj2A)
447+
append!(scene.visualObject3Ds, world.supportVisuObj3A)
448+
append!(scene.visualObject3Ds, world.supportVisuObj1B)
449+
append!(scene.visualObject3Ds, world.supportVisuObj2B)
450+
append!(scene.visualObject3Ds, world.supportVisuObj3B)
447451
end
448452
if length(world.AABBVisu) > 0
449-
append!(scene.allVisuElements, world.AABBVisu)
453+
append!(scene.visualObject3Ds, world.AABBVisu)
450454
end
451455
end
452456
initializeMassComputation!(scene)
@@ -463,7 +467,7 @@ function chooseAndBuildUpTree(world::Object3D{F}, scene::Scene{F}) where F <: Mo
463467
scene.visualize = false
464468
scene.exportAnimation = false
465469
else
466-
if length(scene.allVisuElements) > 0
470+
if length(scene.visualObject3Ds) > 0
467471
scene.visualize = scene.options.enableVisualization
468472
else
469473
scene.visualize = false
@@ -503,13 +507,13 @@ end
503507
function emptyScene!(scene::Scene{F})::Nothing where F <: Modia3D.VarFloatType
504508
empty!(scene.stack)
505509
empty!(scene.buffer)
506-
507510
empty!(scene.superObjs)
508-
empty!(scene.updateVisuElements)
511+
empty!(scene.userDefinedObject3Ds)
512+
empty!(scene.visualObject3Ds)
513+
empty!(scene.pureResultObject3Ds)
514+
empty!(scene.allCollisionElements)
509515
empty!(scene.treeAccVelo)
510516
empty!(scene.tree)
511-
empty!(scene.allVisuElements)
512-
empty!(scene.allCollisionElements)
513517
empty!(scene.noCPairs)
514518
empty!(scene.noCPairsHelp)
515519
empty!(scene.allowedToMove)
@@ -527,7 +531,7 @@ end
527531
function closeAnalysis!(scene::Scene{F})::Nothing where F <: Modia3D.VarFloatType
528532
# Close Visualisation
529533
closeVisualization(Modia3D.renderer[1])
530-
empty!(scene.allVisuElements)
534+
empty!(scene.visualObject3Ds)
531535
scene.visualize = false
532536
# Close Collision detection
533537
if scene.collide

0 commit comments

Comments
 (0)