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

feature/ATC-134 #209

Merged
merged 10 commits into from
Dec 19, 2016
Merged

feature/ATC-134 #209

merged 10 commits into from
Dec 19, 2016

Conversation

erikquinn
Copy link
Collaborator

@erikquinn erikquinn commented Dec 15, 2016

Resolves #134.

Prevents collision detection between aircraft when they are outside the airspace. Admittedly not the most elegant solution, but resolves the issue nonetheless.

@erikquinn erikquinn added this to the v3.2.0 milestone Dec 15, 2016
@erikquinn erikquinn requested a review from n8rzz December 15, 2016 08:52
@n8rzz n8rzz self-assigned this Dec 15, 2016
Copy link
Owner

@n8rzz n8rzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a little more elegant than you think. It's clean and readable. 👍 👍

Just a few syntactical changes I'd like to see before we merge this in. But otherwise, good work!

if (airport.perimeter) { // polygonal airspace boundary
inside = point_in_area(this.position, airport.perimeter);
} else { // simple circular airspace boundary
inside = this.distance <= airport.ctr_radius && this.altitude <= airport.ctr_ceiling;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not initialize inside with this condition and then only update inside if airport.perimeter? This has the same effect as the if/else block, but its a little cleaner because now there is no else block.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. 👍

this.crossBoundary(inside);
}
const isInsideAirspace = this.isInsideAirspace(window.airportController.airport_get());
if (isInsideAirspace !== this.inside_ctr) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember to add a line between constants and conditional blocks

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. 👍

@@ -130,8 +130,9 @@ 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)) &&
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember to add a line between constants and conditional blocks

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. 👍

* @return {Boolean}
* @private
*/
isInsideAirspace(airport) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to do this, but in cases like this where you only need a few properties from a massive object you could destructure them:

isInsideAirspace(airport) { }
// becomes
isInsideAirspace({ perimeter, ctr_radius, ctr_ceiling }) { }

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Good information; wouldn't have thought of that.

Didn't implement here... thought it looked more clean just as airport since we used three of its properties.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

totally cool. I just wanted to call that out in case you ever need it in the future 😉

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))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 for setting airport to a const and sending that in to this method.

@erikquinn erikquinn requested a review from n8rzz December 15, 2016 18:00
@n8rzz n8rzz temporarily deployed to atc-dev-pr-209 December 16, 2016 02:52 Inactive
withinAirspaceLateralBoundaries = point_in_area(this.position, airport.perimeter);
}

return withinAirspaceAltitudeRange && withinAirspaceLateralBoundaries;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes!!! 👍

one thing to remember and I don't think we've gone over this yet, so I'll let this go as is this time. When a method returns a boolean or a constant is a boolean, it should be prepended with is. so instead of

return isWithinAirspaceAltitudeRange && isWithinAirspaceLateralBoundaries;

this reads a little better and you can immediately tell that those two things are booleans.

Copy link
Owner

@n8rzz n8rzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good!

But it seems this has created a new issue where planes on the ground, when spawned, crash into each other. This may be localized to the Great Britain airports, but it is definitely a thing.

I'm also getting an error when changing airports:

TypeError: Cannot read property 'poly' of null at area_to_poly

Which seems to come from airport.perimeter getting passed as null. I saw that you had a _has() check, which is good, but _has() doesn't care about value. Only that a key exists.

There is also now a conflicted file. So when you investigate the above, be sure to also pull in develop.

@n8rzz n8rzz requested a deployment to atc-dev-pr-209 December 17, 2016 00:45 Pending
@n8rzz n8rzz temporarily deployed to atc-dev-pr-209 December 17, 2016 00:46 Inactive
@n8rzz n8rzz temporarily deployed to atc-dev-pr-209 December 17, 2016 02:36 Inactive
@erikquinn erikquinn temporarily deployed to atc-dev-pr-209 December 18, 2016 22:40 Inactive
@erikquinn erikquinn temporarily deployed to atc-dev-pr-209 December 18, 2016 22:41 Inactive
@erikquinn erikquinn temporarily deployed to atc-dev-pr-209 December 18, 2016 23:16 Inactive
@erikquinn erikquinn requested a review from n8rzz December 18, 2016 23:17
Copy link
Owner

