Skip to content

Instantly share code, notes, and snippets.

@rdeits
Created May 25, 2018 15:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rdeits/91c13fc607c7ce606c940a4530a53273 to your computer and use it in GitHub Desktop.
Save rdeits/91c13fc607c7ce606c940a4530a53273 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from __future__ import division"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import opensim as osim\n",
"import math\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Part 1A: Create a Model object."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"model = osim.Model()\n",
"model.setName(\"leg\")\n",
"model.setUseVisualizer(True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Part 2: Create the thigh body."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"hipHeight = 1.0\n",
"linkLength = 0.5\n",
"linkMass = 5\n",
"thigh = osim.Body(\"thigh\", linkMass, osim.Vec3(0), osim.Inertia(1))\n",
"thigh.attachGeometry(osim.Ellipsoid(linkLength/10, linkLength/2, linkLength/10))\n",
"model.addBody(thigh)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Part 3: Create the hip joint."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"hip = osim.PinJoint(\"hip\",\n",
" model.getGround(), # parent body\n",
" osim.Vec3(0, hipHeight, 0), # location in parent\n",
" osim.Vec3(0), # orientation in child\n",
" thigh, # child body\n",
" osim.Vec3(0, linkLength/2, 0), # location in child\n",
" osim.Vec3(0) # orientation in child\n",
")\n",
"model.addJoint(hip)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Part 4: Set the default value of the hip coordinate to +90 degrees."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"hip.getCoordinate().setDefaultValue(0.5 * math.pi)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Part 8A: Lock the hip coordinate."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"hip.getCoordinate().setDefaultLocked(True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Part 5: Create the shank body and knee joint.\n",
"* Create a body named 'shank', with the same mass properties as the thigh.\n",
"* Attach the same ellipsoid geometry as for the thigh.\n",
"* Add the shank body to the model.\n",
"\n",
"\n",
"* Create a PinJoint named 'knee' Parent: thigh; child: shank.\n",
"* The location of the joint in the parent body is (0, -linkLength/2, 0).\n",
"* The location of the joint in the child body is (0, +linkLength/2, 0)."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"shank = osim.Body(\"shank\", linkMass, osim.Vec3(0), osim.Inertia(1))\n",
"shank.attachGeometry(osim.Ellipsoid(linkLength/10, linkLength/2, linkLength/10))\n",
"model.addBody(shank)\n",
"\n",
"knee = osim.PinJoint(\"knee\",\n",
" thigh, # parent body\n",
" osim.Vec3(0, -linkLength/2, 0), # location in parent\n",
" osim.Vec3(0), # orientation in child\n",
" shank, # child body\n",
" osim.Vec3(0, linkLength/2, 0), # location in child\n",
" osim.Vec3(0) # orientation in child\n",
")\n",
"model.addJoint(knee)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Part 8B: Set the default value of the knee coordinate."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"knee.getCoordinate().setDefaultValue(-0.5 * math.pi)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 6A: Add a vastus muscle (actuator)."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"vastus = osim.Millard2012EquilibriumMuscle()\n",
"vastus.setName(\"vastus\")\n",
"vastus.setMaxIsometricForce(500)\n",
"vastus.setOptimalFiberLength(0.19)\n",
"vastus.setTendonSlackLength(0.19)\n",
"\n",
"vastus.addNewPathPoint(\"origin\", thigh, osim.Vec3(linkLength/10, 0, 0))\n",
"insertion = osim.Vec3(0.75 * linkLength/10, 0.7 * linkLength/2, 0)\n",
"vastus.addNewPathPoint(\"insertion\", shank, insertion)\n",
"\n",
"model.addForce(vastus)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 7: The vastus muscle wraps over the knee cap."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"patella = osim.WrapCylinder()\n",
"patella.setName(\"patella\")\n",
"patella.set_translation(osim.Vec3(0, -linkLength/2, 0))\n",
"patella.set_radius(0.04)\n",
"patella.set_length(0.1)\n",
"patella.set_quadrant(\"x\")\n",
"thigh.addWrapObject(patella)\n",
"vastus.updGeometryPath().addPathWrap(patella)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 9: Add an open-loop controller for the muscle."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"brain = osim.PrescribedController()\n",
"brain.addActuator(vastus)\n",
"\n",
"# Between 0.3 and 0.35 seconds, excitation transitions from 0.05 to 0.5\n",
"brain.prescribeControlForActuator(\"vastus\", \n",
" osim.StepFunction(0.3, 0.35, 0.05, 0.5))\n",
"model.addController(brain)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 10A: Add reflex control (and disable the open-loop control)."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# Disable the open-loop control\n",
"brain.setEnabled(False)\n",
"\n",
"reflex = osim.ToyReflexController()\n",
"reflex.addActuator(vastus)\n",
"reflex.set_gain(40.0)\n",
"model.addController(reflex)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 11A: Add a reporter to obtain muscle behavior."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"o1 = vastus.getOutput(\"normalized_fiber_length\")"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"reporter = osim.TableReporter()\n",
"reporter.set_report_time_interval(0.01)\n",
"reporter.addToReport(vastus.getOutput(\"normalized_fiber_length\"), \"1m\")\n",
"reporter.addToReport(vastus.getOutput(\"active_force_length_multiplier\"), \"fl\")\n",
"model.addComponent(reporter)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 1B: Build the model and obtain its default state."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"state = model.initSystem()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 10B: Set the initial speed of the knee coordinate."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"knee.getCoordinate().setSpeedValue(state, -3.0) # units: radians per second"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 6B: Initialize the muscle fiber length state."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"model.equilibrateMuscles(state)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 1C: Simulate the model."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<opensim.simbody.State; proxy of <Swig Object of type 'SimTK::State *' at 0x7f0ddebaac90> >"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"osim.simulate(model, state, 3.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"### Part 11B: Plot muscle behavior."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"table = reporter.getTable()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"columns = {\n",
" \"1m\": table.getDependentColumn(\"1m\"),\n",
" \"fl\": table.getDependentColumn(\"fl\"),\n",
"}\n",
"signals = {\n",
" name: [col.getElt(i, 0) for i in range(col.nrow())] for (name, col) in columns.items()\n",
"}\n",
"t = list(table.getIndependentColumn())"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f0e0123c250>,\n",
" <matplotlib.lines.Line2D at 0x7f0de7d7b9d0>]"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f0de245d490>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(t, signals[\"1m\"], t, signals[\"fl\"])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
@chrisdembia
Copy link

Fantastic. Thanks for doing this @rdeits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment