Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix position/orientation results #128

Merged
merged 3 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ FileIO = "1"
HTTP = "0.9"
JSON = "0.21"
Measurements = "2"
MeshIO = "0.4.10"
Modia = "0.12.0"
MeshIO = ">= 0.4.10"
Modia = "0.12.1"
MonteCarloMeasurements = "1"
OrderedCollections = "1"
Reexport = "1.0"
Expand Down
1 change: 1 addition & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ julia -JModia3D_sysimage.so (otherwise)
- Add Result Element infrastructure and Result Element ContactResult
- Bugfix: Correct parent Object3D torque calculation for Fix Joint with non-zero rotation
- Bugfix: Enable AnimationExport in case of no renderer available
- Bugfix: Enable position/orientation result signals independent of visualization/animation configuration


### Version 0.12.1
Expand Down
12 changes: 6 additions & 6 deletions docs/src/internal/Profiling.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ see next section.
## logTiming

Function `simulate!(..., logTiming=true, ...)` has keyword argument `logTiming`. When set to true,
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.
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.
Example:

```julia
Expand Down Expand Up @@ -164,16 +164,16 @@ is the following:

1. `1.363270 seconds` is the time for the first evaluation of `getDerivatives!`.
This time is nearly completely used for compilation of this function

2. `0.002773 seconds` is the time for the second evaluation of `getDerivatives!`.
This time is nearly irrelevant for the timing of `@instantiateModel.`

3. `2.540190` seconds is the total time spent in `@instantiateModel`, including the
two calls of `getDerivatives!`. This time, together with (1.) shows the following:
- `0.47*2.5 = 1.1` seconds are used to process the model, generate `getDerivatives!` and
process `getDerivatives!` twice.
- `0.53*2.5 = 1.32` seconds are used to compile `getDerivatives!`.


The meaning of column `Section` is the following:

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


Expand Down
20 changes: 6 additions & 14 deletions src/AnimationExport/exportAnimation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,9 @@ function createAnimationQuaternionTrack(object, animation, obj, iobj, R_obj::Not
end


function exportAnimation(scene)
allVisuElements = scene.allVisuElements
if scene.exportAnimation && length(allVisuElements) > 0
function exportAnimation(scene::Modia3D.Composition.Scene{F}) where F <: Modia3D.VarFloatType
visualObject3Ds = scene.visualObject3Ds
if scene.exportAnimation && length(visualObject3Ds) > 0
animationFile = scene.options.animationFile
(head,ext) = splitext(animationFile)
if ext != ".json"
Expand Down Expand Up @@ -467,7 +467,7 @@ function exportAnimation(scene)
if !isnothing(animation) && length(animation) != 0
iobj = 0
tracks = []
for obj in allVisuElements
for obj in visualObject3Ds
iobj = iobj + 1
(r_obj, R_obj) = printObjectToJSON(object, elements, obj, initPos=animation[1].objectData[iobj].position, initRot=Modia3D.from_q(animation[1].objectData[iobj].quaternion))
if !isnothing(R_obj)
Expand All @@ -478,7 +478,7 @@ function exportAnimation(scene)
animations = [(; name="Simulation", uuid=uuid, tracks)]
scene = (; metadata, elements.geometries, elements.materials, elements.shapes, object, animations)
else
for obj in allVisuElements
for obj in visualObject3Ds
(r_obj, R_obj) = printObjectToJSON(object, elements, obj)
end
scene = (; metadata, elements.geometries, elements.materials, elements.shapes, object)
Expand All @@ -490,13 +490,5 @@ function exportAnimation(scene)

println("done.")
end
end


function Composition.isVisible(feature::Shapes.Solid{F}, exportAnimation::Bool) where F <: Modia3D.VarFloatType
return exportAnimation && !isnothing(feature.shape) && !isnothing(feature.visualMaterial)
end

function Composition.isVisible(feature::Shapes.Visual, exportAnimation::Bool)
return exportAnimation && !isnothing(feature.visualMaterial) && !isnothing(feature.shape)
return nothing
end
53 changes: 28 additions & 25 deletions src/Composition/assignObjects.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
assignObj(scene, superObjType, obj, actPos) = nothing

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

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

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

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

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


# assign obj to field vectors of superObj
function assignAll(scene::Scene{F}, superObj::SuperObjsRow{F}, obj::Object3D{F}, world::Object3D{F}, actPos::Int64)::Nothing where F <: Modia3D.VarFloatType
names = fieldnames(typeof(superObj))
for val in names
tmp = getfield(superObj,val)
tmp = getfield(superObj, val)
obj.interactionManner.originPos = actPos
assignObj(scene,tmp,obj,actPos)
assignObj(scene, tmp, obj, actPos)
end
return nothing
end


function fillVisuElements!(scene::Scene{F}, obj::Object3D{F}, world::Object3D{F})::Nothing where F <: Modia3D.VarFloatType
if scene.options.enableVisualization || scene.provideAnimationData
if isNotCoordinateSystem(obj) && obj.visualizeFrame != Modia3D.False &&
((scene.options.visualizeFrames && obj.visualizeFrame == Modia3D.Inherited) || obj.visualizeFrame == Modia3D.True)
name = Symbol(obj.path, ".", "visualizationFrame")
if obj != world
addObject3DVisualizationFrame!(obj, scene.autoCoordsys, name)
else
addObject3DVisualizationFrame!(obj, Shapes.CoordinateSystem(length=2*scene.options.defaultFrameLength), name)
end
append!(scene.allVisuElements, obj.visualizationFrame)
# if an Object3D is for visualization only it is stored in updateVisuElements
if !(obj in scene.updateVisuElements)
push!(scene.updateVisuElements, obj)
end
if isNotCoordinateSystem(obj) && obj.visualizeFrame != Modia3D.False &&
((scene.options.visualizeFrames && obj.visualizeFrame == Modia3D.Inherited) || obj.visualizeFrame == Modia3D.True)
name = Symbol(obj.path, ".", "visualizationFrame")
if obj != world
addObject3DVisualizationFrame!(obj, scene.autoCoordsys, name)
else
addObject3DVisualizationFrame!(obj, Shapes.CoordinateSystem(length=2*scene.options.defaultFrameLength), name)
end
if isVisible(obj, Modia3D.renderer[1]) || isVisible(obj, scene.exportAnimation) # visible in visualization or animation export
push!(scene.allVisuElements, obj)
append!(scene.visualObject3Ds, obj.visualizationFrame)
if !(obj in scene.pureResultObject3Ds)
push!(scene.pureResultObject3Ds, obj)
end
end
if isVisible(obj)
push!(scene.visualObject3Ds, obj)
end
if isUserDefined(obj)
push!(scene.userDefinedObject3Ds, obj)
end
return nothing
end

Expand Down
39 changes: 19 additions & 20 deletions src/Composition/dynamics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,17 +202,13 @@ function initSegment_Model3D!(partiallyInstantiatedModel::Modia.InstantiatedMode
zStartIndex = 0
end

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

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

if objIndices[i,1] > 0
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,1], obj.r_abs)
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,2], obj.R_abs)
end

# is executed only if an internal Object3D called
if length( obj.visualizationFrame ) == 1
obj.visualizationFrame[1].r_abs = obj.r_abs
Expand All @@ -583,6 +573,15 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
end

if storeResult && !isTerminalOfAllSegments
# copy r_abs and rot123_abs of all user-defined Object3Ds to results
objIndices = mbs.objIndices
for (i, obj) in enumerate(scene.userDefinedObject3Ds)
if objIndices[i,1] > 0
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,1], obj.r_abs)
Modia.copy_w_segmented_value_to_result(instantiatedModel, objIndices[i,2], Modia3D.rot123fromR(obj.R_abs))
end
end

# evaluate result elements
for result in resultElements
evaluateResultElement(instantiatedModel, scene, result, time)
Expand All @@ -606,7 +605,7 @@ function computeGeneralizedForces!(mbs::MultibodyData{F,TimeType}, qdd_hidden::V
if provideAnimationData
TimerOutputs.@timeit instantiatedModel.timer "Modia3D_3 provideAnimationData" begin
objectData = []
for obj in scene.allVisuElements
for obj in scene.visualObject3Ds
pos = Modia3D.convertToFloat64(obj.r_abs)
ori = Modia3D.from_R(Modia3D.convertToFloat64(obj.R_abs))
dat = animationData(pos, ori)
Expand Down
42 changes: 23 additions & 19 deletions src/Composition/handler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@


function build_tree!(scene::Scene{F}, world::Object3D{F})::Nothing where F <: Modia3D.VarFloatType
tree = scene.tree
stack = scene.stack
tree = scene.tree
stack = scene.stack
allCollisionElements = scene.allCollisionElements
empty!(tree)
empty!(stack)
empty!(scene.allVisuElements)
empty!(scene.userDefinedObject3Ds)
empty!(scene.visualObject3Ds)
empty!(scene.pureResultObject3Ds)
empty!(allCollisionElements)

fillVisuElements!(scene, world, world)
Expand Down Expand Up @@ -186,8 +188,10 @@ function build_superObjs!(scene::Scene{F}, world::Object3D{F})::Nothing where F
treeAccVelo = scene.treeAccVelo
empty!(stack)
empty!(buffer)
empty!(scene.allVisuElements)
empty!(treeAccVelo)
empty!(scene.userDefinedObject3Ds)
empty!(scene.visualObject3Ds)
empty!(scene.pureResultObject3Ds)

world.computeAcceleration = true
world.isRootObj = true # all objs stored in buffer are root objs
Expand Down Expand Up @@ -434,19 +438,19 @@ function chooseAndBuildUpTree(world::Object3D{F}, scene::Scene{F}) where F <: Mo
if scene.options.enableContactDetection && scene.collide
initializeContactDetection!(world, scene)
if length(world.contactVisuObj1) > 0
append!(scene.allVisuElements, world.contactVisuObj1)
append!(scene.allVisuElements, world.contactVisuObj2)
append!(scene.visualObject3Ds, world.contactVisuObj1)
append!(scene.visualObject3Ds, world.contactVisuObj2)
end
if length(world.supportVisuObj1A) > 0
append!(scene.allVisuElements, world.supportVisuObj1A)
append!(scene.allVisuElements, world.supportVisuObj2A)
append!(scene.allVisuElements, world.supportVisuObj3A)
append!(scene.allVisuElements, world.supportVisuObj1B)
append!(scene.allVisuElements, world.supportVisuObj2B)
append!(scene.allVisuElements, world.supportVisuObj3B)
append!(scene.visualObject3Ds, world.supportVisuObj1A)
append!(scene.visualObject3Ds, world.supportVisuObj2A)
append!(scene.visualObject3Ds, world.supportVisuObj3A)
append!(scene.visualObject3Ds, world.supportVisuObj1B)
append!(scene.visualObject3Ds, world.supportVisuObj2B)
append!(scene.visualObject3Ds, world.supportVisuObj3B)
end
if length(world.AABBVisu) > 0
append!(scene.allVisuElements, world.AABBVisu)
append!(scene.visualObject3Ds, world.AABBVisu)
end
end
initializeMassComputation!(scene)
Expand All @@ -463,7 +467,7 @@ function chooseAndBuildUpTree(world::Object3D{F}, scene::Scene{F}) where F <: Mo
scene.visualize = false
scene.exportAnimation = false
else
if length(scene.allVisuElements) > 0
if length(scene.visualObject3Ds) > 0
scene.visualize = scene.options.enableVisualization
else
scene.visualize = false
Expand Down Expand Up @@ -503,13 +507,13 @@ end
function emptyScene!(scene::Scene{F})::Nothing where F <: Modia3D.VarFloatType
empty!(scene.stack)
empty!(scene.buffer)

empty!(scene.superObjs)
empty!(scene.updateVisuElements)
empty!(scene.userDefinedObject3Ds)
empty!(scene.visualObject3Ds)
empty!(scene.pureResultObject3Ds)
empty!(scene.allCollisionElements)
empty!(scene.treeAccVelo)
empty!(scene.tree)
empty!(scene.allVisuElements)
empty!(scene.allCollisionElements)
empty!(scene.noCPairs)
empty!(scene.noCPairsHelp)
empty!(scene.allowedToMove)
Expand All @@ -527,7 +531,7 @@ end
function closeAnalysis!(scene::Scene{F})::Nothing where F <: Modia3D.VarFloatType
# Close Visualisation
closeVisualization(Modia3D.renderer[1])
empty!(scene.allVisuElements)
empty!(scene.visualObject3Ds)
scene.visualize = false
# Close Collision detection
if scene.collide
Expand Down
Loading
Loading