The code below helps to visualize the test I have made. The lines commented with "#~ " are the parts from the original file that builds the model. In the end, there is the code for loading the same model from a file that represents this example. After initializing the system, I still need to reset the state of two joints that I was expecting to have been recorded when the XML was first created.
Code: Select all
import opensim as osim
#~ arm = osim.Model()
#~ arm.setName("bicep_curl")
#~ arm.setUseVisualizer(True)
#~ # ---------------------------------------------------------------------------
#~ # Create two links, each with a mass of 1 kg, centre of mass at the body's
#~ # origin, and moments and products of inertia of zero.
#~ # ---------------------------------------------------------------------------
#~ humerus = osim.Body("humerus",
#~ 1.0,
#~ osim.Vec3(0),
#~ osim.Inertia(0, 0, 0))
#~ radius = osim.Body("radius",
#~ 1.0,
#~ osim.Vec3(0),
#~ osim.Inertia(0, 0, 0))
#~ # ---------------------------------------------------------------------------
#~ # Connect the bodies with pin joints. Assume each body is 1m long.
#~ # ---------------------------------------------------------------------------
#~ shoulder = osim.PinJoint("shoulder",
#~ arm.getGround(), # PhysicalFrame
#~ osim.Vec3(0),
#~ osim.Vec3(0),
#~ humerus, # PhysicalFrame
#~ osim.Vec3(0, 1, 0),
#~ osim.Vec3(0))
#~ elbow = osim.PinJoint("elbow",
#~ humerus, # PhysicalFrame
#~ osim.Vec3(0),
#~ osim.Vec3(0),
#~ radius, # PhysicalFrame
#~ osim.Vec3(0, 1, 0),
#~ osim.Vec3(0))
#~ # ---------------------------------------------------------------------------
#~ # Add a muscle that flexes the elbow (actuator for robotics people).
#~ # ---------------------------------------------------------------------------
#~ biceps = osim.Millard2012EquilibriumMuscle("biceps", # Muscle name
#~ 200.0, # Max isometric force
#~ 0.6, # Optimal fibre length
#~ 0.55, # Tendon slack length
#~ 0.0) # Pennation angle
#~ biceps.addNewPathPoint("origin",
#~ humerus,
#~ osim.Vec3(0, 0.8, 0))
#~ biceps.addNewPathPoint("insertion",
#~ radius,
#~ osim.Vec3(0, 0.7, 0))
#~ # ---------------------------------------------------------------------------
#~ # Add a controller that specifies the excitation of the muscle.
#~ # ---------------------------------------------------------------------------
#~ brain = osim.PrescribedController()
#~ brain.addActuator(biceps)
#~ brain.prescribeControlForActuator("biceps",
#~ osim.StepFunction(0.5, 3.0, 0.3, 1.0))
#~ # ---------------------------------------------------------------------------
#~ # Build model with components created above.
#~ # ---------------------------------------------------------------------------
#~ arm.addBody(humerus)
#~ arm.addBody(radius)
#~ arm.addJoint(shoulder) # Now required in OpenSim4.0
#~ arm.addJoint(elbow)
#~ arm.addForce(biceps)
#~ arm.addController(brain)
#~ # ---------------------------------------------------------------------------
#~ # Add a console reporter to print the muscle fibre force and elbow angle.
#~ # ---------------------------------------------------------------------------
#~ # We want to write our simulation results to the console.
#~ reporter = osim.ConsoleReporter()
#~ reporter.set_report_time_interval(1.0)
#~ reporter.addToReport(biceps.getOutput("fiber_force"))
#~ elbow_coord = elbow.getCoordinate().getOutput("value")
#~ reporter.addToReport(elbow_coord, "elbow_angle")
#~ arm.addComponent(reporter)
#~ # ---------------------------------------------------------------------------
#~ # Add display geometry.
#~ # ---------------------------------------------------------------------------
#~ bodyGeometry = osim.Ellipsoid(0.1, 0.5, 0.1)
#~ bodyGeometry.setColor(osim.Vec3(0.5)) # Gray
#~ humerusCenter = osim.PhysicalOffsetFrame()
#~ humerusCenter.setName("humerusCenter")
#~ humerusCenter.setParentFrame(humerus)
#~ humerusCenter.setOffsetTransform(osim.Transform(osim.Vec3(0, 0.5, 0)))
#~ humerus.addComponent(humerusCenter)
#~ humerusCenter.attachGeometry(bodyGeometry.clone())
#~ radiusCenter = osim.PhysicalOffsetFrame()
#~ radiusCenter.setName("radiusCenter")
#~ radiusCenter.setParentFrame(radius)
#~ radiusCenter.setOffsetTransform(osim.Transform(osim.Vec3(0, 0.5, 0)))
#~ radius.addComponent(radiusCenter)
#~ radiusCenter.attachGeometry(bodyGeometry.clone())
#~ # ---------------------------------------------------------------------------
#~ # Configure the model.
#~ # ---------------------------------------------------------------------------
#~ state = arm.initSystem()
#~ # Fix the shoulder at its default angle and begin with the elbow flexed.
#~ shoulder.getCoordinate().setLocked(state, True)
#~ elbow.getCoordinate().setValue(state, 0.5 * osim.SimTK_PI)
#~ arm.equilibrateMuscles(state)
#~ arm.printToXML('arm.xml')
# ---------------------------------------------------------------------------
# Loading model from XML
# ---------------------------------------------------------------------------
arm = osim.Model('arm.xml')
arm.setUseVisualizer(True)
state = arm.initSystem()
# ---------------------------------------------------------------------------
# Why do I need this? Isn't it recorded in the model?
# ---------------------------------------------------------------------------
shoulder = arm.updJointSet().get('shoulder')
elbow = arm.updJointSet().get('elbow')
shoulder.getCoordinate().setLocked(state, True)
elbow.getCoordinate().setValue(state, 0.5 * osim.SimTK_PI)
arm.equilibrateMuscles(state)
# ---------------------------------------------------------------------------
# Configure the visualizer.
# ---------------------------------------------------------------------------
viz = arm.updVisualizer().updSimbodyVisualizer()
viz.setBackgroundColor(osim.Vec3(0)) # white
viz.setGroundHeight(-2)
# ---------------------------------------------------------------------------
# Simulate.
# ---------------------------------------------------------------------------
manager = osim.Manager(arm)
state.setTime(0)
manager.initialize(state)
state = manager.integrate(10.0)