MbdAnalysis (hwx.inspire.motion)#

class MbdAnalysis(mbdModel=None, outputPath=None)#

Bases: ModelListener

An analysis of the model using MotionSolve

Attribute Table#

Name

Type

analyzing

property

animating

property

animationRunning

property

endTime

property

loadRunData

bool

logInvalidation

bool

outputInterval

property

writeMsAfterAnalyze

bool

wrtPart

property

Method Table#

Name

Description

abortAnalysis (self)

Let the GUI abort the analysis

analyze (self, mbdModel=None, end=None, dtout=None, type=None, animate=None, validate=True, **kwds)

Run a analysis on the model

getAnimationRange (self)

getContactRunData (self, obj, component, frame=None)

Get run data from contact. Can request: location, normal, tangential,

getCurrent (ifvalid=True)

getOutputPath (self)

The directory for the solver output files

getRunComponent (self, name, obj=None)

Called from the PlotManager to return a RunObject Component from the

getRunComponentNames (self, obj, withPlotLabels=’flat’)

To see available components for use in getRunData.

getRunData (self, obj, component, units=None, frame=None)

Return the list of values for the specified obj.component

getRunObjects (self)

Return all of the RunObjects for this run

getRunPartPosition (self, part, frame)

Return a Matrix44 for the part at the specified frame

getRunPosition (self, part, frame, pos=None)

Return the specified position wrt the part at the frame

getRunPositions (self, part, startFrame=0)

Get list of part positions at every time step

getRunTimeFrames (self, static=True, intermediate=True, animationRange=False)

Return a list of output time frames

getRunTimeSteps (self, convertUnits=True)

Return the time data for this run

getRunTimeStepsForGui (self, **kwds)

Return a filtered list of time steps for animation

getSystemRunPositions (self, system, startFrame=0)

Get list of system positions at every time step

getTypeOfRunContactData (self)

Used by the ForceDrawer to determine of it can sum the vectors

hasRunData (self, obj)

Any run data for the specified object?

isValid (self)

Did the analyze succeed in getting results

load (fname=None)

Reload a saved analysis

makeInvalid (self)

onIntegrationStepDoneCB (self)

Called at each integration step, updates the gui so the user can

onObjectCreated (self, obj)

onObjectDeleted (self, obj)

onObjectModified (self, obj, attr)

onSensorTriggered (self, **kwds)

Called by MbdModel when a sensor is triggered

onSolverMessageCB (self, msg)

onTimeStepDoneCB (self)

Called at each output step, updates inspire part positions from the

openHG (self)

Opens the current analyis results file in HG. Requires analysis to be run

openHV (self)

Opens the current analyis results file in HV. Requires analysis to be run

resetTheModel (self, redraw=True)

Called when analysis is done to reset model positions

save (self, fname=None)

Save the run to a file so it can be reloaded without running an analysys

setAnimationRange (self, enabled=None, startFrame=None, endFrame=None)

Called from the ReviewContext animation toolbar when the user

setPositionsAtFrame (self, frame)

Set animation position of all the inspire parts to the specified frame.

setupEvent (mbdModel=None, end=None, dtout=None, type=None)

Creates and returns an mbd.Event populated with input arguments if

updateModelPositions (self, updateSpringPreloads=True)

Set the design space positions of all the inspire parts to their position

updateSpringPreloads (self, frame)

usingUnits (self)

Context manager to use when working with analysis run data. E.g.

writePartDependentsLocations (self, part, file)

Write the locations of the i and j markers of the objects that are

Example

from hwx import inspire
from hwx.inspire import motion

model = inspire.openTutorialFile("Motion/M01_FourBar.stmod")
analysis = motion.MbdAnalysis()
analysis.analyze()

motor = model.getChild('Motor 1')
spring = model.getChild('Coil Spring 1')
#the pin connecting the Link Single Slot to the Link Dual Slot
joint = model.getChild('Joint 2')

# to see available choices do
# print(analysis.run.components.get(motor))
torque = analysis.getRunData(motor, 'motor.output.Torque', units='torque')

