1 ######################################################################
3 # Terrain reactions for JSBSim (friction, bumpiness, water sinking).
7 # Add the following to ...-set.xml:
12 # <file>path/to/friction.nas</file>
19 # <zsink-in type="double">INCHES</zsink-in>
23 # where N is the index of the point of contact (<zsink-in> should be
24 # specified for every point of contact, not just the gears) and INCHES
25 # is how deep that point should sink in the water.
27 # Information about surface properties will appear in
29 # /fdm/jsbsim/gear/unit[*]/friction/
30 # /fdm/jsbsim/contact/unit[*]/friction/
34 setprop("sim/fdm/surface/override-level", 1);
36 var rain_factor = 0.3;
37 var snow_factor = 0.45;
38 var meters_in_degree = 1852 * 60;
39 var degrees_in_inch = 0.0254 / meters_in_degree;
40 var radians_in_degree = math.pi / 180;
42 var points_of_contact = getprop("fdm/jsbsim/gear/num-units");
44 for (var i = 0; i < points_of_contact; i += 1) {
45 var x = getprop("gear/gear["~i~"]/xoffset-in") * degrees_in_inch;
46 var y = getprop("gear/gear["~i~"]/yoffset-in") * degrees_in_inch;
47 var z = getprop("gear/gear["~i~"]/zoffset-in");
48 var zs = getprop("gear/gear["~i~"]/zsink-in");
55 if (props.globals.getNode("fdm/jsbsim/gear/unit["~i~"]") != nil) {
56 prop = "fdm/jsbsim/gear/unit["~i~"]";
58 r = getprop(prop~"/rolling_friction_coeff");
60 prop = "fdm/jsbsim/contact/unit["~i~"]";
62 var s = getprop(prop~"/static_friction_coeff");
63 var d = getprop(prop~"/dynamic_friction_coeff");
65 append(point_info, { g: g, x: x, y: y, z: z, zs: zs, s: s, d: d, r: r });
69 var update_reactions = func {
70 settimer(update_reactions, 0.1);
72 if (getprop("fdm/jsbsim/position/h-agl-ft") > 100)
75 var lat = getprop("fdm/jsbsim/position/lat-geod-deg");
76 var lon = getprop("fdm/jsbsim/position/long-gc-deg");
77 var rot = -getprop("fdm/jsbsim/attitude/heading-true-rad");
78 var h_cos = math.cos(rot);
79 var h_sin = math.sin(rot);
80 var cg = -getprop("fdm/jsbsim/inertia/cg-x-in") * degrees_in_inch;
82 var rain_coeff = (getprop("environment/rain-norm")
83 or getprop("environment/metar/rain-norm")
85 var snow_coeff = (getprop("environment/snow-norm")
86 or getprop("environment/metar/snow-norm")
88 var wave_amp = ((getprop("environment/wave/amp") or 1) - 1) * 40;
89 var wave_freq = (getprop("environment/wave/freq") or 0) * 60;
91 for (var i = 0; i < points_of_contact; i += 1) {
92 if (!getprop("gear/gear["~i~"]/wow"))
95 var north = (point_info[i].x - cg) * h_cos + point_info[i].y * h_sin;
96 var east = (point_info[i].x - cg) * -h_sin + point_info[i].y * h_cos;
97 var lat_corr = math.cos(lat * radians_in_degree) or 0.0000000001;
99 var p_lat = lat + north;
100 var p_lon = lon + east;
102 var info = geodinfo(p_lat, p_lon);
103 var rolling_friction = point_info[i].r;
104 var dynamic_friction = point_info[i].d;
105 var friction_factor = 1;
108 if (info != nil and info[1] != nil) {
109 friction_factor = info[1].friction_factor;
110 rolling_friction = info[1].rolling_friction;
111 bumpiness = info[1].bumpiness;
112 solid = info[1].solid;
117 z = -point_info[i].z;
118 # Bumpiness has a period of about 16m and an amplitude
119 # of about 1m (40 inches) for bumpiness == 1.
121 var l = p_lon / lat_corr;
122 var dist_m = math.sqrt(p_lat*p_lat + l*l) * meters_in_degree;
123 z += 20 * bumpiness * math.sin(math.pi * dist_m * 0.125);
126 var static_friction = point_info[i].s - rain_coeff - snow_coeff;
127 static_friction *= friction_factor;
128 if (static_friction < rolling_friction)
129 static_friction = rolling_friction;
130 if (static_friction < 0.1)
131 static_friction = 0.1;
134 rolling_friction = 1;
136 z = point_info[i].zs;
137 z += wave_amp * math.sin(wave_freq * systime() + i);
138 static_friction = rolling_friction; # Make brakes ineffective.
141 if (dynamic_friction > static_friction)
142 dynamic_friction = static_friction;
144 var prop = (point_info[i].g
145 ? "fdm/jsbsim/gear/unit["~i~"]"
146 : "fdm/jsbsim/contact/unit["~i~"]");
148 setprop(prop~"/static_friction_coeff", static_friction);
149 setprop(prop~"/dynamic_friction_coeff", dynamic_friction);
151 setprop(prop~"/rolling_friction_coeff", rolling_friction);
152 setprop(prop~"/z-position", z);
154 setprop(prop~"/friction/friction_factor", friction_factor);
155 setprop(prop~"/friction/rolling_friction", rolling_friction);
156 setprop(prop~"/friction/bumpiness", bumpiness);
157 setprop(prop~"/friction/solid", solid);
158 setprop(prop~"/friction/lat", p_lat);
159 setprop(prop~"/friction/lon", p_lon);