From 92a142c3b20b64ecf2b18c042713afc540de8e9e Mon Sep 17 00:00:00 2001 From: Erik Quinn Date: Thu, 15 Dec 2016 03:10:55 -0500 Subject: [PATCH 1/7] Create AircraftInstanceModel.isInsideAirspace method --- .../scripts/aircraft/AircraftInstanceModel.js | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/assets/scripts/aircraft/AircraftInstanceModel.js b/src/assets/scripts/aircraft/AircraftInstanceModel.js index 947ea1da..07499160 100644 --- a/src/assets/scripts/aircraft/AircraftInstanceModel.js +++ b/src/assets/scripts/aircraft/AircraftInstanceModel.js @@ -1383,7 +1383,7 @@ export default class Aircraft { * @param data */ runReroute(data) { - // capitalize everything + // TODO: capitalize everything? data = data[0].toUpperCase(); let worked = true; const route = this.fms.formatRoute(data); @@ -1698,6 +1698,26 @@ export default class Aircraft { return this.approachOffset <= 0.048; } + /** + * Checks if the aircraft is inside the airspace of a specified airport + * + * @for AircraftInstanceModel + * @method isInsideAirspace + * @param {airport} airport the airport whose airspace we are checking + * @return {Boolean} + * @private + */ + isInsideAirspace(airport) { + let withinAirspaceLateralBoundaries = this.distance <= airport.ctr_radius; + const withinAirspaceAltitudeRange = this.altitude <= airport.ctr_ceiling; + + if (_has(airport, 'perimeter')) { // polygonal airspace boundary + withinAirspaceLateralBoundaries = point_in_area(this.position, airport.perimeter); + } + + return withinAirspaceAltitudeRange && withinAirspaceLateralBoundaries; + } + /** * Aircraft is actively following an instrument approach * @for AircraftInstanceModel @@ -2381,22 +2401,10 @@ export default class Aircraft { this.radial += tau(); } - // polygonal airspace boundary - if (window.airportController.airport_get().perimeter) { - let inside = point_in_area(this.position, window.airportController.airport_get().perimeter); - - // TODO: this logic is duplicated below. abstract to new method - if (inside !== this.inside_ctr) { - this.crossBoundary(inside); - } - } else { - // simple circular airspace boundary - let inside = this.distance <= window.airportController.airport_get().ctr_radius && - this.altitude <= window.airportController.airport_get().ctr_ceiling; + const isInsideAirspace = this.isInsideAirspace(window.airportController.airport_get()); - if (inside !== this.inside_ctr) { - this.crossBoundary(inside); - } + if (isInsideAirspace !== this.inside_ctr) { + this.crossBoundary(isInsideAirspace); } } From dd4597091ed5d3832eaf9bc77354f1146730451b Mon Sep 17 00:00:00 2001 From: Erik Quinn Date: Thu, 15 Dec 2016 03:41:44 -0500 Subject: [PATCH 2/7] Only trigger collision if aircraft are inside the airspace --- src/assets/scripts/aircraft/AircraftConflict.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/assets/scripts/aircraft/AircraftConflict.js b/src/assets/scripts/aircraft/AircraftConflict.js index fffeb60e..55d4caf6 100644 --- a/src/assets/scripts/aircraft/AircraftConflict.js +++ b/src/assets/scripts/aircraft/AircraftConflict.js @@ -130,8 +130,10 @@ export default class AircraftConflict { // TODO: enumerate the magic numbers. // Collide within 160 feet + const airport = window.airportController.airport_get(); + if (((this.distance < 0.05) && (this.altitude < 160)) && - (this.aircraft[0].isVisible() && this.aircraft[1].isVisible()) + (this.aircraft[0].isInsideAirspace(airport) && this.aircraft[1].isInsideAirspace(airport)) ) { this.collided = true; const isWarning = true; From 6cea57eab744a1094bc95fb091e4dd9bc2462055 Mon Sep 17 00:00:00 2001 From: Erik Quinn Date: Thu, 15 Dec 2016 03:46:46 -0500 Subject: [PATCH 3/7] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01b66f50..d79d218a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,8 @@ - Adds gulp-cli and adds [tools readme](tools/README.md) link to gulp issues with Windows [#194](https://github.com/n8rzz/atc/issues/194) - Changes `routeString` to `routeCode` to better fit what it is and also fixs trancpercy in to the `routeModel` [#188] (https://github.com/n8rzz/atc/issues/188) -.toUpperCase() is now called on intilization and removed from the getter - +- Prevents collision detection for aircraft that are outside of our airspace [#134](https://github.com/n8rzz/atc/issues/134) + - Originally reported under [#736](https://github.com/zlsa/atc/issues/736) From 90bd8a44d8e00dd505a04d51799541618568ce65 Mon Sep 17 00:00:00 2001 From: Erik Quinn Date: Sun, 18 Dec 2016 18:04:39 -0500 Subject: [PATCH 4/7] fix improper use of _.has / _.isNil --- src/assets/scripts/aircraft/AircraftInstanceModel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/scripts/aircraft/AircraftInstanceModel.js b/src/assets/scripts/aircraft/AircraftInstanceModel.js index bea829c8..45a42fe5 100644 --- a/src/assets/scripts/aircraft/AircraftInstanceModel.js +++ b/src/assets/scripts/aircraft/AircraftInstanceModel.js @@ -1717,7 +1717,7 @@ export default class Aircraft { let withinAirspaceLateralBoundaries = this.distance <= airport.ctr_radius; const withinAirspaceAltitudeRange = this.altitude <= airport.ctr_ceiling; - if (_has(airport, 'perimeter')) { // polygonal airspace boundary + if (!_isNil(airport.perimeter)) { // polygonal airspace boundary withinAirspaceLateralBoundaries = point_in_area(this.position, airport.perimeter); } From 3bde8155f85319a7f05445cf9e6225b21e4a89e7 Mon Sep 17 00:00:00 2001 From: Erik Quinn Date: Sun, 18 Dec 2016 18:11:25 -0500 Subject: [PATCH 5/7] Rename and repair method for weight-on-wheels logic from .wow() to .isOnGround() --- .../scripts/aircraft/AircraftInstanceModel.js | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/assets/scripts/aircraft/AircraftInstanceModel.js b/src/assets/scripts/aircraft/AircraftInstanceModel.js index 45a42fe5..330a6d01 100644 --- a/src/assets/scripts/aircraft/AircraftInstanceModel.js +++ b/src/assets/scripts/aircraft/AircraftInstanceModel.js @@ -1473,7 +1473,7 @@ export default class Aircraft { return ['fail', 'inbound']; } - if (!this.wow()) { + if (!this.isOnGround()) { return ['fail', 'already airborne']; } if (this.mode === FLIGHT_MODES.APRON) { @@ -1724,6 +1724,22 @@ export default class Aircraft { return withinAirspaceAltitudeRange && withinAirspaceLateralBoundaries; } + /** + * Aircraft has "weight-on-wheels" (on the ground) + * @for AircraftInstanceModel + * @method isOnGround + */ + isOnGround() { + const error_allowance_ft = 5; + const apt = window.airportController.airport_get(); + const rwy_elev = apt.getRunway(this.rwy_dep || this.rwy_arr).elevation; + const apt_elev = apt.position.elevation; + const nearRunwayAltitude = abs(this.altitude - rwy_elev) < error_allowance_ft; + const nearAirportAltitude = abs(this.altitude - apt_elev) < error_allowance_ft; + + return nearRunwayAltitude || nearAirportAltitude; + } + /** * Aircraft is actively following an instrument approach and is elegible for reduced separation * @@ -1745,7 +1761,7 @@ export default class Aircraft { */ isStopped() { // TODO: enumerate the magic number. - return this.wow() && this.speed < 5; + return this.isOnGround() && this.speed < 5; } /** @@ -2000,7 +2016,7 @@ export default class Aircraft { this.fms.setCurrent({ start_speed: this.fms.currentWaypoint.speed }); } - if (this.wow()) { + if (this.isOnGround()) { this.target.altitude = runway.elevation; this.target.speed = 0; } else { @@ -2156,7 +2172,7 @@ export default class Aircraft { } // If stalling, make like a meteorite and fall to the earth! - if (this.speed < this.model.speed.min && !this.wow()) { + if (this.speed < this.model.speed.min && !this.isOnGround()) { this.target.altitude = Math.min(0, this.target.altitude); } @@ -2255,7 +2271,7 @@ export default class Aircraft { // TURNING // this.target.heading = radians_normalize(this.target.heading); - if (!this.wow() && this.heading !== this.target.heading) { + if (!this.isOnGround() && this.heading !== this.target.heading) { // Perform standard turns 3 deg/s or 25 deg bank, whichever // requires less bank angle. // Formula based on http://aviation.stackexchange.com/a/8013 @@ -2310,7 +2326,7 @@ export default class Aircraft { } } - if (this.wow()) { + if (this.isOnGround()) { this.trend = 0; } @@ -2320,7 +2336,7 @@ export default class Aircraft { if (this.target.speed < this.speed - 0.01) { difference = -this.model.rate.decelerate * window.gameController.game_delta() / 2; - if (this.wow()) { + if (this.isOnGround()) { difference *= 3.5; } } else if (this.target.speed > this.speed + 0.01) { @@ -2368,7 +2384,7 @@ export default class Aircraft { const wind = window.airportController.airport_get().wind; let vector; - if (this.wow()) { + if (this.isOnGround()) { vector = vscale([sin(angle), cos(angle)], scaleSpeed); } else { let crab_angle = 0; @@ -2489,7 +2505,7 @@ export default class Aircraft { }); } - if (this.terrain_ranges && !this.wow()) { + if (this.terrain_ranges && !this.isOnGround()) { const terrain = prop.airport.current.terrain; const prev_level = this.terrain_ranges[this.terrain_level]; const ele = Math.ceil(this.altitude, 1000); @@ -2672,17 +2688,4 @@ export default class Aircraft { removeConflict(other) { delete this.conflicts[other.getCallsign()]; } - - /** - * Aircraft has "weight-on-wheels" (on the ground) - * @for AircraftInstanceModel - * @method wow - */ - wow() { - const error_allowance = 5; - const apt = window.airportController.airport_get(); - const rwy_elev = apt.getRunway(this.rwy_dep || this.rwy_arr).elevation; - const apt_elev = apt.position.elevation; - return this.altitude - (rwy_elev || apt_elev) < error_allowance; - } } From 2e4cb1b9b06692a4cf0cc34849442ce1134eabc4 Mon Sep 17 00:00:00 2001 From: Erik Quinn Date: Sun, 18 Dec 2016 18:11:58 -0500 Subject: [PATCH 6/7] Replace all references to .wow() with .isOnGround() --- src/assets/scripts/aircraft/AircraftConflict.js | 2 +- src/assets/scripts/aircraft/AircraftController.js | 2 +- src/assets/scripts/aircraft/FlightManagementSystem/Leg.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/assets/scripts/aircraft/AircraftConflict.js b/src/assets/scripts/aircraft/AircraftConflict.js index 55d4caf6..b2e64e05 100644 --- a/src/assets/scripts/aircraft/AircraftConflict.js +++ b/src/assets/scripts/aircraft/AircraftConflict.js @@ -124,7 +124,7 @@ export default class AircraftConflict { * Check for collision */ checkCollision() { - if (this.aircraft[0].wow() || this.aircraft[1].wow()) { + if (this.aircraft[0].isOnGround() || this.aircraft[1].isOnGround()) { return; // TEMPORARY FIX FOR CRASHES BTWN ARRIVALS AND TAXIIED A/C } diff --git a/src/assets/scripts/aircraft/AircraftController.js b/src/assets/scripts/aircraft/AircraftController.js index 7b3a4098..49c0cc36 100644 --- a/src/assets/scripts/aircraft/AircraftController.js +++ b/src/assets/scripts/aircraft/AircraftController.js @@ -200,7 +200,7 @@ export default class AircraftController { remove = true; } - if (aircraft.hit && aircraft.wow()) { + if (aircraft.hit && aircraft.isOnGround()) { window.uiController.ui_log(`Lost radar contact with ${aircraft.getCallsign()}`); speech_say([ { type: 'callsign', content: aircraft }, diff --git a/src/assets/scripts/aircraft/FlightManagementSystem/Leg.js b/src/assets/scripts/aircraft/FlightManagementSystem/Leg.js index 657940c6..025ed0bf 100644 --- a/src/assets/scripts/aircraft/FlightManagementSystem/Leg.js +++ b/src/assets/scripts/aircraft/FlightManagementSystem/Leg.js @@ -178,7 +178,7 @@ export default class Leg { // TODO: refactor/abstract this boolean logic // Remove the placeholder leg (if present) - if (fms.my_aircraft.wow() && + if (fms.my_aircraft.isOnGround() && fms.legs.length > 0 && fms.legs[0].route === airport.icao && pairs.length > 0 From d8b7239a15e6408abbf62576547ba24dbe2b1560 Mon Sep 17 00:00:00 2001 From: Erik Quinn Date: Sun, 18 Dec 2016 20:45:17 -0500 Subject: [PATCH 7/7] Clean up AircraftInstanceModel.isOnGround() method --- src/assets/scripts/aircraft/AircraftInstanceModel.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/assets/scripts/aircraft/AircraftInstanceModel.js b/src/assets/scripts/aircraft/AircraftInstanceModel.js index 330a6d01..019de1e7 100644 --- a/src/assets/scripts/aircraft/AircraftInstanceModel.js +++ b/src/assets/scripts/aircraft/AircraftInstanceModel.js @@ -1731,11 +1731,10 @@ export default class Aircraft { */ isOnGround() { const error_allowance_ft = 5; - const apt = window.airportController.airport_get(); - const rwy_elev = apt.getRunway(this.rwy_dep || this.rwy_arr).elevation; - const apt_elev = apt.position.elevation; - const nearRunwayAltitude = abs(this.altitude - rwy_elev) < error_allowance_ft; - const nearAirportAltitude = abs(this.altitude - apt_elev) < error_allowance_ft; + const airport = window.airportController.airport_get(); + const runway = airport.getRunway(this.rwy_dep || this.rwy_arr); + const nearRunwayAltitude = abs(this.altitude - runway.elevation) < error_allowance_ft; + const nearAirportAltitude = abs(this.altitude - airport.position.elevation) < error_allowance_ft; return nearRunwayAltitude || nearAirportAltitude; }