godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.99k stars 21.16k forks source link

Issue with bullet physics vehicle #12521

Closed bkeys closed 6 years ago

bkeys commented 7 years ago

Operating system or device, Godot version, GPU Model and driver (if graphics related): Fedora 26, master

Issue description: I am having issues getting the vehicle implementation working on the bullet fork, here is a link to my test project

The only tweaking I have done to the vehicle is set the suspension to 10, but there is no way to get the vehicle to stay reasonably still. In other C++ projects where i used the vehicle it stays relatively still while the engine hums. This vehicle goes all over the place and is not quite usable.

Steps to reproduce: Create a default vehicle, then set the suspension to 10 for each wheel (default vehicle sits there slumped and uneven, despite it being symmetrical)

Link to minimal example project: https://my.mixtape.moe/utbpoy.zip

@AndreaCatania

AndreaCatania commented 7 years ago

Hi @Zireael07 I need to check if your project with cars, that you sent me some time ago, has this problem. Can you please send me a copy of your test project that you sent me?

Thanks in advance

Zireael07 commented 7 years ago

As far as I can tell this was the project: https://www.dropbox.com/s/8bn3lxhtm8latrx/FreeRoamRacer.zip?dl=0

AndreaCatania commented 7 years ago

@Zireael07 Thanks you!

AndreaCatania commented 7 years ago

@Zireael07 In this archive the project.godot file is missing, are you sure that it is the right one?

Zireael07 commented 7 years ago

Not quite sure - I will try to look tomorrow for the correct folder :)

Zireael07 commented 7 years ago

This is the correct folder - https://www.dropbox.com/s/wtlehmskd4uzv7y/exportproto%20-%20Kopia.zip?dl=0

AndreaCatania commented 7 years ago

@Zireael07 Yes this is the correct one, Thanks you!

@bkeys My old projects and the Zireael project doesn't have this problem on my PC, but your project does.

I get the same behaviour with both Godot and Bullet (the reason is because the vehicle code is the same).

What do to fix it:

Try something like: stiffness 50, MF: 24000

Please take as example the @Zireael07 project that works correctly.

Here the modified project to run the current Godot version. exportproto - Kopia.zip

Let me know

bkeys commented 7 years ago

Wouldn't it make more sense to have the default vehicle be more sane? Perhaps the default vehicle can behave more like the vehicles in @Zireael07's project

bkeys commented 7 years ago

I applied the settings you mentioned on my test project I made, the car still vibrates and moves all over the place even with the brakes set to 1

Zireael07 commented 7 years ago

@bkeys: Are you 100% sure that you had bullet selected as the physics engine? Vibrations sounds like #9254 which is fixed by both bullet and by the Godot physics joints fix that went in just before bullet.

LinuxUserGD commented 6 years ago

I have the same issue when I use a vehicle from https://github.com/Zireael07/FreeRoamRoguelikeRacerPrototype and put it on a ground plane without a position3d node. But it only appears for me when I use Godot physics, bullet physics is smooth.

LinuxUserGD commented 6 years ago

Now I get this issue with both godot and bullet physics when I move the collision shape. Demo.zip Here is the scene based on Zireael's game. @bkeys @AndreaCatania

AndreaCatania commented 6 years ago

Sorry all if I didn't respond but in this moment I'm a bit busy. I'll look on this ASAP

On Dec 20, 2017 11:02 PM, "LinuxUserGD" notifications@github.com wrote:

Now I have the same issue with both godot and bullet physics when I use another car mesh. Demo.zip https://github.com/godotengine/godot/files/1577139/Demo.zip Here is the scene based on Zireael's demo.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/12521#issuecomment-353195262, or mute the thread https://github.com/notifications/unsubscribe-auth/AH9MR-S74x29f8q6k2fRVbvFyRJzMydhks5tCYPbgaJpZM4QLuQT .

akien-mga commented 6 years ago

Not critical for the upcoming 3.0 release, so moving to the next milestone. A fix can still be cherry-picked for 3.0.x maintenance releases once available in the master branch.

