hybridgroup-argus 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/lib/argus/at_commander.rb +24 -3
  3. data/lib/argus/cad_type.rb +22 -0
  4. data/lib/argus/cfields.rb +98 -0
  5. data/lib/argus/controller.rb +34 -5
  6. data/lib/argus/drone.rb +28 -1
  7. data/lib/argus/float_encoding.rb +13 -0
  8. data/lib/argus/led_animation.rb +48 -0
  9. data/lib/argus/nav_data.rb +66 -49
  10. data/lib/argus/nav_monitor.rb +78 -0
  11. data/lib/argus/nav_option.rb +29 -0
  12. data/lib/argus/nav_option_checksum.rb +20 -0
  13. data/lib/argus/nav_option_demo.rb +79 -0
  14. data/lib/argus/nav_option_unknown.rb +9 -0
  15. data/lib/argus/nav_option_vision_detect.rb +83 -0
  16. data/lib/argus/nav_streamer.rb +12 -4
  17. data/lib/argus/nav_tag.rb +35 -0
  18. data/lib/argus/version.rb +1 -1
  19. data/lib/argus/video_data.rb +15 -0
  20. data/lib/argus/video_data_envelope.rb +55 -0
  21. data/lib/argus/video_streamer.rb +23 -0
  22. data/lib/argus.rb +5 -9
  23. data/spec/argus/controller_spec.rb +49 -0
  24. data/spec/argus/drone_spec.rb +24 -0
  25. data/spec/argus/float_encoding_spec.rb +12 -0
  26. data/spec/argus/led_animation_spec.rb +21 -0
  27. data/spec/argus/nav_data_spec.rb +147 -0
  28. data/spec/argus/nav_option_checksum_spec.rb +21 -0
  29. data/spec/argus/nav_option_demo_spec.rb +44 -0
  30. data/spec/argus/nav_option_spec.rb +32 -0
  31. data/spec/argus/nav_option_unknown_spec.rb +19 -0
  32. data/spec/argus/nav_option_vision_detect_spec.rb +65 -0
  33. data/spec/argus/nav_streamer_spec.rb +28 -0
  34. data/spec/argus/udp_sender_spec.rb +1 -1
  35. data/spec/argus/video_data_envelope_spec.rb +26 -0
  36. data/spec/argus/video_data_spec.rb +18 -0
  37. data/spec/argus/video_streamer_spec.rb +16 -0
  38. data/spec/spec_helper.rb +3 -0
  39. data/spec/support/bytes.rb +48 -0
  40. metadata +36 -15
  41. data/lib/argus/pave_parser.rb +0 -39
  42. data/lib/argus/tcp_video_streamer.rb +0 -20
  43. data/lib/argus/udp_nav_streamer.rb +0 -24
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module Argus
4
+ describe NavOption do
5
+ let(:raw_checksum) { [ NavTag::CHECKSUM, 8, 0x5555aaaa].pack("vvV") }
6
+ let(:raw_demo) { [ NavTag::DEMO, 148 ].pack("vv") + "\0" * 148 }
7
+ let(:raw_vision_detect) { [ NavTag::VISION_DETECT, 328 ].pack("vv") + "\0" * 328 }
8
+ let(:raw_unknown_tag) { [ 12345, 8 ].pack("vv") + " " }
9
+
10
+ When(:result) { NavOption.parse(raw_data) }
11
+
12
+ describe "parsing checksum options" do
13
+ Given(:raw_data) { raw_checksum }
14
+ Then { result.is_a?(NavOptionChecksum) }
15
+ end
16
+
17
+ describe "parsing demo option" do
18
+ Given(:raw_data) { raw_demo }
19
+ Then { result.is_a?(NavOptionDemo) }
20
+ end
21
+
22
+ describe "parsing vision detect option" do
23
+ Given(:raw_data) { raw_vision_detect }
24
+ Then { result.is_a?(NavOptionVisionDetect) }
25
+ end
26
+
27
+ describe "parsing bad tag" do
28
+ Given(:raw_data) { raw_unknown_tag }
29
+ Then { result.is_a?(NavOptionUnknown) }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module Argus
4
+
5
+ describe NavOptionUnknown do
6
+ Given(:raw_data) { [0x5231, 8, 0x12345678].pack("vvV") }
7
+ Given(:opt) { NavOptionUnknown.new(raw_data) }
8
+
9
+ describe ".tag" do
10
+ Then { NavOptionUnknown.tag == 0xfffe }
11
+ end
12
+
13
+ describe "data fields" do
14
+ Then { opt.tag == 0x5231 }
15
+ Then { opt.size == raw_data.size }
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ module Argus
4
+
5
+ describe NavOptionVisionDetect do
6
+ def f(float)
7
+ FloatEncoding.encode_float(float)
8
+ end
9
+
10
+ Given(:raw_data) {
11
+ [
12
+ NavTag::VISION_DETECT, 328,
13
+ 2,
14
+ 1, 2, 3, 4,
15
+ 10, 11, 12, 13,
16
+ 20, 21, 22, 23,
17
+ 30, 31, 32, 33,
18
+ 40, 41, 42, 43,
19
+ 50, 51, 52, 53,
20
+ f(60.0), f(61.0), f(62.0), f(63.0),
21
+ 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,
22
+ 0,0,0, 0,0,0, 0,0,0, 0,0,0,
23
+ 70, 71, 72, 73
24
+ ].flatten.pack("vv V V4 V4 V4 V4 V4 V4 V4 V36 V12 V4")
25
+ }
26
+
27
+ When(:detect) { NavOptionVisionDetect.new(raw_data) }
28
+
29
+ Then { NavOptionVisionDetect.tag == NavTag::VISION_DETECT }
30
+ Then { detect.tag == Argus::NavTag::VISION_DETECT }
31
+ Then { detect.size == 328 }
32
+
33
+ describe "C fields" do
34
+ Then { detect.nb_detected == 2 }
35
+ Then { detect.type == [1, 2, 3, 4] }
36
+ Then { detect.type_name == [:vertical, :vision, :none, :cocarde] }
37
+ Then { detect.xc == [10, 11, 12, 13] }
38
+ Then { detect.yc == [20, 21, 22, 23] }
39
+ Then { detect.width == [30, 31, 32, 33] }
40
+ Then { detect.height == [40, 41, 42, 43] }
41
+ Then { detect.dist == [50, 51, 52, 53] }
42
+ Then { detect.distance == [50, 51, 52, 53] }
43
+ Then { detect.orientation_angle == [60.0, 61.0, 62.0, 63.0] }
44
+ Then { detect.rotation == [nil, nil, nil, nil] }
45
+ Then { detect.translation == [nil, nil, nil, nil] }
46
+ Then { detect.camera_source == [70, 71, 72, 73] }
47
+ end
48
+
49
+ describe "detection info" do
50
+ Then { detect.detections.size == 2 }
51
+
52
+ let(:d0) { detect.detections[0] }
53
+ Then { d0.type == 1 }
54
+ Then { d0.type_name == :vertical }
55
+ Then { d0.x == 10 }
56
+ Then { d0.y == 20 }
57
+ Then { d0.width == 30 }
58
+ Then { d0.height == 40 }
59
+ Then { d0.orientation_angle == 60.0 }
60
+ Then { d0.camera_source == 70 }
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ module Argus
4
+ describe NavStreamer do
5
+ Given(:socket) { flexmock("Socket", send: nil).should_ignore_missing }
6
+ Given(:streamer) { NavStreamer.new(socket) }
7
+
8
+ context "starting the stream" do
9
+ When { streamer.start }
10
+ Then { socket.should have_received(:bind).with(String, Object) }
11
+ Then { socket.should have_received(:send) }
12
+ end
13
+
14
+ context "when receiving good data" do
15
+ Given(:bytes) { Bytes.make_nav_data(Bytes.make_header(0x1234, 0, 0)) }
16
+ Given { socket.should_receive(:recvfrom => bytes) }
17
+ When(:nav_data) { streamer.receive_data }
18
+ Then { nav_data.state_mask == 0x1234}
19
+ end
20
+
21
+ context "when receiving bad data" do
22
+ Given(:bytes) { [0x89, 0x77, 0x66, 0x55, 0x34, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].pack("C*") }
23
+ Given { socket.should_receive(:recvfrom => bytes) }
24
+ When(:nav_data) { streamer.receive_data }
25
+ Then { nav_data.nil? }
26
+ end
27
+ end
28
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'socket'
3
3
 
