argus 0.0.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/MIT-LICENSE +1 -1
- data/README.md +25 -1
- data/Rakefile +4 -0
- data/lib/argus.rb +5 -0
- data/lib/argus/ardrone_control_modes.rb +14 -0
- data/lib/argus/at_commander.rb +104 -0
- data/lib/argus/cad_type.rb +22 -0
- data/lib/argus/cfields.rb +80 -0
- data/lib/argus/controller.rb +165 -0
- data/lib/argus/drone.rb +62 -0
- data/lib/argus/float_encoding.rb +13 -0
- data/lib/argus/led_animation.rb +48 -0
- data/lib/argus/nav_data.rb +78 -0
- data/lib/argus/nav_monitor.rb +83 -0
- data/lib/argus/nav_option.rb +35 -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 +111 -0
- data/lib/argus/nav_tag.rb +35 -0
- data/lib/argus/null_nav_monitor.rb +13 -0
- data/lib/argus/pave_parser.rb +39 -0
- data/lib/argus/tcp_video_streamer.rb +20 -0
- data/lib/argus/time_queue.rb +62 -0
- data/lib/argus/udp_sender.rb +13 -0
- data/lib/argus/version.rb +10 -0
- data/spec/argus/at_commander_spec.rb +82 -0
- data/spec/argus/controller_spec.rb +149 -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 +56 -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 +111 -0
- data/spec/argus/null_nav_monitor_spec.rb +17 -0
- data/spec/argus/time_queue_spec.rb +61 -0
- data/spec/argus/udp_sender_spec.rb +33 -0
- data/spec/spec_helper.rb +13 -0
- metadata +51 -12
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Argus
|
4
|
+
|
5
|
+
# NavStreamer State Transitions:
|
6
|
+
#
|
7
|
+
# State Trigger Next Action
|
8
|
+
# ------ -------------- ---- -----------------
|
9
|
+
# init start wait reconnect
|
10
|
+
#
|
11
|
+
# wait short_timeout wait request_nav_data
|
12
|
+
# wait long_timeout wait reconnect
|
13
|
+
# wait received_data run --
|
14
|
+
#
|
15
|
+
# run short_timeout run --
|
16
|
+
# run long_timeout wait reconnect
|
17
|
+
# run received_data run --
|
18
|
+
|
19
|
+
class NavStreamer
|
20
|
+
attr_reader :state
|
21
|
+
|
22
|
+
def initialize(opts={})
|
23
|
+
@state = :init
|
24
|
+
@socket = nil
|
25
|
+
@remote_host = opts.fetch(:remote_host)
|
26
|
+
@local_host = opts[:local_host] || '0.0.0.0'
|
27
|
+
@port = opts[:port] || 5554
|
28
|
+
@socket_class = opts[:UDPSocket] || UDPSocket
|
29
|
+
start_timer
|
30
|
+
end
|
31
|
+
|
32
|
+
def start
|
33
|
+
@state = :wait
|
34
|
+
reconnect
|
35
|
+
end
|
36
|
+
|
37
|
+
def short_timeout
|
38
|
+
if state == :wait
|
39
|
+
request_nav_data
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def long_timeout
|
44
|
+
if @state == :wait || @state == :run
|
45
|
+
@state = :wait
|
46
|
+
reconnect
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def receive_data
|
51
|
+
data, from = @socket.recvfrom(1024)
|
52
|
+
if data.unpack("V").first == 0x55667788
|
53
|
+
received_data
|
54
|
+
NavData.new(data)
|
55
|
+
else
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def received_data
|
61
|
+
if state == :wait || state == :run
|
62
|
+
@state = :run
|
63
|
+
@long_flag = false
|
64
|
+
@short_flag = false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def request_nav_data
|
71
|
+
@socket.send("\x01\x00\x00\x00", 0, @remote_host, @port)
|
72
|
+
end
|
73
|
+
|
74
|
+
def reconnect
|
75
|
+
disconnect if @socket
|
76
|
+
@socket = new_socket
|
77
|
+
@socket.bind(@local_host, @port) rescue nil
|
78
|
+
request_nav_data
|
79
|
+
end
|
80
|
+
|
81
|
+
def disconnect
|
82
|
+
@socket.close
|
83
|
+
@socket = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def new_socket
|
87
|
+
@socket_class.new
|
88
|
+
end
|
89
|
+
|
90
|
+
def tick
|
91
|
+
short_timeout if @short_flag
|
92
|
+
@short_flag = true
|
93
|
+
if @n == 0
|
94
|
+
long_timeout if @long_flag
|
95
|
+
@long_flag = true
|
96
|
+
end
|
97
|
+
@n += 1
|
98
|
+
@n = 0 if @n == 10
|
99
|
+
end
|
100
|
+
|
101
|
+
def start_timer
|
102
|
+
@n = 0
|
103
|
+
@thread = Thread.new do
|
104
|
+
loop do
|
105
|
+
tick
|
106
|
+
sleep 1.0
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
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
|
@@ -0,0 +1,39 @@
|
|
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
|
@@ -0,0 +1,20 @@
|
|
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
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class TimeQueue
|
2
|
+
Item = Struct.new(:time, :value) do
|
3
|
+
def <=>(other)
|
4
|
+
time <=> other.time
|
5
|
+
end
|
6
|
+
|
7
|
+
def key
|
8
|
+
object_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s(basetime=nil)
|
12
|
+
if basetime
|
13
|
+
"#{value.inspect}@+#{time-basetime}"
|
14
|
+
else
|
15
|
+
"#{value.inspect}@#{time.strftime('%H:%M:%S.%L')}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@items = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(time, value)
|
25
|
+
item = Item.new(time, value)
|
26
|
+
@items << item
|
27
|
+
@items.sort!
|
28
|
+
item.key
|
29
|
+
end
|
30
|
+
|
31
|
+
def remove(key)
|
32
|
+
@items.delete_if { |item| item.key == key }
|
33
|
+
end
|
34
|
+
|
35
|
+
def any_ready?(time)
|
36
|
+
! @items.empty? && @items.first.time <= time
|
37
|
+
end
|
38
|
+
|
39
|
+
def all_ready(time)
|
40
|
+
result = []
|
41
|
+
each_ready(time) do |value| result << value end
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def each_ready(time)
|
46
|
+
while any_ready?(time)
|
47
|
+
item = @items.shift
|
48
|
+
yield item.value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
base_time = nil
|
54
|
+
strings = @items[0,3].map { |item|
|
55
|
+
string = item.to_s(base_time)
|
56
|
+
base_time ||= item.time
|
57
|
+
string
|
58
|
+
}
|
59
|
+
strings << "..." if @items.size > 3
|
60
|
+
"[#{strings.join(', ')}]"
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Argus
|
2
|
+
class UdpSender
|
3
|
+
def initialize(opts={})
|
4
|
+
@udp_socket = opts[:socket] || UDPSocket.new
|
5
|
+
@host = opts.fetch(:remote_host)
|
6
|
+
@port = opts.fetch(:port, 5556)
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_packet(data)
|
10
|
+
@udp_socket.send(data, 0, @host, @port)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Argus::ATCommander do
|
4
|
+
Given(:sender) { flexmock(:on, Argus::UdpSender) }
|
5
|
+
Given(:cmdr) { Argus::ATCommander.new(sender) }
|
6
|
+
|
7
|
+
describe "#tick" do
|
8
|
+
Given(:expected_commands) {
|
9
|
+
[
|
10
|
+
"AT\\*REF=\\d+,0",
|
11
|
+
"AT\\*PCMD=\\d+,0,0,0,0,0",
|
12
|
+
]
|
13
|
+
}
|
14
|
+
Given(:command_pattern) { Regexp.new('\A' + expected_commands.map { |s| "#{s}\r" }.join + '\Z') }
|
15
|
+
|
16
|
+
When { cmdr.send(:tick) }
|
17
|
+
|
18
|
+
context "with no commands" do
|
19
|
+
Then { sender.should have_received(:send_packet).with(command_pattern) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with a ref command" do
|
23
|
+
Given { expected_commands[0] = 'AT\*REF=\d+,512' }
|
24
|
+
Given { cmdr.ref("512") }
|
25
|
+
Then { sender.should have_received(:send_packet).with(command_pattern) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with a pcmd command" do
|
29
|
+
Given { expected_commands[1] = 'AT\*PCMD=\d+,1,2,3,4,5' }
|
30
|
+
Given { cmdr.pcmd("1,2,3,4,5") }
|
31
|
+
Then { sender.should have_received(:send_packet).with(command_pattern) }
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with a config command" do
|
35
|
+
Given { expected_commands.unshift('AT\*CONFIG=\d+,"general:navdata_demo","TRUE"') }
|
36
|
+
Given { cmdr.config("general:navdata_demo", "TRUE") }
|
37
|
+
Then { sender.should have_received(:send_packet).with(command_pattern) }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with a reset watchdog command" do
|
41
|
+
Given { expected_commands.unshift('AT\*COMWDG=\d+') }
|
42
|
+
Given { cmdr.comwdg }
|
43
|
+
Then { sender.should have_received(:send_packet).with(command_pattern) }
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with a contrl command" do
|
47
|
+
Given { expected_commands.unshift('AT\*CTRL=\d+,4,0') }
|
48
|
+
Given { cmdr.ctrl(4) }
|
49
|
+
Then { sender.should have_received(:send_packet).with(command_pattern) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "increasing sequence numbers" do
|
54
|
+
Given(:seq_numbers) { [ ] }
|
55
|
+
Given {
|
56
|
+
sender.should_receive(:send_packet).and_return { |data|
|
57
|
+
data.scan(%r{=(\d+),}) { |seq|
|
58
|
+
seq_numbers << seq.first.to_i }
|
59
|
+
}
|
60
|
+
}
|
61
|
+
When { 2.times { cmdr.tick } }
|
62
|
+
Then { seq_numbers.should == [1, 2, 3, 4] }
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "sending thread" do
|
66
|
+
Given {
|
67
|
+
@count = 0
|
68
|
+
sender.should_receive(:send_packet).and_return {
|
69
|
+
@count += 1
|
70
|
+
cmdr.stop if @count > 5
|
71
|
+
}
|
72
|
+
}
|
73
|
+
When {
|
74
|
+
cmdr.start
|
75
|
+
cmdr.join
|
76
|
+
}
|
77
|
+
Then { sender.should have_received(:send_packet) }
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Argus::Controller do
|
4
|
+
|
5
|
+
REF_BASE = 0x11540000
|
6
|
+
|
7
|
+
def ref_bits(n=nil)
|
8
|
+
if n.nil?
|
9
|
+
REF_BASE.to_s
|
10
|
+
else
|
11
|
+
(REF_BASE | (1 << n)).to_s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Given(:at) { flexmock(:on, Argus::ATCommander) }
|
16
|
+
Given(:controller) { Argus::Controller.new(at) }
|
17
|
+
|
18
|
+
context "navigating commands" do
|
19
|
+
Invariant { result.should == controller }
|
20
|
+
|
21
|
+
context "when taking off" do
|
22
|
+
When(:result) { controller.take_off }
|
23
|
+
Then { at.should have_received(:ref).with(ref_bits(9)) }
|
24
|
+
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
|
+
end
|
149
|
+
end
|