argus 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f89d5eb3a36569a8fb2d9e6c17a2eebd17e92d8
4
- data.tar.gz: ec1b2d028705b04ae55f8eeaa5dfb91c4352347f
3
+ metadata.gz: a5bfdb6916c2a3d0cd8dc924b5633e2de3bdbdff
4
+ data.tar.gz: 77c42e8e23f91fa3be7aea5c59b3521ff6e5b9bb
5
5
  SHA512:
6
- metadata.gz: 80bde0b4804b76b9be1d79d8c3c2537767a1fc35027bf52811d1324fc4a407d645412ab441675049e2dcf9bdaac14382c5f39fb2520f71e9469dbb4dafe533e9
7
- data.tar.gz: 330df98c125cfb917f81da99d26dcdc9b25a506e5ffe57ad0c55bc6aad08d035bc2fa6050a377be3f02fe1df58b0d3a1f6e8d587883c5e5753aaba56165244e2
6
+ metadata.gz: f0a9cefb0fcac10f6295cfc990e9bbaed5c419b19a7ec88c4171bff272628e53753db0af6e456c4bf28b29657d3d38302b04557dc6f14ba65202e34519dd25bb
7
+ data.tar.gz: fc58f050f88a77cc0a15cc83f77cad71b1e7610b8ac58f9f679ca956399c96cdf7a02fadf089ad02c5f27b6c93018d2f3f373bb245be6072fb8503b38f86b658
@@ -3,6 +3,7 @@ require 'thread'
3
3
  module Argus
4
4
  class ATCommander
5
5
  attr_reader :timestamps
6
+ attr_accessor :interval
6
7
 
7
8
  def initialize(sender)
8
9
  @sender = sender
@@ -44,10 +45,6 @@ module Argus
44
45
  @thread.join if @thread
45
46
  end
46
47
 
47
- def interval=(new_interval)
48
- @mutex.synchronize do @interval = new_interval end
49
- end
50
-
51
48
  def ref(data)
52
49
  @mutex.synchronize do @ref_data = data end
53
50
  end
@@ -107,22 +107,24 @@ module Argus
107
107
 
108
108
  def config(key, value)
109
109
  @at_commander.config(key, value)
110
+ self
110
111
  end
111
112
 
112
113
  def demo_mode
113
- @at_commander.config("general:navdata_demo", "TRUE")
114
+ config("general:navdata_demo", "TRUE")
114
115
  end
115
116
 
116
117
  def front_camera
117
- @at_commander.config("video:video_channel", "2")
118
+ config("video:video_channel", "2")
118
119
  end
119
120
 
120
121
  def bottom_camera
121
- @at_commander.config("video:video_channel", "1")
122
+ config("video:video_channel", "1")
122
123
  end
123
124
 
124
125
  def reset_watchdog
125
126
  @at_commander.comwdg
127
+ self
126
128
  end
127
129
 
128
130
  def ack_control_mode
@@ -7,13 +7,15 @@ module Argus
7
7
  attr_reader :controller, :nav
8
8
 
9
9
  def initialize(opts={})
10
- @host = opts[:remote_host] || '192.168.1.1'
10
+ host = opts[:remote_host] || '192.168.1.1'
11
11
  port = opts[:post] || '5556'
12
- @sender = opts[:sender] || Argus::UdpSender.new(socket: opts[:socket], remote_host: @host, port: port)
13
- @at = Argus::ATCommander.new(@sender)
14
- @controller = Argus::Controller.new(@at)
15
- if opts.fetch(:enable_nav_monitor, true)
16
- @nav = NavMonitor.new(@controller, @host)
12
+ @sender = opts[:sender] || Argus::UdpSender.new(socket: opts[:socket], remote_host: host, port: port)
13
+ @at = opts[:commander] || Argus::ATCommander.new(@sender)
14
+ @controller = opts[:controller] || Argus::Controller.new(@at)
15
+ if opts[:nav_monitor]
16
+ @nav = opts[:nav_monitor]
17
+ elsif opts.fetch(:enable_nav_monitor, true)
18
+ @nav = NavMonitor.new(@controller, host)
17
19
  else
18
20
  @nav = NullNavMonitor.new
19
21
  end
@@ -3,9 +3,9 @@ module Argus
3
3
  class NavMonitor
4
4
  attr_reader :streamer
5
5
 
6
- def initialize(controller, remote_host)
6
+ def initialize(controller, remote_host, opts={})
7
7
  @controller = controller
8
- @streamer = NavStreamer.new(remote_host: remote_host)
8
+ @streamer = opts.fetch(:streamer) { NavStreamer.new(remote_host: remote_host) }
9
9
  @callbacks = []
