I'm trying to compute the total work done by a btGeneric6DofConstraint in the last timestep. Has anyone figured out how to do this?
I am using Bullet to evolve neural controllers for simulated robots. The robot legs are powered by btGeneric6DofConstraint joints (I'm only using the btRotationalLimitMotor part). I will make the evolutionary fitness consider the total work done by all the legs. (This will make the running more natural.)
I think I would understand how to do this with btRotationalLimitMotor::solveAngularLimits(). (There you can get the impulse that is actually applied. So if you just get the angle it's applied over, I think you can compute the work.)
However, looks like solveAngularLimits() is now obsolete - it is not called anywhere in the bullet libraries. There is a function btTypedConstraint::getAppliedImpulse(), but this returns a scalar. Work = distance * impulse (both are vectors) / time, so a scalar is not enough.
Has anybody else computed total work done by a rotational motor, or have any tips where I should try to get the work, or the impulse & angle traveled? E.g., a hint like "the best place to get both is after the total impulse is computed in function XYZ".
Thanks!
P.S. Here are some videos of the evolved robots, you may recognize the body model from one of the Bullet demos called MotorDemo. http://youtube.com/geccospider
computing work done by a btGeneric6DofConstraint?
-
- Posts: 5
- Joined: Fri Dec 17, 2010 12:26 am
-
- Posts: 55
- Joined: Sun Jan 01, 2012 7:37 pm
Re: computing work done by a btGeneric6DofConstraint?
Wait, are you doing evolutionary neural networks that are connected to sensors and emitters?
This is really cool
This is really cool
-
- Posts: 5
- Joined: Fri Dec 17, 2010 12:26 am
Re: computing work done by a btGeneric6DofConstraint?
Sensors and effectors, yeah... thanks! Bullet is very good for evolutionary robotics.
Wonder if anyone else has some tips on computing the total work done by a rotational motor. I set the m_targetVelocity of the rotational motor, and at some point this gets converted to a torque, can anyone explain how/where? (That's the point where I might be able to put a callback or something to accumulate the total work.)
I believe the next place the m_targetVelocity pops up is in btGeneric6DofConstraint::get_limit_motor_info2(). Here an m_constraintError is computed from it... but at that point I lose it. Where does the m_constraintError get converted into an actual torque that is applied? I imagine somewhere the constraint errors are all resolved...?
Thanks for any explanation or help!
Cheers,
Mike
Wonder if anyone else has some tips on computing the total work done by a rotational motor. I set the m_targetVelocity of the rotational motor, and at some point this gets converted to a torque, can anyone explain how/where? (That's the point where I might be able to put a callback or something to accumulate the total work.)
I believe the next place the m_targetVelocity pops up is in btGeneric6DofConstraint::get_limit_motor_info2(). Here an m_constraintError is computed from it... but at that point I lose it. Where does the m_constraintError get converted into an actual torque that is applied? I imagine somewhere the constraint errors are all resolved...?
Thanks for any explanation or help!
Cheers,
Mike
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: computing work done by a btGeneric6DofConstraint?
The constraint solver internally updates the m_accumulatedImpulse for each constraint row.
This is not properly updated in this function:
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish( ... )
So perhaps there is a better way to provide the constraint feedback.
You might be able to run the 'obsolete' code path (check out m_useSolveConstraintObsolete) and use the applied impulses as part of each limit/motor.
Hope this helps,
Erwin
This is not properly updated in this function:
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish( ... )
So perhaps there is a better way to provide the constraint feedback.
You might be able to run the 'obsolete' code path (check out m_useSolveConstraintObsolete) and use the applied impulses as part of each limit/motor.
Hope this helps,
Erwin
-
- Posts: 2
- Joined: Mon Apr 23, 2012 2:57 pm
Re: computing work done by a btGeneric6DofConstraint?
Hi,
I am also interested in this topic. I tried to implement a torque sensor on a hinge constraint and a generic 6 dof constraint. I tried to get the obsolete code path to work on a generic 6 dof constraint as proposed by Erwin. I set the flag D6_USE_OBSOLETE_METHOD in btGeneric6DofConstraint.cpp with is used to initialize m_useSolveConstraintObsolete. But if I run my code now, there is an other problem: The first segment of my robot arm is attached to the world frame
The second constraint is set up between this segment and the other segment
But unfortunately the the second constraint seems to be ignored by the solver. The second segment starts to move down (due to gravity) immediately. This does only happen if the obsolete code path is used. I checked the enabled-flag and the constraint seems not to be disabled or broken.
Does the obsolete code path still works in Bullet? What can I do to get this to work and obtain correct values for torques / impulse applied by one rotational motor only? Currently I am using Bullet 2.79.
Please help, I'm really in trouble here.
Greetings,
anyway
I am also interested in this topic. I tried to implement a torque sensor on a hinge constraint and a generic 6 dof constraint. I tried to get the obsolete code path to work on a generic 6 dof constraint as proposed by Erwin. I set the flag D6_USE_OBSOLETE_METHOD in btGeneric6DofConstraint.cpp with is used to initialize m_useSolveConstraintObsolete. But if I run my code now, there is an other problem: The first segment of my robot arm is attached to the world frame
Code: Select all
hingeGen1 = new btGeneric6DofConstraint(*upperArmRB, trans, false);
hingeGen1->setAngularLowerLimit(btVector3(0,0,-3.14));
hingeGen1->setAngularUpperLimit(btVector3(0,0,3.14));
hingeGen1->setLinearLowerLimit(btVector3(0,0,0));
hingeGen1->setLinearUpperLimit(btVector3(0,0,0));
hingeGen1->enableFeedback(true);
mot1 = hingeGen1->getRotationalLimitMotor(2);
dynamicsWorld->addConstraint(hingeGen1, true);
Code: Select all
hingeGen2 = new btGeneric6DofConstraint(*upperArmRB, *lowerArmRB, transA, transB, true);
hingeGen2->setAngularLowerLimit(btVector3(0,0,-3.14));
hingeGen2->setAngularUpperLimit(btVector3(0,0,3.14));
hingeGen2->setLinearLowerLimit(btVector3(0,0,0));
hingeGen2->setLinearUpperLimit(btVector3(0,0,0));
hingeGen2->enableFeedback(true);
mot2 = hingeGen2->getRotationalLimitMotor(2);
dynamicsWorld->addConstraint(hingeGen2, true);
Does the obsolete code path still works in Bullet? What can I do to get this to work and obtain correct values for torques / impulse applied by one rotational motor only? Currently I am using Bullet 2.79.
Please help, I'm really in trouble here.
Greetings,
anyway