From 36bad881f0f1ada5e13d7f796ce1d7d7aeff0699 Mon Sep 17 00:00:00 2001
From: abory <abory>
Date: Mon, 4 May 2009 10:58:27 +0000
Subject: [PATCH] - Gijs de Rooy: Generic pushback.

---
 Nasal/IOrules      |  1 +
 Nasal/pushback.nas | 26 +++++++++++++++++
 Nasal/tanker.nas   | 71 +++++++++++++++++++++++++++++++++++-----------
 3 files changed, 82 insertions(+), 16 deletions(-)
 create mode 100644 Nasal/pushback.nas

diff --git a/Nasal/IOrules b/Nasal/IOrules
index 91d0abd92..ce7febf18 100644
--- a/Nasal/IOrules
+++ b/Nasal/IOrules
@@ -27,6 +27,7 @@
 
 READ ALLOW $FG_ROOT/*
 READ ALLOW $FG_HOME/*
+READ ALLOW /home/alexis/fgfs/*
 
 WRITE ALLOW $FG_HOME/*.sav
 WRITE ALLOW $FG_HOME/*.log
diff --git a/Nasal/pushback.nas b/Nasal/pushback.nas
new file mode 100644
index 000000000..0456c23dc
--- /dev/null
+++ b/Nasal/pushback.nas
@@ -0,0 +1,26 @@
+# Properties under /sim/model/pushback:
+# + position-norm    - Position of pushback. 1 if connected.
+
+# =====
+# Pushback
+# =====
+
+Pushback = {};
+
+Pushback.new = func {
+   obj = { parents : [Pushback],
+           pushback : aircraft.door.new("sim/model/pushback", 10.0),
+         };
+   return obj;
+};
+Pushback.pushbackexport = func {
+   me.pushback.toggle();
+}
+
+
+# ==============
+# Initialization
+# ==============
+
+# objects must be here, otherwise local to init()
+pushbacksystem = Pushback.new();
diff --git a/Nasal/tanker.nas b/Nasal/tanker.nas
index 4a7f0a5c3..9a5f05dfb 100644
--- a/Nasal/tanker.nas
+++ b/Nasal/tanker.nas
@@ -73,6 +73,33 @@ var identity = {
 	},
 };
 
+# functions to indicate the course [deg] (heading/ground) for a given heading [deg] (true heading) and ktas [kt] 
+# just adding wind.
+
+var heading_to_course_dev = func(ktas, heading) {
+	var alpha = (getprop("/environment/wind-from-heading-deg") - heading - 180) * D2R;
+	var wind_speed = getprop("/environment/wind-speed-kt");
+	return math.atan2(math.sin(alpha) * wind_speed, ktas + math.cos(alpha) * wind_speed) * R2D;
+}
+
+var heading_to_course = func(ktas, heading) {
+	return geo.normdeg(heading + heading_to_course_dev(ktas, heading));
+}
+
+# functions to calculate the needed heading [deg] (true heading) to have a desired course on ground [deg] 
+# for a given ktas [kt] the speed is speed on the heading, not on the course.
+# need some improvement to indicate that it's impossible if the wind is too strong, but don't know what to do for this :)
+
+var course_to_heading_dev = func(ktas, course) {
+	var alpha = (getprop("/environment/wind-from-heading-deg") - course) * D2R;
+	var rapport = math.sin(alpha) * getprop("/environment/wind-speed-kt") / ktas;
+	if (rapport > 1) return 1000; # not sure what to return here to indicate wind will be too strong to achieve course
+	else return math.asin(rapport) * R2D;
+}
+
+var course_to_heading = func(ktas, course) {
+	return geo.normdeg(course + course_to_heading_dev(ktas, course));
+}
 
 var Tanker = {
 	new: func(aiid, callsign, tacan, type, kias, heading, coord) {
@@ -92,6 +119,7 @@ var Tanker = {
 		m.mode = "leg";
 		m.rollrate = 2; # deg/s
 		m.maxbank = 25;
+		m.drift_angle = 0;
 
 		var n = props.globals.getNode("models", 1);
 		for (var i = 0; 1; i += 1)
@@ -150,13 +178,22 @@ var Tanker = {
 
 		if ((me.interval += dt) >= 5) {
 			me.interval -= 5;
-			me.headwind = aircraft.wind_speed_from(me.course);
+			if (me.mode == "leg")
+				 me.headwind = aircraft.wind_speed_from(me.course);
 			me.ktas = aircraft.kias_to_ktas(me.kias, alt);
 		}
 
-		var distance = dt * (me.ktas - me.headwind) * NM2M / 3600;
-		var deviation = me.roll ? 0.5 * dt * 1085.941 * math.tan(me.roll * D2R) / me.ktas : 0;
-
+		if (me.roll) {
+			me.headwind = aircraft.wind_speed_from(me.course);
+			me.heading = me.heading - dt * 1085.941 * math.tan(me.roll * D2R) / me.ktas;
+			me.drift_angle = me.heading - me.course;
+		} else {
+			me.drift_angle = course_to_heading_dev(me.ktas, me.course);
+			me.heading = me.course + me.drift_angle;
+		}
+		var deviation = me.roll ? me.course - heading_to_course(me.ktas, me.heading) : 0;
+		var distance = dt * (me.ktas * math.cos(me.drift_angle * D2R) - me.headwind) * NM2M / 3600;
+		
 		if (me.mode == "leg") {
 			if (me.lastmode != "leg") {
 				me.lastmode = "leg";
@@ -170,7 +207,7 @@ var Tanker = {
 				me.roll_target = 0;
 				me.leg_warning = 0;
 			}
-			if ((me.leg_remaining -= distance) < 0)
+			if ((me.leg_remaining -= distance) > 0)
 				me.mode = "turn";
 
 		} else { # me.mode == "turn"
@@ -183,17 +220,20 @@ var Tanker = {
 			if (!me.full_bank_turn_angle and me.roll >= me.roll_target)
 				me.full_bank_turn_angle = geo.normdeg(180 - me.turn_remaining);
 
-			if (me.turn_remaining < me.full_bank_turn_angle)
-				me.roll_target = 0;
+			#if (me.turn_remaining < me.full_bank_turn_angle)
+			#	me.roll_target = 0;
 
-			if ((me.turn_remaining -= deviation) < 0) {
-				if (me.goal[1] == nil)  # define tanker exit point (opposite of anchor point/ARCP)
-					me.goal[1] = geo.Coord.new(me.coord).apply_course_distance(me.track_course - 180,
-							me.length);
-				me.mode = "leg";
-			}
+			#if ((me.turn_remaining -= deviation) < 0) {
+			#	if (me.goal[1] == nil)  # define tanker exit point (opposite of anchor point/ARCP)
+			#		me.goal[1] = geo.Coord.new(me.coord).apply_course_distance(me.track_course - 180,
+			#				me.length);
+			#	me.mode = "leg";
+			#}
+			me.headwind = aircraft.wind_speed_from(me.course);
+			
 		}
 
+		
 		me.coord.apply_course_distance(me.course -= deviation, distance);
 
 		me.ac = geo.aircraft_position();
@@ -206,7 +246,7 @@ var Tanker = {
 		me.latN.setDoubleValue(me.coord.lat());
 		me.lonN.setDoubleValue(me.coord.lon());
 		me.altN.setDoubleValue(alt * M2FT);
-		me.hdgN.setDoubleValue(me.heading = me.course);
+		me.hdgN.setDoubleValue(me.heading);
 		me.pitchN.setDoubleValue(0);
 		me.rollN.setDoubleValue(-me.roll);
 		me.ktasN.setDoubleValue(me.ktas);
@@ -261,7 +301,6 @@ var Tanker = {
 };
 
 
-
 var request = func {
 	var tanker = values(Tanker.active);
 	if (size(tanker))
@@ -276,7 +315,7 @@ var request = func {
 	var hdg = getprop("orientation/heading-deg");
 	var course = hdg + (rand() - 0.5) * 60;
 	var dist = 6000 + rand() * 4000;
-	var alt = int(10 + rand() * 15) * 1000;  # FL100--FL250
+	var alt = int(10 + rand() * 22) * 1000;  # FL100--FL320
 	alt = skip_cloud_layer(alt * FT2M);
 	var coord = geo.aircraft_position().apply_course_distance(course, dist).set_alt(alt);
 	Tanker.new(aiid, callsign, tacanid, type, 250, hdg, coord);