{"action":"created","comment":{"url":"https://api.github.com/repos/opensim-org/opensim-core/pulls/comments/80708126","pull_request_review_id":1745913,"id":80708126,"diff_hunk":"@@ -0,0 +1,1234 @@\n+/* -------------------------------------------------------------------------- *\n+ *                      OpenSim:  VandenBogert.cpp                            *\n+ * -------------------------------------------------------------------------- */\n+\n+\n+//=============================================================================\n+// INCLUDES\n+//=============================================================================\n+#include \"VandenBogert2011Muscle.h\"\n+#include <OpenSim/Simulation/Model/Model.h>\n+\n+\n+//=============================================================================\n+// STATICS\n+//=============================================================================\n+using namespace std;\n+using namespace OpenSim;\n+\n+\n+\n+//=============================================================================\n+// CONSTRUCTOR(S) AND DESTRUCTOR\n+//=============================================================================\n+//_____________________________________________________________________________\n+/*\n+ * Default constructor\n+ */\n+VandenBogert2011Muscle::VandenBogert2011Muscle()\n+{\n+    constructProperties();\n+}\n+\n+//_____________________________________________________________________________\n+/*\n+ * Constructor.\n+ */\n+\n+VandenBogert2011Muscle::VandenBogert2011Muscle(const std::string& aName)\n+{\n+    setName(aName);\n+    constructProperties();\n+}\n+\n+//_____________________________________________________________________________\n+/*\n+ * Construct and initialize properties.\n+ * All properties are added to the property set. Once added, they can be\n+ * read in and written to files.\n+ */\n+void VandenBogert2011Muscle::constructProperties()\n+{\n+    setAuthors(\"A. van den Bogert, B. Humphreys, C. Dembia\");\n+    //constructProperty_max_isometric_force(1000);\n+    constructProperty_fMaxTendonStrain(0.033);\n+    constructProperty_fl_width(0.63);\n+    constructProperty_fv_AHill(0.25);\n+    constructProperty_fv_maxMultiplier(1.5);\n+    //constructProperty_optimal_fiber_length(0.1);\n+    constructProperty_dampingCoefficient(0.01);\n+    constructProperty_normFiberSlackLength(1.0);\n+    //constructProperty_tendon_slack_length(0.2);\n+    constructProperty_activTimeConstant(0.01);\n+    constructProperty_deactivTimeConstant(0.04);\n+    constructProperty_pennAtOptFiberLength(0);\n+    constructProperty_defaultActivation(0.1);\n+    constructProperty_default_fiber_length(1.0);\n+}\n+\n+\n+//--------------------------------------------------------------------------\n+// GET & SET Properties\n+//--------------------------------------------------------------------------\n+\n+\n+void VandenBogert2011Muscle::setFMaxTendonStrain(double fMaxTendonStrain) {\n+    set_fMaxTendonStrain(fMaxTendonStrain); }\n+double VandenBogert2011Muscle::getFMaxTendonStrain() const {\n+     return get_fMaxTendonStrain(); }\n+\n+void VandenBogert2011Muscle::setFlWidth(double flWidth) {\n+     set_fl_width(flWidth); }\n+double VandenBogert2011Muscle::getFlWidth() const\n+    { return get_fl_width(); }\n+\n+void VandenBogert2011Muscle::setFvAHill(double fvAHill) {\n+    set_fv_AHill(fvAHill); }\n+double VandenBogert2011Muscle::getFvAHill() const {\n+     return get_fv_AHill(); }\n+\n+void VandenBogert2011Muscle::setFvmaxMultiplier(double fvMaxMultiplier) {\n+     set_fv_maxMultiplier(fvMaxMultiplier); }\n+double VandenBogert2011Muscle::getFvmaxMultiplier() const {\n+     return get_fv_maxMultiplier(); }\n+\n+void VandenBogert2011Muscle::setDampingCoefficient(double dampingCoefficient) {\n+     set_dampingCoefficient(dampingCoefficient); }\n+double VandenBogert2011Muscle::getDampingCoefficient() const {\n+     return get_dampingCoefficient(); }\n+\n+void VandenBogert2011Muscle::setNormFiberSlackLength(double\n+                                                     normFiberSlackLength) {\n+     set_normFiberSlackLength(normFiberSlackLength); }\n+double VandenBogert2011Muscle::getNormFiberSlackLength() const {\n+     return get_normFiberSlackLength(); }\n+\n+void VandenBogert2011Muscle::setActivTimeConstant(double activTimeConstant) {\n+     set_activTimeConstant(activTimeConstant); }\n+double VandenBogert2011Muscle::getActivTimeConstant() const {\n+     return get_activTimeConstant(); }\n+\n+void VandenBogert2011Muscle::setDeactivTimeConstant(double\n+                                                    deactivTimeConstant) {\n+     set_deactivTimeConstant(deactivTimeConstant); }\n+double VandenBogert2011Muscle::getDeactivTimeConstant() const {\n+     return get_deactivTimeConstant(); }\n+\n+void VandenBogert2011Muscle::setPennAtOptFiberLength(double\n+                                                     pennAtOptFiberLength) {\n+    set_pennAtOptFiberLength(pennAtOptFiberLength); }\n+double VandenBogert2011Muscle::getPennAtOptFiberLength() const {\n+    return get_pennAtOptFiberLength(); }\n+\n+\n+void VandenBogert2011Muscle::setDefaultActivation(double\n+                                                     defaultActivation) {\n+    set_defaultActivation(defaultActivation); }\n+double VandenBogert2011Muscle::getDefaultActivation() const {\n+    return get_defaultActivation(); }\n+\n+void VandenBogert2011Muscle::setDefaultFiberLength(double fiberLength)\n+{\n+    set_default_fiber_length(fiberLength);\n+}\n+\n+double VandenBogert2011Muscle::getDefaultFiberLength() const\n+{   return get_default_fiber_length(); }\n+\n+\n+void VandenBogert2011Muscle::setFiberLength(SimTK::State& s, double fiberLength)\n+            const\n+{\n+\n+        setStateVariableValue(s, \"fiber_length\",fiberLength);\n+        //markCacheVariableInvalid(s,\"lengthInfo\");\n+        //markCacheVariableInvalid(s,\"velInfo\");\n+        //markCacheVariableInvalid(s,\"dynamicsInfo\");\n+    }\n+\n+\n+// Set the activation\n+void VandenBogert2011Muscle::setActivation(SimTK::State& s,double activation)\n+const\n+//TODO: Add clamping?  Add ignore_activation_dynamics\n+{\n+    setStateVariableValue(s, \"activation\", activation);\n+\n+    //markCacheVariableInvalid(s,\"velInfo\");\n+    //markCacheVariableInvalid(s,\"dynamicsInfo\");\n+}\n+\n+// Get the Residual of muscle\n+// TODO:  This breaks naming convention in that it does not get an already\n+// evaluated constant, it actually performs the calculation.  Without using a\n+// state variable or adding to the cache variables, I think I have to do it this\n+// way?\n+SimTK::Vec2 VandenBogert2011Muscle::getResidual(const SimTK::State& s,\n+                                                double projFibVelNorm_guess,\n+                                                double activdot_guess, double u)\n+                                                const\n+{\n+    ImplicitResidual residualStruct = calcImplicitResidual(s,\n+                                                           projFibVelNorm_guess,\n+                                                           activdot_guess,\n+                                                           u, 0);\n+\n+    SimTK::Vec2 residual = {residualStruct.forceResidual,\n+                            residualStruct.activResidual};\n+    return(residual);\n+}\n+\n+\n+\n+//These are hacks because I am not using muscle.h mli cache variables, yet:\n+double  VandenBogert2011Muscle::getFiberLength(SimTK::State& s) const\n+{\n+    double fiberLength=getStateVariableValue(s, \"fiber_length\");\n+    return fiberLength;\n+}\n+double  VandenBogert2011Muscle::getActivation(SimTK::State& s) const\n+{\n+    double activ=getStateVariableValue(s, \"activation\");\n+    return activ;\n+}\n+\n+\n+\n+//==============================================================================\n+// Muscle.h Interface\n+//==============================================================================\n+\n+\n+double  VandenBogert2011Muscle::computeActuation(const SimTK::State& s) const\n+{\n+    double activ=getActivation(s);\n+    // For now we will start with static guess\n+    // TODO: figure out how to use previous state as guess\n+    SimTK::Vector ydotInitialGuess(2);\n+    ydotInitialGuess[0]=0.0;\n+    ydotInitialGuess[1]=0.0;\n+    SimTK::Vec2 sdot=calcSolveMuscle(s, activ, ydotInitialGuess);\n+\n+    VandenBogert2011Muscle::ImplicitResidual Result= calcImplicitResidual(s,\n+                                          sdot[0],\n+                                          sdot[1],\n+                                          activ,\n+                                          0);\n+\n+    //TODO: Could probably add a check here that residuals =0\n+    double actuation=Result.forceTendon;\n+\n+    return(actuation);\n+}\n+\n+\n+\n+void VandenBogert2011Muscle::computeInitialFiberEquilibrium(SimTK::State& s)\n+const\n+{\n+    // TODO:  this is the same code as computeFiberEquilibriumAtZeroVelocity\n+    //Need to update for v~=0\n+    //Let's start with the default activation and the fiberVelocity=0\n+\n+    computeFiberEquilibriumAtZeroVelocity(s);\n+\n+}\n+\n+\n+\n+void VandenBogert2011Muscle::\n+computeFiberEquilibriumAtZeroVelocity(SimTK::State& s) const\n+{\n+    double activation = getDefaultActivation();\n+    SimTK::Vec2 lenghAndForce=calcFiberStaticEquilbirum(getLength(s),\n+                                                        activation);\n+\n+    double projFibLenNorm=lenghAndForce[0];\n+    double tendonForce=lenghAndForce[1];\n+\n+    //TODO:  Millard Muscle handles non-convergence here and zero muscle length.\n+    //     Need to consider adding.\n+\n+    setActuation(s, tendonForce);\n+    double fiberLength =\n+            projFibLenToFiberLength(projFibLenNorm,1)*getOptimalFiberLength();\n+    setStateVariableValue(s, \"fiber_length\", fiberLength);\n+    setStateVariableValue(s, \"activation\",  activation);\n+\n+}\n+// I am cheating here.  Instead of using mli and mdi caches\n+/*\n+SimTK::Vec2 VandenBogert2011Muscle::getStateVariables(const SimTK::State& s) {\n+    double fiberLength = getStateVariableValue(s, \"fiber_length\");\n+    double activ = getStateVariableValue(s, \"activation\");\n+    SimTK::Vec2 stateVariables = {fiberLength, activ};\n+    return stateVariables;};\n+\n+*/\n+\n+\n+//==============================================================================\n+// MODELCOMPONENT INTERFACE REQUIREMENTS\n+//==============================================================================\n+\n+void VandenBogert2011Muscle::extendConnectToModel(Model& model)\n+{\n+    Super::extendConnectToModel(model);\n+}\n+\n+// Define new states and their derivatives in the underlying system\n+void VandenBogert2011Muscle::extendAddToSystem(SimTK::MultibodySystem& system)\n+const\n+{\n+\n+    Super::extendAddToSystem(system);\n+\n+    SimTK_ASSERT(isObjectUpToDateWithProperties(),\n+                 \"VandenBogert2011Muscle: Muscle properties not up-to-date\");\n+\n+    addStateVariable(\"fiber_length\");\n+    addStateVariable(\"activation\");\n+\n+}\n+\n+void VandenBogert2011Muscle::extendInitStateFromProperties(SimTK::State& s)\n+const\n+{\n+    Super::extendInitStateFromProperties(s);\n+\n+        setActivation(s, getDefaultActivation());\n+        setFiberLength(s, getDefaultFiberLength());\n+}\n+\n+void VandenBogert2011Muscle::extendSetPropertiesFromState(const SimTK::State& s)\n+{\n+    Super::extendSetPropertiesFromState(s);\n+\n+        setDefaultActivation(getStateVariableValue(s,\"activation\"));\n+        setDefaultFiberLength(getStateVariableValue(s,\"fiber_length\"));\n+\n+}\n+\n+\n+void VandenBogert2011Muscle::\n+computeStateVariableDerivatives(const SimTK::State& s) const\n+{\n+\n+    double activ=getActivation(s);\n+    // For now we will start with static guess\n+    // TODO: figure out how to use previous state as guess\n+    SimTK::Vector ydotInitialGuess(2);\n+    ydotInitialGuess[0]=0.0;\n+    ydotInitialGuess[1]=0.0;\n+    SimTK::Vec2 sdot=calcSolveMuscle(s, activ, ydotInitialGuess);\n+\n+    setStateVariableDerivativeValue(s, \"fiber_length\", sdot[0]);\n+    setStateVariableDerivativeValue(s, \"activation\", sdot[1]);\n+\n+\n+}\n+\n+\n+//=============================================================================\n+// COMPUTATION\n+//=============================================================================\n+double VandenBogert2011Muscle::fiberLengthToProjectedLength\n+        (double fiberLength , bool normalizedValues=0) const {\n+\n+    double pennAtOptFiberLength = getPennAtOptFiberLength();\n+    double projFibLen = 0;\n+\n+    if (pennAtOptFiberLength < 0.01) {\n+        projFibLen = fiberLength;\n+    }\n+\n+    else {\n+\n+        double optimalFiberLength=getOptimalFiberLength();\n+\n+        if (normalizedValues) {fiberLength=fiberLength*optimalFiberLength;};\n+\n+\n+        double muscleWidth = sin(\n+                pennAtOptFiberLength);  //b is the fixed distance of the fiber\n+        //perpindicular to the tendon (width)\n+\n+        /*TODO: muscleWidth as cache variable\n+         * recalculated. Should be moved info muslceLengthInfo cache */\n+\n+        // The fiber can not be shorter than b; if it is, the projected length\n+        // equation below will return a complex value.  It also physically can\n+        // not happen (the fiber being shorter than the fixed width)\n+        if (fiberLength >= muscleWidth) {\n+            projFibLen = sqrt(pow(fiberLength, 2) - pow(muscleWidth, 2));\n+        }\n+        else {\n+            projFibLen = SimTK::NaN;\n+        }  //TODO: Doing this for now, but need to\n+        // come up with a clamping scheme (Millard has one)\n+\n+        if (normalizedValues) {projFibLen=projFibLen/optimalFiberLength;};\n+\n+\n+    };\n+    return projFibLen;\n+};\n+\n+\n+//------------------------------------------------------------------------------\n+double VandenBogert2011Muscle::projFibLenToFiberLength (double projFibLen,\n+                                                        bool normalizedValues=0)\n+                                                        const\n+{\n+    double pennAtOptFiberLength=getPennAtOptFiberLength();\n+    double fiberLength=0;\n+\n+    double optimalFiberLength=getOptimalFiberLength();\n+\n+    if (normalizedValues){\n+        projFibLen=projFibLen * optimalFiberLength;  //Convert from Norm\n+    }\n+\n+    if (pennAtOptFiberLength < 0.01) {\n+        fiberLength = projFibLen; }\n+    else {\n+        double static muscleWidth = sin(pennAtOptFiberLength);\n+        fiberLength = sqrt(pow(projFibLen, 2) + pow(muscleWidth, 2));}\n+\n+    if (normalizedValues){                      //Convert back to Norm if needed\n+        fiberLength=fiberLength / optimalFiberLength;\n+    }\n+\n+    return fiberLength;\n+}\n+\n+//------------------------------------------------------------------------------\n+double VandenBogert2011Muscle::fiberVelocityToProjFibVel\n+        (double fiberVelocity, double fiberLength, double projFiberLength,\n+         bool normalizedValues=0) const\n+{\n+    // Note that this normalized by fiber optimal length (not by max velocity)\n+    double optimalFiberLength = getOptimalFiberLength();\n+\n+    if (normalizedValues) {\n+        fiberLength = fiberLength * getOptimalFiberLength();\n+        fiberVelocity = fiberVelocity * optimalFiberLength;\n+        projFiberLength = projFiberLength * optimalFiberLength;\n+    }\n+\n+    double projFibVel = 0;\n+\n+    if (fiberVelocity != 0) {\n+        projFibVel = fiberVelocity / cos(projFiberLength / fiberLength);\n+    }\n+    else { projFibVel = 0; }\n+\n+    if (normalizedValues) {projFibVel\n+                                   = projFibVel / optimalFiberLength; };\n+\n+    return projFibVel;\n+};\n+\n+//------------------------------------------------------------------------------\n+double VandenBogert2011Muscle::fiberVelocityToProjFibVel\n+        (double fiberVelocity, double fiberLength, bool normalizedValues=0)\n+                const {\n+\n+    //overload method when projFiberLength is not known/provided\n+\n+    double projFiberLength=fiberLengthToProjectedLength(fiberLength,\n+                                                        normalizedValues);\n+    double projFiberVelocity = fiberVelocityToProjFibVel (fiberVelocity,\n+                                                          fiberLength,\n+                                                          projFiberLength,\n+                                                          normalizedValues);\n+    return projFiberVelocity;\n+};\n+\n+\n+//------------------------------------------------------------------------------\n+double VandenBogert2011Muscle::projFibVelToFiberVelocity(double projFibVel,\n+                                                         double fiberLength,\n+                                                         double projFiberLength,\n+                                                         bool normalizedValues=0)\n+                                                         const\n+{\n+// Note that this normalized by fiber optimal length (not by max velocity)\n+    double optimalFiberLength = getOptimalFiberLength();\n+\n+    if (normalizedValues)\n+    {\n+        fiberLength = fiberLength * getOptimalFiberLength();\n+        projFibVel = projFibVel * optimalFiberLength;\n+        projFiberLength = projFiberLength * optimalFiberLength;\n+    }\n+\n+    double fiberVelocity = 0;\n+\n+    if (projFibVel != 0)\n+    {\n+        fiberVelocity = projFibVel * cos(projFiberLength / fiberLength);\n+    }\n+    else { fiberVelocity = 0; }\n+\n+    if (normalizedValues)\n+    {\n+        fiberVelocity = fiberVelocity / optimalFiberLength;\n+    };\n+\n+    return fiberVelocity;}\n+\n+//------------------------------------------------------------------------------\n+double VandenBogert2011Muscle::projFibVelToFiberVelocity\n+        (double projFibVel, double projFibLength, bool normalizedValues=0)\n+                        const {\n+\n+    //overload method when fiberLength is not known/provided\n+\n+    double fiberLength=projFibLenToFiberLength(fiberLength ,normalizedValues);\n+    double fiberVelocity = projFibVelToFiberVelocity(projFibVel, fiberLength,\n+                                                     projFibLength,\n+                                                     normalizedValues);\n+\n+    return fiberVelocity;\n+};\n+\n+\n+\n+//------------------------------------------------------------------------------\n+VandenBogert2011Muscle::ImplicitResidual\n+VandenBogert2011Muscle::calcImplicitResidual(const SimTK::State& s,\n+                                             double projFibVelNorm_guess,\n+                                             double activdot_guess,\n+                                             double u, int returnJacobians)\n+\n+\n+{\n+    // Overload method for state as parameters\n+\n+    double muscleLength = getLength(s);\n+\n+    //double activ =getActivations(s); //Does not work because info not implemented\n+    //double activ = getStateVariableValues(s,\"activation\");  // does not work\n+    //double fiberLength = getStateVariableValues(s,\"fiber_length\");\n+\n+    SimTK::Vector stateVec =getStateVariableValues(s);\n+    double fiberLength =stateVec[0];\n+    double activ =stateVec[1];\n+\n+\n+    double projFibLenNorm =\n+            fiberLengthToProjectedLength(fiberLength/getOptimalFiberLength(),1);\n+\n+    VandenBogert2011Muscle::ImplicitResidual Results= calcImplicitResidual(\n+            muscleLength, projFibLenNorm, activ, projFibVelNorm_guess,\n+            activdot_guess, u, 0);\n+\n+    return Results;\n+}\n+\n+\n+//------------------------------------------------------------------------------\n+VandenBogert2011Muscle::ImplicitResidual\n+VandenBogert2011Muscle::calcImplicitResidual(SimTK::Vec2 y,\n+                                             SimTK::Vec2 ydot_guess,\n+                                             double muscleLength,\n+                                             double u, int returnJacobians=0)\n+const\n+{\n+    // Overload method for state vectors as parameters\n+    VandenBogert2011Muscle::ImplicitResidual Results= calcImplicitResidual(\n+            muscleLength, y[0], y[1], ydot_guess[0], ydot_guess[1], u,\n+            returnJacobians);\n+    return Results;\n+\n+}\n+\n+//------------------------------------------------------------------------------\n+VandenBogert2011Muscle::ImplicitResidual VandenBogert2011Muscle::\n+calcImplicitResidual(double muscleLength, double projFibLenNorm, double activ,\n+                     double projFibVelNorm, double activdot, double u,","path":"OpenSim/Actuators/VandenBogert2011Muscle.cpp","position":null,"original_position":550,"commit_id":"0a6fba664cc2d559403e700d1a7f56d78c0db8b4","original_commit_id":"f0d6af332e031c03f15b602fef41eb6481306e83","user":{"login":"humphreysb","id":7395691,"avatar_url":"https://avatars.githubusercontent.com/u/7395691?v=3","gravatar_id":"","url":"https://api.github.com/users/humphreysb","html_url":"https://github.com/humphreysb","followers_url":"https://api.github.com/users/humphreysb/followers","following_url":"https://api.github.com/users/humphreysb/following{/other_user}","gists_url":"https://api.github.com/users/humphreysb/gists{/gist_id}","starred_url":"https://api.github.com/users/humphreysb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/humphreysb/subscriptions","organizations_url":"https://api.github.com/users/humphreysb/orgs","repos_url":"https://api.github.com/users/humphreysb/repos","events_url":"https://api.github.com/users/humphreysb/events{/privacy}","received_events_url":"https://api.github.com/users/humphreysb/received_events","type":"User","site_admin":false},"body":"A general comment has been added to doxygen:  \r\n Symbols with the a \\f$ \\bar{bar} \\f$ indicate that the quantity has been normalized by a constant parameter.  For forces, this will all ways be \\f$F_{m,opt}\\f$.  For velocities and lengths this will be \\f$l_{m_opt}\\f$ (velocities will therefore have units of \"optimal lengths per second\")\r\n","created_at":"2016-09-27T14:40:36Z","updated_at":"2016-09-27T14:40:36Z","html_url":"https://github.com/opensim-org/opensim-core/pull/1160#discussion_r80708126","pull_request_url":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160","_links":{"self":{"href":"https://api.github.com/repos/opensim-org/opensim-core/pulls/comments/80708126"},"html":{"href":"https://github.com/opensim-org/opensim-core/pull/1160#discussion_r80708126"},"pull_request":{"href":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160"}}},"pull_request":{"url":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160","id":80186131,"html_url":"https://github.com/opensim-org/opensim-core/pull/1160","diff_url":"https://github.com/opensim-org/opensim-core/pull/1160.diff","patch_url":"https://github.com/opensim-org/opensim-core/pull/1160.patch","issue_url":"https://api.github.com/repos/opensim-org/opensim-core/issues/1160","number":1160,"state":"open","locked":false,"title":"[WIP] New Implicit Muscle (vandenBogert)","user":{"login":"humphreysb","id":7395691,"avatar_url":"https://avatars.githubusercontent.com/u/7395691?v=3","gravatar_id":"","url":"https://api.github.com/users/humphreysb","html_url":"https://github.com/humphreysb","followers_url":"https://api.github.com/users/humphreysb/followers","following_url":"https://api.github.com/users/humphreysb/following{/other_user}","gists_url":"https://api.github.com/users/humphreysb/gists{/gist_id}","starred_url":"https://api.github.com/users/humphreysb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/humphreysb/subscriptions","organizations_url":"https://api.github.com/users/humphreysb/orgs","repos_url":"https://api.github.com/users/humphreysb/repos","events_url":"https://api.github.com/users/humphreysb/events{/privacy}","received_events_url":"https://api.github.com/users/humphreysb/received_events","type":"User","site_admin":false},"body":"Work In Process.  This muscle has Implicit Dynamics.\r\n\r\n**This PR is for the muscle only.**  The files of interest are:\r\n- VandenBogert2011Muscle.h\r\n- VandenBogert2011Muscle.cpp\r\n\r\n\r\nSee @chrisdembia's  PR #1147 for the implicit  components implementation (I had merged his branch with mine so they are inadvertently both contained here).","created_at":"2016-08-05T04:07:15Z","updated_at":"2016-09-27T14:40:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f29ce697adc7fe73a62d501334572b4b47c26c03","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160/commits","review_comments_url":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160/comments","review_comment_url":"https://api.github.com/repos/opensim-org/opensim-core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/opensim-org/opensim-core/issues/1160/comments","statuses_url":"https://api.github.com/repos/opensim-org/opensim-core/statuses/0a6fba664cc2d559403e700d1a7f56d78c0db8b4","head":{"label":"humphreysb:vandenBogertMuscle","ref":"vandenBogertMuscle","sha":"0a6fba664cc2d559403e700d1a7f56d78c0db8b4","user":{"login":"humphreysb","id":7395691,"avatar_url":"https://avatars.githubusercontent.com/u/7395691?v=3","gravatar_id":"","url":"https://api.github.com/users/humphreysb","html_url":"https://github.com/humphreysb","followers_url":"https://api.github.com/users/humphreysb/followers","following_url":"https://api.github.com/users/humphreysb/following{/other_user}","gists_url":"https://api.github.com/users/humphreysb/gists{/gist_id}","starred_url":"https://api.github.com/users/humphreysb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/humphreysb/subscriptions","organizations_url":"https://api.github.com/users/humphreysb/orgs","repos_url":"https://api.github.com/users/humphreysb/repos","events_url":"https://api.github.com/users/humphreysb/events{/privacy}","received_events_url":"https://api.github.com/users/humphreysb/received_events","type":"User","site_admin":false},"repo":{"id":62158268,"name":"opensim-core","full_name":"humphreysb/opensim-core","owner":{"login":"humphreysb","id":7395691,"avatar_url":"https://avatars.githubusercontent.com/u/7395691?v=3","gravatar_id":"","url":"https://api.github.com/users/humphreysb","html_url":"https://github.com/humphreysb","followers_url":"https://api.github.com/users/humphreysb/followers","following_url":"https://api.github.com/users/humphreysb/following{/other_user}","gists_url":"https://api.github.com/users/humphreysb/gists{/gist_id}","starred_url":"https://api.github.com/users/humphreysb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/humphreysb/subscriptions","organizations_url":"https://api.github.com/users/humphreysb/orgs","repos_url":"https://api.github.com/users/humphreysb/repos","events_url":"https://api.github.com/users/humphreysb/events{/privacy}","received_events_url":"https://api.github.com/users/humphreysb/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/humphreysb/opensim-core","description":"SimTK OpenSim 4.0 C++ libraries and command-line applications, and Java/Python wrapping.","fork":true,"url":"https://api.github.com/repos/humphreysb/opensim-core","forks_url":"https://api.github.com/repos/humphreysb/opensim-core/forks","keys_url":"https://api.github.com/repos/humphreysb/opensim-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/humphreysb/opensim-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/humphreysb/opensim-core/teams","hooks_url":"https://api.github.com/repos/humphreysb/opensim-core/hooks","issue_events_url":"https://api.github.com/repos/humphreysb/opensim-core/issues/events{/number}","events_url":"https://api.github.com/repos/humphreysb/opensim-core/events","assignees_url":"https://api.github.com/repos/humphreysb/opensim-core/assignees{/user}","branches_url":"https://api.github.com/repos/humphreysb/opensim-core/branches{/branch}","tags_url":"https://api.github.com/repos/humphreysb/opensim-core/tags","blobs_url":"https://api.github.com/repos/humphreysb/opensim-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/humphreysb/opensim-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/humphreysb/opensim-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/humphreysb/opensim-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/humphreysb/opensim-core/statuses/{sha}","languages_url":"https://api.github.com/repos/humphreysb/opensim-core/languages","stargazers_url":"https://api.github.com/repos/humphreysb/opensim-core/stargazers","contributors_url":"https://api.github.com/repos/humphreysb/opensim-core/contributors","subscribers_url":"https://api.github.com/repos/humphreysb/opensim-core/subscribers","subscription_url":"https://api.github.com/repos/humphreysb/opensim-core/subscription","commits_url":"https://api.github.com/repos/humphreysb/opensim-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/humphreysb/opensim-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/humphreysb/opensim-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/humphreysb/opensim-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/humphreysb/opensim-core/contents/{+path}","compare_url":"https://api.github.com/repos/humphreysb/opensim-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/humphreysb/opensim-core/merges","archive_url":"https://api.github.com/repos/humphreysb/opensim-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/humphreysb/opensim-core/downloads","issues_url":"https://api.github.com/repos/humphreysb/opensim-core/issues{/number}","pulls_url":"https://api.github.com/repos/humphreysb/opensim-core/pulls{/number}","milestones_url":"https://api.github.com/repos/humphreysb/opensim-core/milestones{/number}","notifications_url":"https://api.github.com/repos/humphreysb/opensim-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/humphreysb/opensim-core/labels{/name}","releases_url":"https://api.github.com/repos/humphreysb/opensim-core/releases{/id}","deployments_url":"https://api.github.com/repos/humphreysb/opensim-core/deployments","created_at":"2016-06-28T16:45:14Z","updated_at":"2016-06-28T16:45:29Z","pushed_at":"2016-08-24T12:53:53Z","git_url":"git://github.com/humphreysb/opensim-core.git","ssh_url":"git@github.com:humphreysb/opensim-core.git","clone_url":"https://github.com/humphreysb/opensim-core.git","svn_url":"https://github.com/humphreysb/opensim-core","homepage":"https://opensim.stanford.edu","size":132048,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"opensim-org:master","ref":"master","sha":"50369ea26651d6257dc1574a13685590a2ba645d","user":{"login":"opensim-org","id":4370782,"avatar_url":"https://avatars.githubusercontent.com/u/4370782?v=3","gravatar_id":"","url":"https://api.github.com/users/opensim-org","html_url":"https://github.com/opensim-org","followers_url":"https://api.github.com/users/opensim-org/followers","following_url":"https://api.github.com/users/opensim-org/following{/other_user}","gists_url":"https://api.github.com/users/opensim-org/gists{/gist_id}","starred_url":"https://api.github.com/users/opensim-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opensim-org/subscriptions","organizations_url":"https://api.github.com/users/opensim-org/orgs","repos_url":"https://api.github.com/users/opensim-org/repos","events_url":"https://api.github.com/users/opensim-org/events{/privacy}","received_events_url":"https://api.github.com/users/opensim-org/received_events","type":"Organization","site_admin":false},"repo":{"id":20775600,"name":"opensim-core","full_name":"opensim-org/opensim-core","owner":{"login":"opensim-org","id":4370782,"avatar_url":"https://avatars.githubusercontent.com/u/4370782?v=3","gravatar_id":"","url":"https://api.github.com/users/opensim-org","html_url":"https://github.com/opensim-org","followers_url":"https://api.github.com/users/opensim-org/followers","following_url":"https://api.github.com/users/opensim-org/following{/other_user}","gists_url":"https://api.github.com/users/opensim-org/gists{/gist_id}","starred_url":"https://api.github.com/users/opensim-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opensim-org/subscriptions","organizations_url":"https://api.github.com/users/opensim-org/orgs","repos_url":"https://api.github.com/users/opensim-org/repos","events_url":"https://api.github.com/users/opensim-org/events{/privacy}","received_events_url":"https://api.github.com/users/opensim-org/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/opensim-org/opensim-core","description":"SimTK OpenSim 4.0 C++ libraries and command-line applications, and Java/Python wrapping.","fork":false,"url":"https://api.github.com/repos/opensim-org/opensim-core","forks_url":"https://api.github.com/repos/opensim-org/opensim-core/forks","keys_url":"https://api.github.com/repos/opensim-org/opensim-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/opensim-org/opensim-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/opensim-org/opensim-core/teams","hooks_url":"https://api.github.com/repos/opensim-org/opensim-core/hooks","issue_events_url":"https://api.github.com/repos/opensim-org/opensim-core/issues/events{/number}","events_url":"https://api.github.com/repos/opensim-org/opensim-core/events","assignees_url":"https://api.github.com/repos/opensim-org/opensim-core/assignees{/user}","branches_url":"https://api.github.com/repos/opensim-org/opensim-core/branches{/branch}","tags_url":"https://api.github.com/repos/opensim-org/opensim-core/tags","blobs_url":"https://api.github.com/repos/opensim-org/opensim-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/opensim-org/opensim-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/opensim-org/opensim-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/opensim-org/opensim-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/opensim-org/opensim-core/statuses/{sha}","languages_url":"https://api.github.com/repos/opensim-org/opensim-core/languages","stargazers_url":"https://api.github.com/repos/opensim-org/opensim-core/stargazers","contributors_url":"https://api.github.com/repos/opensim-org/opensim-core/contributors","subscribers_url":"https://api.github.com/repos/opensim-org/opensim-core/subscribers","subscription_url":"https://api.github.com/repos/opensim-org/opensim-core/subscription","commits_url":"https://api.github.com/repos/opensim-org/opensim-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/opensim-org/opensim-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/opensim-org/opensim-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/opensim-org/opensim-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/opensim-org/opensim-core/contents/{+path}","compare_url":"https://api.github.com/repos/opensim-org/opensim-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/opensim-org/opensim-core/merges","archive_url":"https://api.github.com/repos/opensim-org/opensim-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/opensim-org/opensim-core/downloads","issues_url":"https://api.github.com/repos/opensim-org/opensim-core/issues{/number}","pulls_url":"https://api.github.com/repos/opensim-org/opensim-core/pulls{/number}","milestones_url":"https://api.github.com/repos/opensim-org/opensim-core/milestones{/number}","notifications_url":"https://api.github.com/repos/opensim-org/opensim-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/opensim-org/opensim-core/labels{/name}","releases_url":"https://api.github.com/repos/opensim-org/opensim-core/releases{/id}","deployments_url":"https://api.github.com/repos/opensim-org/opensim-core/deployments","created_at":"2014-06-12T16:57:56Z","updated_at":"2016-09-22T13:11:39Z","pushed_at":"2016-09-27T05:45:55Z","git_url":"git://github.com/opensim-org/opensim-core.git","ssh_url":"git@github.com:opensim-org/opensim-core.git","clone_url":"https://github.com/opensim-org/opensim-core.git","svn_url":"https://github.com/opensim-org/opensim-core","homepage":"https://opensim.stanford.edu","size":156591,"stargazers_count":38,"watchers_count":38,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":45,"mirror_url":null,"open_issues_count":359,"forks":45,"open_issues":359,"watchers":38,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160"},"html":{"href":"https://github.com/opensim-org/opensim-core/pull/1160"},"issue":{"href":"https://api.github.com/repos/opensim-org/opensim-core/issues/1160"},"comments":{"href":"https://api.github.com/repos/opensim-org/opensim-core/issues/1160/comments"},"review_comments":{"href":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160/comments"},"review_comment":{"href":"https://api.github.com/repos/opensim-org/opensim-core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/opensim-org/opensim-core/pulls/1160/commits"},"statuses":{"href":"https://api.github.com/repos/opensim-org/opensim-core/statuses/0a6fba664cc2d559403e700d1a7f56d78c0db8b4"}}}}
{"actor":{"display_login":"humphreysb"}}