10
10
  @mutex = Mutex.new
11
11
  @nav_data = nil
@@ -28,6 +28,7 @@ module Argus
28
28
  end
29
29
 
30
30
  def join
31
+ stop
31
32
  @nav_thread.join
32
33
  end
33
34
 
@@ -46,8 +47,6 @@ module Argus
46
47
  @mutex.synchronize { @nav_options[tag] }
47
48
  end
48
49
 
49
- private
50
-
51
50
  def update_nav_data(data)
52
51
  @mutex.synchronize do
53
52
  update_internal_nav_data(data)
@@ -60,6 +59,8 @@ module Argus
60
59
  $stdout.flush
61
60
  end
62
61
 
62
+ private
63
+
63
64
  def update_internal_nav_data(data)
64
65
  @nav_data = data
65
66
  if @nav_data.bootstrap?
@@ -26,7 +26,7 @@ module Argus
26
26
  @local_host = opts[:local_host] || '0.0.0.0'
27
27
  @port = opts[:port] || 5554
28
28
  @socket_class = opts[:UDPSocket] || UDPSocket
29
- start_timer
29
+ start_timer unless opts[:disable_timer]
30
30
  end
31
31
 
32
32
  def start
@@ -2,7 +2,7 @@ module Argus
2
2
  module Version # :nodoc: all
3
3
  NUMBERS = [
4
4
  MAJOR = 0,
5
- MINOR = 3,
5
+ MINOR = 4,
6
6
  BUILD = 0,
7
7
  ]
8
8
  end
@@ -0,0 +1,15 @@
1
+ module Argus
2
+ class VideoData
3
+ attr_reader :socket, :envelope, :frame
4
+
5
+ def initialize(socket)
6
+ @socket = socket
7
+ @envelope = VideoDataEnvelope.new(@socket)
8
+ @frame = parse_frame
9
+ end
10
+
11
+ def parse_frame
12
+ socket.read(envelope.payload_size) if envelope
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,55 @@
1
+ module Argus
2
+ class VideoDataEnvelope
3
+ attr_reader :socket
4
+
5
+ def initialize(socket)
6
+ @socket = socket
7
+ parse
8
+ end
9
+
10
+ def parse
11
+ data(:signature, 4, "A*")
12
+ data(:version, 1, "C")
13
+ data(:video_codec, 1, "C")
14
+ data(:header_size, 2, "v")
15
+ data(:payload_size, 4, "V")
16
+ data(:encoded_stream_width, 2, "v")
17
+ data(:encoded_stream_height, 2, "v")
18
+ data(:display_width, 2, "v")
19
+ data(:display_height, 2, "v")
20
+ data(:frame_number, 4, "V")
21
+ data(:timestamp, 4, "V")
22
+ data(:total_chunks, 1, "C")
23
+ data(:chunk_index, 1, "C")
24
+ data(:frame_type, 1, "C")
25
+ data(:control, 1, "C")
26
+ data(:stream_byte_position_lw, 4, "V")
27
+ data(:stream_byte_position_uw, 4, "V")
28
+ data(:stream_id, 2, "v")
29
+ data(:total_slices, 1, "C")
30
+ data(:slice_index, 1, "C")
31
+ data(:header1_size, 1, "C")
32
+ data(:header2_size, 1, "C")
33
+ data(:reserved_2, 2, "H*")
34
+ data(:advertised_size, 4, "V")
35
+ data(:reserved_12, 12, "H*")
36
+ socket.read(4) # TODO: look at why just throwing this data away
37
+ end
38
+
39
+ def data(name, size, format)
40
+ define_data(name, get_data(size, format))
41
+ end
42
+
43
+ def get_data(size, format)
44
+ socket.read(size).unpack(format).first
45
+ end
46
+
47
+ def define_data(name, value)
48
+ ivar = "@#{name}".to_sym
49
+ instance_variable_set(ivar, value)
50
+ self.class.send(:define_method, name) do
51
+ instance_variable_get(ivar)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,23 @@
1
+ require 'socket'
2
+
3
+ module Argus
4
+ class VideoStreamer
5
+ attr_reader :tcp_socket, :host, :port
6
+
7
+ def initialize(opts={})
8
+ @host = opts[:host] || '192.168.1.1'
9
+ @port = opts[:port] || 5555
10
+ @tcp_socket = opts[:socket] || TCPSocket.new(@host, @port)
11
+ end
12
+
13
+ def start(udp_socket=nil)
14
+ @udp_socket = udp_socket || UDPSocket.new
15
+ @udp_socket.send("\x01\x00\x00\x00", 0, host, port)
16
+ @udp_socket.close
17
+ end
18
+
19
+ def receive_data
20
+ VideoData.new(tcp_socket)
21
+ end
22
+ end
23
+ end
@@ -77,6 +77,9 @@ describe Argus::ATCommander do
77
77
  Then { sender.should have_received(:send_packet) }
