Discussion Setting Touchdown Points for Vessels on Solid Planet Surfaces II: Friction Coefficients and Why Vessels Slide Down Hills Even With the Brakes On.

Thunder Chicken

Resident Lua Script Rabble-Rouser
Donator
Joined
Mar 22, 2008
Messages
5,847
Reaction score
5,509
Points
188
Location
Massachusetts
I've talked about the touchdown point model at length in other posts, but mostly with a focus on the normal spring forces and displacements in that model. Another aspect of that model are lateral frictional forces, which unfortunately are modeled very simplisticly and, due to the incorporation of the collision model and the landing gear touchdown models into the same function, means that it currently cannot be tweaked/hacked/modified to accurately model even simple landing skids, never mind wheels and braking systems. As I am working to develop more usable functions for these features in my add-ons, I figured a technical discussion of the problems in the current model and the typical hacks to attempt to remedy them could be useful for others struggling with it.

Setting up the touchdown model might look something like this:

Code:
stiffness_value = (rho*g)/4
 
damping_value = math.sqrt(4.0*empty_mass*stiffness_value) --critical damping

mu_value = 0.2

td_points  =
{
     {pos = {x = 0.5, y = 0.0, z = 0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
     {pos = {x = -0.5, y = 0.0, z = 0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
     {pos = {x = 0.5, y = 0.0, z = -0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
     {pos = {x = -0.5, y = 0.0, z = -0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
     {pos = {x = 0.5, y = 1.0, z = 0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
     {pos = {x = -0.5, y = 1.0, z = 0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
     {pos = {x = 0.5, y = 1.0, z = -0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
     {pos = {x = -0.5, y = 1.0, z = -0.5}, stiffness = stiffness_value, damping = damping_value, mu = mu_value, mu_lng = mu_value},
 
}
vi:set_touchdownpoints(td_points)

We've discussed previously how the stiffness and damping values are inputs to the mass-spring-damper model that defines the normal contact forces and displacements of the touchdown points. We'll now focus on the additional parameters in the point definitions, mu and mu_lng. These values define the dynamic or kinetic friction coefficient between two surfaces which may be made of different materials and have different mechanical textures, which influence these coefficients. They are unfortunately only one part of a dry friction model. The dynamic friction force between the two surfaces, acting orthogonal to the surface normal, is calculated as:

[math] F_{fd} = \mu_d F_n[/math]

[imath]\mu_d[/imath] is the dynamic friction coefficient that can vary from 0 to 1, and [imath]F_n[/imath] is the normal force pushing the surfaces together. The model applies a general value of [imath]\mu_d[/imath] a.k.a. mu that is applied generally in any direction of relative motion, and a value [imath]\mu_{dlng}[/imath] a.k.a mu_lng that acts in the longitudinal direction of the vessel. This would permit some rudimentary skids or runners to be modeled, where it may be easier to slide front to back but less easy side to side (if you consider the metal runners on old fashioned snow sleds, that is about the right idea).

This dynamic frictional force will oppose relative motion between a touchdown point and a surface, but it cannot halt motion completely. For example, if you take a situation that looks like this, of a simple block on a ramp [from Wikipedia]:

300px-Free_body_diagram2.svg.png

If only dynamic friction is modeled in this situation, the block will slide down the slope and will not stop. How fast it slides depends on the friction coefficient and the normal force, but it cannot remain stationary as the friction force vector is in the direction opposite of vessel motion.

However, you may know that simply because you put an object on a slope doesn't necessarily mean that it must slide down it when released. The object may remain stationary on a somewhat rough surface at modest but non-zero slope angles. However, if you increase the slope, or apply an external force, at some point it will overcome that static friction and start sliding. This is the second (missing) part of the friction model - the static friction. It is defined with an equation similar to the dynamic friction:

[math] F_{fs} = \mu_s F_n[/math]

Here [imath]\mu_s[/imath] is the static friction coefficient that can vary from 0 to 1. [imath]F_{fs}[/imath] is the minimum lateral force required to initiate sliding motion. Any lateral force less than that will be opposed by the static friction force and the object will remain stationary. Once the force exceeds this value, the object begins to slide and the dynamic friction model takes over.

To be fair, the reason the touchdown model neglects the static friction component is that that would require continuous calculation of normal contact forces and lateral static forces for every touchdown point and integration of all the forces acting on the vessel, then extracting the lateral components to each touchdown point to see if they exceed the static limit. For general collision it's not bad for modeling a vessel hull crashing about on surface terrain, but without the static friction it's completely unusable for any sort of landing gear system unless you want to model ice skates on ice. Simple skids like on many helicopters cannot be modeled - the vessel will slide under the slightest lateral force or slope.

It also cannot be used to model wheel motion at all for the same reason. You could establish the general dynamic coefficient mu to be a large number (to resist motion laterally), but make mu_lng low, making it mimic sliding/rolling forward to some degree. But what if you want to hit the brakes to stop? Well, you could try switching mu_lng to a high number (1.0) which would increase dynamic friction in the direction of motion, but you will continue to slide. And you can't park on a slope of any angle greater than exactly 0 without sliding. Depending on the aerodynamic properties of your vessel, simply enabling wind can cause your vessel to slide on its landing gear because there is no static friction cabability.

So I use the touchdown point model to establish the collision point cloud for the vessel, but I generally just set mu and mu_lng to zero for the touchdown points associated with landing gear and basically implement my own models for wheel and brake action using add_force. In my J-3 add-on, I had good results modeling lateral tire friction by eliminating any lateral sliding motion with a function that forced lateral momentum to zero each time step:

Code:
function set_feature.Set_Rolling_Wheels()

    --Following is to mimic realistic rolling tires without side scrub

    if vi:get_groundcontact() then

        local groundspeed = vi:get_groundspeedvector(REFFRAME.LOCAL)
        local side_slip = groundspeed.x
        local mass = empty_mass + vi:get_propellantmass(main_fuel_tank)
        local simdt =  oapi.get_simstep()

        side_force = mass * side_slip /simdt
   
        vi:add_force({x=-side_force, y=0, z=0}, {x=0,y=right_wheel_contact.y,z=right_wheel_contact.z})
   
    end
   
end

This does not permit ANY lateral motion of the touchdown points, which is fine for the J-3 because it realistically doesn't ever skid sideways. This could potentially be improved by noting that side_force is opposing all of the lateral forces on the vessel. If a normal contact force could be calculated from from the touchdown point stiffness and deflection, a static friction coefficient could be applied to define the maximum lateral static force before the tire starts to skid, and that could be compared to side_force, modifying the above code with something like this:

Code:
mu_s = 0.3 --static friction coefficent
mu_d = 0.2 --dynamic friction coefficient

spring_deflection = ??? --need way to get touchdown point normal deflection from Orbiter (TBD)

F_n = stiffness*spring_deflection --normal force calculated from spring model
F_fs = mu_s*F_n --maximum static friction force

side_force = mass * side_slip /simdt

if side_force <= F_fs then --side force insufficient to cause lateral tire skid, apply side_force as opposing force.

    side_force = side_force

elseif side_force > F_fs --side force overcomes static friction, side force is dynamic friction force

    side_force = mu_d*F_n

end

vi:add_force({x=-side_force, y=0, z=0}, {x=0,y=right_wheel_contact.y,z=right_wheel_contact.z})

This could produce a model that would allow both rolling and skidding lateral motion of a wheel.

Brakes can be implemented by a similar add_force model in the longitudinal direction. In my J-3 addon, I basically specify the maximum braking acceleration (1 g or 9.81 m/s2) and use add_force to deliver it to each main wheel indendently. If the vessel is stationary and the brakes are applied, I set the braking force to exactly match the longitudinal component of thrust parallel to the surface, so static engine run-ups can be modeled. The independent brakes permit very good ground steering control, allowing one to increase thrust and apply one of the main wheel brakes which allows a very tight turn about one touchdown point. This model does not include surface static or dynamic friction effects, so the wheels can't skid in the longitudinal direction if the brakes are locked up, but that could be implemented in a similar fashion to the lateral tire skid model.

Code:
function set_feature.Apply_Brake_Force()
 
    local groundspeed = vi:get_groundspeedvector(REFFRAME.LOCAL)
    local forward_speed = groundspeed.z
    local mass = empty_mass + vi:get_propellantmass(main_fuel_tank)
    local simdt =  oapi.get_simstep()

    if forward_speed == 0 then --set brake force to counter thrust parallel to ground

        F = vi:get_thrustvector(th_main)
        pitch = vi:get_pitch()

        brake_force = 0.5*F.z*math.cos(pitch)

    else

        if math.abs(forward_speed/simdt) > 9.81 then

            --determine if velocity is positive or negative
           
            if forward_speed > 0 then
           
                brake_force = 0.5*mass*9.81

            else

                brake_force = -0.5*mass*9.81

            end

        else

            brake_force = 0.5*mass*forward_speed/simdt
       
        end

    end

    return brake_force

end

For wheel-driven vehicles, where the propulsive force is delivered by friction between the tires and ground, that could be implemented similar to the braking model, just using add_force to deliver a propulsive force vs. a braking force.

This is all more-or-less doable, and many have done similar things. The major problem with this is the usage of multiple instances of add_force which must continuously be calculated and applied to keep the vessel stationary. But, no matter how well implemented, getting the vessel velocity to achieve exactly 0 with numerous force vectors continuously pushing on the vessel is nearly impossible, and so the vessel never achieves a Landed state, which raises havoc when attempting to use time warp. Many add-ons (mine included) are notoriously unstable at any time acceleration due to this reliance on add_force. There may be ways to protect from these instabilities, perhaps by not applying the add_force calculation when the force is close to zero, but all instances of add_force must be checked and shut down like this. Many add-ons simply disable time warp as the nuclear option to "fix" the problem.

This is about the state of affairs for modeling landing points and wheels in Orbiter - there is little or nothing suitable within Orbiter itself, and so add-on developers are left to flail in the wilderness trying to hack something that kinda works. If anything, I wanted to start this discussion to see if something more generally applicable to ground handling models could be developed and implemented in perhaps a helper function manner, something more suitable than the current touchdown point model.
 
Last edited:
Back
Top