The demo car in my Minetest Vehicles mod can accelerate, so far so good. But it won’t slow down on its own because of Newton’s first law of motion, due to the lack of resisting forces, namely:
- Rolling Resistance
- Aerodynamic drag
- Engine brake
To make a vehicle slow down, we need to apply all of these resisting forces. This article discusses what rolling resistance is, how it’s calculated and how it’s implemented in the mod itself.
What is rolling resistance?
Rolling resistance is a force, that affects rolling objects and points to the opposite direction of movement, therefore slowing the motion down until it stops. It is only applied to rolling objects and disappears when they stop rolling. The counterparts are sliding friction for sliding objects (this one is interesting when the wheels lock up) and stiction, which has to be overcome to make a stationary object move.
The formula used to calculate rolling resistance (Frr) is relatively easy and doesn’t contain any big surprises:
Crr is the so called rolling resistance coefficient. You can use pre-calculated values of Crr, or calculate in on your own. This may be required if you are in a non-standard scenario (big wheels or special ground). In the latter case, you would use this formula:
z is the sinkage depth of the wheel, r is the wheel’s radius. For now we’ll just use a pre-calculated value of 0.015 (car tires on concrete) for Crr to keep it simple.
Fn is the normal force:
m is the mass of the object, ɑ is the slope angle, g is the gravitational acceleration.
We’ll split the calculation up in two standalone functions: one for Frr and one for Fn because we might need Fn again in another context. The unknown variables are Crr, m and ɑ; g is a constant (9.81 m/s2).
In theory, all we need to do now is to call
f_rr() every frame and apply the returned force to the vehicle. In practice, we have to deal with something that we previously ignored: Forces are vectors. On the one hand, this makes our code bit more complex, on the other hand these vectors include the information of movement direction. We need this information to make sure our will work in all directions, not just one. Also it’s worth noting that Minetest comes with a useful set of vector helpers.
Note the angle argument in line 6 being 0 because there are no real slopes in Minetest and the method get_mass() which should be self-explanatory.
The attentive reader might have noticed a function in the code that I didn’t mention yet:
This helper function returns the direction of movement of the vehicle which is either a unit vector (length 1) or the zero vector. It is calculated by normalizing the velocity vector. Without normalization, the length of the vector would be > 1, resulting in a manipulated rolling resistance.
It also comes in handy when determining whether the car is moving at all (remember: rolling resistance only affects rolling objects). If the speed of the car (and therefore the velocity) is 0,
vector.normalize() returns the zero vector (0, 0, 0) and makes the rolling resistance 0, too.
The code then multiplies the direction vector
vec and the rolling resistance
frr and applies the resulting force vector to the vehicle.
We now have a working implementation rolling resistance that should slow the car down when releasing the accelerator pedal. The next article will discuss the implementation of aerodynamic drag.