78
78
  end
79
79
 
80
-
80
+ describe "setting the interval" do
81
+ Given { cmdr.interval = 1.0 }
82
+ Then { cmdr.interval == 1.0 }
83
+ end
81
84
 
82
85
  end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module CFieldsSpec
4
+ describe Argus::CFields do
5
+ class Example < Argus::NavOption
6
+ include Argus::CFields
7
+ uint32_t :u32
8
+ uint16_t :u16
9
+ float32_t :f32
10
+ int32_t :i32
11
+ matrix33_t :m33
12
+ vector31_t :v31
13
+
14
+ def self.tag
15
+ 14263
16
+ end
17
+
18
+ Argus::NavOption.register(self)
19
+ end
20
+
21
+ Given(:raw_data) {
22
+ [
23
+ Bytes.int16(Example.tag),
24
+ Bytes.int16(10),
25
+ Bytes.int32(1),
26
+ Bytes.int16(2),
27
+ Bytes.float32(3.4),
28
+ ].flatten.pack("C*")
29
+ }
30
+
31
+ When(:data) { Example.new(raw_data) }
32
+
33
+ Then { data.size == 10 }
34
+ Then { data.tag == Example.tag }
35
+ Then { data.u32 == 1 }
36
+ Then { data.u16 == 2 }
37
+ Then { data.f32 == about(3.4).percent(1) }
38
+ end
39
+ end
@@ -15,135 +15,153 @@ describe Argus::Controller do
15
15
  Given(:at) { flexmock(:on, Argus::ATCommander) }
16
16
  Given(:controller) { Argus::Controller.new(at) }
17
17
 
18
- context "navigating commands" do
18
+ describe "controller commands" do
19
19
  Invariant { result.should == controller }
20
20
 