@n8rzz n8rzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking better, just a few things to change. Please let me know if you have any questions.

@@ -124,14 +124,16 @@ 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()) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I like this name a lot better. doesn't leave anything to the imagination about what its for.

isOnGround() {
const error_allowance_ft = 5;
const apt = window.airportController.airport_get();
const rwy_elev = apt.getRunway(this.rwy_dep || this.rwy_arr).elevation;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two things here:

  • apt.getRunway(this.rwy_dep || this.rwy_arr).elevation is confusing. is this something getRunway could do internally?
  • although not bad, I'm not a fan of the someMethod().property style. I know this is littered throughout the app and it works, I just find it confusing. if you need a property from the return of a method destructure it or use the returned object:
// destructure
const { elevation } = airport.getRunway();

// use object
const runway = airport.getRunway();
runway.elevation

In most cases I would lean towards the second option just for readability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@n8rzz Yeah this whole block looks new but really it's all old; I just renamed it and then moved it so it was aligned alphabetically... but I've fixed the items you've pointed out with it.

And no, the Runway couldn't do it internally... the Aircraft maybe could, but in this particular case, I don't know if it would make much more sense. I could pull the this.rwy_dep || this.rwy_arr part into a variable, but other than that, I don't really know what else to do with it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erikquinn ha, we must have been commenting at the same time. I just added a few more inline about this.

*/
isOnGround() {
const error_allowance_ft = 5;
const apt = window.airportController.airport_get();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you rename this airport? This is sort of a nit-pick, I know. I much prefer these things to be spelled out instead of shortened like this. Its just clearer about what, exactly, that var represents.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. 👍

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;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just use this inline on line 1738? whats the advantage of storing it in a const?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. 👍

@erikquinn erikquinn temporarily deployed to atc-dev-pr-209 December 19, 2016 01:45 Inactive
isOnGround() {
const error_allowance_ft = 5;
const airport = window.airportController.airport_get();
const runway = airport.getRunway(this.rwy_dep || this.rwy_arr);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this assuming that one of this.rwy_dep || this.rwy_arr will always be null (or undefined)? Why not just create a getter in the AirportModel for something like activeRunway or something?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get activeRunway() {
    return this.rwy_dep 
        ? this.rwy_dep 
        : this.rwy_arr; 
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the one instance where I am ok with ternaries, by the way. In a case like this I think it makes sense and is just as readable as the alternative

Copy link
Collaborator Author

@erikquinn erikquinn Dec 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that getter simply doesn't make sense though... it's not in relation to the airport, it has to do with each individual aircraft. Aircraft.rwy_dep is the runway they are assigned or have already used to take off. Aircraft.rwy_arr is the runway they are assigned or have already used to land. It's not the active arrival runway and active departure runway; it's what each aircraft used, and it's stored for reasons of retrieving the appropriate rwy sections within instrument procedures.

In the current way the game works, each aircraft will only have one of rwy_dep or rwy_arr, because we don't have departures come back and land. So this simpleton solution is one that works at this stage in time. It could be made a getter of the AircraftInstanceModel, but this is a very bizarre, hard to name, only-going-to-be-needed-here operation. We're essentially asking "Hey aircraft, what runway have/did/will you use(d) at the airport, regardless of what you used it for"? The only information we'd be likely to need in other cases is "What runway did/will you depart?" or "What runway did/will you use to land?"

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I understand. and you're right, the getter would be in the AircraftInstanceModel.

Essentially whats happening here, from what I understand, is 'give me the runway you used/or are going to use'. This is where the getter would be helpful because it can do that logic on its own. Thus, anything calling the getter simply says 'give me the runway info' and the getter figures out which one it should send back. and then everything is right in the world.

But, if this isn't used all over the place, it probably isn't really worth the effort.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added #225 so if we ever decide to fix it, we have an issue to refer to :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not like it's a lot of effort, but this is literally the only place it would be used. Adding it would increase readability, but shouldn't single-use methods be avoided if possible? If not, I could just add another method to the pile-- no biggie.

@erikquinn erikquinn mentioned this pull request Dec 19, 2016
@n8rzz n8rzz merged commit 02c6844 into develop Dec 19, 2016
@n8rzz n8rzz deleted the feature/ATC-134 branch December 19, 2016 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants