Open Amil-francescolima74 opened 6 years ago
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:
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.
3.2.3, still not fixed >:(
3.2.3, still not fixed >:(
Can you reproduce this issue after upgrading to 3.3.2? The Godot 3.2.x series is not supported anymore.
3.2.3, still not fixed >:(
Can you reproduce this issue after upgrading to 3.3.2? The Godot 3.2.x series is not supported anymore.
will try soon. will need to download it, as well as the export files...
@Calinou I just opened the minimal reproduction project made by @Amil-francescolima74 in the web editor and the issue is still reproducible.
@Calinou I just opened the minimal reproduction project made by @Amil-francescolima74 in the web editor and the issue is still reproducible.
how to workaround then?
how to workaround then?
Well you could do the following:
angular_velocity
angular_damping
to 0Now you have different possibilities:
add_torque
in the _ready
functionapply_impulse
in the _process
functionProblem with the first two is, that if you want a (physically incorrect) motor that spins with a constant velocity even when under load you need to constantly check the angular_velocity
and rise or lower the torque/impulse (you might need PID control then). With changing the state directly you can force the body to do what you want (haven't worked with states so this might be not correct).
I wanted to add a simple workaround example but I ran into #42842 so I really had to add a control sequence watching the velocity. I'm still not sure why the torque isn't applied constantly though (without readding torque the body slows down) 😕:
extends RigidBody
const torque = Vector3(0,0,1)
func _process(delta):
if angular_velocity.z < 1:
add_torque(torque)
I think it could be better to manipulate the velocity directly in the BodyState.
Give my solution a try if you wish: hingejoint_issue_workaround.zip
how to workaround then?
Well you could do the following:
1. Deactivate the motor 2. Add a constant `angular_velocity` 3. Change the `angular_damping` to 0 4. Add a script to give your body a constant push.
Now you have different possibilities:
* Use `add_torque` in the `_ready` function * Use `apply_impulse` in the `_process` function * Use the [PhysicsDirectBodyState](https://docs.godotengine.org/en/stable/classes/class_physicsdirectbodystate.html) to manipulate the velocity to your liking
Problem with the first two is, that if you want a (physically incorrect) motor that spins with a constant velocity even when under load you need to constantly check the
angular_velocity
and rise or lower the torque/impulse (you might need PID control then). With changing the state directly you can force the body to do what you want (haven't worked with states so this might be not correct).I wanted to add a simple workaround example but I ran into #42842 so I really had to add a control sequence watching the velocity. I'm still not sure why the torque isn't applied constantly though (without readding torque the body slows down) 😕:
extends RigidBody const torque = Vector3(0,0,1) func _process(delta): if angular_velocity.z < 1: add_torque(torque)
I think it could be better to manipulate the velocity directly in the BodyState.
Give my solution a try if you wish: hingejoint_issue_workaround.zip
will try that, except i think motor is in local coordinates, and angular velocity is in global, right? i dunno how to translate rotation from global to local space...
will try that, except i think motor is in local coordinates, and angular velocity is in global, right? i dunno how to translate rotation from global to local space...
I think not. I'm pretty sure that the angular_velocity
is a parameter based on the bodys local coordinate system.
But anyway: I found a better workaround! As @AndreaCatania said you could use the Generic6DOFJoint. It also has the motor ability and the issue isn't present there.
Here is the reworked workaround (the one on the right is the 6DOFJoint): hingejoint_issue_workaround.zip
will try that, except i think motor is in local coordinates, and angular velocity is in global, right? i dunno how to translate rotation from global to local space...
I think not. I'm pretty sure that the
angular_velocity
is a parameter based on the bodys local coordinate system.But anyway: I found a better workaround! As @AndreaCatania said you could use the Generic6DOFJoint. It also has the motor ability and the issue isn't present there.
Here is the reworked workaround (the one on the right is the 6DOFJoint): hingejoint_issue_workaround.zip
will try later. ty!
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