hybridgroup-sphero 1.1.6 → 1.2.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.
- data/README.markdown +17 -0
- data/Rakefile +0 -1
- data/lib/sphero/request.rb +68 -0
- data/lib/sphero/response.rb +118 -3
- data/lib/sphero.rb +122 -9
- data/test/test_sphero.rb +46 -45
- metadata +2 -18
data/README.markdown
CHANGED
|
@@ -77,6 +77,23 @@ sleep 1
|
|
|
77
77
|
s.stop
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
## Pairing sphero with ubuntu
|
|
81
|
+
Add your user to the `dialout` group
|
|
82
|
+
```
|
|
83
|
+
$ sudo usermod -a -G dialout <user>
|
|
84
|
+
```
|
|
85
|
+
Then logout or restart your computer. Once your user is logged back in, pair the sphero with the ubuntu bluetooth manager.
|
|
86
|
+
|
|
87
|
+
Once paired, you may now bind your sphero to a rfcomm port
|
|
88
|
+
```
|
|
89
|
+
$ sudo hcitool scan
|
|
90
|
+
Scanning ...
|
|
91
|
+
<address> Sphero
|
|
92
|
+
$ sudo rfcomm bind /dev/rfcomm0 <address> 1
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
You may now access the sphero from `/dev/rfcomm0`
|
|
96
|
+
|
|
80
97
|
## REQUIREMENTS:
|
|
81
98
|
|
|
82
99
|
* A Sphero ball connected to your computer
|
data/Rakefile
CHANGED
|
@@ -14,7 +14,6 @@ Hoe.spec 'hybridgroup-sphero' do
|
|
|
14
14
|
self.readme_file = 'README.markdown'
|
|
15
15
|
self.history_file = 'CHANGELOG.rdoc'
|
|
16
16
|
self.extra_rdoc_files = FileList['*.{rdoc,markdown}']
|
|
17
|
-
self.extra_deps << ['hybridgroup-serialport']
|
|
18
17
|
|
|
19
18
|
self.spec_extras = {
|
|
20
19
|
:required_ruby_version => '>= 1.9.2'
|
data/lib/sphero/request.rb
CHANGED
|
@@ -113,5 +113,73 @@ class Sphero
|
|
|
113
113
|
@data.pack 'nC'
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
|
+
|
|
117
|
+
class SetPowerNotification < Sphero
|
|
118
|
+
def initialize seq, enable
|
|
119
|
+
super(seq, [enable])
|
|
120
|
+
@cid = 0x21
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
GYRO_AXIS_H_FILTERED = 0x0000_0001
|
|
125
|
+
GYRO_AXIS_M_FILTERED = 0x0000_0002
|
|
126
|
+
GYRO_AXIS_L_FILTERED = 0x0000_0004
|
|
127
|
+
LEFT_MOTOR_BACK_EMF_FILTERED = 0x0000_0020
|
|
128
|
+
RIGHT_MOTOR_BACK_EMF_FILTERED = 0x0000_0040
|
|
129
|
+
MAGNETOMETER_AXIS_Z_FILTERED = 0x0000_0080
|
|
130
|
+
MAGNETOMETER_AXIS_Y_FILTERED = 0x0000_0100
|
|
131
|
+
MAGNETOMETER_AXIS_X_FILTERED = 0x0000_0200
|
|
132
|
+
GYRO_AXIS_Z_FILTERED = 0x0000_0400
|
|
133
|
+
GYRO_AXIS_Y_FILTERED = 0x0000_0800
|
|
134
|
+
GYRO_AXIS_X_FILTERED = 0x0000_1000
|
|
135
|
+
ACCELEROMETER_AXIS_Z_FILTERED = 0x0000_2000
|
|
136
|
+
ACCELEROMETER_AXIS_Y_FILTERED = 0x0000_4000
|
|
137
|
+
ACCELEROMETER_AXIS_X_FILTERED = 0x0000_8000
|
|
138
|
+
IMU_YAW_ANGLE_FILTERED = 0x0001_0000
|
|
139
|
+
IMU_ROLL_ANGLE_FILTERED = 0x0002_0000
|
|
140
|
+
IMU_PITCH_ANGLE_FILTERED = 0x0004_0000
|
|
141
|
+
LEFT_MOTOR_BACK_EMF_RAW = 0x0020_0000
|
|
142
|
+
RIGHT_MOTOR_BACK_EMF_RAW = 0x0040_0000
|
|
143
|
+
MAGNETOMETER_AXIS_Z_RAW = 0x0080_0000
|
|
144
|
+
MAGNETOMETER_AXIS_Y_RAW = 0x0100_0000
|
|
145
|
+
MAGNETOMETER_AXIS_X_RAW = 0x0200_0000
|
|
146
|
+
GYRO_AXIS_Z_RAW = 0x0400_0000
|
|
147
|
+
GYRO_AXIS_Y_RAW = 0x0800_0000
|
|
148
|
+
GYRO_AXIS_X_RAW = 0x1000_0000
|
|
149
|
+
ACCELEROMETER_AXIS_Z_RAW = 0x2000_0000
|
|
150
|
+
ACCELEROMETER_AXIS_Y_RAW = 0x4000_0000
|
|
151
|
+
ACCELEROMETER_AXIS_X_RAW = 0x8000_0000
|
|
152
|
+
|
|
153
|
+
QUATERNION_Q0 = 0x0000_0001
|
|
154
|
+
QUATERNION_Q1 = 0x0000_0002
|
|
155
|
+
QUATERNION_Q2 = 0x0000_0004
|
|
156
|
+
QUATERNION_Q3 = 0x0000_0008
|
|
157
|
+
ODOMETER_X = 0x0000_0010
|
|
158
|
+
ODOMETER_Y = 0x0000_0020
|
|
159
|
+
ACCELONE = 0x0000_0040
|
|
160
|
+
VELOCITY_X = 0x0000_0080
|
|
161
|
+
VELOCITY_Y = 0x0000_0100
|
|
162
|
+
|
|
163
|
+
class SetDataStreaming < Sphero
|
|
164
|
+
def initialize seq, n, m, mask, pcnt, mask2
|
|
165
|
+
super(seq, [n, m, mask, pcnt, mask2])
|
|
166
|
+
@cid = 0x12
|
|
167
|
+
@mask = mask
|
|
168
|
+
@mask2 = mask2
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
private
|
|
172
|
+
|
|
173
|
+
def packet_body
|
|
174
|
+
@data.pack 'nnNCN'
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
class ConfigureCollisionDetection < Sphero
|
|
179
|
+
def initialize seq, meth, x_t, y_t, x_spd, y_spd, dead
|
|
180
|
+
super(seq, [meth, x_t, y_t, x_spd, y_spd, dead])
|
|
181
|
+
@cid = 0x12
|
|
182
|
+
end
|
|
183
|
+
end
|
|
116
184
|
end
|
|
117
185
|
end
|
data/lib/sphero/response.rb
CHANGED
|
@@ -7,22 +7,36 @@ class Sphero
|
|
|
7
7
|
DLEN = 4
|
|
8
8
|
|
|
9
9
|
CODE_OK = 0
|
|
10
|
+
SIMPLE_RESPONSE = 0xFF
|
|
11
|
+
ASYNC_RESPONSE = 0xFE
|
|
12
|
+
|
|
13
|
+
def self.simple?(header)
|
|
14
|
+
header[SOP2] == SIMPLE_RESPONSE
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.async?(header)
|
|
18
|
+
header[SOP2] == ASYNC_RESPONSE
|
|
19
|
+
end
|
|
10
20
|
|
|
11
21
|
def initialize header, body
|
|
12
22
|
@header = header
|
|
13
23
|
@body = body
|
|
14
24
|
end
|
|
15
25
|
|
|
26
|
+
def valid?
|
|
27
|
+
@header && @body
|
|
28
|
+
end
|
|
29
|
+
|
|
16
30
|
def empty?
|
|
17
|
-
@header[DLEN] == 1
|
|
31
|
+
valid? && @header[DLEN] == 1
|
|
18
32
|
end
|
|
19
33
|
|
|
20
34
|
def success?
|
|
21
|
-
@header[MRSP] == CODE_OK
|
|
35
|
+
valid? && @header[MRSP] == CODE_OK
|
|
22
36
|
end
|
|
23
37
|
|
|
24
38
|
def seq
|
|
25
|
-
@header[SEQ]
|
|
39
|
+
valid? && @header[SEQ]
|
|
26
40
|
end
|
|
27
41
|
|
|
28
42
|
def body
|
|
@@ -84,5 +98,106 @@ class Sphero
|
|
|
84
98
|
def g; body[1]; end
|
|
85
99
|
def b; body[2]; end
|
|
86
100
|
end
|
|
101
|
+
|
|
102
|
+
class AsyncResponse < Response
|
|
103
|
+
ID_CODE = 2
|
|
104
|
+
DLEN_MSB = 3
|
|
105
|
+
DLEN_LSB = 4
|
|
106
|
+
|
|
107
|
+
POWER_NOTIFICATION = 0x01
|
|
108
|
+
LEVEL_1_DIAGNOSTIC = 0x02
|
|
109
|
+
SENSOR_DATA = 0x03
|
|
110
|
+
CONFIG_BLOCK = 0x04
|
|
111
|
+
PRESLEEP_WARNING = 0x05
|
|
112
|
+
MACRO_MARKERS = 0x06
|
|
113
|
+
COLLISION_DETECTED = 0x07
|
|
114
|
+
|
|
115
|
+
VALID_REPONSES = {POWER_NOTIFICATION => 'Sphero::Response::PowerNotification',
|
|
116
|
+
#LEVEL_1_DIAGNOSTIC => 'AsyncResponse',
|
|
117
|
+
SENSOR_DATA => 'Sphero::Response::SensorData',
|
|
118
|
+
#CONFIG_BLOCK => 'AsyncResponse',
|
|
119
|
+
#PRESLEEP_WARNING => 'AsyncResponse',
|
|
120
|
+
#MACRO_MARKERS => 'AsyncResponse',
|
|
121
|
+
COLLISION_DETECTED => 'Sphero::Response::CollisionDetected'}
|
|
122
|
+
|
|
123
|
+
def self.valid?(header)
|
|
124
|
+
VALID_REPONSES.keys.include?(header[ID_CODE])
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def self.response header, body
|
|
128
|
+
raise "no good" unless self.valid?(header)
|
|
129
|
+
constantize(VALID_REPONSES[header[ID_CODE]]).new(header, body)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.constantize(camel_cased_word)
|
|
133
|
+
names = camel_cased_word.split('::')
|
|
134
|
+
names.shift if names.empty? || names.first.empty?
|
|
135
|
+
|
|
136
|
+
constant = Object
|
|
137
|
+
names.each do |name|
|
|
138
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
|
139
|
+
end
|
|
140
|
+
constant
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def empty?
|
|
144
|
+
@header[DLEN_LSB] == 1
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def success?
|
|
148
|
+
AsyncResponse.valid?(@header)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def seq
|
|
152
|
+
1
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class PowerNotification < GetPowerState
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class SensorData < AsyncResponse
|
|
160
|
+
def body
|
|
161
|
+
@body.unpack 's*'
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
class CollisionDetected < AsyncResponse
|
|
166
|
+
def body
|
|
167
|
+
@body.unpack 'nnnCnnCN'
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def x
|
|
171
|
+
body[0]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def y
|
|
175
|
+
body[1]
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def z
|
|
179
|
+
body[2]
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def axis
|
|
183
|
+
body[3]
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def x_magnitude
|
|
187
|
+
body[4]
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def y_magnitude
|
|
191
|
+
body[5]
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def speed
|
|
195
|
+
body[6]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def timestamp
|
|
199
|
+
body[7]
|
|
200
|
+
end
|
|
201
|
+
end
|
|
87
202
|
end
|
|
88
203
|
end
|
data/lib/sphero.rb
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
require 'serialport'
|
|
2
1
|
require 'sphero/request'
|
|
3
2
|
require 'sphero/response'
|
|
4
3
|
require 'thread'
|
|
5
4
|
|
|
6
5
|
class Sphero
|
|
7
|
-
VERSION = '1.
|
|
6
|
+
VERSION = '1.2.0'
|
|
8
7
|
|
|
9
8
|
FORWARD = 0
|
|
10
9
|
RIGHT = 90
|
|
11
10
|
BACKWARD = 180
|
|
12
11
|
LEFT = 270
|
|
13
12
|
|
|
13
|
+
DEFAULT_RETRIES = 3
|
|
14
|
+
|
|
15
|
+
attr_accessor :connection_types, :async_messages
|
|
16
|
+
|
|
14
17
|
class << self
|
|
15
18
|
def start(dev, &block)
|
|
19
|
+
retries_left = DEFAULT_RETRIES
|
|
16
20
|
sphero = self.new dev
|
|
17
21
|
if (block_given?)
|
|
18
22
|
begin
|
|
@@ -24,15 +28,23 @@ class Sphero
|
|
|
24
28
|
end
|
|
25
29
|
return sphero
|
|
26
30
|
rescue Errno::EBUSY
|
|
27
|
-
|
|
31
|
+
puts retries_left
|
|
32
|
+
retries_left = retries_left - 1
|
|
33
|
+
retry unless retries_left > 0
|
|
28
34
|
end
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
def initialize dev
|
|
32
|
-
|
|
38
|
+
if dev.is_a?(String)
|
|
39
|
+
initialize_serialport dev
|
|
40
|
+
else
|
|
41
|
+
@sp = dev
|
|
42
|
+
end
|
|
43
|
+
|
|
33
44
|
@dev = 0x00
|
|
34
45
|
@seq = 0x00
|
|
35
46
|
@lock = Mutex.new
|
|
47
|
+
@async_messages = []
|
|
36
48
|
end
|
|
37
49
|
|
|
38
50
|
def close
|
|
@@ -110,6 +122,42 @@ class Sphero
|
|
|
110
122
|
Kernel::sleep duration
|
|
111
123
|
end
|
|
112
124
|
|
|
125
|
+
## async messages
|
|
126
|
+
|
|
127
|
+
# configure power notification messages
|
|
128
|
+
def set_power_notification enable=true
|
|
129
|
+
write Request::SetPowerNotification.new(@seq, enable ? 0x01 : 0x00)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# configure data streaming notification messages
|
|
133
|
+
def set_data_streaming n, m, mask, pcnt, mask2
|
|
134
|
+
write Request::SetDataStreaming.new(@seq, n, m, mask, pcnt, mask2)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# configure collision detection messages
|
|
138
|
+
def configure_collision_detection meth, x_t, y_t, x_spd, y_spd, dead
|
|
139
|
+
write Request::ConfigureCollisionDetection.new(@seq, meth, x_t, y_t, x_spd, y_spd, dead)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# read all outstanding async packets and store in async_responses
|
|
143
|
+
# would not do well to receive simple responses this way...
|
|
144
|
+
def read_async_messages
|
|
145
|
+
header, body = nil
|
|
146
|
+
new_responses = []
|
|
147
|
+
|
|
148
|
+
@lock.synchronize do
|
|
149
|
+
header, body = read_next_response
|
|
150
|
+
|
|
151
|
+
while header && Response.async?(header)
|
|
152
|
+
new_responses << Response::AsyncResponse.response(header, body)
|
|
153
|
+
header, body = read_next_response
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
async_messages.concat(new_responses) unless new_responses.empty?
|
|
158
|
+
return !new_responses.empty?
|
|
159
|
+
end
|
|
160
|
+
|
|
113
161
|
private
|
|
114
162
|
|
|
115
163
|
def is_windows?
|
|
@@ -122,24 +170,39 @@ class Sphero
|
|
|
122
170
|
end
|
|
123
171
|
|
|
124
172
|
def initialize_serialport dev
|
|
173
|
+
require 'serialport'
|
|
125
174
|
@sp = SerialPort.new dev, 115200, 8, 1, SerialPort::NONE
|
|
126
175
|
if is_windows?
|
|
127
176
|
@sp.read_timeout=1000
|
|
128
177
|
@sp.write_timeout=0
|
|
129
178
|
@sp.initial_byte_offset=5
|
|
130
179
|
end
|
|
180
|
+
rescue LoadError
|
|
181
|
+
puts "Please 'gem install hybridgroup-serialport' for serial port support."
|
|
131
182
|
end
|
|
132
183
|
|
|
133
184
|
def write packet
|
|
134
|
-
header = nil
|
|
135
|
-
body = nil
|
|
185
|
+
header, body = nil
|
|
136
186
|
|
|
137
187
|
@lock.synchronize do
|
|
188
|
+
rs, ws = IO.select([], [@sp], [], 20)
|
|
138
189
|
@sp.write packet.to_str
|
|
139
190
|
@seq += 1
|
|
140
191
|
|
|
141
|
-
header
|
|
142
|
-
|
|
192
|
+
header = nil
|
|
193
|
+
loop do
|
|
194
|
+
header = read_header(true)
|
|
195
|
+
break if header
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
body = read_body(header.last, true) if header
|
|
199
|
+
|
|
200
|
+
# pick off asynch packets and store, till we get to the message response
|
|
201
|
+
while header && Response.async?(header)
|
|
202
|
+
async_messages << Response::AsyncResponse.response(header, body)
|
|
203
|
+
header = read_header(true)
|
|
204
|
+
body = read_body(header.last, true) if header
|
|
205
|
+
end
|
|
143
206
|
end
|
|
144
207
|
|
|
145
208
|
response = packet.response header, body
|
|
@@ -147,8 +210,58 @@ class Sphero
|
|
|
147
210
|
if response.success?
|
|
148
211
|
response
|
|
149
212
|
else
|
|
150
|
-
raise
|
|
213
|
+
raise "Unable to write to Sphero!"
|
|
151
214
|
end
|
|
152
215
|
end
|
|
216
|
+
|
|
217
|
+
def read_header(blocking=false)
|
|
218
|
+
begin
|
|
219
|
+
data = read_next_chunk(5, blocking)
|
|
220
|
+
return nil unless data && data.length == 5
|
|
221
|
+
header = data.unpack 'C5'
|
|
222
|
+
rescue Errno::EBUSY
|
|
223
|
+
retry
|
|
224
|
+
rescue Exception => e
|
|
225
|
+
puts e.message
|
|
226
|
+
puts e.backtrace.inspect
|
|
227
|
+
retry
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
header
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def read_body(len, blocking=false)
|
|
234
|
+
begin
|
|
235
|
+
data = read_next_chunk(len, blocking)
|
|
236
|
+
return nil unless data && data.length == len
|
|
237
|
+
rescue Errno::EBUSY
|
|
238
|
+
retry
|
|
239
|
+
rescue Exception => e
|
|
240
|
+
puts e.message
|
|
241
|
+
puts e.backtrace.inspect
|
|
242
|
+
retry
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
data
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def read_next_chunk(len, blocking=false)
|
|
249
|
+
begin
|
|
250
|
+
if blocking || is_windows?
|
|
251
|
+
rs, ws, = IO.select([@sp], [], [], 20)
|
|
252
|
+
data = @sp.read(len)
|
|
253
|
+
return nil unless data && data.length == len
|
|
254
|
+
else
|
|
255
|
+
data = @sp.read_nonblock(len)
|
|
256
|
+
end
|
|
257
|
+
rescue Errno::EBUSY
|
|
258
|
+
retry
|
|
259
|
+
rescue Exception => e
|
|
260
|
+
puts e.message
|
|
261
|
+
puts e.backtrace.inspect
|
|
262
|
+
return nil
|
|
263
|
+
end
|
|
264
|
+
data
|
|
265
|
+
end
|
|
153
266
|
end
|
|
154
267
|
|
data/test/test_sphero.rb
CHANGED
|
@@ -3,11 +3,12 @@ require 'sphero'
|
|
|
3
3
|
require 'mocha/setup'
|
|
4
4
|
|
|
5
5
|
class TestSphero < MiniTest::Unit::TestCase
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
def setup
|
|
7
|
+
Sphero.any_instance.stubs(:initialize_serialport)
|
|
8
|
+
Sphero.any_instance.stubs(:initialize_socket)
|
|
9
|
+
@sphero = Sphero.new 'port123'
|
|
10
|
+
@seq = 0x00
|
|
11
|
+
end
|
|
11
12
|
|
|
12
13
|
def test_start_returns_new_sphero
|
|
13
14
|
assert_kind_of Sphero, Sphero.start('someport')
|
|
@@ -22,77 +23,77 @@ class TestSphero < MiniTest::Unit::TestCase
|
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def test_ping
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
Sphero::Request::Ping.expects(:new).with(@seq)
|
|
27
|
+
@sphero.expects(:write)
|
|
28
|
+
@sphero.ping
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def test_version
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
Sphero::Request::GetVersioning.expects(:new).with(@seq)
|
|
33
|
+
@sphero.expects(:write)
|
|
34
|
+
@sphero.version
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
def test_bluetooth_info
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
Sphero::Request::GetBluetoothInfo.expects(:new).with(@seq)
|
|
39
|
+
@sphero.expects(:write)
|
|
40
|
+
@sphero.bluetooth_info
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def test_auto_reconnect=
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
@time_s = "10"
|
|
45
|
+
Sphero::Request::SetAutoReconnect.expects(:new).with(@seq, @time_s)
|
|
46
|
+
@sphero.expects(:write)
|
|
47
|
+
@sphero.auto_reconnect = @time_s
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
def test_auto_reconnect
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
@time_s = "10"
|
|
52
|
+
packet = mock 'packet'
|
|
53
|
+
packet.stubs(:time).returns(@time_s)
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
Sphero::Request::GetAutoReconnect.expects(:new).with(@seq)
|
|
56
|
+
@sphero.expects(:write).returns(packet)
|
|
57
|
+
assert_equal @sphero.auto_reconnect, @time_s
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def test_disable_auto_reconnect
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
Sphero::Request::SetAutoReconnect.expects(:new).with(@seq, 0, 0x00)
|
|
62
|
+
@sphero.expects(:write)
|
|
63
|
+
@sphero.disable_auto_reconnect
|
|
63
64
|
end
|
|
64
65
|
|
|
65
66
|
def test_power_state
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
Sphero::Request::GetPowerState.expects(:new).with(@seq)
|
|
68
|
+
@sphero.expects(:write)
|
|
69
|
+
@sphero.power_state
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
def test_sphero_sleep
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
wakeup = 1
|
|
74
|
+
macro = 2
|
|
75
|
+
Sphero::Request::Sleep.expects(:new).with(@seq, wakeup, macro)
|
|
76
|
+
@sphero.expects(:write)
|
|
77
|
+
@sphero.sphero_sleep wakeup, macro
|
|
77
78
|
end
|
|
78
79
|
|
|
79
80
|
def test_roll
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
speed = 1
|
|
82
|
+
heading = 2
|
|
83
|
+
state = 1
|
|
84
|
+
Sphero::Request::Roll.expects(:new).with(@seq, speed, heading, state)
|
|
85
|
+
@sphero.expects(:write)
|
|
86
|
+
@sphero.roll speed, heading, true
|
|
86
87
|
end
|
|
87
88
|
|
|
88
89
|
def test_stop
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
@sphero.expects(:roll).with(0, 0)
|
|
91
|
+
@sphero.stop
|
|
91
92
|
end
|
|
92
93
|
|
|
93
94
|
def test_keepgoing
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
Kernel.expects(:sleep).with(3)
|
|
96
|
+
@sphero.keep_going 3
|
|
96
97
|
end
|
|
97
98
|
|
|
98
99
|
def test_directions
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hybridgroup-sphero
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,24 +9,8 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
12
|
+
date: 2013-02-23 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
|
-
- !ruby/object:Gem::Dependency
|
|
15
|
-
name: hybridgroup-serialport
|
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
|
-
requirements:
|
|
19
|
-
- - ! '>='
|
|
20
|
-
- !ruby/object:Gem::Version
|
|
21
|
-
version: '0'
|
|
22
|
-
type: :runtime
|
|
23
|
-
prerelease: false
|
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
|
-
requirements:
|
|
27
|
-
- - ! '>='
|
|
28
|
-
- !ruby/object:Gem::Version
|
|
29
|
-
version: '0'
|
|
30
14
|
- !ruby/object:Gem::Dependency
|
|
31
15
|
name: minitest
|
|
32
16
|
requirement: !ruby/object:Gem::Requirement
|