hybridgroup-argus 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/argus/at_commander.rb +24 -3
- data/lib/argus/cad_type.rb +22 -0
- data/lib/argus/cfields.rb +98 -0
- data/lib/argus/controller.rb +34 -5
- data/lib/argus/drone.rb +28 -1
- data/lib/argus/float_encoding.rb +13 -0
- data/lib/argus/led_animation.rb +48 -0
- data/lib/argus/nav_data.rb +66 -49
- data/lib/argus/nav_monitor.rb +78 -0
- data/lib/argus/nav_option.rb +29 -0
- data/lib/argus/nav_option_checksum.rb +20 -0
- data/lib/argus/nav_option_demo.rb +79 -0
- data/lib/argus/nav_option_unknown.rb +9 -0
- data/lib/argus/nav_option_vision_detect.rb +83 -0
- data/lib/argus/nav_streamer.rb +12 -4
- data/lib/argus/nav_tag.rb +35 -0
- data/lib/argus/version.rb +1 -1
- data/lib/argus/video_data.rb +15 -0
- data/lib/argus/video_data_envelope.rb +55 -0
- data/lib/argus/video_streamer.rb +23 -0
- data/lib/argus.rb +5 -9
- data/spec/argus/controller_spec.rb +49 -0
- data/spec/argus/drone_spec.rb +24 -0
- data/spec/argus/float_encoding_spec.rb +12 -0
- data/spec/argus/led_animation_spec.rb +21 -0
- data/spec/argus/nav_data_spec.rb +147 -0
- data/spec/argus/nav_option_checksum_spec.rb +21 -0
- data/spec/argus/nav_option_demo_spec.rb +44 -0
- data/spec/argus/nav_option_spec.rb +32 -0
- data/spec/argus/nav_option_unknown_spec.rb +19 -0
- data/spec/argus/nav_option_vision_detect_spec.rb +65 -0
- data/spec/argus/nav_streamer_spec.rb +28 -0
- data/spec/argus/udp_sender_spec.rb +1 -1
- data/spec/argus/video_data_envelope_spec.rb +26 -0
- data/spec/argus/video_data_spec.rb +18 -0
- data/spec/argus/video_streamer_spec.rb +16 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/bytes.rb +48 -0
- metadata +36 -15
- data/lib/argus/pave_parser.rb +0 -39
- data/lib/argus/tcp_video_streamer.rb +0 -20
- data/lib/argus/udp_nav_streamer.rb +0 -24
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 61222b712f9c3d858153e12e2a386aa03e8e06a1
|
4
|
+
data.tar.gz: a0c4785df6cde5776eb45c997382b96f5de4e656
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7f306362aafe950603de3dba9d6efefbaa834a23b4fa27c6e655f85d146b702b115543665dc6d7ea1c273ace9cadbc5a4aec7f68fe3280a763ddbf2c3580d29d
|
7
|
+
data.tar.gz: 028aa4c216e1ebec8a6756635b54221ba87f6bfa6c6d34fb9d0f9ebd8226e464911048d2b9c954dbbb7d84cd46f19cbc138f163b76a9fdec3c480e20ea68e8c0
|
data/lib/argus/at_commander.rb
CHANGED
@@ -2,6 +2,8 @@ require 'thread'
|
|
2
2
|
|
3
3
|
module Argus
|
4
4
|
class ATCommander
|
5
|
+
attr_reader :timestamps
|
6
|
+
|
5
7
|
def initialize(sender)
|
6
8
|
@sender = sender
|
7
9
|
@seq = 0
|
@@ -11,12 +13,14 @@ module Argus
|
|
11
13
|
@thread = nil
|
12
14
|
@interval = 0.020
|
13
15
|
@mutex = Mutex.new
|
16
|
+
@timestamps = []
|
14
17
|
end
|
15
18
|
|
16
19
|
def start
|
17
20
|
@running = true
|
18
21
|
@thread = Thread.new do
|
19
22
|
while @running
|
23
|
+
log_time
|
20
24
|
tick
|
21
25
|
sleep @interval
|
22
26
|
end
|
@@ -53,11 +57,24 @@ module Argus
|
|
53
57
|
end
|
54
58
|
|
55
59
|
def config(key, value)
|
56
|
-
@
|
60
|
+
@mutex.synchronize do
|
61
|
+
command("CONFIG", "\"#{key}\",\"#{value}\"")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def reset_watchdog
|
66
|
+
@mutex.synchronize do
|
67
|
+
command("COMWDG")
|
68
|
+
end
|
57
69
|
end
|
58
70
|
|
59
71
|
private
|
60
72
|
|
73
|
+
def log_time
|
74
|
+
@timestamps.shift if @timestamps.size >= 1000
|
75
|
+
@timestamps << Time.now.to_f
|
76
|
+
end
|
77
|
+
|
61
78
|
def packet
|
62
79
|
yield self
|
63
80
|
flush
|
@@ -68,9 +85,13 @@ module Argus
|
|
68
85
|
@buffer = ""
|
69
86
|
end
|
70
87
|
|
71
|
-
def command(name, args)
|
88
|
+
def command(name, args=nil)
|
72
89
|
@seq += 1
|
73
|
-
|
90
|
+
if args
|
91
|
+
@buffer << "AT*#{name}=#{@seq},#{args}\r"
|
92
|
+
else
|
93
|
+
@buffer << "AT*#{name}=#{@seq}\r"
|
94
|
+
end
|
74
95
|
end
|
75
96
|
end
|
76
97
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Argus
|
2
|
+
module CadType
|
3
|
+
|
4
|
+
NAMES = [
|
5
|
+
:horizontal, # Deprecated
|
6
|
+
:vertical, # Deprecated
|
7
|
+
:vision, # Detection of 2D horizontal tags on drone shells
|
8
|
+
:none, # Detection disabled
|
9
|
+
:cocarde, # Detects a roundel under the drone
|
10
|
+
:oriented_cocarde, # Detects an oriented roundel under the drone
|
11
|
+
:stripe, # Detects a uniform stripe on the ground
|
12
|
+
:h_cocarde, # Detects a roundel in front of the drone
|
13
|
+
:h_oriented_cocarde, # Detects an oriented roundel in front of the drone
|
14
|
+
:stripe_v,
|
15
|
+
:multiple_detection_mode, # The drone uses several detections at the same time
|
16
|
+
:cap, # Detects a Cap orange and green in front of the drone
|
17
|
+
:oriented_cocarde_bw, # Detects the black and white roundel
|
18
|
+
:vision_v2, # Detects 2nd version of shell/tag in front of the drone
|
19
|
+
:tower_side, # Detect a tower side with the front camera
|
20
|
+
]
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'argus/float_encoding'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
module CFields
|
6
|
+
include FloatEncoding
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.send :extend, ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
super
|
14
|
+
@data = unpack_data(args.first)
|
15
|
+
end
|
16
|
+
|
17
|
+
def unpack_data(data)
|
18
|
+
@data = data.unpack(self.class.format_string)
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def data_index
|
23
|
+
@data_index ||= 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def format_string
|
27
|
+
@format_string ||= "x4"
|
28
|
+
end
|
29
|
+
|
30
|
+
def allot(n=1)
|
31
|
+
result = data_index
|
32
|
+
@data_index += n
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def define_field(name, size, format, width=1, &transform)
|
37
|
+
if size
|
38
|
+
define_array_field(name, size, format, width, transform)
|
39
|
+
else
|
40
|
+
define_scaler_field(name, format, width, transform)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def define_scaler_field(name, format, width, transform)
|
45
|
+
index = allot(width)
|
46
|
+
format_string << (width==1 ? format : "#{format}#{width}")
|
47
|
+
if transform
|
48
|
+
ivar = "@#{name}".to_sym
|
49
|
+
define_method(name) {
|
50
|
+
instance_variable_get(ivar) ||
|
51
|
+
instance_variable_set(ivar, transform.call(@data[index]))
|
52
|
+
}
|
53
|
+
else
|
54
|
+
define_method(name) { @data[index] }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def define_array_field(name, size, format, width, transform)
|
59
|
+
index = allot(width*size)
|
60
|
+
format_string << "#{format}#{width*size}"
|
61
|
+
if transform
|
62
|
+
ivar = "@#{name}".to_sym
|
63
|
+
define_method(name) {
|
64
|
+
instance_variable_get(ivar) ||
|
65
|
+
instance_variable_set(ivar, @data[index, size].map(&transform))
|
66
|
+
}
|
67
|
+
else
|
68
|
+
define_method(name) { @data[index, size] }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def uint32_t(name, size=nil)
|
73
|
+
define_field(name, size, "V")
|
74
|
+
end
|
75
|
+
|
76
|
+
def uint16_t(name, size=nil)
|
77
|
+
define_field(name, size, "v")
|
78
|
+
end
|
79
|
+
|
80
|
+
def float32_t(name, size=nil)
|
81
|
+
define_field(name, size, "V") { |v| FloatEncoding.decode_float(v) }
|
82
|
+
end
|
83
|
+
|
84
|
+
def int32_t(name, size=nil)
|
85
|
+
define_field(name, size, "l<")
|
86
|
+
end
|
87
|
+
|
88
|
+
def matrix33_t(name, size=nil)
|
89
|
+
define_field(name, size, "V", 9) { |v| nil }
|
90
|
+
end
|
91
|
+
|
92
|
+
def vector31_t(name, size=nil)
|
93
|
+
define_field(name, size, "V", 3) { |v| nil }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
data/lib/argus/controller.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
require 'argus/float_encoding'
|
2
|
+
|
1
3
|
module Argus
|
2
4
|
class Controller
|
5
|
+
include FloatEncoding
|
3
6
|
|
4
7
|
def initialize(at_commander)
|
5
8
|
@at_commander = at_commander
|
@@ -83,14 +86,44 @@ module Argus
|
|
83
86
|
update_pcmd
|
84
87
|
end
|
85
88
|
|
89
|
+
def led(selection, hertz, duration)
|
90
|
+
selection = LedAnimation.lookup_value(selection)
|
91
|
+
value = [
|
92
|
+
selection,
|
93
|
+
FloatEncoding.encode_float(hertz),
|
94
|
+
duration
|
95
|
+
].join(',')
|
96
|
+
@at_commander.config("leds:leds_anim",value)
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
def enable_detection(colors, type=10, select=32)
|
101
|
+
config("detect:enemy_colors",colors.to_s)
|
102
|
+
config("detect:detect_type", type.to_s)
|
103
|
+
config("detect:detections_select_h", select.to_s)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
def config(key, value)
|
108
|
+
@at_commander.config(key, value)
|
109
|
+
end
|
110
|
+
|
111
|
+
def demo_mode
|
112
|
+
@at_commander.config("general:navdata_demo", "TRUE")
|
113
|
+
end
|
114
|
+
|
86
115
|
def front_camera
|
87
116
|
@at_commander.config("video:video_channel", "2")
|
88
117
|
end
|
89
|
-
|
118
|
+
|
90
119
|
def bottom_camera
|
91
120
|
@at_commander.config("video:video_channel", "1")
|
92
121
|
end
|
93
122
|
|
123
|
+
def reset_watchdog
|
124
|
+
@at_commander.reset_watchdog
|
125
|
+
end
|
126
|
+
|
94
127
|
private
|
95
128
|
|
96
129
|
REF_BASE = [18, 20, 22, 24, 28].
|
@@ -122,9 +155,5 @@ module Argus
|
|
122
155
|
self
|
123
156
|
end
|
124
157
|
|
125
|
-
def encode_float(float)
|
126
|
-
[float].pack('g').unpack("l>").first
|
127
|
-
end
|
128
|
-
|
129
158
|
end
|
130
159
|
end
|
data/lib/argus/drone.rb
CHANGED
@@ -1,22 +1,47 @@
|
|
1
1
|
require 'socket'
|
2
|
+
require 'argus/nav_monitor'
|
2
3
|
|
3
4
|
module Argus
|
5
|
+
|
4
6
|
class Drone
|
7
|
+
attr_reader :controller, :enable_nav_monitor
|
8
|
+
|
5
9
|
def initialize(socket=nil, host='192.168.1.1', port='5556')
|
6
10
|
@socket = socket || UDPSocket.new
|
7
11
|
@sender = Argus::UdpSender.new(@socket, host, port)
|
8
12
|
@at = Argus::ATCommander.new(@sender)
|
9
13
|
@controller = Argus::Controller.new(@at)
|
14
|
+
|
15
|
+
@enable_nav_monitor = false
|
10
16
|
end
|
11
17
|
|
12
|
-
def
|
18
|
+
def commander
|
19
|
+
@at
|
20
|
+
end
|
21
|
+
|
22
|
+
def start(enable_nav_monitor=true)
|
23
|
+
@enable_nav_monitor = enable_nav_monitor
|
24
|
+
|
25
|
+
if enable_nav_monitor
|
26
|
+
@nav = NavMonitor.new(@controller)
|
27
|
+
@nav.start
|
28
|
+
end
|
29
|
+
|
13
30
|
@at.start
|
14
31
|
end
|
15
32
|
|
16
33
|
def stop
|
17
34
|
@controller.land
|
35
|
+
|
18
36
|
@at.stop
|
37
|
+
@nav.stop if enable_nav_monitor
|
38
|
+
|
19
39
|
@at.join
|
40
|
+
@nav.join if enable_nav_monitor
|
41
|
+
end
|
42
|
+
|
43
|
+
def nav_callback(*args, &block)
|
44
|
+
@nav.callback(*args, &block)
|
20
45
|
end
|
21
46
|
|
22
47
|
%w(
|
@@ -26,6 +51,8 @@ module Argus
|
|
26
51
|
up down
|
27
52
|
turn_left turn_right
|
28
53
|
front_camera bottom_camera
|
54
|
+
config
|
55
|
+
reset_watchdog
|
29
56
|
).each do |meth|
|
30
57
|
define_method(meth) { |*args|
|
31
58
|
@controller.send(meth, *args)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Argus
|
2
|
+
|
3
|
+
module LedAnimation
|
4
|
+
NAMES = [
|
5
|
+
:blink_green_red,
|
6
|
+
:blink_green,
|
7
|
+
:blink_red,
|
8
|
+
:blink_orange,
|
9
|
+
:snake_green_red,
|
10
|
+
:fire,
|
11
|
+
:standard,
|
12
|
+
:red,
|
13
|
+
:green,
|
14
|
+
:red_snake,
|
15
|
+
:blank,
|
16
|
+
:right_missile,
|
17
|
+
:left_missile,
|
18
|
+
:double_missile,
|
19
|
+
:front_left_green_others_red,
|
20
|
+
:front_right_green_others_red,
|
21
|
+
:rear_right_green_others_red,
|
22
|
+
:rear_left_green_others_red,
|
23
|
+
:left_green_right_red,
|
24
|
+
:left_red_right_green,
|
25
|
+
:blink_standard,
|
26
|
+
]
|
27
|
+
|
28
|
+
VALUES = {}
|
29
|
+
NAMES.each.with_index { |name, index| VALUES[name] = index }
|
30
|
+
|
31
|
+
def self.lookup_name(numeric_value)
|
32
|
+
NAMES[numeric_value]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.lookup_value(symbolic_name)
|
36
|
+
case symbolic_name
|
37
|
+
when Symbol
|
38
|
+
VALUES[symbolic_name]
|
39
|
+
when Integer
|
40
|
+
symbolic_name
|
41
|
+
when /^\d+/
|
42
|
+
symbolic_name.to_i
|
43
|
+
when String
|
44
|
+
VALUES[symbolic_name.intern]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/argus/nav_data.rb
CHANGED
@@ -1,61 +1,78 @@
|
|
1
1
|
module Argus
|
2
2
|
class NavData
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :state_mask, :vision_flag, :sequence_number, :options
|
4
|
+
|
4
5
|
def initialize(data)
|
5
6
|
@data = data
|
6
7
|
parse_nav_data(@data)
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
+
def raw
|
11
|
+
@data
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.bit_mask_readers(*names)
|
15
|
+
names.each.with_index do |name, bit_number|
|
16
|
+
if name.is_a?(Array)
|
17
|
+
name, off_value, on_value = name
|
18
|
+
else
|
19
|
+
off_value = false
|
20
|
+
on_value = true
|
21
|
+
end
|
22
|
+
define_method(name) { @state_mask[bit_number] == 0 ? off_value : on_value }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
bit_mask_readers(
|
27
|
+
:flying?, # FLY MASK : (0) ardrone is landed, (1) ardrone is flying
|
28
|
+
:video_enabled?, # VIDEO MASK : (0) video disable, (1) video enable
|
29
|
+
:vision_enabled?, # VISION MASK : (0) vision disable, (1) vision enable
|
30
|
+
[:control_algorithm, # CONTROL ALGO : (0) euler angles control, (1) angular speed control
|
31
|
+
:euler, :angular_speed],
|
32
|
+
:altitude_control_algorithm_active?, # ALTITUDE CONTROL ALGO : (0) altitude control inactive (1) altitude control active
|
33
|
+
:start_button_pressed?, # USER feedback : Start button state
|
34
|
+
:control_command_ack?, # Control command ACK : (0) None, (1) one received
|
35
|
+
:camera_ready?, # CAMERA MASK : (0) camera not ready, (1) Camera ready
|
36
|
+
:travelling_enabled?, # Travelling mask : (0) disable, (1) enable
|
37
|
+
:usb_ready?, # USB key : (0) usb key not ready, (1) usb key ready
|
38
|
+
[:mode, :all, :demo], # Navdata demo : (0) All navdata, (1) only navdata demo
|
39
|
+
:bootstrap?, # Navdata bootstrap : (0) options sent in all or demo mode, (1) no navdata options sent
|
40
|
+
:moter_problem?, # Motors status : (0) Ok, (1) Motors problem
|
41
|
+
:communication_lost?, # Communication Lost : (1) com problem, (0) Com is ok
|
42
|
+
:software_fault?, # Software fault detected - user should land as quick as possible (1)
|
43
|
+
:low_battery?, # VBat low : (1) too low, (0) Ok
|
44
|
+
:emergency_landing_requested?, # User Emergency Landing : (1) User EL is ON, (0) User EL is OF
|
45
|
+
:timer_elapsed?, # Timer elapsed : (1) elapsed, (0) not elapsed
|
46
|
+
:magnometer_needs_calibration?, # Magnetometer calibration state : (0) Ok, no calibration needed, (1) not ok, calibration needed
|
47
|
+
:angles_out_of_range?, # Angles : (0) Ok, (1) out of range
|
48
|
+
:too_much_wind?, # WIND MASK: (0) ok, (1) Too much wind
|
49
|
+
:ultrasonic_sensor_deaf?, # Ultrasonic sensor : (0) Ok, (1) deaf
|
50
|
+
:cutout_detected?, # Cutout system detection : (0) Not detected, (1) detected
|
51
|
+
:pic_version_number_ok?, # PIC Version number OK : (0) a bad version number, (1) version number is OK
|
52
|
+
:at_codec_thread_on?, # ATCodec thread ON : (0) thread OFF (1) thread ON
|
53
|
+
:navdata_thread_on?, # Navdata thread ON : (0) thread OFF (1) thread ON
|
54
|
+
:video_thread_on?, # Video thread ON : (0) thread OFF (1) thread ON
|
55
|
+
:acquisition_thread_on?, # Acquisition thread ON : (0) thread OFF (1) thread ON
|
56
|
+
:control_watchdog_delayed?, # CTRL watchdog : (1) delay in control execution (> 5ms), (0) control is well scheduled
|
57
|
+
:adc_watchdog_delayed?, # ADC Watchdog : (1) delay in uart2 dsr (> 5ms), (0) uart2 is good
|
58
|
+
:com_watchdog_problem?, # Communication Watchdog : (1) com problem, (0) Com is ok
|
59
|
+
:emergency_landing?) # Emergency landing : (0) no emergency, (1) emergency
|
60
|
+
|
61
|
+
private
|
62
|
+
|
10
63
|
def parse_nav_data(data)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
:controlAlgorithm=>state[3], #/*!< CONTROL ALGO : (0) euler angles control, (1) angular speed control */
|
17
|
-
:altitudeControlAlgorithm=>state[4], #/*!< ALTITUDE CONTROL ALGO : (0) altitude control inactive (1) altitude control active */
|
18
|
-
:startButtonState=>state[5], #/*!< USER feedback : Start button state */
|
19
|
-
:controlCommandAck=>state[6], #/*!< Control command ACK : (0) None, (1) one received */
|
20
|
-
:cameraReady=>state[7], #/*!< CAMERA MASK : (0) camera not ready, (1) Camera ready */
|
21
|
-
:travellingEnabled=>state[8], #/*!< Travelling mask : (0) disable, (1) enable */
|
22
|
-
:usbReady=>state[9], #/*!< USB key : (0) usb key not ready, (1) usb key ready */
|
23
|
-
:navdataDemo=>state[10], #/*!< Navdata demo : (0) All navdata, (1) only navdata demo */
|
24
|
-
:navdataBootstrap=>state[11], #/*!< Navdata bootstrap : (0) options sent in all or demo mode, (1) no navdata options sent */
|
25
|
-
:motorProblem=>state[12], #/*!< Motors status : (0) Ok, (1) Motors problem */
|
26
|
-
:communicationLost=>state[13], #/*!< Communication Lost : (1) com problem, (0) Com is ok */
|
27
|
-
:softwareFault=>state[14], #/*!< Software fault detected - user should land as quick as possible (1) */
|
28
|
-
:lowBattery=>state[15], #/*!< VBat low : (1) too low, (0) Ok */
|
29
|
-
:userEmergencyLanding=>state[16], #/*!< User Emergency Landing : (1) User EL is ON, (0) User EL is OFF*/
|
30
|
-
:timerElapsed=>state[17], #/*!< Timer elapsed : (1) elapsed, (0) not elapsed */
|
31
|
-
:MagnometerNeedsCalibration=>state[18], #/*!< Magnetometer calibration state : (0) Ok, no calibration needed, (1) not ok, calibration needed */
|
32
|
-
:anglesOutOfRange=>state[19], #/*!< Angles : (0) Ok, (1) out of range */
|
33
|
-
:tooMuchWind=>state[20], #/*!< WIND MASK: (0) ok, (1) Too much wind */
|
34
|
-
:ultrasonicSensorDeaf=>state[21], #/*!< Ultrasonic sensor : (0) Ok, (1) deaf */
|
35
|
-
:cutoutDetected=>state[22], #/*!< Cutout system detection : (0) Not detected, (1) detected */
|
36
|
-
:picVersionNumberOk=>state[23], #/*!< PIC Version number OK : (0) a bad version number, (1) version number is OK */
|
37
|
-
:atCodecThreadOn=>state[24], #/*!< ATCodec thread ON : (0) thread OFF (1) thread ON */
|
38
|
-
:navdataThreadOn=>state[25], #/*!< Navdata thread ON : (0) thread OFF (1) thread ON */
|
39
|
-
:videoThreadOn=>state[26], #/*!< Video thread ON : (0) thread OFF (1) thread ON */
|
40
|
-
:acquisitionThreadOn=>state[27], #/*!< Acquisition thread ON : (0) thread OFF (1) thread ON */
|
41
|
-
:controlWatchdogDelay=>state[28], #/*!< CTRL watchdog : (1) delay in control execution (> 5ms), (0) control is well scheduled */
|
42
|
-
:adcWatchdogDelay=>state[29], #/*!< ADC Watchdog : (1) delay in uart2 dsr (> 5ms), (0) uart2 is good */
|
43
|
-
:comWatchdogProblem=>state[30], #/*!< Communication Watchdog : (1) com problem, (0) Com is ok */
|
44
|
-
:emergencyLanding=>state[31] #/*!< Emergency landing : (0) no emergency, (1) emergency */
|
45
|
-
}
|
46
|
-
data.slice!(0..3)
|
47
|
-
@sequence_number = data.unpack("V").first
|
48
|
-
data.slice!(0..3)
|
49
|
-
@vision_flag = data.unpack("V").first
|
64
|
+
tag, @state_mask, @sequence_number, @vision_flag = data.unpack("VVVV")
|
65
|
+
parse_nav_options(data[16..-1])
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_nav_options(data)
|
50
69
|
@options = []
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
option1[:data] = data.unpack("V").first
|
58
|
-
@options.push(option1)
|
70
|
+
loop do
|
71
|
+
opt = NavOption.parse(data)
|
72
|
+
data = data[opt.size .. -1]
|
73
|
+
@options << opt
|
74
|
+
break if data.nil? || data.empty?
|
75
|
+
end
|
59
76
|
end
|
60
77
|
end
|
61
78
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Argus
|
2
|
+
|
3
|
+
class NavMonitor
|
4
|
+
def initialize(controller)
|
5
|
+
@controller = controller
|
6
|
+
@nav = NavStreamer.new
|
7
|
+
@callbacks = []
|
8
|
+
@mutex = Mutex.new
|
9
|
+
@nav_data = nil
|
10
|
+
@nav_options = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def start
|
14
|
+
@nav.start
|
15
|
+
@running = true
|
16
|
+
@nav_thread = Thread.new do
|
17
|
+
while @running
|
18
|
+
data = @nav.receive_data
|
19
|
+
update_nav_data(data) if data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def stop
|
25
|
+
@running = false
|
26
|
+
end
|
27
|
+
|
28
|
+
def join
|
29
|
+
@nav_thread.join
|
30
|
+
end
|
31
|
+
|
32
|
+
def callback(callback=nil, &block)
|
33
|
+
@mutex.synchronize do
|
34
|
+
@callbacks << callback unless callback.nil?
|
35
|
+
@callbacks << block if block_given?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def data
|
40
|
+
@mutex.synchronize { @nav_data }
|
41
|
+
end
|
42
|
+
|
43
|
+
def option(tag)
|
44
|
+
@mutex.synchronize { @nav_options[tag] }
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def update_nav_data(data)
|
50
|
+
@mutex.synchronize do
|
51
|
+
update_internal_nav_data(data)
|
52
|
+
do_callbacks(data)
|
53
|
+
end
|
54
|
+
rescue Exception => ex
|
55
|
+
puts "ERROR in callback: #{ex}"
|
56
|
+
puts ex.message
|
57
|
+
puts ex.backtrace
|
58
|
+
$stdout.flush
|
59
|
+
end
|
60
|
+
|
61
|
+
def update_internal_nav_data(data)
|
62
|
+
@nav_data = data
|
63
|
+
if @nav_data.bootstrap?
|
64
|
+
@controller.demo_mode
|
65
|
+
end
|
66
|
+
data.options.each do |opt|
|
67
|
+
@nav_options[opt.tag] = opt if opt.tag < 100
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def do_callbacks(data)
|
72
|
+
@callbacks.each do |callback|
|
73
|
+
callback.call(data)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Argus
|
2
|
+
|
3
|
+
class NavOption
|
4
|
+
attr_reader :tag
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@tag, @size = data.unpack("vv")
|
8
|
+
end
|
9
|
+
|
10
|
+
def size
|
11
|
+
@size < 4 ? 4 : @size
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.options
|
15
|
+
@options ||= { }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.register(option)
|
19
|
+
options[option.tag] = option
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.parse(raw_data)
|
23
|
+
tag = raw_data.unpack("v").first
|
24
|
+
option = options[tag] || NavOptionUnknown
|
25
|
+
option.new(raw_data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'argus/cfields'
|
2
|
+
require 'argus/nav_option'
|
3
|
+
require 'argus/nav_tag'
|
4
|
+
|
5
|
+
module Argus
|
6
|
+
|
7
|
+
class NavOptionChecksum < NavOption
|
8
|
+
include CFields
|
9
|
+
|
10
|
+
uint32_t :chks
|
11
|
+
alias :checksum :chks
|
12
|
+
|
13
|
+
def self.tag
|
14
|
+
NavTag::CHECKSUM
|
15
|
+
end
|
16
|
+
|
17
|
+
NavOption.register(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|