4
4
  describe Argus::UdpSender do
5
- Given(:port) { 5500 }
5
+ Given(:port) { '5500' }
6
6
  Given(:socket) { UDPSocket.new }
7
7
  Given(:sender) { Argus::UdpSender.new(socket, 'localhost', port) }
8
8
  Given!(:server) {
@@ -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
+ pending "TODO: handle invalid envelope"
25
+ end
26
+ end
@@ -0,0 +1,18 @@
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
+ pending "TODO: handle invalid envelope"
15
+ pending "TODO: handle valid envelope but invalid frame"
16
+
17
+ end
18
+ end
@@ -0,0 +1,16 @@
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(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
+ end
16
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,7 +4,10 @@ require 'rspec/given'
4
4
  require 'flexmock'
5
5
 
6
6
  require 'argus'
7
+ require 'support/bytes'
7
8
 
8
9
  RSpec.configure do |config|
9
10
  config.mock_with :flexmock
10
11
  end
12
+
13
+ RSpec::Given.use_natural_assertions
@@ -0,0 +1,48 @@
1
+ module Bytes
2
+ module_function
3
+
4
+ def int16(n)
5
+ [n].pack("v").unpack("C*")
6
+ end
7
+
8
+ def int32(n)
9
+ [n].pack("V").unpack("C*")
10
+ end
11
+
12
+ def make_nav_data(*options)
13
+ result = options.flatten
14
+ add_checksum(result)
15
+ result.pack("C*")
16
+ end
17
+
18
+ def make_header(state_bits, seq_number, vision_flag)
19
+ Bytes.int32(0x55667788) +
20
+ Bytes.int32(state_bits) +
21
+ Bytes.int32(seq_number) +
22
+ Bytes.int32(vision_flag)
23
+ end
24
+
25
+ def make_demo_data
26
+ Bytes.int16(0) + Bytes.int16(148) + [0] * 144
27
+ end
28
+
29
+ def add_checksum(bytes)
30
+ [0xff, 0xff, 0x08, 0x00, 0x61, 0x04, 0x00, 0x00].each do |b| bytes << b end
31
+ bytes
32
+ end
33
+
34
+ def make_video_envelope
35
+ val = "PaVE".bytes.to_a +
36
+ Bytes.int16(0x01) +
37
+ Bytes.int16(0x02) +
38
+ Bytes.int32(0x68) +
39
+ [0] * 60
40
+ val.pack("C*")
41
+ end
42
+
43
+ def make_video_data(*options)
44
+ result = options.flatten
45
+ result << Bytes.make_demo_data
46
+ result
47
+ end
48
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hybridgroup-argus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jim Weirich
@@ -11,12 +10,11 @@ authors:
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2013-02-23 00:00:00.000000000 Z
13
+ date: 2013-05-13 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: rspec-given
18
17
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
18
  requirements:
21
19
  - - ~>
22
20
  - !ruby/object:Gem::Version
@@ -24,7 +22,6 @@ dependencies:
24
22
  type: :development
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
25
  requirements:
29
26
  - - ~>
30
27
  - !ruby/object:Gem::Version
@@ -44,22 +41,48 @@ files:
44
41
  - Rakefile
45
42
  - lib/argus.rb
46
43
  - lib/argus/at_commander.rb
44
+ - lib/argus/cad_type.rb
45
+ - lib/argus/cfields.rb
47
46
  - lib/argus/controller.rb
48
47
  - lib/argus/drone.rb
48
+ - lib/argus/float_encoding.rb
49
+ - lib/argus/led_animation.rb
49
50
  - lib/argus/nav_data.rb
51
+ - lib/argus/nav_monitor.rb
52
+ - lib/argus/nav_option.rb
53
+ - lib/argus/nav_option_checksum.rb
54
+ - lib/argus/nav_option_demo.rb
55
+ - lib/argus/nav_option_unknown.rb
56
+ - lib/argus/nav_option_vision_detect.rb
50
57
  - lib/argus/nav_streamer.rb
51
- - lib/argus/pave_parser.rb
52
- - lib/argus/tcp_video_streamer.rb
53
- - lib/argus/udp_nav_streamer.rb
58
+ - lib/argus/nav_tag.rb
54
59
  - lib/argus/udp_sender.rb
55
60
  - lib/argus/version.rb
61
+ - lib/argus/video_data.rb
62
+ - lib/argus/video_data_envelope.rb
63
+ - lib/argus/video_streamer.rb
56
64
  - spec/spec_helper.rb
57
65
  - spec/argus/at_commander_spec.rb
58
66
  - spec/argus/controller_spec.rb
67
+ - spec/argus/drone_spec.rb
68
+ - spec/argus/float_encoding_spec.rb
69
+ - spec/argus/led_animation_spec.rb
70
+ - spec/argus/nav_data_spec.rb
71
+ - spec/argus/nav_option_checksum_spec.rb
72
+ - spec/argus/nav_option_demo_spec.rb
73
+ - spec/argus/nav_option_spec.rb
74
+ - spec/argus/nav_option_unknown_spec.rb
75
+ - spec/argus/nav_option_vision_detect_spec.rb
76
+ - spec/argus/nav_streamer_spec.rb
59
77
  - spec/argus/udp_sender_spec.rb
78
+ - spec/argus/video_data_envelope_spec.rb
79
+ - spec/argus/video_data_spec.rb
80
+ - spec/argus/video_streamer_spec.rb
81
+ - spec/support/bytes.rb
60
82
  - MIT-LICENSE
61
- homepage: http://github.com/hybridgroup/argus
83
+ homepage: http://github.com/jimweirich/argus
62
84
  licenses: []
85
+ metadata: {}
63
86
  post_install_message:
64
87
  rdoc_options:
65
88
  - --line-numbers
@@ -71,21 +94,19 @@ rdoc_options:
71
94
  require_paths:
72
95
  - lib
73
96
  required_ruby_version: !ruby/object:Gem::Requirement
74
- none: false
75
97
  requirements:
76
- - - ! '>='
98
+ - - '>='
77
99
  - !ruby/object:Gem::Version
78
100
  version: '1.9'
79
101
  required_rubygems_version: !ruby/object:Gem::Requirement
80
- none: false
81
102
  requirements:
82
- - - ! '>='
103
+ - - '>='
83
104
  - !ruby/object:Gem::Version
84
105
  version: '1.0'
85
106
  requirements: []
86
107
  rubyforge_project: n/a
87
- rubygems_version: 1.8.23
108
+ rubygems_version: 2.0.3
88
109
  signing_key:
89
- specification_version: 3
110
+ specification_version: 4
90
111
  summary: Ruby API for a Parrot AD Drone Quadcopter
91
112
  test_files: []
@@ -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(tcp_socket=nil, host='192.168.1.1', port=5555)
5
- @tcp_socket = tcp_socket || TCPSocket.new(host, port)
6
- @host = host
7
- @port = 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
@@ -1,24 +0,0 @@
1
- module Argus
2
- class UdpNavStreamer
3
- def initialize(udp_socket, host='192.168.1.1', port=5554)
4
- @udp_socket = udp_socket
5
- @host = host
6
- @port = port
7
- @udp_socket.bind("0.0.0.0", port)
8
- end
9
-
10
- def start_stream
11
- @udp_socket.send("\x01\x00\x00\x00", 0, @host, @port)
12
- end
13
-
14
- def receive_packet
15
- data, from = @udp_socket.recvfrom(1024)
16
- if data.unpack("V").first == "0x55667788".hex
17
- data.slice!(0..3)
18
- return NavData.new(data)
19
- else
20
- return "Not nav data!"
21
- end
22
- end
23
- end
24
- end