Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with bullet physics vehicle #12521

Closed
bkeys opened this issue Oct 30, 2017 · 38 comments
Closed

Issue with bullet physics vehicle #12521

bkeys opened this issue Oct 30, 2017 · 38 comments

Comments

@bkeys
Copy link
Contributor

bkeys commented Oct 30, 2017

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
Copy link
Contributor

AndreaCatania commented Oct 31, 2017

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
Copy link
Contributor

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

@AndreaCatania
Copy link
Contributor

@Zireael07 Thanks you!

@AndreaCatania
Copy link
Contributor

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

@Zireael07
Copy link
Contributor

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

@akien-mga akien-mga added this to the 3.0 milestone Nov 1, 2017
@Zireael07
Copy link
Contributor

@AndreaCatania
Copy link
Contributor

@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:

  • To stop the vibration you should set more stifnnes and max force for each wheel.

Try something like: stiffness 50, MF: 24000

  • To stop the vehicle from going around you must set brake using a script.

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
Copy link
Contributor Author

bkeys commented Nov 4, 2017

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
Copy link
Contributor Author

bkeys commented Nov 4, 2017

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
Copy link
Contributor

@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
Copy link
Contributor

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
Copy link
Contributor

LinuxUserGD commented Dec 20, 2017

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
Copy link
Contributor

AndreaCatania commented Dec 21, 2017 via email

@akien-mga
Copy link
Member

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
Copy link
Contributor

LinuxUserGD commented Feb 16, 2018

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

@AndreaCatania
Copy link
Contributor

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

@BastiaanOlij
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

MrMinimal commented Feb 22, 2018

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
Copy link
Contributor

LinuxUserGD commented Feb 22, 2018

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
Copy link
Contributor

MrMinimal commented Feb 22, 2018

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

@LinuxUserGD
Copy link
Contributor

But only for the TruckTownDemo?

@BastiaanOlij
Copy link
Contributor

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
Copy link
Contributor

MrMinimal commented Feb 22, 2018 via email

@BastiaanOlij
Copy link
Contributor

@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
Copy link
Contributor

LinuxUserGD commented Feb 22, 2018

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

bug.zip

@BastiaanOlij
Copy link
Contributor

@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
Copy link
Contributor

BastiaanOlij commented Feb 26, 2018

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link

drarem commented Apr 10, 2018

Ugh.. any other ideas?

@LinuxUserGD
Copy link
Contributor

LinuxUserGD commented Apr 10, 2018

@AndreaCatania
Copy link
Contributor

What's the status of this issue?

@LinuxUserGD
Copy link
Contributor

I think it's fixed

@DVLP
Copy link

DVLP commented Jun 15, 2019

@LinuxUserGD In which version was it fixed?

@LinuxUserGD
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants