One of my hobby projects involves cars. Up until now I had a quick and dirty "one class" implementation of engine+gearbox+wheels, but I thought that this is ugly, and I want to go a bit more realistic. Sadly I couldn't find much on Google (either wrong search terms or there really isn't anything that is what I want). It seems like
Setup in scene: Four wheelcolliders attached to a big boxcollider.
Things that I want in the system:
Separate classes for engine, clutch, gearbox, differential and wheels (and whatever else does stuff with torque). Throttlecontrol with revlimiter (works!), steering (works too!), brakes (not yet made, but also not very complex and will likely work).
- First thing I tried:
Mainly this rotates around how I tell the engine that the wheels are actually using or giving (engine braking) power to the system. so first I created all the classes each with their own updatemethod
(not called directly by mainloop, but from a fixedupdate of a controllerclass). updatemethod
of engine calculates engine torque from throttle, torque curve (animation curve) and engine friction. This is then used to speed up the virtual crankshaft which has its own inertia. But before speeding up the shaft, I decided to put some feedback torques on the engine torque, so if the wheels can't keep up, the engine can't speed up, or even slows down. Such a feedback torque is added for example by the gearbox, which in turn also has feedback forces from the differential and with that the wheels. The wheels calculate the torque needed to spin up to the speed of the shaft coming out of the gearbox and then it propagates all back to the engine over a few updates.
Problem was, the torque feedback didn't really do engine braking, but catapulted it to several million RPM in a split second. Dividing the feedback torque by 1000 did work, but then the car didn't move at all. So this is fail number 1.
- Fail number 2:
Okay screw this, I thought, and tidied up all the stuff. This doesn't use several updatemethod
anymore, but recursive updating. Basically I call update on the engine, which in turn then calculates what torque it has available. With that it tells the transmission that it has t
torques at r
RPMs. The gearbox changes the values according to the current gear and then again puts the values into the differential. The differential SHOULD split the torque between its outputs. To do this I calculate how much torque the output (in this case wheels) would need to speed up to r
RPMs. I do this for each output and make a list of it for each output. I also save the sum of these values. With this I can get a value of 0...1
for each output, that determines how much torque each output gets in its updatemethod
. Its basically an intelligent differential that gives the output which needs more torque, more torque. I guess modeling a real differential would involve some more complex stuff. Now the torque is at the wheels and gets put into the motorTorque property of the wheelcollider. Up until here it works. If I throttle up and then let go of it the wheels start turning backwards. It's basically another feedbackloop just like with the first try. So also fail
- And fail 3:
Instead of returning the torque that's left, I tried backpropagating the RPMs to the engine instead. So I apply torque, and get RPMs back. But again everything tries to move the car in the opposite direction that I want it to go.
Here is where I'm out of ideas. I want a relatively realistic drivetrain, that is modular and can do enginebraking. A bought asset will most probably not solve my problem, and I also want to understand how it works, and not just use it.
Does anybody have experience with how to properly model a drivetrain?
If I forgot to mention something, please ask.