void HuntCrossleyForce::extendAddToSystem(SimTK::MultibodySystem& system) const { Super::extendAddToSystem(system); const ContactParametersSet& contactParametersSet = get_contact_parameters(); const double& transitionVelocity = get_transition_velocity(); SimTK::GeneralContactSubsystem& contacts = system.updContactSubsystem(); SimTK::ContactSetIndex set = contacts.createContactSet(); SimTK::HuntCrossleyForce force(_model->updForceSubsystem(), contacts, set); force.setTransitionVelocity(transitionVelocity); for (int i = 0; i < contactParametersSet.getSize(); ++i) { ContactParameters& params = contactParametersSet.get(i); for (int j = 0; j < params.getGeometry().size(); ++j) { // get the ContactGeometry from the Model const ContactGeometry& geom = getModel().getComponent<ContactGeometry>(params.getGeometry()[j]); // B: base Frame (Body or Ground) // F: PhysicalFrame that this ContactGeometry is connected to // P: the frame defined (relative to F) by the location and // orientation properties. const auto& X_BF = geom.getFrame().findTransformInBaseFrame(); const auto& X_FP = geom.getTransform(); const auto X_BP = X_BF * X_FP; contacts.addBody(set, geom.getFrame().getMobilizedBody(), geom.createSimTKContactGeometry(), X_BP); force.setBodyParameters( SimTK::ContactSurfaceIndex(contacts.getNumBodies(set)-1), params.getStiffness(), params.getDissipation(), params.getStaticFriction(), params.getDynamicFriction(), params.getViscousFriction()); } } // Beyond the const Component get the index so we can access the // SimTK::Force later. HuntCrossleyForce* mutableThis = const_cast<HuntCrossleyForce *>(this); mutableThis->_index = force.getForceIndex(); }
void ElasticFoundationForce::addToSystem(SimTK::MultibodySystem& system) const { Super::addToSystem(system); const ContactParametersSet& contactParametersSet = get_contact_parameters(); const double& transitionVelocity = get_transition_velocity(); SimTK::GeneralContactSubsystem& contacts = system.updContactSubsystem(); SimTK::SimbodyMatterSubsystem& matter = system.updMatterSubsystem(); SimTK::ContactSetIndex set = contacts.createContactSet(); SimTK::ElasticFoundationForce force(_model->updForceSubsystem(), contacts, set); force.setTransitionVelocity(transitionVelocity); for (int i = 0; i < contactParametersSet.getSize(); ++i) { ContactParameters& params = contactParametersSet.get(i); for (int j = 0; j < params.getGeometry().size(); ++j) { if (!_model->updContactGeometrySet().contains(params.getGeometry()[j])) { std::string errorMessage = "Invalid ContactGeometry (" + params.getGeometry()[j] + ") specified in ElasticFoundationForce" + getName(); throw (Exception(errorMessage.c_str())); } ContactGeometry& geom = _model->updContactGeometrySet().get(params.getGeometry()[j]); contacts.addBody(set, matter.updMobilizedBody(SimTK::MobilizedBodyIndex(geom.getBody().getIndex())), geom.createSimTKContactGeometry(), geom.getTransform()); if (dynamic_cast<ContactMesh*>(&geom) != NULL) force.setBodyParameters(SimTK::ContactSurfaceIndex(contacts.getNumBodies(set)-1), params.getStiffness(), params.getDissipation(), params.getStaticFriction(), params.getDynamicFriction(), params.getViscousFriction()); } } // Beyond the const Component get the index so we can access the SimTK::Force later ElasticFoundationForce* mutableThis = const_cast<ElasticFoundationForce *>(this); mutableThis->_index = force.getForceIndex(); }