Discussion Nosewheel Steering (sample + code)

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
One of the most annoying things about wheeled Orbiter vessels is that the nosewheel steering is extremely poor. I've got this great airport Wideawake, but none of the vessels out there can turn tight enough for the taxiways!

Sample Solution:
https://webspace.utexas.edu/btb289/www/Orbiter/Modules/DeltaGlider_wheel.zip
This is a replacement for the default DeltaGlider.dll in the Modules directory of your Orbiter install. Make a backup beforehand, if it matters to you.

The Details:
There is an undocumented function in the Vessel class, SetNosewheelSteering(bool), which wheeled vessels currently use. However, the turn rate even with this active is still fairly pitiful and makes it difficult to navigate taxiways.

Here's a simple solution I came up with which adds a more realistic tighter turning radius to the default DG: (all code first, then an analysis after)
Code:
void DeltaGlider::clbkPreStep (double simt, double simdt, double mjd)
{
    if (gear_status == DOOR_OPEN && GetAirspeed() > 0 && GetAltitude() < GetCOG_elev() + .001) {
        VECTOR3 pt1, pt2, pt3;

        double airspd = GetAirspeed();
        GetTouchdownPoints(pt1, pt2, pt3);
        double wheelbase = pt1.z - (pt2.z + pt3.z) / 2.0;
        double max_deflection = airspd < 10.0 ? 15.0 : 15.0 - 15.0 * ((airspd - 10.0) / 90.0);
        if (max_deflection < 0.0)
            max_deflection = 0.0;
        double theta = -max_deflection * GetControlSurfaceLevel(AIRCTRL_RUDDER);

        VECTOR3 avel;
        GetAngularVel(avel);
        avel.y = airspd/(wheelbase * tan((90 - theta) * PI / 180));
        SetAngularVel(avel);
    }
}
Note that this adds a clbkPreStep function to the DG, which doesn't currently have it.

The maths:
Code:
    if (gear_status == DOOR_OPEN && GetAirspeed() > 0 && GetAltitude() < GetCOG_elev() + .001) {
This only turns the ship if the gear is deployed, the vessel is moving, and the nosegear is on the ground (estimated by checking the altitude).

Code:
        double wheelbase = pt1.z - (pt2.z + pt3.z) / 2.0;
This determines the length of the wheelbase in meters by finding the distance between the nose gear and the point between the main gears, in the z direction.

Code:
        double max_deflection = airspd < 10.0 ? 15.0 : 15.0 - 15.0 * ((airspd - 10.0) / 90.0);
        if (max_deflection < 0.0)
            max_deflection = 0.0;
This calculates the maximum angle of the nosegear--for speeds under 10m/s, the maximum angle is 15 degrees...for speeds between 10 and 100 m/s, the maximum angle is a decreasing line from 15 to 0 degrees, and for speeds above 100m/s the maximum angle is 0 degrees. These numbers can be adjusted to suit the desires of the vessel.

Code:
        double theta = -max_deflection * GetControlSurfaceLevel(AIRCTRL_RUDDER);
This determines the actual angle of the nosegear (theta), based on the rudder deflection.

Code:
        avel.y = airspd/(wheelbase * tan((90 - theta) * PI / 180));
This determines the rotational velocity by making use of the equations:

Code:
radius (m) = wheelbase * tan(90 - theta)
and
Code:
turning rate (rad/s) = spd / radius
The PI / 180 is to convert "90-theta" into radians from degrees.

Thoughts?
 
Last edited:

TSPenguin

The Seeker
Joined
Jan 27, 2008
Messages
4,075
Reaction score
4
Points
63
I tried it and it adds a whole new level of immersion to ground operations.
This code should be mandatory for any vessel capable of nose wheel steering and adjusted with fixed values to reflect the model.

It could very well be the basis for a generic (4 Wheel) vehicle SDK which enables realistic driving. And indeed, all it needs is a function to determine acceleration and maximum speed.

Very well done, I salute you!
 

DarkWanderer

Active member
Orbiter Contributor
Donator
Joined
Apr 27, 2008
Messages
213
Reaction score
83
Points
43
Location
Moscow
From the looks of the code, there will be a problem: SetAngularVel will totally cancel rudder effect when rolling on runway on high speed. This will be an issue for high takeoff speed vessels like HyperDart.
However, a good thing to start with. Well done.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
From the looks of the code, there will be a problem: SetAngularVel will totally cancel rudder effect when rolling on runway on high speed. This will be an issue for high takeoff speed vessels like HyperDart.
However, a good thing to start with. Well done.
Good catch, thanks. Easy fix, though...replace the "avel.y = ..." line with:

Code:
        double newvel = airspd/(wheelbase * tan((90 - theta) * PI / 180));
        if (fabs(newvel) > fabs(avel.y))
            avel.y = newvel;
This way, the nosewheel steering rotational velocity will only overwrite the existing rotational velocity if it would have a larger effect.

I've updated the .zip file linked in the first post with this change.
 

Jax6213

Donator
Donator
Joined
Feb 22, 2008
Messages
36
Reaction score
0
Points
0
Location
Seattle
I love it! Thank you!

FINALLY someone dealt with this issue!
 

sputnik

Addon Developer
Addon Developer
Donator
Joined
Apr 3, 2008
Messages
424
Reaction score
0
Points
31
Location
Palmdale
Website
www.worldof2001.com
Nice!

I use a nosewheel steering code based on David Hopkins' nosewheel steering code, but it works using AddForce, not setting avel.y directly. This might be in improvement I carry through all my vehicles.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Nice!

I use a nosewheel steering code based on David Hopkins' nosewheel steering code, but it works using AddForce, not setting avel.y directly. This might be in improvement I carry through all my vehicles.
I tried using AddForce, but:
a) I didn't know how to calculate the correct forces for the gear
b) The surface contact friction parameters cannot be overridden for only one wheel, so I'd have to manually recalculate the friction on the rear wheels