21
- context "when taking off" do
22
- When(:result) { controller.take_off }
23
- Then { at.should have_received(:ref).with(ref_bits(9)) }
21
+ context "navigating commands" do
22
+ context "when taking off" do
23
+ When(:result) { controller.take_off }
24
+ Then { at.should have_received(:ref).with(ref_bits(9)) }
25
+ end
26
+
27
+ context "when landing" do
28
+ When(:result) { controller.land }
29
+ Then { at.should have_received(:ref).with(ref_bits).twice }
30
+ end
31
+
32
+ context "when emergency" do
33
+ Given { controller.take_off }
34
+ When(:result) { controller.emergency }
35
+ Then { at.should have_received(:ref).with(ref_bits(8)) }
36
+ end
37
+
38
+ context "when taking off after an emergency" do
39
+ Given { controller.emergency }
40
+ When(:result) { controller.take_off }
41
+ Then { at.should have_received(:ref).with(ref_bits(9)) }
42
+ end
43
+
44
+ context "when hovering" do
45
+ When(:result) { controller.hover }
46
+ Then { at.should have_received(:pcmd).with("0,0,0,0,0") }
47
+ end
48
+
49
+ context "when moving forward" do
50
+ When(:result) { controller.forward(0.80) }
51
+ Then { at.should have_received(:pcmd).with("1,0,-1085485875,0,0") }
52
+ end
53
+
54
+ context "when moving backward" do
55
+ When(:result) { controller.backward(0.80) }
56
+ Then { at.should have_received(:pcmd).with("1,0,1061997773,0,0") }
57
+ end
58
+
59
+ context "when moving to the left" do
60
+ When(:result) { controller.left(0.80) }
61
+ Then { at.should have_received(:pcmd).with("1,-1085485875,0,0,0") }
62
+ end
63
+
64
+ context "when moving to the right" do
65
+ When(:result) { controller.right(0.80) }
66
+ Then { at.should have_received(:pcmd).with("1,1061997773,0,0,0") }
67
+ end
68
+
69
+ context "when moving up" do
70
+ When(:result) { controller.up(0.80) }
71
+ Then { at.should have_received(:pcmd).with("1,0,0,1061997773,0") }
72
+ end
73
+
74
+ context "when moving down" do
75
+ When(:result) { controller.down(0.80) }
76
+ Then { at.should have_received(:pcmd).with("1,0,0,-1085485875,0") }
77
+ end
78
+
79
+ context "when turning left" do
80
+ When(:result) { controller.turn_left(0.80) }
81
+ Then { at.should have_received(:pcmd).with("1,0,0,0,-1085485875") }
82
+ end
83
+
84
+ context "when turning right" do
85
+ When(:result) { controller.turn_right(0.80) }
86
+ Then { at.should have_received(:pcmd).with("1,0,0,0,1061997773") }
87
+ end
88
+
89
+ context "when executing several directions" do
90
+ When(:result) {
91
+ controller.forward(1.0).left(0.5).up(0.2).turn_left(0.8)
92
+ }
93
+ Then { at.should have_received(:pcmd).with("1,-1090519040,-1082130432,1045220557,-1085485875") }
94
+ end
95
+ end
96
+
97
+ describe "config command" do
98
+ context "when setting with numeric sequence" do
99
+ When(:result) { controller.led(3, 2.0, 4) }
100
+ Then {
101
+ at.should have_received(:config)
102
+ .with("leds:leds_anim", "3,1073741824,4")
103
+ }
104
+ end
105
+
106
+ context "when setting with symbolic sequence" do
107
+ When(:result) { controller.led(:blink_orange, 2.0, 4) }
108
+ Then {
109
+ at.should have_received(:config)
110
+ .with("leds:leds_anim", "3,1073741824,4")
111
+ }
112
+ end
113
+ end
114
+
115
+ describe "enabled detection command" do
116
+ context "when setting all parameters" do
117
+ Given(:enemy) { 2 }
118
+ Given(:type) { 11 }
119
+ Given(:select) { 33 }
120
+
121
+ When(:result) { controller.enable_detection(enemy, type, select) }
122
+
123
+ Then { at.should have_received(:config).with("detect:enemy_colors", enemy.to_s) }
124
+ Then { at.should have_received(:config).with("detect:detect_type", type.to_s) }
125
+ Then { at.should have_received(:config).with("detect:detections_select_h", select.to_s) }
126
+ end
127
+
128
+ context "when setting with only enemy" do
129
+ Given(:enemy) { 2 }
130
+ Given(:type) { 10 }
131
+ Given(:select) { 32 }
132
+
133
+ When(:result) { controller.enable_detection(enemy) }
134
+
135
+ Then { at.should have_received(:config).with("detect:enemy_colors", enemy.to_s) }
136
+ Then { at.should have_received(:config).with("detect:detect_type", type.to_s) }
137
+ Then { at.should have_received(:config).with("detect:detections_select_h", select.to_s) }
138
+ end
139
+
140
+ context "when doing demo mode" do
141
+ When(:result) { controller.demo_mode }
142
+ Then { at.should have_received(:config).with("general:navdata_demo", "TRUE") }
143
+ end
144
+
145
+ context "when selecting the forward camera" do
146
+ When(:result) { controller.front_camera }
147
+ Then { at.should have_received(:config).with("video:video_channel", "2") }
148
+ end
149
+
150
+ context "when selecting the bottom camera" do
151
+ When(:result) { controller.bottom_camera }
152
+ Then { at.should have_received(:config).with("video:video_channel", "1") }
153
+ end
154
+
155
+ end
156
+
157
+ describe "reset watchdog command" do
158
+ When(:result) { controller.reset_watchdog}
159
+ Then { at.should have_received(:comwdg).with() }
160
+ end
161
+
162
+ describe "ack control mode command" do
163
+ When(:result) { controller.ack_control_mode }
164
+ Then { at.should have_received(:ctrl).with(5) }
24
165
  end
25
-
26
- context "when landing" do
27
- When(:result) { controller.land }
28
- Then { at.should have_received(:ref).with(ref_bits).twice }
29
- end
30
-
31
- context "when emergency" do
32
- Given { controller.take_off }
33
- When(:result) { controller.emergency }
34
- Then { at.should have_received(:ref).with(ref_bits(8)) }
35
- end
36
-
37
- context "when taking off after an emergency" do
38
- Given { controller.emergency }
39
- When(:result) { controller.take_off }
40
- Then { at.should have_received(:ref).with(ref_bits(9)) }
41
- end
42
-
43
- context "when hovering" do
44
- When(:result) { controller.hover }
45
- Then { at.should have_received(:pcmd).with("0,0,0,0,0") }
46
- end
47
-
48
- context "when moving forward" do
49
- When(:result) { controller.forward(0.80) }
50
- Then { at.should have_received(:pcmd).with("1,0,-1085485875,0,0") }
51
- end
52
-
53
- context "when moving backward" do
54
- When(:result) { controller.backward(0.80) }
55
- Then { at.should have_received(:pcmd).with("1,0,1061997773,0,0") }
56
- end
57
-
58
- context "when moving to the left" do
59
- When(:result) { controller.left(0.80) }
60
- Then { at.should have_received(:pcmd).with("1,-1085485875,0,0,0") }
61
- end
62
-
63
- context "when moving to the right" do
64
- When(:result) { controller.right(0.80) }
65
- Then { at.should have_received(:pcmd).with("1,1061997773,0,0,0") }
66
- end
67
-
68
- context "when moving up" do
69
- When(:result) { controller.up(0.80) }
70
- Then { at.should have_received(:pcmd).with("1,0,0,1061997773,0") }
71
- end
72
-
73
- context "when moving down" do
74
- When(:result) { controller.down(0.80) }
75
- Then { at.should have_received(:pcmd).with("1,0,0,-1085485875,0") }
76
- end
77
-
78
- context "when turning left" do
79
- When(:result) { controller.turn_left(0.80) }
80
- Then { at.should have_received(:pcmd).with("1,0,0,0,-1085485875") }
81
- end
82
-
83
- context "when turning right" do
84
- When(:result) { controller.turn_right(0.80) }
85
- Then { at.should have_received(:pcmd).with("1,0,0,0,1061997773") }
86
- end
87
-
88
- context "when executing several directions" do
89
- When(:result) {
90
- controller.forward(1.0).left(0.5).up(0.2).turn_left(0.8)
91
- }
92
- Then { at.should have_received(:pcmd).with("1,-1090519040,-1082130432,1045220557,-1085485875") }
93
- end
94
- end
95
-
96
- describe "led command" do
97
- Invariant { result.should == controller }
98
-
99
- context "when setting with numeric sequence" do
100
- When(:result) { controller.led(3, 2.0, 4) }
101
- Then {
102
- at.should have_received(:config)
103
- .with("leds:leds_anim", "3,1073741824,4")
104
- }
105
- end
106
-
107
- context "when setting with symbolic sequence" do
108
- When(:result) { controller.led(:blink_orange, 2.0, 4) }
109
- Then {
110
- at.should have_received(:config)
111
- .with("leds:leds_anim", "3,1073741824,4")
112
- }
113
- end
114
- end
115
-
116
- describe "enabled detection command" do
117
- Invariant { result.should == controller }
118
-
119
- context "when setting all parameters" do
120
- Given(:enemy) { 2 }
121
- Given(:type) { 11 }
122
- Given(:select) { 33 }
123
-
124
- When(:result) { controller.enable_detection(enemy, type, select) }
125
-
126
- Then { at.should have_received(:config).with("detect:enemy_colors", enemy.to_s) }
127
- Then { at.should have_received(:config).with("detect:detect_type", type.to_s) }
128
- Then { at.should have_received(:config).with("detect:detections_select_h", select.to_s) }
129
- end
130
-
131
- context "when setting with only enemy" do
132
- Given(:enemy) { 2 }
133
- Given(:type) { 10 }
134
- Given(:select) { 32 }
135
-
136
- When(:result) { controller.enable_detection(enemy) }
137
-
138
- Then { at.should have_received(:config).with("detect:enemy_colors", enemy.to_s) }
139
- Then { at.should have_received(:config).with("detect:detect_type", type.to_s) }
140
- Then { at.should have_received(:config).with("detect:detections_select_h", select.to_s) }
141
- end
142
- end
143
-
144
- describe "ack controll command" do
145
- Invariant { result.should == controller }
146
- When(:result) { controller.ack_control_mode }
147
- Then { at.should have_received(:ctrl).with(5) }
148
166
  end
149
167
  end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'argus'
3
+
4
+ describe Argus::Drone do
5
+ Given(:controller) { flexmock("controller", :on, Argus::Controller) }
6
+ Given(:commander) { flexmock("commander", :on, Argus::ATCommander) }
7
+ Given(:nav_monitor) { flexmock("navmonitor", :on, Argus::NavMonitor) }
8
+ Given(:drone) {
9
+ Argus::Drone.new(
10
+ nav_monitor: nav_monitor,
11
+ commander: commander,
12
+ controller: controller)
13
+ }
14
+
15
+ Then { drone.commander == commander }
16
+
17
+ context "when starting the drone" do
18
+ When { drone.start }
19
+ Then { commander.should have_received(:start).once }
20
+ Then { nav_monitor.should have_received(:start).once }
21
+
22
+ context "and then stopped" do
23
+ When { drone.stop }
24
+ Then { controller.should have_received(:land).once }
25
+ Then { commander.should have_received(:stop).once }
26
+ Then { commander.should have_received(:join).once }
27
+ Then { nav_monitor.should have_received(:stop).once }
28
+ Then { nav_monitor.should have_received(:join).once }
29
+ end
30
+ end
31
+
32
+ describe "setting nav callbacks" do
33
+ When { drone.nav_callback(:a) }
34
+ Then { nav_monitor.should have_received(:callback).with(:a).once }
35
+ end
36
+
37
+ describe "flight controls" do
38
+ When { drone.take_off }
39
+ Then { controller.should have_received(:take_off).once }
40
+ end
41
+
42
+ context "when created normally" do
43
+ Given { flexmock(Argus::NavMonitor).should_receive(:new => nil) }
44
+ When { Argus::Drone.new }
45
+ Then { Argus::NavMonitor.should have_received(:new).with(Argus::Controller, String).once }
46
+ end
47
+
48
+ context "when NavMonitor is disabled" do
49
+ Given { flexmock(Argus::NullNavMonitor).should_receive(:new => nil) }
50
+ When { Argus::Drone.new(enable_nav_monitor: false) }
51
+ Then { Argus::NullNavMonitor.should have_received(:new).with().once }
52
+ end
53
+ end
@@ -12,6 +12,7 @@ module Argus
12
12
 
13
13
  Then { nav_data.sequence_number == 173064 }
14
14
  Then { nav_data.vision_flag == 0 }
15
+ Then { nav_data.raw == raw_nav_bytes }
15
16
 
16
17
  describe "sequence number" do
17
18
  Given(:seq_num) { 1234 }
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'thread'
3
+
4
+ describe Argus::NavMonitor do
5
+ Given(:streamer) { flexmock("streamer", :on, Argus::NavStreamer) }
6
+ Given(:controller) { flexmock("controller", :on, Argus::Controller) }
7
+ Given(:nav) {
8
+ Argus::NavMonitor.new(controller, "localhost", streamer: streamer)
9
+ }
10
+
11
+ context "when the monitor is started" do
12
+ after do nav.join end
13
+ When { nav.start; Thread.pass }
14
+ Then { streamer.should have_received(:start).once }
15
+ end
16
+
17
+ context "when data is received" do
18
+ Given(:bootstrap) { false }
19
+ Given(:ack) { false }
20
+ Given(:nav_options) { [ ] }
21
+ Given(:nav_data) {
22
+ flexmock("NavData",
23
+ :bootstrap? => bootstrap,
24
+ :control_command_ack? => ack,
25
+ :options => nav_options)
26
+ }
27
+
28
+ When {
29
+ capture_io { nav.update_nav_data(nav_data) }
30
+ }
31
+
32
+ context "when typical data is received" do
33
+ Then { nav.data == nav_data }
34
+ Then { controller.should have_received(:demo_mode).never }
35
+ Then { controller.should have_received(:ack_control_mode).never }
36
+ end
37
+
38
+ context "when the bootstrap flag is set" do
39
+ Given(:bootstrap) { true }
40
+ Then { controller.should have_received(:demo_mode).once }
41
+ end
42
+
43
+ context "when the control command ack is set" do
44
+ Given(:ack) { true }
45
+ Then { controller.should have_received(:ack_control_mode).once }
46
+ end
47
+
48
+ context "with nav option sections" do
49
+ Given(:opt) { flexmock("option", tag: 0) }
50
+ Given(:nav_options) { [ opt ] }
51
+ Then { nav.data == nav_data }
52
+ Then { nav.option(0) == opt }
53
+ end
54
+
55
+ context "with a callback" do
56
+ Given { nav.callback { |data| @cb_data = data } }
57
+ Then { @cb_data == nav_data }
58
+ end
59
+
60
+ context "with a callback with errors" do
61
+ Given { nav.callback { |data| fail "OUCH" } }
62
+ Then { captured_out =~ /OUCH/ }
63
+ end
64
+ end
65
+ end
@@ -3,10 +3,6 @@ require 'base64'
3
3
 
4
4
  module Argus
5
5
  describe NavOptionDemo do
6
- def f(float)
7
- FloatEncoding.encode_float(float)
8
- end
9
-
10
6
  # NOTE: This is a Base 64 encoded NavData packet recorded directly from the drone.
