Page 1 of 1
Weak hinge motor
Posted: Sun Jul 10, 2011 8:19 pm
by dmp32
Hello,
I'm building a simulator for a 4-legged robot using Bullet, every leg has 2 hinge constraints with motors (simulating servos).
Called at each step :
Code: Select all
btScalar velocity(1.0), maximpulse(10.0);
btScalar diff= phinge->getHingeAngle() - target_angle;
if(diff < -epsilon)
phinge->enableAngularMotor(true, velocity, maximpulse);
else if(diff > epsilon)
phinge->enableAngularMotor(true, -velocity, maximpulse);
else
phinge->enableAngularMotor(false, 0.0, 0.0);
However, the motor is unable to lift the 0.340-kilogram, 20cm-wide robot until I increase the velocity to say 10.0, but then it's moving too fast.
I simply can't simulate a slow but high-torque motor.
Please help me, I don't understand what's the problem here...
Thanks.
Re: Weak hinge motor
Posted: Mon Jul 11, 2011 1:20 pm
by BinhNguyen
I was just working on a similar problem today. I couldn't get a joint to bend slowly by adjusting the target velocity and the maximum impulse. When the target velocity is a small number, the joint would not bend at all no matter how big the maximum impulse was.
Instead I made the target angle vary slowly over time. I also had to constantly activate the rigid bodies or else they went to sleep.
That reminds me, perhaps all I have to do is constantly activate the rigid bodies when the target velocity is small. I'll have to try that tomorrow.
Re: Weak hinge motor
Posted: Mon Jul 11, 2011 1:41 pm
by dmp32
This looks like a bug to me. Isn't it ?
However, in the ForkLift demo, there is a hinge with a very small velocity (0.1), and it works fine with lifting a 4-kilogram load.
But all my attempts to reproduce it have failed so far...
Disabling deactivation doesn't help.
Edit :
I just tried the following code (which updates the target angle dynamically) :
Code: Select all
diff= h->getHingeAngle() - targetangle;
h->enableAngularMotor(true, 0.0, motortorque);
if(diff < -epsilon)
h->setMotorTarget(h->getHingeAngle() + motorspeed * timeStep, timeStep);
else if(diff > epsilon)
h->setMotorTarget(h->getHingeAngle() - motorspeed * timeStep, timeStep);
else
h->enableAngularMotor(false, 0.0, 0.0);
But the result is the same : the motor is still too weak when its speed is low, even with high impulse.
I can't find the origin of the problem.
Please someone, save my neurons xD !
Re: Weak hinge motor
Posted: Mon Jul 11, 2011 6:26 pm
by dmp32
Here is another test :
Re: Weak hinge motor
Posted: Tue Jul 12, 2011 5:28 am
by BinhNguyen
I tried updating the target angle dynamically like you did and it did not work for me either. I suspect that the values are too small and are lost in the calculations.
Instead, I kept my own target angle variable and increased it slowly overtime. This approach worked.
Code: Select all
void Update( float deltaTime )
{
alphaRigidBody->activate();
bravoRigidBody->activate();
bool isEnableMotor = true;
btScalar maxMotorImpulse = 1.0f; // 1.0f / 8.0f is about the minimum
hingeConstraint->enableMotor( isEnableMotor );
hingeConstraint->setMaxMotorImpulse( maxMotorImpulse );
targetAngle += 0.1f * deltaTime;
hingeConstraint->setMotorTarget( targetAngle, deltaTime );
}
Re: Weak hinge motor
Posted: Tue Jul 12, 2011 9:53 am
by dmp32
Yep, this approach actually works ! I figured it out just before reading your response.
Code: Select all
//setMaxMotorImpulse and enableMotor are called at the creation of the hinge
h= hinges[i];
diff= mcurangles[i] - mtargetangles[i];
if(diff < -motorspeed * timeStep)
mcurangles[i] += motorspeed * timeStep;
else if(diff > motorspeed * timeStep)
mcurangles[i] -= motorspeed * timeStep;
else
mcurangles[i]= mtargetangles[i];
h->setMotorTarget(mcurangles[i], timeStep);
Unfortunately, I don't have enough knowledge to write a patch for enableAngularMotor...
Re: Weak hinge motor
Posted: Thu Jul 14, 2011 7:02 am
by BinhNguyen
I'm glad you got your program to work!
Just in case you might find it useful, I was experimenting with btGeneric6DofConstraint and I found that it worked with small velocities without having to use a workaround.