atc-tools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/bin/fpv +3 -0
  3. data/doc/ATCTools.html +133 -0
  4. data/doc/ATCTools/Aircraft.html +309 -0
  5. data/doc/ATCTools/Airport.html +634 -0
  6. data/doc/ATCTools/FlightPlan.html +544 -0
  7. data/doc/ATCTools/FlightPlanValidator.html +265 -0
  8. data/doc/ATCTools/HeadingDiscoveryError.html +135 -0
  9. data/doc/ATCTools/HeadingError.html +135 -0
  10. data/doc/ATCTools/NameDiscoveryError.html +135 -0
  11. data/doc/ATCTools/NoAircraftSelectedError.html +135 -0
  12. data/doc/ATCTools/VRC.html +656 -0
  13. data/doc/Aircraft.html +127 -0
  14. data/doc/Airport.html +564 -0
  15. data/doc/FlightPlan.html +127 -0
  16. data/doc/HeadingError.html +127 -0
  17. data/doc/NameDiscoveryError.html +127 -0
  18. data/doc/created.rid +7 -0
  19. data/doc/images/add.png +0 -0
  20. data/doc/images/arrow_up.png +0 -0
  21. data/doc/images/brick.png +0 -0
  22. data/doc/images/brick_link.png +0 -0
  23. data/doc/images/bug.png +0 -0
  24. data/doc/images/bullet_black.png +0 -0
  25. data/doc/images/bullet_toggle_minus.png +0 -0
  26. data/doc/images/bullet_toggle_plus.png +0 -0
  27. data/doc/images/date.png +0 -0
  28. data/doc/images/delete.png +0 -0
  29. data/doc/images/find.png +0 -0
  30. data/doc/images/loadingAnimation.gif +0 -0
  31. data/doc/images/macFFBgHack.png +0 -0
  32. data/doc/images/package.png +0 -0
  33. data/doc/images/page_green.png +0 -0
  34. data/doc/images/page_white_text.png +0 -0
  35. data/doc/images/page_white_width.png +0 -0
  36. data/doc/images/plugin.png +0 -0
  37. data/doc/images/ruby.png +0 -0
  38. data/doc/images/tag_blue.png +0 -0
  39. data/doc/images/tag_green.png +0 -0
  40. data/doc/images/transparent.png +0 -0
  41. data/doc/images/wrench.png +0 -0
  42. data/doc/images/wrench_orange.png +0 -0
  43. data/doc/images/zoom.png +0 -0
  44. data/doc/index.html +87 -0
  45. data/doc/js/darkfish.js +155 -0
  46. data/doc/js/jquery.js +18 -0
  47. data/doc/js/navigation.js +142 -0
  48. data/doc/js/search.js +94 -0
  49. data/doc/js/search_index.js +1 -0
  50. data/doc/js/searcher.js +228 -0
  51. data/doc/rdoc.css +595 -0
  52. data/doc/table_of_contents.html +132 -0
  53. data/lib/atc-tools.rb +1 -0
  54. data/lib/atc-tools/aircraft.rb +36 -0
  55. data/lib/atc-tools/airport.rb +103 -0
  56. data/lib/atc-tools/flight_plan.rb +119 -0
  57. data/lib/atc-tools/script/flight_plan_validator.rb +65 -0
  58. data/lib/atc-tools/vrc.rb +165 -0
  59. data/license.txt +19 -0
  60. metadata +174 -0