11
7
  Given(:base64_data) {
12
8
  "iHdmVdAEgA/5iwAAAAAAAAAAlAAAAAIAPAAAAADwREUAgCNFQFEiyAAAAABk" +
@@ -56,6 +56,7 @@ module Argus
56
56
  Then { d0.y == 20 }
57
57
  Then { d0.width == 30 }
58
58
  Then { d0.height == 40 }
59
+ Then { d0.distance == 50 }
59
60
  Then { d0.orientation_angle == 60.0 }
60
61
  Then { d0.camera_source == 70 }
61
62
  end
@@ -5,7 +5,7 @@ module Argus
5
5
  Given(:remote_host) { '192.168.1.1' }
6
6
  Given(:port) { 5554 }
7
7
  Given(:socket) { flexmock("Socket", send: nil).should_ignore_missing }
8
- Given(:streamer) { NavStreamer.new(remote_host: remote_host, UDPSocket: flexmock(new: socket)) }
8
+ Given(:streamer) { NavStreamer.new(remote_host: remote_host, UDPSocket: flexmock(new: socket, disabled_timer: true)) }
9
9
 
10
10
  context "after starting" do
11
11
  Given { streamer.start }
@@ -23,6 +23,11 @@ module Argus
23
23
  When(:nav_data) { streamer.receive_data }
24
24
  Then { nav_data.nil? }
25
25
  end
26
+
27
+ context "when receiving and extra start event" do
28
+ Given { streamer.start }
29
+ Then { socket.should have_received(:close) }
30
+ end
26
31
  end
27
32
 
28
33
  describe "State Transitions" do
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Argus
4
+ describe VideoDataEnvelope do
5
+ Given(:unpacker) { flexmock("Unpacker", :unpack => values) }
6
+ Given(:socket) { flexmock("socket", :read => unpacker) }
7
+ Given(:video_data_envelope) { VideoDataEnvelope.new(socket) }
8
+
9
+ describe "version" do
10
+ When(:values) { flexmock("Values", :first => 3) }
11
+ Then { video_data_envelope.version == 3 }
12
+ end
13
+
14
+ describe "frame_number" do
15
+ When(:values) { flexmock("Values", :first => 42) }
16
+ Then { video_data_envelope.frame_number == 42 }
17
+ end
18
+
19
+ describe "payload_size" do
20
+ When(:values) { flexmock("Values", :first => 2048) }
21
+ Then { video_data_envelope.payload_size == 2048 }
22
+ end
23
+
24
+ # TODO: handle invalid envelope
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module Argus
4
+ describe VideoData do
5
+ Given(:raw_header) { Bytes.make_video_envelope }
6
+ Given(:raw_video_bytes) { Bytes.make_video_data(raw_header) }
7
+ Given(:video_data) { VideoData.new(socket) }
8
+
9
+ describe "valid envelope" do
10
+ When(:socket) { StringIO.new(raw_header) }
11
+ Then {video_data.envelope.signature == "PaVE"}
12
+ end
13
+
14
+ # TODO: handle invalid envelope
15
+ # TODO: handle valid envelope but invalid frame
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module Argus
4
+ describe VideoStreamer do
5
+ Given(:tcp_socket) { flexmock("TCPSocket", send: nil).should_ignore_missing }
6
+ Given(:streamer) { VideoStreamer.new(socket: tcp_socket) }
7
+ Given(:udp_socket) { flexmock("UDPSocket", send: nil).should_ignore_missing }
8
+
9
+ describe "starting the stream" do
10
+ When { streamer.start(udp_socket) }
11
+ Then { udp_socket.should have_received(:send) }
12
+ Then { udp_socket.should have_received(:close) }
13
+ end
14
+
15
+ describe "receiving data" do
16
+ Given { streamer.start(udp_socket) }
17
+ When(:result) { streamer.receive_data }
18
+ Then { result.is_a?(VideoData) }
19
+ end
20
+ end
21
+ end
@@ -1,10 +1,14 @@
1
1
  #!/usr/bin/ruby -wKU
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "spec/"
5
+ end
2
6
 
3
7
  require 'rspec/given'
4
8
  require 'flexmock'
5
-
6
9
  require 'argus'
7
10
  require 'support/bytes'
11
+ require 'support/capture_io'
8
12
 
9
13
  RSpec.configure do |config|
10
14
  config.mock_with :flexmock
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: argus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-09-03 00:00:00.000000000 Z
13
+ date: 2013-09-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec-given
@@ -58,17 +58,21 @@ files:
58
58
  - lib/argus/nav_streamer.rb
59
59
  - lib/argus/nav_tag.rb
60
60
  - lib/argus/null_nav_monitor.rb
61
- - lib/argus/pave_parser.rb
62
- - lib/argus/tcp_video_streamer.rb
63
61
  - lib/argus/time_queue.rb
64
62
  - lib/argus/udp_sender.rb
65
63
  - lib/argus/version.rb
64
+ - lib/argus/video_data.rb
65
+ - lib/argus/video_data_envelope.rb
66
+ - lib/argus/video_streamer.rb
66
67
  - spec/spec_helper.rb
67
68
  - spec/argus/at_commander_spec.rb
69
+ - spec/argus/cfields_spec.rb
68
70
  - spec/argus/controller_spec.rb
71
+ - spec/argus/drone_spec.rb
69
72
  - spec/argus/float_encoding_spec.rb
70
73
  - spec/argus/led_animation_spec.rb
71
74
  - spec/argus/nav_data_spec.rb
75
+ - spec/argus/nav_monitor_spec.rb
72
76
  - spec/argus/nav_option_checksum_spec.rb
73
77
  - spec/argus/nav_option_demo_spec.rb
74
78
  - spec/argus/nav_option_spec.rb
@@ -78,9 +82,13 @@ files:
78
82
  - spec/argus/null_nav_monitor_spec.rb
79
83
  - spec/argus/time_queue_spec.rb
80
84
  - spec/argus/udp_sender_spec.rb
85
+ - spec/argus/video_data_envelope_spec.rb
86
+ - spec/argus/video_data_spec.rb
87
+ - spec/argus/video_streamer_spec.rb
81
88
  - MIT-LICENSE
82
89
  homepage: http://github.com/jimweirich/argus
83
- licenses: []
90
+ licenses:
91
+ - MIT-LICENSE
84
92
  metadata: {}
85
93
  post_install_message:
86
94
  rdoc_options:
@@ -1,39 +0,0 @@
1
- module Argus
2
- class PaVEParser
3
- def initialize(tcp_video_streamer)
4
- @tcp_video_streamer = tcp_video_streamer
5
- end
6
-
7
- def get_frame
8
- frame = {
9
- :signature=>(@tcp_video_streamer.read(4)).unpack("A*").first,
10
- :version=>(@tcp_video_streamer.read(1)).unpack("C").first,
11
- :video_codec=>(@tcp_video_streamer.read(1)).unpack("C").first,
12
- :header_size=>(@tcp_video_streamer.read(2)).unpack("v").first,
13
- :payload_size=>(@tcp_video_streamer.read(4)).unpack("V").first,
14
- :encoded_stream_width=>(@tcp_video_streamer.read(2)).unpack("v").first,
15
- :encoded_stream_height=>(@tcp_video_streamer.read(2)).unpack("v").first,
16
- :display_width=>(@tcp_video_streamer.read(2)).unpack("v").first,
17
- :display_height=>(@tcp_video_streamer.read(2)).unpack("v").first,
18
- :frame_number=>(@tcp_video_streamer.read(4)).unpack("V").first,
19
- :timestamp=>(@tcp_video_streamer.read(4)).unpack("V").first,
20
- :total_chunks=>(@tcp_video_streamer.read(1)).unpack("C").first,
21
- :chunk_index=>(@tcp_video_streamer.read(1)).unpack("C").first,
22
- :frame_type=>(@tcp_video_streamer.read(1)).unpack("C").first,
23
- :control=>(@tcp_video_streamer.read(1)).unpack("C").first,
24
- :stream_byte_position_lw=>(@tcp_video_streamer.read(4)).unpack("V").first,
25
- :stream_byte_position_uw=>(@tcp_video_streamer.read(4)).unpack("V").first,
26
- :stream_id=>(@tcp_video_streamer.read(2)).unpack("v").first,
27
- :total_slices=>(@tcp_video_streamer.read(1)).unpack("C").first,
28
- :slice_index=>(@tcp_video_streamer.read(1)).unpack("C").first,
29
- :header1_size=>(@tcp_video_streamer.read(1)).unpack("C").first,
30
- :header2_size=>(@tcp_video_streamer.read(1)).unpack("C").first,
31
- :reserved[2]=>(@tcp_video_streamer.read(2)).unpack("H*").first,
32
- :advertised_size=>(@tcp_video_streamer.read(4)).unpack("V").first,
33
- :reserved[12]=>(@tcp_video_streamer.read(12)).unpack("H*").first
34
- }
35
- @tcp_video_streamer.read(4)
36
- return @tcp_video_streamer.read(frame[:payload_size])
37
- end
38
- end
39
- end
@@ -1,20 +0,0 @@
1
- require 'socket'
2
- module Argus
3
- class TcpVideoStreamer
4
- def initialize(opts={})
5
- @host = opts.fetch(:remote_host)
6
- @port = opts.fetch(:port, 5555)
7
- @tcp_socket = TCPSocket.new(@host, @port)
8
- end
9
-
10
- def start_stream(udp_socket=nil)
11
- sock = udp_socket || UDPSocket.new
12
- sock.send("\x01\x00\x00\x00", 0, @host, @port)
13
- sock.close
14
- end
15
-
16
- def read(n)
17
- @tcp_socket.read(n)
18
- end
19
- end
20
- end