hybridgroup-crubyflie 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE.txt +674 -0
  6. data/README.md +127 -0
  7. data/Rakefile +15 -0
  8. data/bin/crubyflie +94 -0
  9. data/configs/joystick_default.yaml +106 -0
  10. data/crubyflie.gemspec +50 -0
  11. data/examples/params_and_logging.rb +87 -0
  12. data/lib/crubyflie/crazyflie/commander.rb +54 -0
  13. data/lib/crubyflie/crazyflie/console.rb +67 -0
  14. data/lib/crubyflie/crazyflie/log.rb +383 -0
  15. data/lib/crubyflie/crazyflie/log_conf.rb +57 -0
  16. data/lib/crubyflie/crazyflie/param.rb +220 -0
  17. data/lib/crubyflie/crazyflie/toc.rb +239 -0
  18. data/lib/crubyflie/crazyflie/toc_cache.rb +87 -0
  19. data/lib/crubyflie/crazyflie.rb +282 -0
  20. data/lib/crubyflie/crazyradio/crazyradio.rb +301 -0
  21. data/lib/crubyflie/crazyradio/radio_ack.rb +48 -0
  22. data/lib/crubyflie/crubyflie_logger.rb +74 -0
  23. data/lib/crubyflie/driver/crtp_packet.rb +146 -0
  24. data/lib/crubyflie/driver/radio_driver.rb +363 -0
  25. data/lib/crubyflie/exceptions.rb +36 -0
  26. data/lib/crubyflie/input/input_reader.rb +190 -0
  27. data/lib/crubyflie/input/joystick_input_reader.rb +328 -0
  28. data/lib/crubyflie/version.rb +22 -0
  29. data/lib/crubyflie.rb +36 -0
  30. data/spec/commander_spec.rb +67 -0
  31. data/spec/console_spec.rb +76 -0
  32. data/spec/crazyflie_spec.rb +176 -0
  33. data/spec/crazyradio_spec.rb +228 -0
  34. data/spec/crtp_packet_spec.rb +79 -0
  35. data/spec/crubyflie_logger_spec.rb +39 -0
  36. data/spec/crubyflie_spec.rb +21 -0
  37. data/spec/input_reader_spec.rb +136 -0
  38. data/spec/joystick_cfg.yaml +44 -0
  39. data/spec/joystick_input_reader_spec.rb +323 -0
  40. data/spec/log_spec.rb +266 -0
  41. data/spec/param_spec.rb +166 -0
  42. data/spec/radio_ack_spec.rb +43 -0
  43. data/spec/radio_driver_spec.rb +227 -0
  44. data/spec/spec_helper.rb +53 -0
  45. data/spec/toc_cache_spec.rb +87 -0
  46. data/spec/toc_spec.rb +187 -0
  47. data/tools/sdl-joystick-axis.rb +69 -0
  48. metadata +225 -0