@@ -0,0 +1,132 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
6
+
7
+ <title>Table of Contents - RDoc Documentation</title>
8
+
9
+ <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet">
10
+
11
+ <script type="text/javascript">
12
+ var rdoc_rel_prefix = "./";
13
+ </script>
14
+
15
+ <script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
16
+ <script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script>
17
+ <script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script>
18
+ <script type="text/javascript" charset="utf-8" src="./js/search.js"></script>
19
+ <script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script>
20
+ <script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script>
21
+
22
+
23
+ <body class="indexpage">
24
+ <h1>Table of Contents - RDoc Documentation</h1>
25
+
26
+
27
+ <h2 id="classes">Classes/Modules</h2>
28
+ <ul>
29
+ <li class="module">
30
+ <a href="ATCTools.html">ATCTools</a>
31
+ </li>
32
+ <li class="class">
33
+ <a href="ATCTools/Aircraft.html">ATCTools::Aircraft</a>
34
+ </li>
35
+ <li class="class">
36
+ <a href="ATCTools/Airport.html">ATCTools::Airport</a>
37
+ </li>
38
+ <li class="class">
39
+ <a href="ATCTools/FlightPlan.html">ATCTools::FlightPlan</a>
40
+ </li>
41
+ <li class="class">
42
+ <a href="ATCTools/FlightPlanValidator.html">ATCTools::FlightPlanValidator</a>
43
+ </li>
44
+ <li class="class">
45
+ <a href="ATCTools/HeadingDiscoveryError.html">ATCTools::HeadingDiscoveryError</a>
46
+ </li>
47
+ <li class="class">
48
+ <a href="ATCTools/NameDiscoveryError.html">ATCTools::NameDiscoveryError</a>
49
+ </li>
50
+ <li class="class">
51
+ <a href="ATCTools/NoAircraftSelectedError.html">ATCTools::NoAircraftSelectedError</a>
52
+ </li>
53
+ <li class="class">
54
+ <a href="ATCTools/VRC.html">ATCTools::VRC</a>
55
+ </li>
56
+
57
+ </ul>
58
+
59
+ <h2 id="methods">Methods</h2>
60
+ <ul>
61
+
62
+ <li class="method"><a href="ATCTools/FlightPlanValidator.html#method-c-flight_plan">::flight_plan &mdash; ATCTools::FlightPlanValidator</a>
63
+
64
+ <li class="method"><a href="ATCTools/Airport.html#method-c-new">::new &mdash; ATCTools::Airport</a>
65
+
66
+ <li class="method"><a href="ATCTools/VRC.html#method-c-new">::new &mdash; ATCTools::VRC</a>
67
+
68
+ <li class="method"><a href="ATCTools/Aircraft.html#method-c-new">::new &mdash; ATCTools::Aircraft</a>
69
+
70
+ <li class="method"><a href="ATCTools/FlightPlan.html#method-c-new">::new &mdash; ATCTools::FlightPlan</a>
71
+
72
+ <li class="method"><a href="ATCTools/FlightPlanValidator.html#method-c-run">::run &mdash; ATCTools::FlightPlanValidator</a>
73
+
74
+ <li class="method"><a href="ATCTools/VRC.html#method-i-activate_terminal_window-21">#activate_terminal_window! &mdash; ATCTools::VRC</a>
75
+
76
+ <li class="method"><a href="ATCTools/VRC.html#method-i-activate_vrc_window-21">#activate_vrc_window! &mdash; ATCTools::VRC</a>
77
+
78
+ <li class="method"><a href="ATCTools/VRC.html#method-i-aircraft_selected-3F">#aircraft_selected? &mdash; ATCTools::VRC</a>
79
+
80
+ <li class="method"><a href="ATCTools/FlightPlan.html#method-i-altitude_valid-3F">#altitude_valid? &mdash; ATCTools::FlightPlan</a>
81
+
82
+ <li class="method"><a href="ATCTools/VRC.html#method-i-command_line">#command_line &mdash; ATCTools::VRC</a>
83
+
84
+ <li class="method"><a href="ATCTools/Airport.html#method-i-discover_name">#discover_name &mdash; ATCTools::Airport</a>
85
+
86
+ <li class="method"><a href="ATCTools/Airport.html#method-i-discover_variance">#discover_variance &mdash; ATCTools::Airport</a>
87
+
88
+ <li class="method"><a href="ATCTools/VRC.html#method-i-execute_command">#execute_command &mdash; ATCTools::VRC</a>
89
+
90
+ <li class="method"><a href="ATCTools/VRC.html#method-i-execute_command-21">#execute_command! &mdash; ATCTools::VRC</a>
91
+
92
+ <li class="method"><a href="ATCTools/VRC.html#method-i-flight_plan_title">#flight_plan_title &mdash; ATCTools::VRC</a>
93
+
94
+ <li class="method"><a href="ATCTools/FlightPlan.html#method-i-heading">#heading &mdash; ATCTools::FlightPlan</a>
95
+
96
+ <li class="method"><a href="ATCTools/Airport.html#method-i-magnetic_heading_from">#magnetic_heading_from &mdash; ATCTools::Airport</a>
97
+
98
+ <li class="method"><a href="ATCTools/Airport.html#method-i-magnetic_heading_to">#magnetic_heading_to &mdash; ATCTools::Airport</a>
99
+
100
+ <li class="method"><a href="ATCTools/Airport.html#method-i-magnetic_to_true">#magnetic_to_true &mdash; ATCTools::Airport</a>
101
+
102
+ <li class="method"><a href="ATCTools/Airport.html#method-i-name">#name &mdash; ATCTools::Airport</a>
103
+
104
+ <li class="method"><a href="ATCTools/VRC.html#method-i-selected_aircraft">#selected_aircraft &mdash; ATCTools::VRC</a>
105
+
106
+ <li class="method"><a href="ATCTools/VRC.html#method-i-selected_aircraft_info-21">#selected_aircraft_info! &mdash; ATCTools::VRC</a>
107
+
108
+ <li class="method"><a href="ATCTools/VRC.html#method-i-selected_flight_plan-21">#selected_flight_plan! &mdash; ATCTools::VRC</a>
109
+
110
+ <li class="method"><a href="ATCTools/FlightPlan.html#method-i-to_s">#to_s &mdash; ATCTools::FlightPlan</a>
111
+
112
+ <li class="method"><a href="ATCTools/Aircraft.html#method-i-to_s">#to_s &mdash; ATCTools::Aircraft</a>
113
+
114
+ <li class="method"><a href="ATCTools/Airport.html#method-i-to_s">#to_s &mdash; ATCTools::Airport</a>
115
+
116
+ <li class="method"><a href="ATCTools/Airport.html#method-i-true_heading_from">#true_heading_from &mdash; ATCTools::Airport</a>
117
+
118
+ <li class="method"><a href="ATCTools/Airport.html#method-i-true_heading_to">#true_heading_to &mdash; ATCTools::Airport</a>
119
+
120
+ <li class="method"><a href="ATCTools/Airport.html#method-i-true_to_magnetic">#true_to_magnetic &mdash; ATCTools::Airport</a>
121
+
122
+ <li class="method"><a href="ATCTools/FlightPlan.html#method-i-validate">#validate &mdash; ATCTools::FlightPlan</a>
123
+
124
+ </ul>
125
+
126
+
127
+ <footer id="validator-badges">
128
+ <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
129
+ <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 4.0.1.
130
+ <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
131
+ </footer>
132
+
@@ -0,0 +1 @@
1
+ require 'atc-tools/script/flight_plan_validator'
@@ -0,0 +1,36 @@
1
+ module ATCTools
2
+ class Aircraft
3
+ # Raw data used to initialize the object,
4
+ # typically from the VRC client.
5
+ attr_reader :raw
6
+ # Full aircraft info string.
7
+ attr_accessor :info
8
+ # Aircraft code. The identifier that would be displayed
9
+ # on the radar scope (B732 = Boeing 737-200).
10
+ attr_reader :code
11
+ # Aircraft model number.
12
+ attr_reader :model
13
+ # Aircraft equipment code.
14
+ attr_reader :equipment
15
+
16
+ # Params:
17
+ # :info, :model, :code, :equipment
18
+ # -- See instance variables for descriptions.
19
+ def initialize(aircraft_code = nil, **kvargs)
20
+ @raw = aircraft_code || kvargs.fetch(:code, '')
21
+ @info = kvargs.fetch :info, ''
22
+ @model = kvargs.fetch :model, ''
23
+
24
+ params = @raw.scan(%r{(?:([a-zA-Z]+)/)?(\w+)(?:/([a-zA-Z]+))?}).flatten
25
+
26
+ @code = kvargs.fetch(:code, nil) || params[1] || ''
27
+ @equipment = kvargs.fetch(:equipment, nil) || params[2] || ''
28
+ end
29
+
30
+ # Returns @raw.
31
+ def to_s
32
+ @raw
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,103 @@
1
+ require 'net/http'
2
+
3
+ module ATCTools
4
+ class NameDiscoveryError < StandardError; end
5
+ class HeadingDiscoveryError < StandardError; end
6
+
7
+ class Airport
8
+ # Airport's ICAO code.
9
+ attr_accessor :code
10
+ # Airport's full name.
11
+ attr_writer :name
12
+ # Airport's magnetic variance from true north.
13
+ attr_accessor :variance
14
+
15
+ # URI of the web page used for the last airport name lookup.
16
+ attr_reader :name_uri
17
+ # URI of the web page used for the last heading lookup.
18
+ attr_reader :heading_uri
19
+
20
+ # Params:
21
+ # :code, :name, :variance
22
+ def initialize(code = nil, **kvargs)
23
+ @code = code || (kvargs.fetch :code, '')
24
+ @name = kvargs.fetch :name, ''
25
+ @variance = kvargs.fetch :variance, 17.0 # TODO: Detect this intelligently.
26
+ end
27
+
28
+ # Airport's full name.
29
+ def name
30
+ discover_name if @name.empty?
31
+ @name
32
+ end
33
+
34
+ # Discover the airport's full name based
35
+ # on ICAO code.
36
+ def discover_name
37
+ @name_uri = "http://www.airnav.com/airport/#{@code.to_s.downcase}"
38
+ response = Net::HTTP.get URI name_uri
39
+
40
+ l = response.scan %r{(?i:<title>)(?:AirNav:\s*\w*\s*-\s*)?(.*)(?i:</title>)}
41
+
42
+ raise ATCTools::NameDiscoveryError, "Could not discover name for #{@code.to_s.upcase}" \
43
+ unless l.count > 0
44
+
45
+ @name = l.flatten.first
46
+ end
47
+
48
+ # Discover the airport's magnetic variance
49
+ # based on ICAO code.
50
+ def discover_variance
51
+ end
52
+
53
+ # Calculate the true heading to the specified airport.
54
+ # Takes an ICAO code or Airport object.
55
+ def true_heading_to(arrival)
56
+ @heading_uri = "http://www6.landings.com/cgi-bin/nph-dist_apt?airport1=#{@code.downcase}&airport2=#{arrival.to_s.strip.downcase}"
57
+ response = Net::HTTP.get URI heading_uri
58
+ r = response.scan /(?:heading:)\s*([\d\.]+)\s+/
59
+
60
+ raise ATCTools::HeadingDiscoveryError, "Heading from #{@code.upcase} to #{arrival.to_s.upcase} not found." \
61
+ unless r.count > 0
62
+
63
+ true_hdg = r.flatten.first.to_f
64
+ end
65
+
66
+ # Calculate the true heading from the specified airport.
67
+ # Takes an ICAO code or Airport object.
68
+ def true_heading_from(departure)
69
+ 360.0 - true_heading_to(departure)
70
+ end
71
+
72
+ # Calculate the magnetic heading to the specified airport.
73
+ # Takes an ICAO code or Airport object.
74
+ def magnetic_heading_to(arrival)
75
+ true_to_magnetic true_heading_to(arrival)
76
+ end
77
+
78
+ # Calculate the magnetic heading from the specified airport.
79
+ # Takes an ICAO code or Airport object.
80
+ def magnetic_heading_from(departure)
81
+ true_to_magnetic true_heading_from(departure)
82
+ end
83
+
84
+ # Convert a true heading to magnetic based on the airport's
85
+ # magnetic variance.
86
+ def true_to_magnetic(heading)
87
+ heading - @variance
88
+ end
89
+
90
+ # Convert a magnetic heading to true based on the airport's
91
+ # magnetic variance.
92
+ def magnetic_to_true(heading)
93
+ heading + @variance
94
+ end
95
+
96
+ # Print the Airport ICAO code.
97
+ # Allows the object to act as a direct replacement for string input.
98
+ def to_s
99
+ @code.to_s.upcase
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,119 @@
1
+ require 'atc-tools/aircraft'
2
+ require 'atc-tools/airport'
3
+
4
+ module ATCTools
5
+ class FlightPlan
6
+ # Aircraft callsign.
7
+ attr_accessor :callsign
8
+ # Aircraft type/info.
9
+ attr_accessor :aircraft
10
+ # Flight rules.
11
+ attr_accessor :rules
12
+ # Departure airport.
13
+ attr_accessor :depart
14
+ # Arrival airport.
15
+ attr_accessor :arrive
16
+ # Alternate airport.
17
+ attr_accessor :alternate
18
+ # Cruising altitude.
19
+ attr_accessor :cruise
20
+ # Squawk code.
21
+ attr_accessor :squawk
22
+ # Flight route.
23
+ attr_accessor :route
24
+ # Additional remarks/notes.
25
+ attr_accessor :remarks
26
+ # Scratch pad.
27
+ attr_accessor :scratchpad
28
+
29
+ # Params:
30
+ # :callsign, :aircraft, :rules, :depart, :arrive, :alternate, :cruse,
31
+ # :squawk, :route, :remarks, :scratchpad
32
+ # -- See instance variables for descriptions.
33
+ def initialize(**kvargs)
34
+ @callsign = kvargs.fetch :callsign, ''
35
+ @aircraft = kvargs.fetch :aircraft, ATCTools::Aircraft.new
36
+ @rules = kvargs.fetch :rules, ''
37
+ @depart = kvargs.fetch :depart, ATCTools::Airport.new
38
+ @arrive = kvargs.fetch :arrive, ATCTools::Airport.new
39
+ @alternate = kvargs.fetch :alternate, ATCTools::Airport.new
40
+ @cruise = kvargs.fetch :cruise, 0
41
+ @squawk = kvargs.fetch :squawk, '0000'
42
+ @route = kvargs.fetch :route, ''
43
+ @remarks = kvargs.fetch :remarks, ''
44
+ @scratchpad = kvargs.fetch :scratchpad, ''
45
+
46
+ @heading = nil
47
+ end
48
+
49
+ # Magnetic heading from the departure to arrival airport.
50
+ def heading
51
+ altitude_valid? unless @heading # Run the validator to populate @heading.
52
+ @heading
53
+ end
54
+
55
+ # Validate the cruising altitude given the arrival airport
56
+ # and flight rules.
57
+ def altitude_valid?
58
+ # TODO: This can cause a bug if the destination airport is changed
59
+ # after the heading is calculated. Although a new FlightPlan
60
+ # object should be created in this case, the problem should
61
+ # still be fixed.
62
+ @heading = @depart.magnetic_heading_to @arrive unless @heading
63
+
64
+ # Strip the zeros off of the altitude for even/odd comparison.
65
+ cruise_stripped = @cruise.to_s.gsub(/0/, '').to_i
66
+ is_north_east = (@heading < 180 || @heading >= 360)
67
+
68
+ rules = @rules.upcase.to_sym
69
+ case rules
70
+ when :IFR
71
+ above_fl410 = cruise_stripped > 41
72
+
73
+ if above_fl410
74
+ east_alt = [45, 49, 53, 57, 61]
75
+ west_alt = [43, 47, 51, 55, 59]
76
+
77
+ east_valid = (is_north_east && east_alt.include?(cruise_stripped))
78
+ west_valid = ((not is_north_east) && west_alt.include?(cruise_stripped))
79
+
80
+ return true if east_valid || west_valid
81
+ else
82
+ return true if
83
+ (is_north_east && cruise_stripped.odd?) ||
84
+ ((not is_north_east) && cruise_stripped.even?)
85
+ end
86
+
87
+ when :VFR
88
+ end
89
+
90
+ false
91
+ end
92
+
93
+ # Validate the flight plan.
94
+ def validate
95
+ end
96
+
97
+ # Returns a human-readable version of the flight plan.
98
+ def to_s
99
+ data = <<EOS
100
+ Callsign: #{@callsign}
101
+ A/C Type: #{@aircraft}
102
+ Rules: #{@rules}
103
+
104
+ Depart: #{@depart}
105
+ Arrive: #{@arrive} :: #{@arrive.name}
106
+ Alternate: #{@alternate}
107
+
108
+ Route: #{@route}
109
+
110
+ Cruise: #{@cruise}
111
+ Scratchpad: #{@scratchpad}
112
+ Squawk: #{@squawk}
113
+
114
+ Remarks: #{@remarks}
115
+ EOS
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,65 @@
1
+ require 'launchy'
2
+ require 'atc-tools/vrc'
3
+ require 'atc-tools/flight_plan'
4
+
5
+ module ATCTools
6
+ # Script that extracts a flight plan from VRC.
7
+ class FlightPlanValidator
8
+ private_class_method :new
9
+
10
+ # The last flight plan returned.
11
+ def self.flight_plan
12
+ @flight_plan
13
+ end
14
+
15
+ # Note: Executing this script will call commands in
16
+ # the VRC client and will interfere with the user.
17
+ def self.run
18
+ vrc = ATCTools::VRC.new
19
+
20
+ begin
21
+ @flight_plan = vrc.selected_flight_plan!
22
+ rescue ATCTools::NoAircraftSelectedError
23
+ return 'No aircraft selected.'
24
+ end
25
+
26
+ vrc.activate_terminal_window!
27
+
28
+ heading_thread = Thread.new do
29
+ begin
30
+ @flight_plan.heading
31
+ rescue ATCTools::HeadingDiscoveryError
32
+ Launchy.open @flight_plan.depart.heading_uri
33
+ end
34
+ end
35
+
36
+ airport_name_thread = Thread.new do
37
+ begin
38
+ @flight_plan.arrive.name
39
+ rescue ATCTools::NameDiscoveryError
40
+ Launchy.open "https://www.google.com/#q=#{@flight_plan.arrive.upcase}+airport"
41
+ end
42
+ end
43
+
44
+ heading_thread.join
45
+ airport_name_thread.join
46
+
47
+ output = []
48
+
49
+ output << '------------------------------------------------------------'
50
+ output << vrc.flight_plan_title
51
+ output << ''
52
+ output << @flight_plan.to_s.split("\n")
53
+ output << ''
54
+ output << ''
55
+ output << "Alt Valid? #{(@flight_plan.altitude_valid?) ? 'Yes' : '-NO-'}"
56
+ output << "Heading: #{@flight_plan.heading} mag :: #{@flight_plan.depart.magnetic_to_true @flight_plan.heading} true"
57
+ output << ''
58
+ output << @flight_plan.aircraft.info.split(' - ').join("\n").strip
59
+ output << '------------------------------------------------------------'
60
+
61
+ text = output.join("\n")
62
+ end
63
+
64
+ end
65
+ end