/** * Add extra joints to the SIMM model to represent the joint location/orientation * in the parent body and in the child body. * * @param aJoint The Simbody joint. * @param rParentName The name of the parent body for the "real" joint. * @param rChildName The name of the child body for the "real" joint. * @return Whether or not a 'parent' joint was added. */ bool SimbodySimmModel::addExtraJoints(const OpenSim::Joint& aJoint, string& rParentName, string& rChildName) { SimTK::Vec3 location; SimTK::Vec3 orientation; bool parentJointAdded = false; if (isParentJointNeeded(aJoint)) { location = aJoint.getLocationInParent(); orientation = aJoint.getOrientationInParent(); string bodyName = aJoint.getChildBodyName() + "_pjc"; SimbodySimmBody* b = new SimbodySimmBody(NULL, bodyName); _simmBody.append(b); makeSimmJoint(aJoint.getName() + "_pjc", aJoint.getParentBodyName(), bodyName, location, orientation); rParentName = bodyName; parentJointAdded = true; } else { rParentName = aJoint.getParentBodyName(); parentJointAdded = false; } if (isChildJointNeeded(aJoint)) { location = aJoint.getLocationInChild(); orientation = aJoint.getOrientationInChild(); string bodyName = aJoint.getChildBodyName() + "_jcc"; SimbodySimmBody* b = new SimbodySimmBody(NULL, bodyName); _simmBody.append(b); // This joint is specified in the reverse direction. makeSimmJoint(aJoint.getName() + "_jcc", aJoint.getChildBodyName(), bodyName, location, orientation); rChildName = bodyName; } else { rChildName = aJoint.getChildBodyName(); } return parentJointAdded; }
/** * Check to see if a location (in child) and orientation (in child) are all zeros. * If they are not, then a separate SIMM joint is needed to hold this transform. * * @param aJoint The Simbody joint to check. * @return Whether or not a separate SIMM joint is needed to represent the location * and orientation in child. */ bool SimbodySimmModel::isChildJointNeeded(const OpenSim::Joint& aJoint) { SimTK::Vec3 location; SimTK::Vec3 orientation; location = aJoint.getLocationInChild(); orientation= aJoint.getOrientationInChild(); double sum = location.scalarNormSqr(); if (NOT_EQUAL_WITHIN_ERROR(sum, 0.0)) return true; sum = orientation.scalarNormSqr(); if (NOT_EQUAL_WITHIN_ERROR(sum, 0.0)) return true; return false; }