The advantage of using AddForce might that if you turn too sharply at high speed, you can (realistically) flip over. With this method you can't do that, unfortunately.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
The advantage of using AddForce might that if you turn too sharply at high speed, you can (realistically) flip over. With this method you can't do that, unfortunately.
Why not? Doesn't setting the angular velocity create a side slip which reacts against the latitudinal friction? I think Orbiter sets the attack point for the surface friction at the touchdown points, so it should be possible.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Why not? Doesn't setting the angular velocity create a side slip which reacts against the latitudinal friction? I think Orbiter sets the attack point for the surface friction at the touchdown points, so it should be possible.
Even before adding the angle limiter at high speeds, I just ended up sliding sideways, not flipping over...

---------- Post added at 05:12 PM ---------- Previous post was at 01:36 PM ----------

This is great stuff, will you make it compatable with the XR-ships, also. thank you
Since the XR vessels are closed-source, I can't make it work with them.

However, I can make it work with *all* vessels. Try this. It's a normal Orbiter plugin, so you'll have to activate it in the launch pad.

Let me know how well it works...
https://webspace.utexas.edu/btb289/www/Orbiter/Modules/NoseWheelTurn.zip
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Thank you HIELOR, and keep up the great work. and I'll let you know.
I literally just (like a minute ago) uploaded a new version with a very minor change--it shouldn't be noticeable, but that's the hope. It will now only affect vehicles that had set the built-in nosewheel steering (via SetNosewheelSteering) to true. Hopefully that will prevent conflicts with any vessels which don't want steering.

Also, I forgot to mention: this is a "Release Candidate" version, here. Try it out with your favorite vessel, let me know if there are issues. If no one's reported any major problems in the next couple days, I'll upload it to OrbitHangar.

Thanks!
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Even before adding the angle limiter at high speeds, I just ended up sliding sideways, not flipping over...

Sounds like Orbiter applies the friction force through the CoG then. Possible alternative method:

1. If nose wheel steering is active, set the longitudinal co-efficient of friction to zero;
2. Calculate the centripetal force from the turning radius and vessel mass, and multiply by a unit vector from the vessel CoG to the turning circle axis;
3. Decompose that vector into two components parallel to a vector from the front wheel to the turning circle axis (vF) and parallel to a vector from the rear wheel to the turning circle axis (vR);
4. AddForce(vF,pt1); AddForce(vR/2,pt2); AddForce(vR/2,pt3);

Thoughts?

EDIT: The above assumes zero side-slip
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Sounds like Orbiter applies the friction force through the CoG then. Possible alternative method:

1. If nose wheel steering is active, set the longitudinal co-efficient of friction to zero;
2. Calculate the centripetal force from the turning radius and vessel mass, and multiply by a unit vector from the vessel CoG to the turning circle axis;
3. Decompose that vector into two components parallel to a vector from the front wheel to the turning circle axis (vF) and parallel to a vector from the rear wheel to the turning circle axis (vR);
4. AddForce(vF,pt1); AddForce(vR/2,pt2); AddForce(vR/2,pt3);

Thoughts?

EDIT: The above assumes zero side-slip
That's similar to what I tried in the first time, and it had some issues. The current method seems to work more reliably.

A problem I see with your approach is that the vessel will be moving sideways after the application of those forces, since there is no friction and you have two forces applied to the vessel pointing toward the turn axis...
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
A problem I see with your approach is that the vessel will be moving sideways after the application of those forces, since there is no friction and you have two forces applied to the vessel pointing toward the turn axis...
IRL, what happens is that when the first steering motion occurs from a straight line, the front wheel applies a torque that increases the angular velocity if the vessel (and linear momentum is exchanged for angular momentum). Once the angular velocity reaches the required value the lateral forces on the front and rear wheel balance out and there is no further torque. That is the state I have modelled above, so you still need to do the SetAngularVel to keep the vessel pointing in the right direction.
 
Top