@@ -0,0 +1,176 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2013 Hector Sanjuan
3
+
4
+ # This file is part of Crubyflie.
5
+
6
+ # Crubyflie is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # Crubyflie is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Crubyflie. If not, see <http://www.gnu.org/licenses/>
18
+
19
+ require 'crazyflie'
20
+
21
+
22
+ describe Crazyflie do
23
+ before :all do
24
+ end
25
+ before :each do
26
+ @facility = double("Facility")
27
+ allow(Commander).to receive(:new).and_return(@facility)
28
+ allow(Param).to receive(:new).and_return(@facility)
29
+ allow(Log).to receive(:new).and_return(@facility)
30
+ allow(Commander).to receive(:new).and_return(@facility)
31
+ allow(@facility).to receive(:send_setpoint)
32
+ allow(@facility).to receive(:refresh_toc)
33
+ allow(@facility).to receive(:start_packet_reader_thread)
34
+ allow(@facility).to receive(:stop_packet_reader_thread)
35
+ @link = double("RadioDriver")
36
+ @uri = 'radio://0/0/1M'
37
+ allow(RadioDriver).to receive(:new).and_return(@link)
38
+ allow(@link).to receive(:connect)
39
+ allow(@link).to receive(:disconnect)
40
+ allow(@link).to receive(:receive_packet)
41
+ allow(@link).to receive(:uri).and_return(CrubyflieURI.new(@uri))
42
+
43
+ #allow_any_instance_of(CrubyflieLogger).to receive(:info)
44
+
45
+ @cf = Crazyflie.new()
46
+ @logger = @cf.logger
47
+
48
+ @default_pk = CRTPPacket.new(0b00001100, [1,2,3])
49
+ end
50
+
51
+
52
+ describe "#initialize" do
53
+ it "should initalize correctly" do
54
+ Crazyflie::CALLBACKS.each do |cb|
55
+ @cf.callbacks[cb].size.should >= 0
56
+ end
57
+
58
+ Crazyflie::CRTP_PORTS.keys().each do |port|
59
+ @cf.crtp_queues[port].should be_an_instance_of Queue
60
+ end
61
+ end
62
+ end
63
+
64
+
65
+ describe "#open_link" do
66
+ it "should connect to a crazyradio url" do
67
+ expect(@link).to receive(:receive_packet).and_return(@default_pk)
68
+ m = "Connection initiated to radio://0/0/1M"
69
+ m2 = "Disconnected from radio://0/0/1M"
70
+ m3 = "TOCs extracted from #{@uri}"
71
+ expect(@logger).to receive(:info).with(m)
72
+ expect(@logger).to receive(:info).with("Connected!")
73
+ expect(@logger).to receive(:info).with("Connection ready!")
74
+ expect(@logger).to receive(:info).with(m2)
75
+ expect(@logger).to receive(:debug).with(m3)
76
+
77
+
78
+ expect(@facility).to receive(:refresh_toc).twice
79
+ # only log facility gets this
80
+ expect(@facility).to receive(:start_packet_reader_thread).once
81
+ expect(@facility).to receive(:stop_packet_reader_thread).twice
82
+ @cf.open_link(@uri)
83
+ @cf.close_link()
84
+ end
85
+
86
+ it "should close the link if something happens" do
87
+ expect(@link).to receive(:connect).and_raise(Exception)
88
+ mesg = "Connection failed: Exception"
89
+ expect(@logger).to receive(:info).at_least(:once)
90
+ expect(@logger).to receive(:error).with(mesg)
91
+ expect(@facility).not_to receive(:refresh_toc)
92
+ @cf.open_link(@uri)
93
+ @cf.close_link()
94
+ end
95
+ end
96
+
97
+ describe "#close_link" do
98
+ it "should close the link" do
99
+ expect(@facility).to receive(:send_setpoint)
100
+ expect(@link).to receive(:disconnect)
101
+ m1 = "Connection initiated to radio://0/0/1M"
102
+ m2 = "Connection ready!"
103
+ m3 = "Disconnected from radio://0/0/1M"
104
+ expect(@logger).to receive(:debug)
105
+ expect(@logger).to receive(:info).with(m1)
106
+ expect(@logger).to receive(:info).with(m2)
107
+ expect(@logger).to receive(:info).with(m3)
108
+
109
+ @cf.open_link(@uri)
110
+ @cf.close_link()
111
+ @cf.crtp_queues.each do |k,q|
112
+ q.should be_empty
113
+ end
114
+ end
115
+
116
+ it "should not break closing a non existing link" do
117
+ expect(@facility).not_to receive(:send_setpoint)
118
+ expect_any_instance_of(NilClass).not_to receive(:disconnect)
119
+ expect(@cf).not_to receive(:puts)
120
+ expect_any_instance_of(Thread).not_to receive(:kill)
121
+ expect(@logger).to receive(:info).with("Disconnected from nowhere")
122
+ @cf.close_link()
123
+ end
124
+ end
125
+
126
+ describe "#send_packet" do
127
+ it "should send a packet without expecting answer" do
128
+ expect(@cf).not_to receive(:setup_retry)
129
+ expect(@link).to receive(:send_packet).with(@default_pk)
130
+ expect(@logger).to receive(:info).at_least(:once)
131
+ expect(@logger).to receive(:debug)
132
+ @cf.open_link(@uri)
133
+ @cf.send_packet(@default_pk)
134
+ @cf.close_link()
135
+ end
136
+
137
+ it "should send a packet and set up a timer when expecting answer" do
138
+ pk = @default_pk
139
+ expect(@link).to receive(:send_packet).with(pk).at_least(:twice)
140
+ expect(@logger).to receive(:info).at_least(:once)
141
+ expect(@logger).to receive(:debug).at_least(:once)
142
+ @cf.open_link(@uri)
143
+ @cf.send_packet(@default_pk, true)
144
+ sleep 0.5
145
+ @cf.close_link()
146
+ end
147
+ end
148
+
149
+ describe "#receive_packet" do
150
+ it " should receive a packet, trigger callbacks" do
151
+ proc = Proc.new do
152
+ puts "port 0 ch 0 callback"
153
+ end
154
+
155
+ proc2 = Proc.new do |pk|
156
+ puts "Received packet"
157
+ end
158
+
159
+ @cf.callbacks[:received_packet][:log] = proc
160
+ @cf.callbacks[:received_packet][:log2] = proc2
161
+
162
+ allow_any_instance_of(Thread).to receive(:new).and_return(nil)
163
+ expect(@link).to receive(:receive_packet).and_return(@default_pk)
164
+ expect(proc).to receive(:call).with(@default_pk).at_least(:once)
165
+ expect(proc2).to receive(:call).with(@default_pk).at_least(:once)
166
+ expect(@cf.crtp_queues[:console]).to receive(:<<).once
167
+ expect(@logger).to receive(:info).at_least(:once)
168
+ expect(@logger).to receive(:debug)
169
+ @cf.open_link(@uri)
170
+ @cf.send(:receive_packet)
171
+ # Received packet comes on port 0 - console
172
+
173
+ @cf.close_link()
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,228 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2013 Hector Sanjuan
3
+
4
+ # This file is part of Crubyflie.
5
+
6
+ # Crubyflie is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # Crubyflie is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Crubyflie. If not, see <http://www.gnu.org/licenses/>
18
+
19
+ require 'crazyradio/crazyradio'
20
+
21
+ describe Crazyradio do
22
+ before :each do
23
+ @device = double("LIBUSB::Device")
24
+ @handle = double("LIBUSB::DevHandler")
25
+
26
+ allow(@device).to receive(:is_a?).and_return(LIBUSB::Device)
27
+ allow(@device).to receive(:open).and_return(@handle)
28
+ allow(@device).to receive(:serial_number).and_return("serial123")
29
+ allow(@device).to receive(:manufacturer).and_return("Bitcraze")
30
+ allow(@handle).to receive(:configuration=)
31
+ allow(@handle).to receive(:claim_interface)
32
+ tr_result = [1,2,3].pack('C*')
33
+ allow(@handle).to receive(:control_transfer).and_return(tr_result)
34
+ allow(@handle).to receive(:release_interface)
35
+ allow(@handle).to receive(:reset_device)
36
+ allow(@handle).to receive(:close)
37
+
38
+ @crazyradio = Crazyradio.new(@device)
39
+ end
40
+
41
+ describe "#initialize" do
42
+ it "should initialize the dongle correctly" do
43
+ settings = [:data_rate, :channel, :cont_carrier,
44
+ :address, :power, :arc, :ard_bytes]
45
+ ssize = settings.size
46
+ expect(@device).to receive(:open)
47
+ expect(@handle).to receive(:configuration=).with(1)
48
+ expect(@handle).to receive(:claim_interface).with(0)
49
+ expect(@handle).to receive(:control_transfer).exactly(ssize).times
50
+ crazyradio = Crazyradio.new(@device)
51
+ defaults = Crazyradio::DEFAULT_SETTINGS
52
+ settings.each do |setting|
53
+ crazyradio[setting].should == defaults[setting]
54
+ end
55
+ end
56
+
57
+ it "should not initialize with a nil device" do
58
+ expect { Crazyradio.new() }.to raise_error(USBDongleException,
59
+ "Wrong USB device")
60
+ end
61
+ end
62
+
63
+ describe "#status" do
64
+ it "should return a status" do
65
+ allow(Crazyradio).to receive(:factory).and_return(@crazyradio)
66
+ status = "Found serial123 USB dongle from Bitcraze"
67
+ Crazyradio.status().should == status
68
+ end
69
+ end
70
+
71
+ describe "#close" do
72
+ it "should close the USB" do
73
+ expect(@handle).to receive(:release_interface).with(0)
74
+ expect(@handle).to receive(:reset_device)
75
+ #expect(@handle).to receive(:close)
76
+ @crazyradio.close()
77
+ end
78
+ end
79
+
80
+ describe "#has_fw_scan" do
81
+ it "should say false" do
82
+ @crazyradio.has_fw_scan.should be_false
83
+ end
84
+ end
85
+
86
+ describe "#scan_channels" do
87
+ it "should scan channels and return them" do
88
+ ack = RadioAck.new(true)
89
+ do_this = receive(:send_packet).with([0xFF]).and_return(ack)
90
+ allow(@crazyradio).to do_this
91
+ @crazyradio.scan_channels(0, 125).should == (0..125).to_a
92
+ end
93
+
94
+ it "should scan channels with fw_scan and return them" do
95
+ allow(@crazyradio).to receive(:has_fw_scan).and_return(true)
96
+ @crazyradio.scan_channels(0, 125).should == [1,2,3]
97
+ end
98
+
99
+ it "should not include bad channels in a scan" do
100
+ ack = RadioAck.new(false)
101
+ do_this = receive(:send_packet).with([0xFF]).and_return(ack)
102
+ allow(@crazyradio).to do_this
103
+ @crazyradio.scan_channels(0, 125).should == []
104
+ end
105
+ end
106
+
107
+ describe "#factory" do
108
+ it "should raise an exception if no dongles are found" do
109
+ context = double("Context")
110
+ expect(LIBUSB::Context).to receive(:new).and_return(context)
111
+ expect(context).to receive(:devices).and_return([])
112
+
113
+ expect { Crazyradio.factory() }.to raise_error(USBDongleException,
114
+ "No dongles found")
115
+ end
116
+
117
+ it "should provide a new crazyradio item" do
118
+ context = double("Context")
119
+ expect(LIBUSB::Context).to receive(:new).and_return(context)
120
+ expect(context).to receive(:devices).and_return([@device])
121
+ Crazyradio.factory()
122
+ end
123
+ end
124
+
125
+ describe "#send_packet" do
126
+ it "should send a packet and get a response" do
127
+ dataout = { :endpoint => 1, :dataOut => [1,2,3,4,5].pack('C*')}
128
+ datain = { :endpoint => 0x81, :dataIn => 64}
129
+ response = ([0xFF] * 64).pack('C*')
130
+ do_this = receive(:bulk_transfer)
131
+ expect(@handle).to do_this.with(dataout).and_return(response)
132
+ expect(@handle).to do_this.with(datain).and_return(response)
133
+
134
+ ack = @crazyradio.send_packet([1,2,3,4,5])
135
+ ack.should be_an_instance_of RadioAck
136
+ ack.ack.should == true
137
+ ack.data.should == [0xFF] * 63
138
+ end
139
+ end
140
+
141
+ describe "#[]=" do
142
+ it "should set a setting" do
143
+ expect(@crazyradio).to receive(:set_data_rate).with(58)
144
+ @crazyradio[:data_rate] = 58
145
+ end
146
+ it "should no set a bad setting" do
147
+ expect(@crazyradio).not_to receive(:set_data_rate)
148
+ expect(@crazyradio).not_to receive(:set_channel)
149
+ expect(@crazyradio).not_to receive(:set_arc)
150
+ expect(@crazyradio).not_to receive(:set_cont_carrier)
151
+ expect(@crazyradio).not_to receive(:set_address)
152
+ expect(@crazyradio).not_to receive(:set_power)
153
+ expect(@crazyradio).not_to receive(:set_ard_bytes)
154
+ @crazyradio[:abc] = 3
155
+ @crazyradio[:abc].should be_nil
156
+ end
157
+ end
158
+
159
+ describe "[]" do
160
+ it "should get a setting value" do
161
+ expected = Crazyradio::DEFAULT_SETTINGS[:channel]
162
+ @crazyradio[:channel].should == expected
163
+ end
164
+ end
165
+
166
+ describe "#apply_settings" do
167
+ it "should apply one setting" do
168
+ d = Crazyradio::DEFAULT_SETTINGS
169
+ expect(@crazyradio).to receive(:set_channel).with(d[:channel])
170
+ expect(@crazyradio).to receive(:set_data_rate).with(d[:data_rate])
171
+ expect(@crazyradio).to receive(:set_arc).with(d[:arc])
172
+ scr = :set_cont_carrier
173
+ expect(@crazyradio).to receive(scr).with(d[:cont_carrier])
174
+ expect(@crazyradio).to receive(:set_address).with(d[:address])
175
+ expect(@crazyradio).to receive(:set_power).with(d[:power])
176
+ expect(@crazyradio).to receive(:set_ard_bytes).with(d[:ard_bytes])
177
+ @crazyradio.apply_settings(:channel)
178
+ @crazyradio.apply_settings(:data_rate)
179
+ @crazyradio.apply_settings(:arc)
180
+ @crazyradio.apply_settings(:cont_carrier)
181
+ @crazyradio.apply_settings(:power)
182
+ @crazyradio.apply_settings(:ard_bytes)
183
+ @crazyradio.apply_settings(:address)
184
+ end
185
+
186
+ it "should apply all settings" do
187
+ d = Crazyradio::DEFAULT_SETTINGS
188
+ expect(@crazyradio).to receive(:set_channel).with(d[:channel])
189
+ expect(@crazyradio).to receive(:set_data_rate).with(d[:data_rate])
190
+ expect(@crazyradio).to receive(:set_arc).with(d[:arc])
191
+ scr = :set_cont_carrier
192
+ expect(@crazyradio).to receive(scr).with(d[:cont_carrier])
193
+ expect(@crazyradio).to receive(:set_address).with(d[:address])
194
+ expect(@crazyradio).to receive(:set_power).with(d[:power])
195
+ expect(@crazyradio).to receive(:set_ard_bytes).with(d[:ard_bytes])
196
+ @crazyradio.apply_settings()
197
+ end
198
+ end
199
+
200
+ describe "#send_vendor_setup" do
201
+ it "should make a control_transfer with the proper args set" do
202
+ args = {
203
+ :bmRequestType => LIBUSB::REQUEST_TYPE_VENDOR,
204
+ :bRequest => 38,
205
+ :wValue => 3,
206
+ :wIndex => 2,
207
+ :dataOut => ""
208
+ }
209
+ expect(@handle).to receive(:control_transfer).with(args)
210
+ @crazyradio.send(:send_vendor_setup, 38, 3, 2)
211
+ end
212
+ end
213
+
214
+ describe "#get_vendor_setup" do
215
+ it "should make a control_transfer with the proper args set" do
216
+ args = {
217
+ :bmRequestType => LIBUSB::REQUEST_TYPE_VENDOR | 0x80,
218
+ :bRequest => 38,
219
+ :wValue => 3,
220
+ :wIndex => 2,
221
+ :dataIn => 0
222
+ }
223
+ expect(@handle).to receive(:control_transfer).with(args)
224
+ resp = @crazyradio.send(:get_vendor_setup, 38, 3, 2)
225
+ resp.should == [1,2,3]
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,79 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2013 Hector Sanjuan
3
+
4
+ # This file is part of Crubyflie.
5
+
6
+ # Crubyflie is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # Crubyflie is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Crubyflie. If not, see <http://www.gnu.org/licenses/>
18
+
19
+ require 'driver/crtp_packet'
20
+
21
+ describe CRTPPacket do
22
+ describe "#initalize" do
23
+ it "should initialize correctly a packet" do
24
+ header = 0b11101010 # channel 10; port 1110
25
+ payload = [1,2,3]
26
+ packet = CRTPPacket.new(header, payload)
27
+ packet.size.should == 3
28
+ packet.header.should == header
29
+ packet.data.should == payload
30
+ packet.channel.should == 0b10
31
+ packet.port.should == 0b1110
32
+ end
33
+ end
34
+
35
+ describe "#modify_header" do
36
+ it "should modify only with header if provided" do
37
+ header = 0b11101010 # channel 10; port 1110
38
+ payload = [1,2,3]
39
+ packet = CRTPPacket.new(header, payload)
40
+ packet.modify_header(0, 3, 4)
41
+ packet.header.should == 0
42
+ packet.channel.should == 0
43
+ packet.port.should == 0
44
+ end
45
+
46
+ it "should modify channel and port and set the header" do
47
+ channel = 0b10
48
+ port = 0b1101
49
+ payload = [1,2,3]
50
+ packet = CRTPPacket.new(0, payload)
51
+ packet.modify_header(nil, port, channel)
52
+ packet.header.should == 0b11010010
53
+ packet.channel.should == 0b10
54
+ packet.port.should == 0b1101
55
+ end
56
+ end
57
+
58
+ describe "#unpack" do
59
+ it "should return an empty package if data is empty or not array" do
60
+ CRTPPacket.unpack("abc").pack.should == [0]
61
+ CRTPPacket.unpack([]).pack.should == [0]
62
+ end
63
+
64
+ it "should unpack a data array correctly into header and data" do
65
+ packet = CRTPPacket.unpack([1,2,3])
66
+ packet.data.should == [2,3]
67
+ packet.header.should == 1
68
+ end
69
+ end
70
+
71
+ describe "#pack" do
72
+ it "should concat header and data" do
73
+ header = 0b11101010 # channel 10; port 1110
74
+ payload = [1,2,3]
75
+ packet = CRTPPacket.new(header, payload)
76
+ packet.pack.should == [0b11101010, 1, 2, 3]
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2013 Hector Sanjuan
3
+
4
+ # This file is part of Crubyflie.
5
+
6
+ # Crubyflie is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # Crubyflie is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Crubyflie. If not, see <http://www.gnu.org/licenses/>
18
+
19
+ describe Logging do
20
+ it "should provide a logger" do
21
+ include Logging
22
+ logger.should be_an_instance_of CrubyflieLogger
23
+ end
24
+ end
25
+
26
+ describe CrubyflieLogger do
27
+
28
+ it "should log to debug, info, warn" do
29
+ l = CrubyflieLogger.new(true)
30
+ expect($stderr).to receive(:puts).with("DEBUG: a")
31
+ expect($stdout).to receive(:puts).with("INFO: a")
32
+ expect($stderr).to receive(:puts).with("ERROR: a")
33
+ expect($stderr).to receive(:puts).with("WARNING: a")
34
+ l.debug "a"
35
+ l.info "a"
36
+ l.warn "a"
37
+ l.error "a"
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2013 Hector Sanjuan
3
+
4
+ # This file is part of Crubyflie.
5
+
6
+ # Crubyflie is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # Crubyflie is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Crubyflie. If not, see <http://www.gnu.org/licenses/>
18
+
19
+ $: << File.dirname(__FILE__)
20
+ require 'rspec'
21
+ require 'spec_helper'
@@ -0,0 +1,136 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2013 Hector Sanjuan
3
+
4
+ # This file is part of Crubyflie.
5
+
6
+ # Crubyflie is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # Crubyflie is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Crubyflie. If not, see <http://www.gnu.org/licenses/>
18
+
19
+ describe InputReader do
20
+
21
+ before :each do
22
+ @sdl_joystick = double("Joystick")
23
+ allow(SDL::Joystick).to receive(:update_all)
24
+ allow(SDL).to receive(:init).with(SDL::INIT_JOYSTICK)
25
+ allow(SDL::Joystick).to receive(:num).and_return(3)
26
+ allow(SDL::Joystick).to receive(:open).and_return(@sdl_joystick)
27
+ allow(SDL::Joystick).to receive(:index_name).and_return("My Joystick")
28
+ allow(SDL::Joystick).to receive(:poll).with(false)
29
+ expect(SDL::Joystick).not_to receive(:poll).with(true)
30
+ path = File.join(File.dirname(__FILE__), 'joystick_cfg.yaml')
31
+ @joystick = Joystick.new(path)
32
+
33
+ @logger = @joystick.logger
34
+ allow(@logger).to receive(:info)
35
+ @joystick.init()
36
+
37
+ @cf = double("Crazyflie")
38
+ end
39
+
40
+ describe "#read_input" do
41
+ it "should read axis and buttons" do
42
+ do_this = receive(:axis).and_return(0,32768,0,-32767)
43
+ do_this = do_this.exactly(4).times
44
+ expect(@sdl_joystick).to do_this
45
+
46
+ expect(@sdl_joystick).to receive(:button) { |arg|
47
+ false
48
+ }.twice
49
+
50
+ @joystick.read_input()
51
+ @joystick.axis_readings.should == {
52
+ :roll => 0,
53
+ :pitch => -30,
54
+ :yaw => 0,
55
+ :thrust => 49900
56
+ }
57
+
58
+ @joystick.button_readings.should == {
59
+ :switch_xmode => 0,
60
+ :close_link => 0
61
+ }
62
+ end
63
+ end
64
+
65
+
66
+ describe "#apply_input" do
67
+ it "should apply the read input to an active crazyflie" do
68
+ do_this = receive(:axis).and_return(0,32768,0,-32767)
69
+ do_this = do_this.exactly(4).times
70
+ expect(@sdl_joystick).to do_this
71
+
72
+ expect(@sdl_joystick).to receive(:button) { |arg|
73
+ false
74
+ }.twice
75
+
76
+ expect(@cf).to receive(:active?).and_return(true).twice
77
+ cmder = double("Commander")
78
+ expect(@cf).to receive(:commander).and_return(cmder)
79
+ expect(cmder).to receive(:send_setpoint).with(0, -30, 0,
80
+ 49900, false)
81
+ @joystick.read_input()
82
+ @joystick.apply_input(@cf)
83
+ end
84
+
85
+ it "should not send commands to a non active crazyflie" do
86
+ do_this = receive(:axis).and_return(0,32768,0,-32767)
87
+ do_this = do_this.exactly(4).times
88
+ expect(@sdl_joystick).to do_this
89
+
90
+ expect(@sdl_joystick).to receive(:button) { |arg|
91
+ false
92
+ }.twice
93
+
94
+ expect(@cf).to receive(:active?).and_return(false)
95
+ expect(@cf).not_to receive(:commander)
96
+ @joystick.read_input()
97
+ @joystick.apply_input(@cf)
98
+ end
99
+
100
+ it "should close the link to the crazyflie" do
101
+ do_this = receive(:axis).and_return(0,32768,0,-32767)
102
+ do_this = do_this.exactly(4).times
103
+ expect(@sdl_joystick).to do_this
104
+
105
+ expect(@sdl_joystick).to receive(:button) { |arg|
106
+ arg == 0 ? false : true
107
+ }.twice
108
+
109
+ expect(@cf).to receive(:active?).and_return(true, false).twice
110
+ expect(@cf).not_to receive(:commander)
111
+ expect(@cf).to receive(:close_link)
112
+ @joystick.read_input()
113
+ @joystick.apply_input(@cf)
114
+ end
115
+
116
+ it "should enable xmode" do
117
+ do_this = receive(:axis).and_return(0,32768,0,-32767)
118
+ do_this = do_this.exactly(4).times
119
+ expect(@sdl_joystick).to do_this
120
+
121
+ expect(@sdl_joystick).to receive(:button) { |arg|
122
+ arg == 1 ? false : true
123
+ }.twice
124
+
125
+ expect(@cf).to receive(:active?).and_return(true).twice
126
+ cmder = double("Commander")
127
+ expect(@cf).to receive(:commander).and_return(cmder)
128
+ expect(cmder).to receive(:send_setpoint).with(0, -30, 0,
129
+ 49900, true)
130
+ @joystick.read_input()
131
+ @joystick.apply_input(@cf)
132
+ @joystick.xmode.should == true
133
+ end
134
+ end
135
+
136
+ end