LinuxUserGD commented 6 years ago

I can also reproduce the car vibrations in the new Truck Town demo with bullet and godot physics.

AndreaCatania commented 6 years ago

I didn't check it yet, but strange thing is that vehicle code is exactly the same for two physics engines

BastiaanOlij commented 6 years ago

Note that for the truck demo I've kept everything pretty much as the demo was in 2.x I did notice that the bullet physics are less erratic then the build in physics but indeed, it needs more work but I don't know if this is due to settings or due to bugs in the physics implementation :)

Hope someone will one day write some proper documentation on what all the settings actually do :)

BastiaanOlij commented 6 years ago

Ok, just an update. I'm working on a new demo that has a complete race track and a car setup properly.

While it has been a frustrating week last night I finally got it to a point where it's become a really solid solution. I'm really impressed with it. One thing that really helped was when I found some documentation on the bullet raycast vehicle implementation.

From what I understand, we're using the underlying bullet physics engine but part of the vehicle implementation is still the same as the original Godot implementation, it's just working off of the back of the collision detections and such in bullet. As a result there might be a difference in how the values are applied in the full Godot physics engine and the Bullet physics engine.

I'll be adding stuff into the documentation soon based on my findings and the range of values was surprising. Below is a quick summary of a few things I remember of the top of my head:

Just to react directly on the OP mentioning setting suspension to 10:

suspension_travel is the amount the suspension can move from resting point (controlled by wheel_rest_length). The bullet documentation has this in cm but Godot assumes meters (it really depends on the size of your car in game off course), so if you set this to 10, thats not going to do you much good. In my test I have this set to 0.1 which is a 10cm travel, which is pretty normal for a car, probably even high for a race car.

suspension_stiffness is how stiff the springs are, I am not sure what the unit is here but the lower this number, the bouncier your car. Bullet suggest a value less then 50 for a offroad car, 50 - 100 for a road car, 200 for something like an Formula one car. For me having a very low racecar I originally had this on 70 or 80 which worked well except when going over a bump, it would compress the spring so much the main collission shape would hit the ground and that would send my car flying. I've got it set to 100 which works well for my racecar but I would set it lower if you have a car with a more normal ride height. But definately not as low as 10 :)

suspension_max_force, again I don't know the units but this was the setting I had the most problems understanding. It caps the maximum force the springs can counter, setting this to something as low as 10 makes the spring completely non-functional. I've found the minimum value that doesn't bottom out the car is a quarter of the weight of the car which makes sense as each spring holds a quarter of the weight of the car, but it is far too low in practice, the moment the springs start to work they get easily overpowered as the forces working on the springs are a multiple of this. I found a value of 1000 worked well for my racecar.

damping_compression and damping_relaxation effect the damping on respectively compressing the spring and decompressing the springs. A value of 0.0 means no damping and your car will keep bouncing around. The documentation suggested putting relaxation slightly higher then compression. For a normal car values of respectively 0.3 and 0.5 seem to work well, for my racecar I've got it on 0.5 and 0.8 which seems to work well but I'm still playing around with it

Finally the last two settings that are important to note: wheel_roll_influence is a value that counters rolling the car. 0.0 and your car will easily roll, 1.0 and your car won't have body roll, but from what I've read its mostly trickery and not real physics. I've set mine at 0.5 and it works fine. wheel_friction_slip is a value combined with the friction of the road and basically determine how grippy your tires are. 0.0 means no grip at all, 1.0 should be full grip but I think there is more going on here with multiplying the friction of the surface and the wheels being able to loose grip. For a F1 car you'd thus probably put this even higher. If you set the rear wheels grip lower then your front wheels, you can have fun making donuts :) I've found a value around 0.9 - 1.0 on all tires works well for driving on tarmac. This can be a fun value to play around with to simulate wear on tires :)

