artoo 0.1.3 → 0.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.
@@ -0,0 +1,34 @@
1
+ module Artoo
2
+ module Events
3
+ # Subscribe to an event from a device
4
+ def on(device, events={})
5
+ events.each do |k, v|
6
+ subscribe("#{safe_name}_#{device.name}_#{k}", create_proxy_method(k, v))
7
+ end
8
+ end
9
+
10
+ # Create an anonymous subscription method so we can wrap the
11
+ # subscription method fire into a valid method regardless
12
+ # of where it is defined
13
+ def create_proxy_method(k, v)
14
+ proxy_method_name(k).tap do |name|
15
+ self.class.send :define_method, name do |*args|
16
+ case v
17
+ when Symbol
18
+ self.send v.to_sym, *args
19
+ when Proc
20
+ v.call(*args)
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ # A simple loop to create a 'fake' anonymous method
27
+ def proxy_method_name(k)
28
+ begin
29
+ meth = "#{k}_#{Random.rand(999)}"
30
+ end while respond_to?(meth)
31
+ meth
32
+ end
33
+ end
34
+ end
data/lib/artoo/robot.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  require 'celluloid/io'
2
2
  require 'multi_json'
3
3
 
4
+ require 'artoo/basic'
4
5
  require 'artoo/connection'
5
6
  require 'artoo/device'
7
+ require 'artoo/events'
6
8
  require 'artoo/api'
7
9
  require 'artoo/master'
8
10
  require 'artoo/port'
@@ -14,7 +16,9 @@ module Artoo
14
16
  class Robot
15
17
  include Celluloid
16
18
  include Celluloid::Notifications
19
+ extend Artoo::Basic
17
20
  include Artoo::Utility
21
+ include Artoo::Events
18
22
 
19
23
  attr_reader :connections, :devices, :name
20
24
 
@@ -25,15 +29,18 @@ module Artoo
25
29
  end
26
30
 
27
31
  class << self
28
- attr_accessor :connection_types, :device_types, :working_code,
32
+ attr_accessor :device_types, :working_code,
29
33
  :use_api, :api_host, :api_port
30
34
 
35
+ def connection_types
36
+ @@connection_types ||= []
37
+ end
38
+
31
39
  # connection to some hardware that has one or more devices via some specific protocol
32
40
  # Example:
33
41
  # connection :arduino, :adaptor => :firmata, :port => '/dev/tty.usbmodemxxxxx'
34
42
  def connection(name, params = {})
35
43
  Celluloid::Logger.info "Registering connection '#{name}'..."
36
- self.connection_types ||= []
37
44
  self.connection_types << {:name => name}.merge(params)
38
45
  end
39
46
 
@@ -92,81 +99,6 @@ module Artoo
92
99
  def test?
93
100
  ENV["ARTOO_TEST"] == 'true'
94
101
  end