# to see available choices do
# print(analysis.run.components.get(spring))
springFM = analysis.getRunData(spring, 'FORCE.FM', units='force')
springFX = analysis.getRunData(spring, 'FORCE.FX', units='force')
springFY = analysis.getRunData(spring, 'FORCE.FY', units='force')
springFZ = analysis.getRunData(spring, 'FORCE.FZ', units='force')

# to see available choices do
# print(analysis.run.components.get(joint))
jointFM = analysis.getRunData(joint, 'FORCE.FM', units='force')
jointFX = analysis.getRunData(joint, 'FORCE.FX', units='force')
jointFY = analysis.getRunData(joint, 'FORCE.FY', units='force')
jointFZ = analysis.getRunData(joint, 'FORCE.FZ', units='force')

time = analysis.getRunTimeSteps()

# Let's plot Torque and Force
from hwx import gui
from hwx.gui.XyPlot import XyPlot

plot1 = XyPlot(
   title='{}Motor - Torque Required'.format(motor.name),
   xlabel="Time (s)",
   ylabel="Torque (N*m)",
   footer="Analysis Type: {}".format(
         model.motionAnalysisSettings.analysisType)
)
plot1.addCurve(x=time, y=torque, label='Torque')

plot2 = XyPlot(
   title='{}Force'.format(spring.name),
   xlabel="Time (s)",
   ylabel="Force (N)",
   footer="Analysis Type: {}".format(
         model.motionAnalysisSettings.analysisType)
)
plot2.addCurve(x=time, y=springFM, label='FM')
plot2.addCurve(x=time, y=springFX, label='FX')
plot2.addCurve(x=time, y=springFY, label='FY')
plot2.addCurve(x=time, y=springFZ, label='FZ')

plot3 = XyPlot(
   title='{}Force'.format(joint.name),
   xlabel="Time (s)",
   ylabel="Force (N)",
   footer="Analysis Type: {}".format(
         model.motionAnalysisSettings.analysisType)
)
plot3.addCurve(x=time, y=jointFM, label='FM')
plot3.addCurve(x=time, y=jointFX, label='FX')
plot3.addCurve(x=time, y=jointFY, label='FY')
plot3.addCurve(x=time, y=jointFZ, label='FZ')

frame = gui.HFrame(children=[plot1, plot2, plot3], minimumHeight=250)

show(frame)
analyze(mbdModel=None, end=None, dtout=None, type=None, animate=None, validate=True, **kwds)#

Run a analysis on the model

end[float] : Number of seconds to run the analysis. dtout[float] : Time between consecutive output steps. type[str] : TRANSIENT or STATICS or “STATICS TRANSIENT”. validate[bool] : Call valdidateMdb on the model, if there are

any errors or warnings dont analyze.

animate[bool] : Update part positions and redraw. **kwds : Passed to MbdModel constructor.

save(fname=None)#

Save the run to a file so it can be reloaded without running an analysys

abortAnalysis()#

Let the GUI abort the analysis

isValid()#

Did the analyze succeed in getting results

setPositionsAtFrame(frame)#

Set animation position of all the inspire parts to the specified frame.

Pass None to exit animation and reset the model

property wrtPart#

(inspire.Part | None) Animate parts relative to a reference part when calling setPositionsAtFrame.

resetTheModel(redraw=True)#

Called when analysis is done to reset model positions

updateModelPositions(updateSpringPreloads=True)#

Set the design space positions of all the inspire parts to their position in the current analysis frame

Spring preloads can also be updated

setAnimationRange(enabled=None, startFrame=None, endFrame=None)#

Called from the ReviewContext animation toolbar when the user changes the animation range.

openHG()#

Opens the current analyis results file in HG. Requires analysis to be run in same session.

openHV()#

Opens the current analyis results file in HV. Requires analysis to be run in same session.

usingUnits()#

Context manager to use when working with analysis run data. E.g. - Creating / updating core objects using run data - Get unit labels for showing run data in the gui

onIntegrationStepDoneCB()#

Called at each integration step, updates the gui so the user can abort the simulation

onTimeStepDoneCB()#

Called at each output step, updates inspire part positions from the ‘solved’ mbd part positions from MotionSolve and calls user’s onTimeStepDone, which can redraw model or process GUI inputs

exception SensorMessage(**kwds)#

Bases: Problem

onSensorTriggered(**kwds)#

Called by MbdModel when a sensor is triggered

