Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix/1240 - Fix readback from departures in runway queue is not correct #1257

Merged
merged 5 commits into from Dec 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -3,7 +3,8 @@


### Bugfixes
- [#1250](https://github.com/openscope/openscope/issues/1250) - Fix error code 128: fatal: unable to look up github.com (port 9418)
- [#1250](https://github.com/openscope/openscope/issues/1250) - Fix fatal error code 128 during `npm install`
- [#1240](https://github.com/openscope/openscope/issues/1240) - Fix readback from departure cleared for takeoff when they aren't first in line


### Enhancements & Refactors
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/assets/scripts/client/AppController.js
Expand Up @@ -172,7 +172,7 @@ export default class AppController {
this.spawnPatternCollection = new SpawnPatternCollection(initialAirportData);
this.spawnScheduler = new SpawnScheduler(this.spawnPatternCollection, this.aircraftController);
this.canvasController = new CanvasController(this.$canvasesElement, this.aircraftController, this.scopeModel);
this.aircraftCommander = new AircraftCommander(this.aircraftController.onRequestToChangeTransponderCode);
this.aircraftCommander = new AircraftCommander(this.aircraftController);
this.inputController = new InputController(this.$element, this.aircraftCommander, this.aircraftController, this.scopeModel);
this.airportInfoController = new AirportInfoController(this.$element);

Expand Down
33 changes: 18 additions & 15 deletions src/assets/scripts/client/aircraft/AircraftCommander.js
Expand Up @@ -30,9 +30,10 @@ import { radiansToDegrees } from '../utilities/unitConverters';
* @class AircraftCommander
*/
export default class AircraftCommander {
constructor(onChangeTransponderCode) {
constructor(aircraftController) {
this._eventBus = EventBus;
this._onChangeTransponderCode = onChangeTransponderCode;
this._aircraftController = aircraftController;
this._onChangeTransponderCode = aircraftController.onRequestToChangeTransponderCode;
}

/**
Expand Down Expand Up @@ -82,6 +83,7 @@ export default class AircraftCommander {
response.push(retval[1]);

if (retval[2]) {
// eslint-disable-next-line prefer-destructuring
response_end = retval[2];
}
}
Expand Down Expand Up @@ -335,10 +337,10 @@ export default class AircraftCommander {
if (_isNil(runwayModel)) {
const previousRunwayModel = aircraft.fms.arrivalRunwayModel;
const readback = {};
readback.log = `unable to find Runway ${runwayName} on our charts, ` +
`expecting Runway ${previousRunwayModel.name} instead`;
readback.say = `unable to find Runway ${radio_runway(runwayName)} on our ` +
`charts, expecting Runway ${previousRunwayModel.getRadioName()} instead`;
readback.log = `unable to find Runway ${runwayName} on our charts, `
+ `expecting Runway ${previousRunwayModel.name} instead`;
readback.say = `unable to find Runway ${radio_runway(runwayName)} on our `
+ `charts, expecting Runway ${previousRunwayModel.getRadioName()} instead`;

return [false, readback];
}
Expand Down Expand Up @@ -603,7 +605,7 @@ export default class AircraftCommander {
const runway = aircraft.fms.departureRunwayModel;
const spotInQueue = runway.getAircraftQueuePosition(aircraft.id);
const isInQueue = spotInQueue > -1;
const aircraftAhead = runway.queue[spotInQueue - 1];
const aircraftAhead = this._aircraftController.findAircraftById(runway.queue[spotInQueue - 1]);
const wind = airport.getWind();
const roundedWindAngleInDegrees = round(radiansToDegrees(wind.angle) / 10) * 10;
const roundedWindSpeed = round(wind.speed);
Expand Down Expand Up @@ -645,10 +647,10 @@ export default class AircraftCommander {

// see #1154, we may have been rerouted since we started taxiing.
if (!aircraft.fms.isRunwayModelValidForSid(runway)) {
readback.log = `according to our charts, Runway ${runway.name} ` +
`is not valid for the ${aircraft.fms.getSidIcao()} departure`;
readback.say = `according to our charts, Runway ${runway.getRadioName()} ` +
`is not valid for the ${aircraft.fms.getSidName()} departure`;
readback.log = `according to our charts, Runway ${runway.name} `
+ `is not valid for the ${aircraft.fms.getSidIcao()} departure`;
readback.say = `according to our charts, Runway ${runway.getRadioName()} `
+ `is not valid for the ${aircraft.fms.getSidName()} departure`;

return [false, readback];
}
Expand All @@ -659,12 +661,13 @@ export default class AircraftCommander {
aircraft.setFlightPhase(FLIGHT_PHASE.TAKEOFF);
aircraft.scoreWind('taking off');

readback.log = `wind ${roundedWindAngleInDegrees} at ${roundedWindSpeed}, Runway ${runway.name}, ` +
'cleared for takeoff';
readback.log = `wind ${roundedWindAngleInDegrees} at ${roundedWindSpeed}, `
+ `Runway ${runway.name}, cleared for takeoff`;

// We have to make it say winned to make it sound like "Wind" and not "Whined"
readback.say = `winned ${radio_spellOut(roundedWindAngleInDegrees)} at ` +
`${radio_spellOut(roundedWindSpeed)}, Runway ${radio_runway(runway.name)}, cleared for takeoff`;
readback.say = `winned ${radio_spellOut(roundedWindAngleInDegrees)} at `
+ `${radio_spellOut(roundedWindSpeed)}, Runway ${radio_runway(runway.name)}, `
+ 'cleared for takeoff';

return [true, readback];
}
Expand Down
44 changes: 33 additions & 11 deletions src/assets/scripts/client/aircraft/AircraftController.js
Expand Up @@ -75,8 +75,8 @@ export default class AircraftController {
constructor(aircraftTypeDefinitionList, airlineController, scopeModel) {
if (isEmptyOrNotArray(aircraftTypeDefinitionList)) {
// eslint-disable-next-line max-len
throw new TypeError('Invalid aircraftTypeDefinitionList passed to AircraftTypeDefinitionCollection. ' +
`Expected and array but received ${typeof aircraftTypeDefinitionList}`);
throw new TypeError('Invalid aircraftTypeDefinitionList passed to AircraftTypeDefinitionCollection. '
+ `Expected and array but received ${typeof aircraftTypeDefinitionList}`);
}

// TODO: this may need to use instanceof instead, but that may be overly defensive
Expand Down Expand Up @@ -383,16 +383,35 @@ export default class AircraftController {
}

/**
* Finds an aircraft by its callsign
*
* @method findAircraftByCallsign
* @param {string} [callsign='']
* @return {AircraftModel|null}
* @param {string} callsign
* @return {AircraftModel}
*/
findAircraftByCallsign(callsign = '') {
if (callsign === '') {
return null;
findAircraftByCallsign(callsign) {
if (!callsign) {
erikquinn marked this conversation as resolved.
Show resolved Hide resolved
return;
}

return _find(this.aircraft.list, (aircraft) => aircraft.callsign.toLowerCase() === callsign.toLowerCase());
const normalizedCallsign = callsign.toUpperCase();

return _find(this.aircraft.list, (aircraft) => aircraft.callsign === normalizedCallsign);
}

/**
* Finds an aircraft by its internal id
*
erikquinn marked this conversation as resolved.
Show resolved Hide resolved
* @method findAircraftById
* @param {string} id
* @return {AircraftModel}
*/
findAircraftById(id) {
if (!id) {
return;
}

return _find(this.aircraft.list, (aircraft) => aircraft.id === id);
}

/**
Expand Down Expand Up @@ -421,7 +440,7 @@ export default class AircraftController {
/**
* @method debug
* @param {string} [callsign='']
* @return {AircraftModel|null}
* @return {AircraftModel}
*/
debug(callsign = '') {
return this.findAircraftByCallsign(callsign);
Expand Down Expand Up @@ -584,7 +603,7 @@ export default class AircraftController {
// TODO: this may need to be reworked.
// if we are building a preSpawn aircraft, cap the altitude at 18000 so aircraft that spawn closer to
// airspace can safely enter controlled airspace properly
let altitude = spawnPatternModel.altitude;
let { altitude } = spawnPatternModel;

if (isPreSpawn && spawnPatternModel.category === FLIGHT_CATEGORY.ARRIVAL) {
altitude = Math.min(18000, altitude);
Expand Down Expand Up @@ -713,7 +732,10 @@ export default class AircraftController {
* @return {boolean}
*/
_isDiscreteTransponderCode(transponderCode) {
return this._isValidTransponderCode(transponderCode) && RESERVED_SQUAWK_CODES.indexOf(transponderCode) === INVALID_INDEX;
const isValidCode = this._isValidTransponderCode(transponderCode);
const isReservedCode = RESERVED_SQUAWK_CODES.indexOf(transponderCode) !== INVALID_INDEX;

return isValidCode && !isReservedCode;
}

/**
Expand Down