From e969dbc8f496b2f81ae7f146ebe9cd348df06190 Mon Sep 17 00:00:00 2001 From: Stuart Buchanan Date: Wed, 10 Apr 2013 21:25:59 +0100 Subject: [PATCH] Improve air-to-air refueling by supporting multiple contact points offset from the tanker center, and an offset probe/recepticle position on the receiving aircraft. --- Nasal/geo.nas | 6 +++++ Nasal/tanker.nas | 59 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Nasal/geo.nas b/Nasal/geo.nas index c0d73fd6f..024a52b68 100644 --- a/Nasal/geo.nas +++ b/Nasal/geo.nas @@ -163,6 +163,12 @@ var Coord = { me._pupdate(); course *= D2R; dist /= ERAD; + + if (dist < 0.0) { + dist = abs(dist); + course = course - math.pi; + } + me._lat = math.asin(math.sin(me._lat) * math.cos(dist) + math.cos(me._lat) * math.sin(dist) * math.cos(course)); diff --git a/Nasal/tanker.nas b/Nasal/tanker.nas index 420d09fd2..18d962693 100644 --- a/Nasal/tanker.nas +++ b/Nasal/tanker.nas @@ -70,7 +70,7 @@ var identity = { var Tanker = { - new: func(aiid, callsign, tacan, type, model, kias, maxfuel, pattern, heading, coord) { + new: func(aiid, callsign, tacan, type, model, kias, maxfuel, pattern, contacts, heading, coord) { var m = { parents: [Tanker] }; m.callsign = callsign; m.tacan = tacan; @@ -79,6 +79,7 @@ var Tanker = { m.out_of_range_time = 0; m.interval = 10; m.length = pattern; + m.contacts = contacts; m.roll = 0; m.coord = geo.Coord.new(coord); m.anchor = geo.Coord.new(coord).apply_course_distance(m.track_course, m.length); # ARCP @@ -218,9 +219,43 @@ var Tanker = { me.brgN.setDoubleValue(me.bearing); me.elevN.setDoubleValue(elev); - me.contactN.setBoolValue(me.distance < ac_contact_dist and - dalt > 0 and - abs(view.normdeg(me.bearing - ac_hdg)) < 20); + # Determine if any of the contact points are in contact + var offset_x = getprop("/systems/refuel/offset-x-m") or 0; + var offset_y = getprop("/systems/refuel/offset-y-m") or 0; + var offset_z = getprop("/systems/refuel/offset-z-m") or 0; + var roll = getprop("/orientation/roll-deg") * globals.D2R; + + # Determine contact position + var probe_pos = geo.Coord.new(me.ac); + + probe_pos.apply_course_distance(ac_hdg, offset_x); + probe_pos.apply_course_distance(ac_hdg + 90, offset_y * math.cos(roll) + offset_z * math.sin(roll)); + probe_pos.set_alt(me.ac.alt() + offset_z * math.cos(roll) - offset_y * math.sin(roll)); + + me.contactN.setBoolValue(0); + + foreach (var c; me.contacts) { + var drogue_pos = geo.Coord.new(me.coord); + + # Offset longitudonally + drogue_pos.apply_course_distance(me.course, c.x); + + var r = me.roll * globals.D2R; + + # Offset laterally, taking into account any roll + drogue_pos.apply_course_distance(me.course +90, c.y * math.cos(r) + c.z * math.sin(r)); + + # Offset vertically, again, taking into account any roll + drogue_pos.set_alt(drogue_pos.alt() + c.z * math.cos(r) - c.y * math.sin(r)); + + #print("Distance: " ~ probe_pos.distance_to(drogue_pos) ~ " vs. " ~ me.distance); + + if (probe_pos.distance_to(drogue_pos) < ac_contact_dist and + abs(view.normdeg(me.course - ac_hdg)) < 20) { + # Contact! + me.contactN.setBoolValue(1); + } + } me.hOffsetN.setDoubleValue(me.bearing - ac_hdg); me.vOffsetN.setDoubleValue(elev - ac_pitch); @@ -278,13 +313,27 @@ var create_tanker = func(tanker_node, course) { var spd = tanker_node.getNode("speed-kts", 1).getValue() or 250; var pattern = (tanker_node.getNode("pattern-length-nm", 1).getValue() or 50) * NM2M; var maxfuel = tanker_node.getNode("max-fuel-transfer-lbs-min", 1).getValue() or 6000; + + var contacts = []; + + foreach (var contact; tanker_node.getChildren("contact")) { + var x = (contact.getNode("x-m") != nil) ? contact.getNode("x-m").getValue() : 0; + var y = (contact.getNode("y-m") != nil) ? contact.getNode("y-m").getValue() : 0; + var z = (contact.getNode("z-m") != nil) ? contact.getNode("z-m").getValue() : 0; + append(contacts, { "x" : x, "y" : y, "z" : z }); + } + + + if (size(contacts) == 0) { + append(contacts, {x: 0, y:0, z:0}); + } var alt = int(10 + rand() * 15) * 1000; # FL100--FL250 alt = skip_cloud_layer(alt * FT2M); var dist = 6000 + rand() * 4000; var coord = geo.aircraft_position().apply_course_distance(course, dist).set_alt(alt); - Tanker.new(aiid, callsign, tacanid, type, model, spd, maxfuel, pattern, course, coord); + Tanker.new(aiid, callsign, tacanid, type, model, spd, maxfuel, pattern, contacts, course, coord); } # Request a new tanker