4141
4242#include < iostream>
4343
44- #define DART_CFM 1e-9
44+ #include < cmath>
45+
46+ namespace {
47+
48+ constexpr inline double kConstraintForceMixing = 1e-6 ;
49+ constexpr inline double kDefaultForceLimit = 800.0 ;
50+ constexpr inline double kDefaultVelocityLimit = 50.0 ;
51+ constexpr inline double kDefaultErp = 0.4 ;
52+
53+ } // namespace
4554
4655namespace dart {
4756namespace constraint {
4857
49- double MimicMotorConstraint::mConstraintForceMixing = DART_CFM;
58+ double MimicMotorConstraint::mConstraintForceMixing = kConstraintForceMixing ;
59+ double MimicMotorConstraint::mErrorReductionParameter = kDefaultErp ;
5060
5161// ==============================================================================
5262MimicMotorConstraint::MimicMotorConstraint (
@@ -117,6 +127,31 @@ double MimicMotorConstraint::getConstraintForceMixing()
117127 return mConstraintForceMixing ;
118128}
119129
130+ // ==============================================================================
131+ void MimicMotorConstraint::setErrorReductionParameter (double erp)
132+ {
133+ double clamped = erp;
134+ if (clamped < 0.0 ) {
135+ DART_WARN (
136+ " Error reduction parameter [{}] is lower than 0.0. It is set to 0.0." ,
137+ erp);
138+ clamped = 0.0 ;
139+ } else if (clamped > 1.0 ) {
140+ DART_WARN (
141+ " Error reduction parameter [{}] is greater than 1.0. It is set to 1.0." ,
142+ erp);
143+ clamped = 1.0 ;
144+ }
145+
146+ mErrorReductionParameter = clamped;
147+ }
148+
149+ // ==============================================================================
150+ double MimicMotorConstraint::getErrorReductionParameter ()
151+ {
152+ return mErrorReductionParameter ;
153+ }
154+
120155// ==============================================================================
121156void MimicMotorConstraint::update ()
122157{
@@ -128,21 +163,33 @@ void MimicMotorConstraint::update()
128163 const auto & mimicProp = mMimicProps [i];
129164
130165 double timeStep = mJoint ->getSkeleton ()->getTimeStep ();
166+ double velLower = mJoint ->getVelocityLowerLimit (i);
167+ double velUpper = mJoint ->getVelocityUpperLimit (i);
168+ if (!std::isfinite (velLower))
169+ velLower = -kDefaultVelocityLimit ;
170+ if (!std::isfinite (velUpper))
171+ velUpper = kDefaultVelocityLimit ;
131172 double qError
132173 = mimicProp.mReferenceJoint ->getPosition (mimicProp.mReferenceDofIndex )
133174 * mimicProp.mMultiplier
134175 + mimicProp.mOffset - mJoint ->getPosition (i);
135- double desiredVelocity = math::clip (
136- qError / timeStep,
137- mJoint ->getVelocityLowerLimit (i),
138- mJoint ->getVelocityUpperLimit (i));
176+ const double erp = mErrorReductionParameter ;
177+ double desiredVelocity
178+ = math::clip ((erp * qError) / timeStep, velLower, velUpper);
139179
140180 mNegativeVelocityError [i] = desiredVelocity - mJoint ->getVelocity (i);
141181
142182 if (mNegativeVelocityError [i] != 0.0 ) {
143183 // Note that we are computing impulse not force
144- mUpperBound [i] = mJoint ->getForceUpperLimit (i) * timeStep;
145- mLowerBound [i] = mJoint ->getForceLowerLimit (i) * timeStep;
184+ double upper = mJoint ->getForceUpperLimit (i);
185+ double lower = mJoint ->getForceLowerLimit (i);
186+ if (!std::isfinite (upper))
187+ upper = kDefaultForceLimit ;
188+ if (!std::isfinite (lower))
189+ lower = -kDefaultForceLimit ;
190+
191+ mUpperBound [i] = upper * timeStep;
192+ mLowerBound [i] = lower * timeStep;
146193
147194 if (mActive [i]) {
148195 ++(mLifeTime [i]);
0 commit comments