The only problem I have left is that when my car was in rest it would still slowly slide away even when the brake is on. The car was on a slope and the fiction on the road was lowered so that might explain that but its something that I think needs more investigation (@AndreaCatania already has a copy of my setup).

The other thing here I think that could use a bit more work is that when the wheels loose grip, they stop turning instead of spinning freely if engine_force is still set. That would be a neat thing to implement. Also I think we should be able to get feedback of the speed at which the wheels are rotating but thats not relative to this discussion :)

Zireael07 commented 6 years ago

Wheel roll influence is indeed trickery. Godot's car implementation is basically a 1:1 copy of the Bullet physics raycast vehicle, so a couple months back I added the roll influence hack the Bullet raycast vehicle has to be able to avoid rolling over all of the time. I admit I don't really understand how it works, but I went with a value of 0.5 in my project too :)

MrMinimal commented 6 years ago

Basically the same issue as mentioned here. Just confirmed the shaking behaviour with the truck demo project for both Bullet and GodotPhysics.

shake with Bullet

LinuxUserGD commented 6 years ago

The shaking / vibration doesn't happen in bullet with this car setup: https://github.com/Zireael07/FreeRoamRoguelikeRacerPrototype https://github.com/HugeGameArtGD/Solus-Stunts

But it turns into vibrations after resizing / extending the collision shape.

MrMinimal commented 6 years ago

@LinuxUserGD Can confirm... what a weird kind of behavior.

LinuxUserGD commented 6 years ago

But only for the TruckTownDemo?

BastiaanOlij commented 6 years ago

I don't have it as bad as the truck town demo but when I ported the truck town demo to Godot 3 I didn't spend any time tweaking/improving settings.

The new demo project I'm working on which uses the settings I described above results in a pretty stable car when moving. Only when standing still on sloped ground it still gets moved ever so slightly.

So there is definately still an issue somewhere but with the right setup almost all issues are fine.

@LinuxUserGD keep in mind that the bullet examples you are referring to probably have cars that are way better set up then the ones in truck demo.

MrMinimal commented 6 years ago

Well its hard for users of the engine to determine what settings work. Trial and error seems to be the only option right now. Its rightfully still a bug.

On 22 Feb 2018 11:48 PM, "Bastiaan Olij" notifications@github.com wrote:

I don't have it as bad as the truck town demo but when I ported the truck town demo to Godot 3 I didn't spend any time tweaking/improving settings.

The new demo project I'm working on which uses the settings I described above results in a pretty stable car when moving. Only when standing still on sloped ground it still gets moved ever so slightly.

So there is definately still an issue somewhere but with the right setup almost all issues are fine.

@LinuxUserGD https://github.com/linuxusergd keep in mind that the bullet examples you are referring to probably have cars that are way better set up then the ones in truck demo.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/12521#issuecomment-367849482, or mute the thread https://github.com/notifications/unsubscribe-auth/AIVbam-rm76wEqpeKWy8js5TcHNScCPuks5tXe7RgaJpZM4QLuQT .

BastiaanOlij commented 6 years ago

@MrMinimal yes and no.

Not using the right settings isn't a bug. It is however a problem in lack of documentation (which is why I've submitted a PR with that information to be added to the documentation) and a lack of tutorials (which is why I'll be making a video this weekend on the subject and will likely eventually do a write-up for the tutorial section in the Godot docs).

The car not standing completely still when the settings are within sensible ranges is however a bug and I've send my test files to @AndreaCatania so he can play around with them. I still haven't ruled out however that the fault lies in my code :)

LinuxUserGD commented 6 years ago

Strangely the extent setting of the collision shape influences how the car behaves on ground:

bug.zip

BastiaanOlij commented 6 years ago

@LinuxUserGD I'll try out your test when I'm home tonight.

I have had problems with the collision shape of the car hitting the ground when the suspension is set to soft and the car bottoms out. The collision results in a big impulse (Newtons third law, For every action, there is an equal and opposite reaction) often sending the car flying.

