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.
- 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
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'argus/cfields'
|
2
|
+
require 'argus/float_encoding'
|
3
|
+
require 'argus/nav_option'
|
4
|
+
require 'argus/nav_tag'
|
5
|
+
|
6
|
+
module Argus
|
7
|
+
|
8
|
+
class NavOptionDemo < NavOption
|
9
|
+
include CFields
|
10
|
+
|
11
|
+
uint32_t :ctrl_state # Flying state (landed, flying,
|
12
|
+
alias :control_state :ctrl_state
|
13
|
+
# hovering, etc.) defined in
|
14
|
+
# CTRL_STATES enum.
|
15
|
+
uint32_t :vbat_flying_percentage # battery voltage filtered (mV)
|
16
|
+
alias :battery_level :vbat_flying_percentage
|
17
|
+
|
18
|
+
float32_t :theta # UAV's pitch in milli-degrees
|
19
|
+
float32_t :phi # UAV's roll in milli-degrees
|
20
|
+
float32_t :psi # UAV's yaw in milli-degrees
|
21
|
+
|
22
|
+
int32_t :altitude # UAV's altitude in centimeters
|
23
|
+
|
24
|
+
float32_t :vx # UAV's estimated linear velocity
|
25
|
+
float32_t :vy # UAV's estimated linear velocity
|
26
|
+
float32_t :vz # UAV's estimated linear velocity
|
27
|
+
|
28
|
+
uint32_t :num_frames # streamed frame index // Not
|
29
|
+
# used -> To integrate in video
|
30
|
+
# stage.
|
31
|
+
|
32
|
+
# Camera parameters compute by detection
|
33
|
+
matrix33_t :detection_camera_rot # Deprecated ! Don't use !
|
34
|
+
vector31_t :detection_camera_trans # Deprecated ! Don't use !
|
35
|
+
uint32_t :detection_tag_index # Deprecated ! Don't use !
|
36
|
+
|
37
|
+
uint32_t :detection_camera_type # Type of tag searched in detection
|
38
|
+
|
39
|
+
# Camera parameters compute by drone
|
40
|
+
matrix33_t :drone_camera_rot # Deprecated ! Don't use !
|
41
|
+
vector31_t :drone_camera_trans # Deprecated ! Don't use !
|
42
|
+
|
43
|
+
CONTROL_STATE_NAMES = [
|
44
|
+
:default,
|
45
|
+
:init,
|
46
|
+
:landed,
|
47
|
+
:flying,
|
48
|
+
:hovering,
|
49
|
+
:test,
|
50
|
+
:trans_takeoff,
|
51
|
+
:trans_gotofix,
|
52
|
+
:trans_landing,
|
53
|
+
:trans_looping,
|
54
|
+
]
|
55
|
+
|
56
|
+
def control_state_name
|
57
|
+
CONTROL_STATE_NAMES[ctrl_state]
|
58
|
+
end
|
59
|
+
|
60
|
+
def pitch
|
61
|
+
theta / 1000.0
|
62
|
+
end
|
63
|
+
|
64
|
+
def roll
|
65
|
+
phi / 1000.0
|
66
|
+
end
|
67
|
+
|
68
|
+
def yaw
|
69
|
+
psi / 1000.0
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.tag
|
73
|
+
NavTag::DEMO
|
74
|
+
end
|
75
|
+
|
76
|
+
NavOption.register(self)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'argus/cfields'
|
2
|
+
require 'argus/nav_tag'
|
3
|
+
|
4
|
+
module Argus
|
5
|
+
|
6
|
+
class NavOptionVisionDetect < NavOption
|
7
|
+
include CFields
|
8
|
+
|
9
|
+
NB_NAVDATA_DETECTION_RESULTS = 4
|
10
|
+
|
11
|
+
uint32_t :nb_detected
|
12
|
+
alias :detected_count :nb_detected
|
13
|
+
uint32_t :type, NB_NAVDATA_DETECTION_RESULTS
|
14
|
+
uint32_t :xc, NB_NAVDATA_DETECTION_RESULTS
|
15
|
+
uint32_t :yc, NB_NAVDATA_DETECTION_RESULTS
|
16
|
+
uint32_t :width, NB_NAVDATA_DETECTION_RESULTS
|
17
|
+
uint32_t :height, NB_NAVDATA_DETECTION_RESULTS
|
18
|
+
uint32_t :dist, NB_NAVDATA_DETECTION_RESULTS
|
19
|
+
alias :distance :dist
|
20
|
+
float32_t :orientation_angle, NB_NAVDATA_DETECTION_RESULTS
|
21
|
+
matrix33_t :rotation, NB_NAVDATA_DETECTION_RESULTS
|
22
|
+
vector31_t :translation, NB_NAVDATA_DETECTION_RESULTS
|
23
|
+
uint32_t :camera_source, NB_NAVDATA_DETECTION_RESULTS
|
24
|
+
|
25
|
+
class Detection
|
26
|
+
def initialize(vision_detected, index)
|
27
|
+
@vision_detected = vision_detected
|
28
|
+
@index = index
|
29
|
+
end
|
30
|
+
|
31
|
+
def type
|
32
|
+
@vision_detected.type[@index]
|
33
|
+
end
|
34
|
+
|
35
|
+
def type_name
|
36
|
+
CadType::NAMES[type]
|
37
|
+
end
|
38
|
+
|
39
|
+
def x
|
40
|
+
@vision_detected.xc[@index]
|
41
|
+
end
|
42
|
+
|
43
|
+
def y
|
44
|
+
@vision_detected.yc[@index]
|
45
|
+
end
|
46
|
+
|
47
|
+
def width
|
48
|
+
@vision_detected.width[@index]
|
49
|
+
end
|
50
|
+
|
51
|
+
def height
|
52
|
+
@vision_detected.height[@index]
|
53
|
+
end
|
54
|
+
|
55
|
+
def distance
|
56
|
+
@vision_detected.distance[@index]
|
57
|
+
end
|
58
|
+
|
59
|
+
def orientation_angle
|
60
|
+
@vision_detected.orientation_angle[@index]
|
61
|
+
end
|
62
|
+
|
63
|
+
def camera_source
|
64
|
+
@vision_detected.camera_source[@index]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def type_name
|
69
|
+
type.map { |t| CadType::NAMES[t] }
|
70
|
+
end
|
71
|
+
|
72
|
+
def detections
|
73
|
+
@detections ||= (0...detected_count).map { |i| Detection.new(self, i) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.tag
|
77
|
+
NavTag::VISION_DETECT
|
78
|
+
end
|
79
|
+
|
80
|
+
NavOption.register(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
data/lib/argus/nav_streamer.rb
CHANGED
@@ -1,18 +1,26 @@
|
|
1
1
|
require 'socket'
|
2
2
|
|
3
3
|
module Argus
|
4
|
-
class NavStreamer
|
4
|
+
class NavStreamer
|
5
5
|
def initialize(socket=nil, host='192.168.1.1', port='5554')
|
6
|
+
# TODO: Why is the port a string?
|
6
7
|
@socket = socket || UDPSocket.new
|
7
|
-
@
|
8
|
+
@host = host
|
9
|
+
@port = port
|
10
|
+
@socket.bind("0.0.0.0", port)
|
8
11
|
end
|
9
12
|
|
10
13
|
def start
|
11
|
-
@
|
14
|
+
@socket.send("\x01\x00\x00\x00", 0, @host, @port)
|
12
15
|
end
|
13
16
|
|
14
17
|
def receive_data
|
15
|
-
@
|
18
|
+
data, from = @socket.recvfrom(1024)
|
19
|
+
if data.unpack("V").first == 0x55667788
|
20
|
+
NavData.new(data)
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
18
26
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Argus
|
2
|
+
module NavTag
|
3
|
+
DEMO,
|
4
|
+
TIME,
|
5
|
+
RAW_MEASURES,
|
6
|
+
PHYS_MEASURES,
|
7
|
+
GYROS_OFFSETS,
|
8
|
+
EULER_ANGLES,
|
9
|
+
REFERENCES,
|
10
|
+
TRIMS,
|
11
|
+
RC_REFERENCES,
|
12
|
+
PWM,
|
13
|
+
ALTITUDE,
|
14
|
+
VISION_RAW,
|
15
|
+
VISION_OF,
|
16
|
+
VISION,
|
17
|
+
VISION_PERF,
|
18
|
+
TRACKERS_SEND,
|
19
|
+
VISION_DETECT,
|
20
|
+
WATCHDOG,
|
21
|
+
ADC_DATA_FRAME,
|
22
|
+
VIDEO_STREAM,
|
23
|
+
GAMES,
|
24
|
+
PRESSURE_RAW,
|
25
|
+
MAGNETO,
|
26
|
+
WIND,
|
27
|
+
KALMAN_PRESSURE,
|
28
|
+
HDVIDEO_STREAM,
|
29
|
+
WIFI = (0..100).to_a
|
30
|
+
|
31
|
+
CHECKSUM = 0xffff
|
32
|
+
UNKNOWN = 0xfffe # Not part of the AR Drone DSK, Only used in Argus
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/argus/version.rb
CHANGED
@@ -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(tcp_socket=nil, host='192.168.1.1', port=5555)
|
8
|
+
@tcp_socket = tcp_socket || TCPSocket.new(host, port)
|
9
|
+
@host = host
|
10
|
+
@port = 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
|
data/lib/argus.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require
|
5
|
-
|
6
|
-
require 'argus/nav_streamer'
|
7
|
-
require 'argus/drone'
|
8
|
-
require 'argus/tcp_video_streamer'
|
9
|
-
require 'argus/pave_parser'
|
1
|
+
# Require all the top level files in argus/*.rb
|
2
|
+
|
3
|
+
Dir[File.dirname(__FILE__) + "/argus/*.rb"].sort.each do |pn|
|
4
|
+
require "argus/#{File.basename(pn, '.rb')}"
|
5
|
+
end
|
@@ -92,4 +92,53 @@ describe Argus::Controller do
|
|
92
92
|
Then { at.should have_received(:pcmd).with("1,-1090519040,-1082130432,1045220557,-1085485875") }
|
93
93
|
end
|
94
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
|
+
|
95
144
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
describe Drone do
|
5
|
+
|
6
|
+
Given(:socket) { flexmock("Socket", send: nil).should_ignore_missing }
|
7
|
+
Given(:drone) { Drone.new(socket) }
|
8
|
+
|
9
|
+
describe "default navigation monitor enabled" do
|
10
|
+
Then { drone.enable_nav_monitor == false }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "default navigation monitor enabled when started" do
|
14
|
+
When { drone.start }
|
15
|
+
Then { drone.enable_nav_monitor == true }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "navigation monitor can be disabled when started" do
|
19
|
+
When { drone.start(false) }
|
20
|
+
Then { drone.enable_nav_monitor == false }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
describe LedAnimation do
|
6
|
+
describe ".lookup_name" do
|
7
|
+
Then { LedAnimation.lookup_name(3) == :blink_orange }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".lookup_value" do
|
11
|
+
Then { LedAnimation.lookup_value(:blink_orange) == 3 }
|
12
|
+
Then { LedAnimation.lookup_value("blink_orange") == 3 }
|
13
|
+
Then { LedAnimation.lookup_value(3) == 3 }
|
14
|
+
Then { LedAnimation.lookup_value("3") == 3 }
|
15
|
+
|
16
|
+
Then { LedAnimation.lookup_value(:unknown) == nil }
|
17
|
+
Then { LedAnimation.lookup_value("UNKNOWN") == nil }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
describe NavData do
|
5
|
+
Given(:state_bits) { 0xcf8a0c94 }
|
6
|
+
Given(:seq_num) { 173064 }
|
7
|
+
Given(:vision_flag) { 0 }
|
8
|
+
Given(:raw_header) { Bytes.make_header(state_bits, seq_num, vision_flag) }
|
9
|
+
Given(:raw_nav_bytes) { Bytes.make_nav_data(raw_header) }
|
10
|
+
|
11
|
+
When(:nav_data) { NavData.new(raw_nav_bytes) }
|
12
|
+
|
13
|
+
Then { nav_data.sequence_number == 173064 }
|
14
|
+
Then { nav_data.vision_flag == 0 }
|
15
|
+
|
16
|
+
describe "sequence number" do
|
17
|
+
Given(:seq_num) { 1234 }
|
18
|
+
Then { nav_data.sequence_number == 1234 }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "vision flag" do
|
22
|
+
Given(:vision_flag) { 1 }
|
23
|
+
Then { nav_data.vision_flag == 1 }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "state queries" do
|
27
|
+
|
28
|
+
def bit(n)
|
29
|
+
0x00000001 << n
|
30
|
+
end
|
31
|
+
|
32
|
+
# Matcher for handling the mask testing for the state mask.
|
33
|
+
#
|
34
|
+
# Usage:
|
35
|
+
# bit(5).should be_the_mask_for(:method [, off_value, on_value])
|
36
|
+
#
|
37
|
+
# If off_value and on_value are not given, then false/true will
|
38
|
+
# be assumed.
|
39
|
+
#
|
40
|
+
matcher :be_the_mask_for do |method, off_result=false, on_result=true|
|
41
|
+
match do |mask|
|
42
|
+
@msg = "OK"
|
43
|
+
try_alternative(method, 0, off_result) &&
|
44
|
+
try_alternative(method, mask, on_result)
|
45
|
+
end
|
46
|
+
|
47
|
+
failure_message_for_should do |mask|
|
48
|
+
@msg
|
49
|
+
end
|
50
|
+
|
51
|
+
# Try one of the alternatives. Sending method to the navdata
|
52
|
+
# constructed with mask should return teh expected value.
|
53
|
+
def try_alternative(method, mask, expected)
|
54
|
+
raw = Bytes.make_nav_data(Bytes.make_header(mask, 1, 0))
|
55
|
+
nav_data = NavData.new(raw)
|
56
|
+
result = nav_data.send(method)
|
57
|
+
return true if result == expected
|
58
|
+
@msg = "expected mask of 0x#{'%08x' % mask} with #{method}\n" +
|
59
|
+
"to return: #{expected.inspect}\n" +
|
60
|
+
"got: #{result.inspect}"
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Then { bit(0).should be_the_mask_for(:flying?) }
|
66
|
+
Then { bit(1).should be_the_mask_for(:video_enabled?) }
|
67
|
+
Then { bit(2).should be_the_mask_for(:vision_enabled?) }
|
68
|
+
Then { bit(3).should be_the_mask_for(:control_algorithm, :euler, :angular_speed) }
|
69
|
+
|
70
|
+
Then { bit(4).should be_the_mask_for(:altitude_control_algorithm_active?) }
|
71
|
+
Then { bit(5).should be_the_mask_for(:start_button_pressed?) }
|
72
|
+
Then { bit(6).should be_the_mask_for(:control_command_ack?) }
|
73
|
+
Then { bit(7).should be_the_mask_for(:camera_ready?) }
|
74
|
+
|
75
|
+
Then { bit(8).should be_the_mask_for(:travelling_enabled?) }
|
76
|
+
Then { bit(9).should be_the_mask_for(:usb_ready?) }
|
77
|
+
Then { bit(10).should be_the_mask_for(:mode, :all, :demo) }
|
78
|
+
Then { bit(11).should be_the_mask_for(:bootstrap?) }
|
79
|
+
|
80
|
+
Then { bit(12).should be_the_mask_for(:moter_problem?) }
|
81
|
+
Then { bit(13).should be_the_mask_for(:communication_lost?) }
|
82
|
+
Then { bit(14).should be_the_mask_for(:software_fault?) }
|
83
|
+
Then { bit(15).should be_the_mask_for(:low_battery?) }
|
84
|
+
|
85
|
+
Then { bit(16).should be_the_mask_for(:emergency_landing_requested?) }
|
86
|
+
Then { bit(17).should be_the_mask_for(:timer_elapsed?) }
|
87
|
+
Then { bit(18).should be_the_mask_for(:magnometer_needs_calibration?) }
|
88
|
+
Then { bit(19).should be_the_mask_for(:angles_out_of_range?) }
|
89
|
+
|
90
|
+
Then { bit(20).should be_the_mask_for(:too_much_wind?) }
|
91
|
+
Then { bit(21).should be_the_mask_for(:ultrasonic_sensor_deaf?) }
|
92
|
+
Then { bit(22).should be_the_mask_for(:cutout_detected?) }
|
93
|
+
Then { bit(23).should be_the_mask_for(:pic_version_number_ok?) }
|
94
|
+
|
95
|
+
Then { bit(24).should be_the_mask_for(:at_codec_thread_on?) }
|
96
|
+
Then { bit(25).should be_the_mask_for(:navdata_thread_on?) }
|
97
|
+
Then { bit(26).should be_the_mask_for(:video_thread_on?) }
|
98
|
+
Then { bit(27).should be_the_mask_for(:acquisition_thread_on?) }
|
99
|
+
|
100
|
+
Then { bit(28).should be_the_mask_for(:control_watchdog_delayed?) }
|
101
|
+
Then { bit(29).should be_the_mask_for(:adc_watchdog_delayed?) }
|
102
|
+
Then { bit(30).should be_the_mask_for(:com_watchdog_problem?) }
|
103
|
+
Then { bit(31).should be_the_mask_for(:emergency_landing?) }
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "state mask" do
|
107
|
+
context "all zeros" do
|
108
|
+
Given(:state_bits) { 0 }
|
109
|
+
Then { nav_data.state_mask == state_bits }
|
110
|
+
end
|
111
|
+
|
112
|
+
context "non-zero" do
|
113
|
+
Given(:state_bits) { 12345 }
|
114
|
+
Then { nav_data.state_mask == state_bits }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#options" do
|
119
|
+
Then { nav_data.options.size == 1 }
|
120
|
+
Then { nav_data.options.first.is_a?(NavOptionChecksum) }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "multiple options" do
|
125
|
+
context "with good data" do
|
126
|
+
Given(:raw_header) { Bytes.make_header(0, 0, 0) }
|
127
|
+
Given(:raw_nav_bytes) {
|
128
|
+
Bytes.make_nav_data(raw_header, Bytes.make_demo_data)
|
129
|
+
}
|
130
|
+
When(:nav_data) { NavData.new(raw_nav_bytes) }
|
131
|
+
Then { nav_data.options.size == 2 }
|
132
|
+
Then { nav_data.options[0].is_a?(NavOptionDemo) }
|
133
|
+
Then { nav_data.options[1].is_a?(NavOptionChecksum) }
|
134
|
+
end
|
135
|
+
|
136
|
+
context "with short data" do
|
137
|
+
Given(:raw_nav_bytes) {
|
138
|
+
Bytes.make_header(0, 0, 0).pack("C*") +
|
139
|
+
[4321, 100, 0].pack("vvV")
|
140
|
+
}
|
141
|
+
When(:nav_data) { NavData.new(raw_nav_bytes) }
|
142
|
+
Then { nav_data.options.size == 1 }
|
143
|
+
Then { nav_data.options[0].is_a?(NavOptionUnknown) }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
describe NavOptionChecksum do
|
6
|
+
Given(:raw_data) { [NavTag::CHECKSUM, 8, 0x12345678].pack("vvV") }
|
7
|
+
Given(:csum) { NavOptionChecksum.new(raw_data) }
|
8
|
+
|
9
|
+
describe ".tag" do
|
10
|
+
Then { NavOptionChecksum.tag == NavTag::CHECKSUM }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "data fields" do
|
14
|
+
Then { csum.tag == NavOptionChecksum.tag }
|
15
|
+
Then { csum.size == raw_data.size }
|
16
|
+
Then { csum.chks == 0x12345678 }
|
17
|
+
Then { csum.checksum == 0x12345678 }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
describe NavOptionDemo do
|
5
|
+
def f(float)
|
6
|
+
FloatEncoding.encode_float(float)
|
7
|
+
end
|
8
|
+
|
9
|
+
Given(:raw_data) { [
|
10
|
+
NavTag::DEMO, 148,
|
11
|
+
3, 0xcacacaca,
|
12
|
+
f(5.0), f(6.0), f(7.0),
|
13
|
+
-100000,
|
14
|
+
f(-5.0), f(-6.0), f(-7.0),
|
15
|
+
33,
|
16
|
+
[0]*9, [0]*3,
|
17
|
+
12, 34,
|
18
|
+
[0]*9, [0]*3,
|
19
|
+
].flatten.pack("vv VV V3 l< V3 V V9 V3 VV V9 v3") }
|
20
|
+
|
21
|
+
When(:demo) { NavOptionDemo.new(raw_data) }
|
22
|
+
|
23
|
+
Then { ! demo.nil? }
|
24
|
+
|
25
|
+
Then { demo.ctrl_state == 3 }
|
26
|
+
Then { demo.control_state_name == :flying }
|
27
|
+
Then { demo.vbat_flying_percentage == 0xcacacaca }
|
28
|
+
Then { demo.battery_level == 0xcacacaca }
|
29
|
+
Then { demo.theta == 5.0 }
|
30
|
+
Then { demo.phi == 6.0 }
|
31
|
+
Then { demo.psi == 7.0 }
|
32
|
+
Then { demo.altitude == -100000 }
|
33
|
+
Then { demo.vx == -5.0 }
|
34
|
+
Then { demo.vy == -6.0 }
|
35
|
+
Then { demo.vz == -7.0 }
|
36
|
+
Then { demo.detection_camera_rot.nil? }
|
37
|
+
Then { demo.detection_camera_trans.nil? }
|
38
|
+
Then { demo.detection_tag_index == 12 }
|
39
|
+
Then { demo.detection_camera_type == 34 }
|
40
|
+
Then { demo.drone_camera_rot.nil? }
|
41
|
+
Then { demo.drone_camera_trans.nil? }
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|