Godot version:
Godot 3.0.2 official
OS/device including version:
macOS Sierra 10.12.6
Issue description:
Using HingeJoint and activating motor it stops and restarts spinning every 360掳.
This happens only using default physics engine settings (Bullet).
Switching to Godot physic engine the motor spins regurarly.
Steps to reproduce:
Create a simple 3D scene and add a camera.
Add a StaticBody and a RigidBody with its own MeshInstance and CollisionShape using a cube as mesh.
Add a HingeJoint and in its nodes properties set the StaticBody (Node A) and the RigidBody (Node B).
In the HingeJoint properties enable the motor and run the project.
I made also a video, see the second half.
https://youtu.be/htBEKQu8Iy4
Minimal reproduction project:
HingeJoint_issue.zip
On my machine (Fedora, 64bit) the cube does not resume spinning at all after the second time it stops. If I set motor/max_impulse as low as 0.06, the cube does not have full stops anymore, it only slows down temporarily instead.
CC @AndreaCatania
Thanks you for the issue report, I will let you know soon
Can you please try to lower the max impulse?
It seems correctly implemented, I should check it with Erwin.
I have this problem. Master branch, windows 7, 64 bit. I am having to lower my max impulse to 0.01 to prevent it happening - 0.03 and it pauses for half a second every time it reaches 180 degrees from the starting point. I can cheerfully provide a Godot project that demonstrates it if anyone needs. The default impulse is 1.0 on HingeJoints.
edit: Increasing the mass or target velocity also helps overcome the hiccup. I'd guess having a momentum significantly higher than the maximum impulse causes smaller problems. It is not going to sleep, although in the cases where it gets stuck forever I suspect it might be eventually going to sleep as a result of the bug, not the cause of it.
OK, I've tracked it down. In
btHingeConstraint::getInfo2InternalUsingFrameOffset
there is a call to
btTypedConstraint::getMotorFactor
which passes in (and then uses) the angular limits of the constraint in calculating the force the motor will apply _even if the limits are disabled_. I consider this a bug in Bullet. We can work around it in Godot, however (well, for non extreme cases) by this. It's a one line change that means that the limits are pretty much never actually reached and so don't cause problems. I'm trying to attract the attention of some Bullet dudes to talk over their bit and see if it needs patching properly:
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index 97ea7ca3d..cc8f18767 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -155,7 +155,7 @@ void HingeJointBullet::set_flag(PhysicsServer::HingeJointFlag p_flag, bool
p_val
switch (p_flag) {
case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT:
if (!p_value) {
- hingeConstraint->setLimit(-Math_PI, Math_PI);
+ hingeConstraint->setLimit(-1.5f * Math_PI, 1.5f * Math_PI);
}
break;
case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR:
EDIT: I realize this may sound like I'm fixing it. I'm not. I'm just explaining how it can be!
Erwin said me couple of times to not use Hinge joint since its implementation is really old, he told me to use btHinge2Constraint. It's a bit different compared to godot hinge and for this reason I didn't implemented it yet.
However I will change it soon, so this bug will be fixed
3.1 still a problem
Confirming that this bug still occurs in 3.1beta3. (Bullet physics engine only)
The workaround (IMHO) is to use the Angular Motor of Generic6DOFJoint.
Wondering if there is any update on this issue ? (as it has been removed from the 3.2 milestone)
More specifically, is the Hinge joint in godot 3.2 still the old implementation ? (It does stop every turn still. And the Generic 6DOF Joint suffer a y axis gimbal lock.)
More specifically, is the Hinge joint in godot 3.2 still the old implementation ?
As far as I can see nothing has changed since then. Went into this issue yesterday with current 3.2.1.stable.
Maybe this was dropped from 3.2 milestone because of the release in January and then it was forgotten to readd it to 4.0. Any chance this is getting on the list again @AndreaCatania?
Hey @AndreaCatania, this problem still occrurs in v3.2.3. When will it be fixed please ?
Hello, sorry for the delay I been busy this period and I can't tell an exact date when this will be fixed. Tho, the 6dof joint has a much better algorithm, you could consider using it in the meanwhile.
Most helpful comment
OK, I've tracked it down. In
btHingeConstraint::getInfo2InternalUsingFrameOffsetthere is a call to
btTypedConstraint::getMotorFactorwhich passes in (and then uses) the angular limits of the constraint in calculating the force the motor will apply _even if the limits are disabled_. I consider this a bug in Bullet. We can work around it in Godot, however (well, for non extreme cases) by this. It's a one line change that means that the limits are pretty much never actually reached and so don't cause problems. I'm trying to attract the attention of some Bullet dudes to talk over their bit and see if it needs patching properly:
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp index 97ea7ca3d..cc8f18767 100644 --- a/modules/bullet/hinge_joint_bullet.cpp +++ b/modules/bullet/hinge_joint_bullet.cpp @@ -155,7 +155,7 @@ void HingeJointBullet::set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_val switch (p_flag) { case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT: if (!p_value) { - hingeConstraint->setLimit(-Math_PI, Math_PI); + hingeConstraint->setLimit(-1.5f * Math_PI, 1.5f * Math_PI); } break; case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR:EDIT: I realize this may sound like I'm fixing it. I'm not. I'm just explaining how it can be!