getOutputPath()#

The directory for the solver output files generated from “Run history path in the settings made unique from the model name and a time stamp

onObjectCreated(obj)#

Implement if interested when an object is created.

Not directly supported for Features but you can detect geometry changes

using onObjectModified of the Part.features attribute.

This can be caused by:
  • Explicit object creation.

  • Undo of destroy.

  • Rollback/forward of construction history.

Parameters:

obj (Named) –

onObjectDeleted(obj)#

Implement if interested when an object is destroyed.

This can be caused by:
  • Explicit obj.destroy()

  • Undo of create.

  • Rollback/forward of construction history.

Parameters:

obj (Named) –

onObjectModified(obj, attr)#

Implement if interested when an object’s attribute value changes.

Parameters:
  • obj (Named) – Object whose attribute got modified. Check if attr == ‘features’ to react to geometry changes.

  • attr (str) – Name of attribute like ‘mass’, ‘name’, …

hasRunData(obj)#

Any run data for the specified object?

getRunTimeSteps(convertUnits=True)#

Return the time data for this run Useful for a plotting time in the X axis

getRunTimeFrames(static=True, intermediate=True, animationRange=False)#

Return a list of output time frames This is a derived list of derived doubles It looks like the run timeSteps with additional functionality to make it useful in animation and plotting: it supports usingUnits can be filter out static and or intermediate (contact) steps can be trimmed to the range in the ReviewContext animation bar

getRunTimeStepsForGui(**kwds)#

Return a filtered list of time steps for animation

the static steps are removed and if motionReviewsSettings.showOutputOnly the contact frames are removed

The returned list an instance of TimeFrames which is derived from list with extra functionality to map the filtered time steps to the true time steps. This so we can pass the list to the analimation frame as the time values, and when the user drags the animation tool bar slider we can get the true animation frame for setting the models part positions

use self.getRunTimeSteps for things like plotting where the number of xs need to match the number of ys since we dont filter non-time run data

getRunObjects()#

Return all of the RunObjects for this run Used by MotionSolve.py to populate the compomemnts at each output step

getRunPartPosition(part, frame)#

Return a Matrix44 for the part at the specified frame Used by MbdLoads to position transforce vectors to design position

getRunPosition(part, frame, pos=None)#

Return the specified position wrt the part at the frame Used by Loads, Traceers, … to calculate a point on a part at a time

getRunPositions(part, startFrame=0)#

Get list of part positions at every time step

getSystemRunPositions(system, startFrame=0)#

Get list of system positions at every time step

getRunComponentNames(obj, withPlotLabels='flat')#

To see available components for use in getRunData.

Parameters:
  • obj (Named) –

  • withPlotLabels (bool | 'flat') – Useful to find component name for a specific curve in Plot Manager.

Returns:

list[str]: Flat list of names elif withPlotLabels == ‘flat’:

dict[str, str]: Label => component name.

elif withPlotLabels:

Tree of dicts with component names as leaves.

Return type:

if not withPlotLabels

getRunComponent(name, obj=None)#

Called from the PlotManager to return a RunObject Component from the specified name

getRunData(obj, component, units=None, frame=None)#

Return the list of values for the specified obj.component

Parameters:
  • obj (Named) –

  • component (str) – Dot separated name identifying the component. Use getRunComponentNames to see list of valid options.

  • units (bool) – True converts values to base units or current inspire.usingUnits. False does no unit conversions and values are returned in solver units.

  • frame (None | int) –

    If you need data for a specific frame.

    Avoids doing unnecessary unit conversions for other frames.

    To get the force magnitude for a CoilSpring

    self.getRunData (spring, “FORCE.FM”, ‘force’)

Returns:

float if frame passed else list[float].

An empty list if the data can not be found because the component is invalid or the Requests are turned off.

getContactRunData(obj, component, frame=None)#

Get run data from contact. Can request: location, normal, tangential, regionLocation, regionNormal, regionTangential, off of a Contact object.

getTypeOfRunContactData()#

Used by the ForceDrawer to determine of it can sum the vectors Can not rely on the settings to because we have to support backward compatability

writePartDependentsLocations(part, file)#

Write the locations of the i and j markers of the objects that are dependent on self.part