95
-
96
- # Taken from Sinatra codebase
97
- # Sets an option to the given value. If the value is a proc,
98
- # the proc will be called every time the option is accessed.
99
- def set(option, value = (not_set = true), ignore_setter = false, &block)
100
- raise ArgumentError if block and !not_set
101
- value, not_set = block, false if block
102
-
103
- if not_set
104
- raise ArgumentError unless option.respond_to?(:each)
105
- option.each { |k,v| set(k, v) }
106
- return self
107
- end
108
-
109
- if respond_to?("#{option}=") and not ignore_setter
110
- return __send__("#{option}=", value)
111
- end
112
-
113
- setter = proc { |val| set option, val, true }
114
- getter = proc { value }
115
-
116
- case value
117
- when Proc
118
- getter = value
119
- when Symbol, Fixnum, FalseClass, TrueClass, NilClass
120
- getter = value.inspect
121
- when Hash
122
- setter = proc do |val|
123
- val = value.merge val if Hash === val
124
- set option, val, true
125
- end
126
- end
127
-
128
- define_singleton_method("#{option}=", setter) if setter
129
- define_singleton_method(option, getter) if getter
130
- define_singleton_method("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
131
- self
132
- end
133
-
134
- # Taken from Sinatra codebase
135
- CALLERS_TO_IGNORE = [ # :nodoc:
136
- /lib\/artoo.*\.rb$/, # artoo code
137
- /^\(.*\)$/, # generated code
138
- /rubygems\/(custom|core_ext\/kernel)_require\.rb$/, # rubygems require hacks
139
- /active_support/, # active_support require hacks
140
- /bundler(\/runtime)?\.rb/, # bundler require hacks
141
- /<internal:/, # internal in ruby >= 1.9.2
142
- /src\/kernel\/bootstrap\/[A-Z]/ # maglev kernel files
143
- ]
144
-
145
- # Taken from Sinatra codebase
146
- # Like Kernel#caller but excluding certain magic entries and without
147
- # line / method information; the resulting array contains filenames only.
148
- def caller_files
149
- cleaned_caller(1).flatten
150
- end
151
-
152
- private
153
-
154
- # Taken from Sinatra codebase
155
- def define_singleton_method(name, content = Proc.new)
156
- # replace with call to singleton_class once we're 1.9 only
157
- (class << self; self; end).class_eval do
158
- undef_method(name) if method_defined? name
159
- String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
160
- end
161
- end
162
-
163
- # Taken from Sinatra codebase
164
- # Like Kernel#caller but excluding certain magic entries
165
- def cleaned_caller(keep = 3)
166
- caller(1).
167
- map { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
168
- reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
169
- end
170
102
  end
171
103
 
172
104
  def safe_name
@@ -184,30 +116,9 @@ module Artoo
184
116
  # start doing the work
185
117
  def work
186
118
  Logger.info "Starting work..."
187
- make_connections
188
- start_devices
189
- current_instance.instance_eval(&working_code)
190
- rescue Exception => e
191
- Logger.error e.message
192
- Logger.error e.backtrace.inspect
193
- end
194
-
195
- def make_connections
196
- result = false
197
- future_connections = []
198
- # block until all connections done
199
- connections.each {|k, c| future_connections << c.future.connect}
200
- future_connections.each {|v| result = v.value}
201
- result
202
- end
203
-
204
- def start_devices
205
- result = false
206
- future_devices = []
207
- # block until all devices done
208
- devices.each {|k, d| future_devices << d.future.start_device}
209
- future_devices.each {|v| result = v.value}
210
- result
119
+ execute_startup(connections) {|c| c.future.connect}
120
+ execute_startup(devices) {|d| d.future.start_device}
121
+ execute_working_code
211
122
  end
212
123
 
213
124
  def disconnect
@@ -219,7 +130,6 @@ module Artoo
219
130
  end
220
131
 
221
132
  def connection_types
222
- current_class.connection_types ||= []
223
133
  current_class.connection_types
224
134
  end
225
135
 
@@ -232,37 +142,6 @@ module Artoo
232
142
  current_class.working_code ||= proc {puts "No work defined."}
233
143
  end
234
144
 
235
- # Subscribe to an event from a device
236
- def on(device, events={})
237
- events.each do |k, v|
238
- subscribe("#{safe_name}_#{device.name}_#{k}", create_proxy_method(k, v))
239
- end
240
- end
241
-
242
- # Create an anonymous subscription method so we can wrap the
243
- # subscription method fire into a valid method regardless
244
- # of where it is defined
245
- def create_proxy_method(k, v)
246
- proxy_method_name(k).tap do |name|
247
- self.class.send :define_method, name do |*args|
248
- case v
249
- when Symbol
250
- self.send v.to_sym, *args
251
- when Proc
252
- v.call(*args)
253
- end
254
- end
255
- end
256
- end
257
-
258
- # A simple loop to create a 'fake' anonymous method
259
- def proxy_method_name(k)
260
- begin
261
- meth = "#{k}_#{Random.rand(999)}"
262
- end while respond_to?(meth)
263
- meth
264
- end
265
-
266
145
  def to_hash
267
146
  {:name => name,
268
147
  :connections => connections.each_value.collect {|c|c.to_hash},
@@ -295,5 +174,17 @@ module Artoo
295
174
  @devices[d.name.intern] = d
296
175
  }
297
176
  end
177
+
178
+ def execute_startup(things, &block)
179
+ future_things = things.each_value.collect {|t| yield(t)}
180
+ future_things.each {|v| result = v.value}
181
+ end
182
+
183
+ def execute_working_code
184
+ current_instance.instance_eval(&working_code)
185
+ rescue Exception => e
186
+ Logger.error e.message
187
+ Logger.error e.backtrace.inspect
188
+ end
298
189
  end
299
- end
190
+ end
data/lib/artoo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Artoo
2
2
  unless const_defined?('VERSION')
3
- VERSION = "0.1.3"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
+ require 'artoo/drivers/motor'
3
+
4
+ describe Artoo::Drivers::Motor do
5
+ before do
6
+ @device = mock('device')
7
+ @device.stubs(:pin).returns([2, 3, 4])
8
+ @motor = Artoo::Drivers::Motor.new(:parent => @device)
9
+
10
+ @connection = mock('connection')
11
+ @connection.stubs(:set_pin_mode)
12
+ @connection.stubs(:analog_write)
13
+ @connection.stubs(:digital_write)
14
+ @device.stubs(:connection).returns(@connection)
15
+ end
16
+
17
+ it 'Motor#speed must be valid' do
18
+ invalid_speed = lambda { @motor2 = Artoo::Drivers::Motor.new(:parent => @device); @motor2.speed("ads") }
19
+ invalid_speed.must_raise RuntimeError
20
+ error = invalid_speed.call rescue $!
21
+ error.message.must_equal 'Motor speed must be an integer between 0-255'
22
+ end
23
+
24
+ it 'Motor#forward' do
25
+ @motor.wrapped_object.expects(:set_legs)
26
+ @motor.forward(100)
27
+ @motor.current_speed.must_equal 100
28
+ end
29
+
30
+ it 'Motor#backward' do
31
+ @motor.wrapped_object.expects(:set_legs)
32
+ @motor.backward(100)
33
+ @motor.current_speed.must_equal 100
34
+ end
35
+
36
+ it 'Motor#stop' do
37
+ @motor.stop
38
+ @motor.current_speed.must_equal 0
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
+ require 'artoo/drivers/servo'
3
+
4
+ describe Artoo::Drivers::Servo do
5
+ before do
6
+ @device = mock('device')
7
+ @device.stubs(:pin).returns(3)
8
+ @servo = Artoo::Drivers::Servo.new(:parent => @device)
9
+
10
+ @connection = mock('connection')
11
+ @connection.stubs(:set_pin_mode)
12
+ @connection.stubs(:analog_write)
13
+ # @connection.stubs(:digital_write)
14
+ @device.stubs(:connection).returns(@connection)
15
+ end
16
+
17
+ it "Servo#angle_to_span" do
18
+ @servo.angle_to_span(0).must_equal 0
19
+ @servo.angle_to_span(30).must_equal 42
20
+ @servo.angle_to_span(90).must_equal 127
21
+ @servo.angle_to_span(180).must_equal 255
22
+ end
23
+
24
+ it 'Servo#move must be valid' do
25
+ invalid_angle = lambda { @servo2 = Artoo::Drivers::Servo.new(:parent => @device); @servo2.move(360) }
26
+ invalid_angle.must_raise RuntimeError
27
+ error = invalid_angle.call rescue $!
28
+ error.message.must_equal 'Servo angle must be an integer between 0-180'
29
+ end
30
+
31
+ it 'Servo#min' do
32
+ @servo.min
33
+ @servo.current_angle.must_equal 0
34
+ end
35
+
36
+ it 'Servo#center' do
37
+ @servo.center
38
+ @servo.current_angle.must_equal 90
39
+ end
40
+
41
+ it 'Servo#max' do
42
+ @servo.max
43
+ @servo.current_angle.must_equal 180
44
+ end
45
+ end
@@ -7,5 +7,10 @@ describe Artoo::Drivers::Wiiclassic do
7
7
  @driver = Artoo::Drivers::Wiiclassic.new(:parent => @device)
8
8
  end
9
9
 
10
- it 'must do things'
10
+ it 'must Artoo::Drivers::Wiiclassic#set_joystick_default_value' do
11
+ val = "101"
12
+ @driver.joystick[:test_axis] = nil
13
+ @driver.set_joystick_default_value(:test_axis, val)
14
+ @driver.joystick[:test_axis].must_equal val
15
+ end
11
16
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: artoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ron Evans
@@ -13,8 +12,106 @@ authors:
13
12
  autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
- date: 2013-02-26 00:00:00.000000000 Z
17
- dependencies: []
15
+ date: 2013-03-08 00:00:00.000000000 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: celluloid-io
19
+ requirement: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: '0.12'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '0.12'
31
+ - !ruby/object:Gem::Dependency
32
+ name: reel
33
+ requirement: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '0.3'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: '0.3'
45
+ - !ruby/object:Gem::Dependency
46
+ name: multi_json
47
+ requirement: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ~>
50
+ - !ruby/object:Gem::Version
51
+ version: '1.6'
52
+ type: :runtime
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ version: '1.6'
59
+ - !ruby/object:Gem::Dependency
60
+ name: active_support
61
+ requirement: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '3.0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ version: '3.0'
73
+ - !ruby/object:Gem::Dependency
74
+ name: rake
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: '10.0'
80
+ type: :runtime
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: '10.0'
87
+ - !ruby/object:Gem::Dependency
88
+ name: minitest
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '4.6'
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ~>
99
+ - !ruby/object:Gem::Version
100
+ version: '4.6'
101
+ - !ruby/object:Gem::Dependency
102
+ name: mocha
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ~>
106
+ - !ruby/object:Gem::Version
107
+ version: '0.13'
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ~>
113
+ - !ruby/object:Gem::Version
114
+ version: '0.13'
18
115
  description: Ruby-based microframework for robotics
19
116
  email:
20
117
  - artoo@hybridgroup.com
@@ -25,6 +122,7 @@ extensions: []
25
122
  extra_rdoc_files: []
26
123
  files:
27
124
  - .gitignore
125
+ - .travis.yml
28
126
  - Gemfile
29
127
  - Gemfile.lock
30
128
  - Guardfile
@@ -70,6 +168,7 @@ files:
70
168
  - examples/ardrone_nav_wiiclassic.rb
71
169
  - examples/ardrone_video.rb
72
170
  - examples/ardrone_wiiclassic.rb
171
+ - examples/christmas_roomba.rb
73
172
  - examples/conway_sphero.rb
74
173
  - examples/firmata.rb
75
174
  - examples/firmata_button.rb
@@ -85,6 +184,8 @@ files:
85
184
  - examples/sphero_firmata.rb
86
185
  - examples/sphero_messages.rb
87
186
  - examples/sphero_multiple.rb
187
+ - examples/sphero_wiichuck.rb
188
+ - examples/wiichuck.rb
88
189
  - lib/artoo.rb
89
190
  - lib/artoo/adaptors/adaptor.rb
90
191
  - lib/artoo/adaptors/ardrone.rb
@@ -92,9 +193,11 @@ files:
92
193
  - lib/artoo/adaptors/ardrone_video.rb
93
194
  - lib/artoo/adaptors/firmata.rb
94
195
  - lib/artoo/adaptors/loopback.rb
196
+ - lib/artoo/adaptors/roomba.rb
95
197
  - lib/artoo/adaptors/sphero.rb
96
198
  - lib/artoo/api.rb
97
199
  - lib/artoo/api_route_helpers.rb
200
+ - lib/artoo/basic.rb
98
201
  - lib/artoo/connection.rb
99
202
  - lib/artoo/delegator.rb
100
203
  - lib/artoo/device.rb
@@ -105,12 +208,16 @@ files:
105
208
  - lib/artoo/drivers/button.rb
106
209
  - lib/artoo/drivers/driver.rb
107
210
  - lib/artoo/drivers/led.rb
211
+ - lib/artoo/drivers/motor.rb
108
212
  - lib/artoo/drivers/passthru.rb
109
213
  - lib/artoo/drivers/pinger.rb
110
214
  - lib/artoo/drivers/pinger2.rb
215
+ - lib/artoo/drivers/roomba.rb
216
+ - lib/artoo/drivers/servo.rb
111
217
  - lib/artoo/drivers/sphero.rb
112
218
  - lib/artoo/drivers/wiichuck.rb
113
219
  - lib/artoo/drivers/wiiclassic.rb
220
+ - lib/artoo/events.rb
114
221
  - lib/artoo/main.rb
115
222
  - lib/artoo/master.rb
116
223
  - lib/artoo/port.rb
@@ -132,6 +239,8 @@ files:
132
239
  - test/drivers/ardrone_video_test.rb
133
240
  - test/drivers/driver_test.rb
134
241
  - test/drivers/led_test.rb
242
+ - test/drivers/motor_test.rb
243
+ - test/drivers/servo_test.rb
135
244
  - test/drivers/sphero_test.rb
136
245
  - test/drivers/wiichuck_test.rb
137
246
  - test/drivers/wiiclassic_test.rb
@@ -141,33 +250,26 @@ files:
141
250
  - test/utility_test.rb
142
251
  homepage: https://github.com/hybridgroup/artoo
143
252
  licenses: []
253
+ metadata: {}
144
254
  post_install_message:
145
255
  rdoc_options: []
146
256
  require_paths:
147
257
  - lib
148
258
  required_ruby_version: !ruby/object:Gem::Requirement
149
- none: false
150
259
  requirements:
151
- - - ! '>='
260
+ - - '>='
152
261
  - !ruby/object:Gem::Version
153
262
  version: '0'
154
- segments:
155
- - 0
156
- hash: -4461140220613461358
157
263
  required_rubygems_version: !ruby/object:Gem::Requirement
158
- none: false
159
264
  requirements:
160
- - - ! '>='
265
+ - - '>='
161
266
  - !ruby/object:Gem::Version
162
267
  version: '0'
163
- segments:
164
- - 0
165
- hash: -4461140220613461358
166
268
  requirements: []
167
269
  rubyforge_project: artoo
168
- rubygems_version: 1.8.25
270
+ rubygems_version: 2.0.0
169
271
  signing_key:
170
- specification_version: 3
272
+ specification_version: 4
171
273
  summary: Ruby-based microframework for robotics
172
274
  test_files:
173
275
  - test/adaptors/adaptor_test.rb
@@ -185,6 +287,8 @@ test_files:
185
287
  - test/drivers/ardrone_video_test.rb
186
288
  - test/drivers/driver_test.rb
187
289
  - test/drivers/led_test.rb
290
+ - test/drivers/motor_test.rb
291
+ - test/drivers/servo_test.rb
188
292
  - test/drivers/sphero_test.rb
189
293
  - test/drivers/wiichuck_test.rb
190
294
  - test/drivers/wiiclassic_test.rb