It's hard to say at this point in time whether that is a bug in the physics engine or whether that is a consequence of setting up a car with to much suspension travel. I do think the impulse provides far to much force to the car for the behaviour though so there may very well be an error in those calculations.

BastiaanOlij commented 6 years ago

Ok guys, I was preoccupied with my own demo and completing a video about setting up a Vehicle Body based car, took way more time then I should have spend on it. So I haven't had time to look into any of the other examples.

Researching things I came across this document: http://blender3d.org.ua/forum/game/iwe/upload/Vehicle_Simulation_With_Bullet.pdf

This is a writeup by someone who as far as I can tell has added the same functionality in the blender game engine and discusses the types of problems he's run into, a number of them sound very familiar to us :)

Thanks to him I finally found out how Max Force is supposed to be taken into account so I'll update the documentation on that soon as well. In a nutshell, it is the counter force the spring provides at full compression. Setting it extremely high amplifies the spring so that might not be a good idea.

Anyway, the chapter on friction in that document describes how forces enacting on wheels are implemented and how each wheel being individually checked leads to the jittering issues.

I'm just putting this info here because I am at work and I don't have time to test any of this out and see if implementing this solution in Godot actually resolves anything. I'll be experimenting more on this later in the week.

BastiaanOlij commented 6 years ago

Finally got a chance to do some debugging specifically looking at the issue of the car jittering and turning around its axis when its standing still.

I think our problem lies in the application of _resolve_single_bilateral: https://github.com/godotengine/godot/blob/master/scene/3d/vehicle_body.cpp#L526

I don't think the code itself is wrong, it actually looks like its doing the right thing. "body2" for us is always the ground which is never in motion so the code in theory could be greatly simplified. One thing that was interesting in comparing the code with the original bullet code is that at the end the contactDamping value for us is 0.4 while it's 0.2 in bullet. Changing it to 0.2 does help a lot but you can see the problem is still there, just limited.

The issue seems to be in the strength of the impulses. One thing that for my example exaggerated things was that my wheels where not exactly mirrored, they were slightly off its enough that you quickly get a small imbalance in counter forces growing into an angular momentum that starts a feedback loop.

The other thing that I think is related, and maybe where the contactDamping is hiding the problem, is that we calculate this impulse every frame and apply it every frame. There doesn't seem to be anything that takes into account our time delta. That would be fine if it was a single impulse but not one applied every frame. Unlike our forward impulse which gets s->get_step() applied.

I'm wondering if our contactDamping should be replaced by s->get_step() ?

AndreaCatania commented 6 years ago

The other thing that I think is related, and maybe where the contactDamping is hiding the problem, is that we calculate this impulse every frame and apply it every frame. There doesn't seem to be anything that takes into account our time delta. That would be fine if it was a single impulse but not one applied every frame. Unlike our forward impulse which gets s->get_step() applied.

This make thing more consistent when you change the fixed delta time from 60 to 120 or 30. It prevent to have different behaviours but doesn't fix the problem since the physics delta time in godot is fixed.

I think that we need to implement an extra algorithm that simulate the anti roll bar of car: https://en.wikipedia.org/wiki/Anti-roll_bar in this way we will be able to connect the two wheels that will result more stable

BastiaanOlij commented 6 years ago

Hmmm, then I'm guessing the value of 0.4 was decided upon after experimenting what would work, but that is heavily dependent on positioning of the wheels, roll influence etc, I wonder if dividing it by roll influence together with the much lower step value was the main ingredient in atleast getting it to be stable.

I do agree, we need something better...

drarem commented 6 years ago

Ugh.. any other ideas?

LinuxUserGD commented 6 years ago

@drarem https://github.com/godotengine/godot-demo-projects/pull/238

AndreaCatania commented 6 years ago

What's the status of this issue?

LinuxUserGD commented 6 years ago

I think it's fixed

DVLP commented 5 years ago

@LinuxUserGD In which version was it fixed?

LinuxUserGD commented 5 years ago

@DVLP It was fixed in the truck town demo and bullet seems to be ok (godot physics is deprecated).