artoo 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +9 -9
- data/README.md +18 -1
- data/Rakefile +8 -0
- data/artoo.gemspec +2 -1
- data/bin/retry.sh +0 -0
- data/bin/robi +42 -0
- data/examples/ardrone_wiiclassic.rb +0 -2
- data/examples/conway_sphero.rb +3 -3
- data/examples/hello_multiple.rb +1 -2
- data/examples/sphero2.rb +3 -3
- data/examples/wiiclassic.rb +26 -0
- data/lib/artoo/adaptors/ardrone.rb +1 -0
- data/lib/artoo/adaptors/roomba.rb +1 -1
- data/lib/artoo/adaptors/sphero.rb +1 -0
- data/lib/artoo/api.rb +17 -7
- data/lib/artoo/connection.rb +8 -0
- data/lib/artoo/device.rb +4 -0
- data/lib/artoo/drivers/wiichuck.rb +20 -73
- data/lib/artoo/drivers/wiiclassic.rb +83 -104
- data/lib/artoo/drivers/wiidriver.rb +89 -0
- data/lib/artoo/ext/actor.rb +18 -0
- data/lib/artoo/ext/timers.rb +41 -0
- data/lib/artoo/master.rb +37 -2
- data/lib/artoo/robot.rb +41 -7
- data/lib/artoo/version.rb +1 -1
- data/test/drivers/wiiclassic_test.rb +1 -6
- data/test/drivers/wiidriver_test.rb +54 -0
- data/test/master_test.rb +45 -0
- metadata +28 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7ec92eb682584d629792c9e30321ec075c44ccc
|
4
|
+
data.tar.gz: 469f3321dd5bf852382c66ecf475ad272d0913bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34faae07ab1729b9ef5dc82549ccb6e140d6452db47dc8eb2c451b12a45b645f22a7e1c47f0ca9624b20ffdcb58c2224d9cc2802590adcad76268bb05b3f9739
|
7
|
+
data.tar.gz: 0b97958c5708ecd774c3de2aa1b2c0cdc3905573f5296781cb92d29622caeb2dea6baef8c78a2a17382ddf760ecfb2d36aaca412de69d133436a8360b705cf24
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
artoo (0.
|
4
|
+
artoo (0.3.0)
|
5
5
|
active_support (~> 3.0)
|
6
|
-
celluloid-io (~> 0.
|
6
|
+
celluloid-io (~> 0.13)
|
7
7
|
multi_json (~> 1.6)
|
8
|
+
pry (~> 0.9)
|
8
9
|
rake (~> 10.0)
|
9
10
|
reel (~> 0.3)
|
10
11
|
|
@@ -16,11 +17,10 @@ GEM
|
|
16
17
|
activesupport (3.0.0)
|
17
18
|
bootstrap-sass (2.2.2.0)
|
18
19
|
sass (~> 3.2)
|
19
|
-
celluloid (0.
|
20
|
-
facter (>= 1.6.12)
|
20
|
+
celluloid (0.13.0)
|
21
21
|
timers (>= 1.0.0)
|
22
|
-
celluloid-io (0.
|
23
|
-
celluloid (
|
22
|
+
celluloid-io (0.13.1)
|
23
|
+
celluloid (>= 0.13.0)
|
24
24
|
nio4r (>= 0.4.0)
|
25
25
|
certified (0.1.1)
|
26
26
|
chunky_png (1.2.7)
|
@@ -41,7 +41,6 @@ GEM
|
|
41
41
|
eventmachine (1.0.0-java)
|
42
42
|
execjs (1.4.0)
|
43
43
|
multi_json (~> 1.0)
|
44
|
-
facter (1.6.17)
|
45
44
|
fssm (0.2.10)
|
46
45
|
guard (1.6.2)
|
47
46
|
listen (>= 0.6.0)
|
@@ -79,6 +78,7 @@ GEM
|
|
79
78
|
metaclass (~> 0.0.1)
|
80
79
|
multi_json (1.6.1)
|
81
80
|
nio4r (0.4.3)
|
81
|
+
nio4r (0.4.3-java)
|
82
82
|
pry (0.9.12)
|
83
83
|
coderay (~> 1.0.5)
|
84
84
|
method_source (~> 0.8)
|
@@ -89,7 +89,7 @@ GEM
|
|
89
89
|
slop (~> 3.4)
|
90
90
|
spoon (~> 0.0)
|
91
91
|
rack (1.5.2)
|
92
|
-
rake (10.0.
|
92
|
+
rake (10.0.4)
|
93
93
|
reel (0.3.0)
|
94
94
|
celluloid-io (>= 0.8.0)
|
95
95
|
http (>= 0.2.0)
|
@@ -108,7 +108,7 @@ GEM
|
|
108
108
|
thor (0.17.0)
|
109
109
|
tilt (1.3.3)
|
110
110
|
timers (1.1.0)
|
111
|
-
websocket_parser (0.1.
|
111
|
+
websocket_parser (0.1.2)
|
112
112
|
http
|
113
113
|
|
114
114
|
PLATFORMS
|
data/README.md
CHANGED
@@ -71,7 +71,7 @@ SPHEROS.each {|p|
|
|
71
71
|
SpheroRobot.work!(robots)
|
72
72
|
```
|
73
73
|
|
74
|
-
Ruby versions supported: Ruby 2.0, 1.9.3, JRuby 1.7.2, and Rubinius 2.0
|
74
|
+
Ruby versions supported: Ruby 2.0, Ruby 1.9.3, JRuby 1.7.2, and Rubinius 2.0-rc1
|
75
75
|
|
76
76
|
|
77
77
|
Artoo is conceptualy influenced by Sinatra (https://github.com/sinatra/sinatra) as well as borrowing some code from it.
|
@@ -100,6 +100,23 @@ end
|
|
100
100
|
|
101
101
|
Once the robot or group is working, you can view the main API page at the host and port specified.
|
102
102
|
|
103
|
+
## CLI:
|
104
|
+
|
105
|
+
Artoo includes Robi, a Command Line Interface (CLI) based on Pry (http://pryrepl.org/) to allow you to interactively control your robot.
|
106
|
+
|
107
|
+
```
|
108
|
+
robi ./examples/hello.rb
|
109
|
+
I, [2013-03-16T18:14:22.281462 #61513] INFO -- : Registering connection 'loop'...
|
110
|
+
I, [2013-03-16T18:14:22.283027 #61513] INFO -- : Preparing work...
|
111
|
+
[1] pry(main)> start
|
112
|
+
I, [2013-03-16T18:14:23.836523 #61513] INFO -- : Initializing connection loop...
|
113
|
+
I, [2013-03-16T18:14:23.842265 #61513] INFO -- : Starting work...
|
114
|
+
I, [2013-03-16T18:14:23.842879 #61513] INFO -- : Connecting to 'loop' on port '#<Artoo::Port:0xe3c0>'...
|
115
|
+
[2] pry(main)> list
|
116
|
+
#<Artoo::MainRobot:0xe5e4>
|
117
|
+
[3] pry(main)> exit
|
118
|
+
```
|
119
|
+
|
103
120
|
## Installing:
|
104
121
|
|
105
122
|
```ruby
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
|
+
require 'pry'
|
3
4
|
|
4
5
|
require 'rake/testtask'
|
5
6
|
|
@@ -9,3 +10,10 @@ Rake::TestTask.new do |t|
|
|
9
10
|
end
|
10
11
|
|
11
12
|
task :default => :test
|
13
|
+
|
14
|
+
desc "Start an interactive session with robot(s) loaded."
|
15
|
+
task :console, :file do |t, args|
|
16
|
+
robot_file = args[:file]
|
17
|
+
exec "bundle exec robi #{robot_file}"
|
18
|
+
end
|
19
|
+
|
data/artoo.gemspec
CHANGED
@@ -19,11 +19,12 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_runtime_dependency 'celluloid-io', '~> 0.
|
22
|
+
s.add_runtime_dependency 'celluloid-io', '~> 0.13'
|
23
23
|
s.add_runtime_dependency 'reel', '~> 0.3'
|
24
24
|
s.add_runtime_dependency 'multi_json', '~> 1.6'
|
25
25
|
s.add_runtime_dependency 'active_support', '~> 3.0'
|
26
26
|
s.add_runtime_dependency 'rake', '~> 10.0'
|
27
|
+
s.add_runtime_dependency 'pry', '~> 0.9'
|
27
28
|
s.add_development_dependency 'minitest', '~> 4.6'
|
28
29
|
s.add_development_dependency 'mocha', '~> 0.13'
|
29
30
|
end
|
data/bin/retry.sh
CHANGED
File without changes
|
data/bin/robi
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
Pry.config.prompt = proc { "robi> " }
|
5
|
+
|
6
|
+
command_set = Pry::CommandSet.new do
|
7
|
+
block_command "start", "Start all robots working" do
|
8
|
+
if defined?(Artoo::MainRobot)
|
9
|
+
output.puts "Starting main robot..."
|
10
|
+
Artoo::MainRobot.work! unless Artoo::MainRobot.is_running?
|
11
|
+
else
|
12
|
+
output.puts "Starting robots..."
|
13
|
+
end
|
14
|
+
|
15
|
+
Celluloid::Actor[:master].start_work
|
16
|
+
end
|
17
|
+
|
18
|
+
block_command "pause", "Pause all robots" do
|
19
|
+
output.puts "Pausing robots..."
|
20
|
+
Celluloid::Actor[:master].pause_work
|
21
|
+
end
|
22
|
+
|
23
|
+
block_command "continue", "Continue all robots" do
|
24
|
+
output.puts "Continuing robots..."
|
25
|
+
Celluloid::Actor[:master].continue_work
|
26
|
+
end
|
27
|
+
|
28
|
+
block_command "stop", "Stop all robots" do
|
29
|
+
output.puts "Not yet implemented..."
|
30
|
+
Celluloid::Actor[:master].stop_work
|
31
|
+
end
|
32
|
+
|
33
|
+
block_command "list", "List all robots" do
|
34
|
+
output.puts Celluloid::Actor[:master].robots
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Pry::Commands.import command_set
|
39
|
+
|
40
|
+
ENV["ARTOO_CLI"] = 'true'
|
41
|
+
require ARGV[0]
|
42
|
+
Pry.start
|
data/examples/conway_sphero.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'artoo/robot'
|
2
2
|
|
3
|
-
class
|
3
|
+
class ConwaySpheroRobot < Artoo::Robot
|
4
4
|
connection :sphero, :adaptor => :sphero
|
5
5
|
device :sphero, :driver => :sphero
|
6
6
|
|
@@ -59,9 +59,9 @@ SPHEROS = {"127.0.0.1:4560" => "/dev/tty.Sphero-BRG-RN-SPP",
|
|
59
59
|
"127.0.0.1:4566" => "/dev/tty.Sphero-PYG-RN-SPP"}
|
60
60
|
robots = []
|
61
61
|
SPHEROS.each_key {|p|
|
62
|
-
robots <<
|
62
|
+
robots << ConwaySpheroRobot.new(:connections =>
|
63
63
|
{:sphero =>
|
64
64
|
{:port => p}})
|
65
65
|
}
|
66
66
|
|
67
|
-
|
67
|
+
ConwaySpheroRobot.work!(robots)
|
data/examples/hello_multiple.rb
CHANGED
@@ -5,7 +5,7 @@ class HelloRobot < Artoo::Robot
|
|
5
5
|
|
6
6
|
work do
|
7
7
|
every(3.seconds) do
|
8
|
-
|
8
|
+
puts "Hello from #{name}"
|
9
9
|
end
|
10
10
|
after(10.seconds) do
|
11
11
|
puts "#{name} is alive!" if name == 'Number 5'
|
@@ -19,4 +19,3 @@ robots = []
|
|
19
19
|
end
|
20
20
|
|
21
21
|
HelloRobot.work!(robots)
|
22
|
-
sleep
|
data/examples/sphero2.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'artoo/robot'
|
2
2
|
|
3
|
-
class
|
3
|
+
class DoubleSpheroRobot < Artoo::Robot
|
4
4
|
connection :sphero, :adaptor => :sphero
|
5
5
|
device :sphero, :driver => :sphero
|
6
6
|
|
@@ -18,9 +18,9 @@ SPHEROS = {"127.0.0.1:4560" => "/dev/tty.Sphero-BRG-RN-SPP",
|
|
18
18
|
"127.0.0.1:4561" => "/dev/tty.Sphero-YBW-RN-SPP"}
|
19
19
|
robots = []
|
20
20
|
SPHEROS.each_key {|p|
|
21
|
-
robots <<
|
21
|
+
robots << DoubleSpheroRobot.new(:connections =>
|
22
22
|
{:sphero =>
|
23
23
|
{:port => p}})
|
24
24
|
}
|
25
25
|
|
26
|
-
|
26
|
+
DoubleSpheroRobot.work!(robots)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'artoo'
|
2
|
+
|
3
|
+
connection :arduino, :adaptor => :firmata, :port => "8023"
|
4
|
+
device :classic, :driver => :wiiclassic, :connection => :arduino, :interval => 0.1
|
5
|
+
|
6
|
+
work do
|
7
|
+
on classic, :a_button => proc { puts "a button pressed!" }
|
8
|
+
on classic, :b_button => proc { puts "b button pressed!" }
|
9
|
+
on classic, :x_button => proc { puts "x button pressed!" }
|
10
|
+
on classic, :y_button => proc { puts "y button pressed!" }
|
11
|
+
on classic, :home_button => proc { puts "home button pressed!" }
|
12
|
+
on classic, :start_button => proc { puts "start button pressed!" }
|
13
|
+
on classic, :select_button => proc { puts "select button pressed!" }
|
14
|
+
on classic, :left_joystick => proc { |*value|
|
15
|
+
puts "left joystick x: #{value[1][:x]}, y: #{value[1][:y]}" unless (value[1][:x] == 0 && value[1][:y] == 0)
|
16
|
+
}
|
17
|
+
on classic, :right_joystick => proc { |*value|
|
18
|
+
puts "right joystick x: #{value[1][:x]}, y: #{value[1][:y]}" unless (value[1][:x] == 0 && value[1][:y] == 0)
|
19
|
+
}
|
20
|
+
on classic, :right_trigger => proc { |*value|
|
21
|
+
puts "right trigger: #{value[1]}" unless (value[1]== 0)
|
22
|
+
}
|
23
|
+
on classic, :left_trigger => proc { |*value|
|
24
|
+
puts "left trigger: #{value[1]}" unless (value[1]== 0)
|
25
|
+
}
|
26
|
+
end
|
data/lib/artoo/api.rb
CHANGED
@@ -17,32 +17,42 @@ module Artoo
|
|
17
17
|
end
|
18
18
|
|
19
19
|
get '/robots' do
|
20
|
-
MultiJson.dump(
|
20
|
+
MultiJson.dump(master.robots.collect {|r|r.to_hash})
|
21
21
|
end
|
22
22
|
|
23
23
|
get '/robots/:robotid' do
|
24
|
-
|
24
|
+
master.get_robot(@params['robotid']).as_json
|
25
25
|
end
|
26
26
|
|
27
27
|
get '/robots/:robotid/devices' do
|
28
|
-
MultiJson.dump(
|
28
|
+
MultiJson.dump(master.get_robot_devices(@params['robotid']).each_value.collect {|d| d.to_hash})
|
29
29
|
end
|
30
30
|
|
31
31
|
get '/robots/:robotid/devices/:deviceid' do
|
32
|
-
|
32
|
+
device(@params['robotid'], @params['deviceid']).as_json
|
33
33
|
end
|
34
34
|
|
35
35
|
get_ws '/robots/:robotid/devices/:deviceid/events' do
|
36
|
-
DeviceEventClient.new(@req,
|
36
|
+
DeviceEventClient.new(@req, device(@params['robotid'], @params['deviceid']).event_topic_name('update'))
|
37
37
|
return nil
|
38
38
|
end
|
39
39
|
|
40
40
|
get '/robots/:robotid/connections' do
|
41
|
-
MultiJson.dump(
|
41
|
+
MultiJson.dump(master.get_robot_connections(@params['robotid']).each_value.collect {|c| c.to_hash})
|
42
42
|
end
|
43
43
|
|
44
44
|
get '/robots/:robotid/connections/:connectionid' do
|
45
|
-
|
45
|
+
master.get_robot_connection(@params['robotid'], @params['connectionid']).as_json
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def master
|
51
|
+
Actor[:master]
|
52
|
+
end
|
53
|
+
|
54
|
+
def device(robot_id, device_id)
|
55
|
+
master.get_robot_device(robot_id, device_id)
|
46
56
|
end
|
47
57
|
end
|
48
58
|
end
|
data/lib/artoo/connection.rb
CHANGED
@@ -47,6 +47,14 @@ module Artoo
|
|
47
47
|
MultiJson.dump(to_hash)
|
48
48
|
end
|
49
49
|
|
50
|
+
def to_s
|
51
|
+
"#{self.class}:0x#{self.object_id}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def inspect
|
55
|
+
"#<#{to_s}>"
|
56
|
+
end
|
57
|
+
|
50
58
|
def method_missing(method_name, *arguments, &block)
|
51
59
|
unless adaptor.connected?
|
52
60
|
Logger.warn "Cannot call unconnected adaptor '#{name}', attempting to reconnect..."
|
data/lib/artoo/device.rb
CHANGED
@@ -1,60 +1,16 @@
|
|
1
|
-
require 'artoo/drivers/
|
1
|
+
require 'artoo/drivers/wiidriver'
|
2
2
|
|
3
3
|
module Artoo
|
4
4
|
module Drivers
|
5
5
|
# Wiichuck driver behaviors for Firmata
|
6
|
-
class Wiichuck <
|
7
|
-
attr_reader :joystick
|
8
|
-
|
9
|
-
def address; 0x52; end
|
10
|
-
|
11
|
-
INITIAL_DEFAULTS = {
|
12
|
-
:sy_origin => nil,
|
13
|
-
:sx_origin => nil
|
14
|
-
}
|
15
|
-
|
16
|
-
def initialize(params={})
|
17
|
-
@joystick = INITIAL_DEFAULTS
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
def start_driver
|
22
|
-
begin
|
23
|
-
listener = ->(value) { update(value) }
|
24
|
-
connection.on("i2c_reply", listener)
|
25
|
-
|
26
|
-
connection.i2c_config(0)
|
27
|
-
every(interval) do
|
28
|
-
connection.i2c_write_request(address, 0x40, 0x00)
|
29
|
-
p
|
30
|
-
connection.i2c_write_request(address, 0x00, 0x00)
|
31
|
-
p
|
32
|
-
connection.i2c_read_request(address, 6)
|
33
|
-
p
|
34
|
-
connection.read_and_process
|
35
|
-
end
|
36
|
-
|
37
|
-
super
|
38
|
-
rescue Exception => e
|
39
|
-
p "start driver"
|
40
|
-
p e.message
|
41
|
-
p e.backtrace.inspect
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
|
6
|
+
class Wiichuck < Wiidriver
|
46
7
|
def update(value)
|
47
8
|
begin
|
48
|
-
|
49
|
-
Logger.error "Encrypted bytes from wiichuck!"
|
50
|
-
return
|
51
|
-
end
|
9
|
+
super
|
52
10
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
update_buttons(data)
|
57
|
-
update_joystick(data)
|
11
|
+
adjust_origins
|
12
|
+
update_buttons
|
13
|
+
update_joystick
|
58
14
|
|
59
15
|
rescue Exception => e
|
60
16
|
Logger.error "wiichuck update exception!"
|
@@ -63,44 +19,35 @@ module Artoo
|
|
63
19
|
end
|
64
20
|
end
|
65
21
|
|
66
|
-
def adjust_origins
|
22
|
+
def adjust_origins
|
67
23
|
set_joystick_default_value(:sy_origin, data[:sy])
|
68
24
|
set_joystick_default_value(:sx_origin, data[:sx])
|
69
25
|
end
|
70
26
|
|
71
|
-
def
|
72
|
-
joystick[joystick_axis] = default_value if joystick[joystick_axis].nil?
|
73
|
-
end
|
74
|
-
|
75
|
-
def update_buttons(data)
|
27
|
+
def update_buttons
|
76
28
|
publish(event_topic_name("c_button")) if data[:c] == true
|
77
29
|
publish(event_topic_name("z_button")) if data[:z] == true
|
78
30
|
end
|
79
31
|
|
80
|
-
def update_joystick
|
81
|
-
publish(event_topic_name("joystick"), {:x =>
|
32
|
+
def update_joystick
|
33
|
+
publish(event_topic_name("joystick"), {:x => calculate_joystick_value(:sx, :sx_origin), :y => calculate_joystick_value(:sy, :sy_origin)})
|
82
34
|
end
|
83
35
|
|
84
36
|
private
|
85
37
|
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
return ( x ^ 0x17 ) + 0x17
|
92
|
-
end
|
93
|
-
|
94
|
-
def get_value(value, index)
|
95
|
-
decode(value[:data][index])
|
38
|
+
def get_defaults
|
39
|
+
{
|
40
|
+
:sy_origin => nil,
|
41
|
+
:sx_origin => nil
|
42
|
+
}
|
96
43
|
end
|
97
44
|
|
98
|
-
def
|
45
|
+
def parse(value)
|
99
46
|
return {
|
100
|
-
:sx =>
|
101
|
-
:sy =>
|
102
|
-
:z => (
|
103
|
-
:c => (
|
47
|
+
:sx => decode_value(value, 0),
|
48
|
+
:sy => decode_value(value, 1),
|
49
|
+
:z => generate_bool(decode_value(value, 5) & 0x01),
|
50
|
+
:c => generate_bool(decode_value(value, 5) & 0x02)
|
104
51
|
}
|
105
52
|
end
|
106
53
|
end
|
@@ -1,66 +1,18 @@
|
|
1
|
-
require 'artoo/drivers/
|
1
|
+
require 'artoo/drivers/wiidriver'
|
2
2
|
|
3
3
|
module Artoo
|
4
4
|
module Drivers
|
5
5
|
# Wiiclassic driver behaviors for Firmata
|
6
|
-
class Wiiclassic <
|
7
|
-
attr_reader :joystick
|
8
|
-
|
9
|
-
def address; 0x52; end
|
10
|
-
|
11
|
-
INITIAL_DEFAULTS = {
|
12
|
-
:ry_origin => nil,
|
13
|
-
:rx_origin => nil,
|
14
|
-
:ly_origin => nil,
|
15
|
-
:lx_origin => nil,
|
16
|
-
:rt_origin => nil,
|
17
|
-
:lt_origin => nil
|
18
|
-
}
|
19
|
-
|
20
|
-
def initialize(params={})
|
21
|
-
@joystick = INITIAL_DEFAULTS
|
22
|
-
super
|
23
|
-
end
|
24
|
-
|
25
|
-
def start_driver
|
26
|
-
begin
|
27
|
-
listener = ->(value) { update(value) }
|
28
|
-
connection.on("i2c_reply", listener)
|
29
|
-
|
30
|
-
connection.i2c_config(0)
|
31
|
-
every(interval) do
|
32
|
-
connection.i2c_write_request(address, 0x40, 0x00)
|
33
|
-
p
|
34
|
-
connection.i2c_write_request(address, 0x00, 0x00)
|
35
|
-
p
|
36
|
-
connection.i2c_read_request(address, 6)
|
37
|
-
p
|
38
|
-
connection.read_and_process
|
39
|
-
end
|
40
|
-
|
41
|
-
super
|
42
|
-
rescue Exception => e
|
43
|
-
p "start driver"
|
44
|
-
p e.message
|
45
|
-
p e.backtrace.inspect
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
6
|
+
class Wiiclassic < Wiidriver
|
50
7
|
def update(value)
|
51
8
|
begin
|
52
|
-
|
53
|
-
Logger.error "Encrypted bytes from wiiclassic!"
|
54
|
-
return
|
55
|
-
end
|
56
|
-
|
57
|
-
data = parse_wiiclassic(value)
|
9
|
+
super
|
58
10
|
|
59
|
-
adjust_origins
|
60
|
-
update_buttons
|
61
|
-
update_left_joystick
|
62
|
-
update_right_joystick
|
63
|
-
update_triggers
|
11
|
+
adjust_origins
|
12
|
+
update_buttons
|
13
|
+
update_left_joystick
|
14
|
+
update_right_joystick
|
15
|
+
update_triggers
|
64
16
|
|
65
17
|
rescue Exception => e
|
66
18
|
Logger.error "wiiclassic update exception!"
|
@@ -69,7 +21,7 @@ module Artoo
|
|
69
21
|
end
|
70
22
|
end
|
71
23
|
|
72
|
-
def adjust_origins
|
24
|
+
def adjust_origins
|
73
25
|
set_joystick_default_value(:ly_origin, data[:ly])
|
74
26
|
set_joystick_default_value(:lx_origin, data[:lx])
|
75
27
|
set_joystick_default_value(:ry_origin, data[:ry])
|
@@ -78,73 +30,100 @@ module Artoo
|
|
78
30
|
set_joystick_default_value(:lt_origin, data[:lt])
|
79
31
|
end
|
80
32
|
|
81
|
-
def
|
82
|
-
|
33
|
+
def update_buttons
|
34
|
+
update_button("a_button", :a)
|
35
|
+
update_button("b_button", :b)
|
36
|
+
update_button("x_button", :x)
|
37
|
+
update_button("y_button", :y)
|
38
|
+
update_button("home_button", :h)
|
39
|
+
update_button("start_button", :+)
|
40
|
+
update_button("select_button", :-)
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_button(name, key)
|
44
|
+
publish(event_topic_name(name)) if data[key] == true
|
83
45
|
end
|
84
46
|
|
85
|
-
def
|
86
|
-
publish(event_topic_name("
|
87
|
-
publish(event_topic_name("b_button")) if data[:b] == true
|
88
|
-
publish(event_topic_name("x_button")) if data[:x] == true
|
89
|
-
publish(event_topic_name("y_button")) if data[:y] == true
|
90
|
-
publish(event_topic_name("home_button")) if data[:h] == true
|
91
|
-
publish(event_topic_name("start_button")) if data[:+] == true
|
92
|
-
publish(event_topic_name("select_button")) if data[:-] == true
|
47
|
+
def update_left_joystick
|
48
|
+
publish(event_topic_name("left_joystick"), {:x => calculate_joystick_value(:lx, :lx_origin), :y => calculate_joystick_value(:ly, :ly_origin)})
|
93
49
|
end
|
94
50
|
|
95
|
-
def
|
96
|
-
publish(event_topic_name("
|
51
|
+
def update_right_joystick
|
52
|
+
publish(event_topic_name("right_joystick"), {:x => calculate_joystick_value(:rx, :rx_origin), :y => calculate_joystick_value(:ry, :ry_origin)})
|
97
53
|
end
|
98
54
|
|
99
|
-
def
|
100
|
-
publish(event_topic_name("
|
55
|
+
def update_triggers
|
56
|
+
publish(event_topic_name("right_trigger"), calculate_joystick_value(:rt, :rt_origin))
|
57
|
+
publish(event_topic_name("left_trigger"), calculate_joystick_value(:lt, :lt_origin))
|
101
58
|
end
|
102
59
|
|
103
|
-
|
104
|
-
|
105
|
-
|
60
|
+
private
|
61
|
+
|
62
|
+
def get_defaults
|
63
|
+
{
|
64
|
+
:ry_origin => nil,
|
65
|
+
:rx_origin => nil,
|
66
|
+
:ly_origin => nil,
|
67
|
+
:lx_origin => nil,
|
68
|
+
:rt_origin => nil,
|
69
|
+
:lt_origin => nil
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse(value)
|
74
|
+
return parse_joysticks(value).
|
75
|
+
merge(parse_buttons(value)).
|
76
|
+
merge(parse_triggers(value)).
|
77
|
+
merge(parse_dpad(value)).
|
78
|
+
merge(parse_zbuttons(value))
|
106
79
|
end
|
107
80
|
|
108
|
-
|
81
|
+
def parse_joysticks(value)
|
82
|
+
{
|
83
|
+
:lx => decode_value(value, 0) & 0x3f,
|
84
|
+
:ly => decode_value(value, 1) & 0x3f,
|
85
|
+
:rx => ((decode_value(value, 0) & 0xC0) >> 2) | ((decode_value(value, 1) & 0xC0) >> 4) | (decode_value(value, 2)[7]),
|
86
|
+
:ry => decode_value(value, 2) & 0x1f
|
87
|
+
}
|
88
|
+
end
|
109
89
|
|
110
|
-
def
|
111
|
-
|
90
|
+
def parse_buttons(value)
|
91
|
+
{
|
92
|
+
:a => get_bool_decoded_value(value, 5, 4),
|
93
|
+
:b => get_bool_decoded_value(value, 5, 6),
|
94
|
+
:x => get_bool_decoded_value(value, 5, 3),
|
95
|
+
:y => get_bool_decoded_value(value, 5, 5),
|
96
|
+
:+ => get_bool_decoded_value(value, 4, 2),
|
97
|
+
:- => get_bool_decoded_value(value, 4, 4),
|
98
|
+
:h => get_bool_decoded_value(value, 4, 3)
|
99
|
+
}
|
112
100
|
end
|
113
101
|
|
114
|
-
def
|
115
|
-
|
102
|
+
def parse_triggers(value)
|
103
|
+
{
|
104
|
+
:lt => ((decode_value(value, 2) & 0x60) >> 3) | ((decode_value(value, 3) & 0xC0) >> 6),
|
105
|
+
:rt => decode_value(value, 3) & 0x1f
|
106
|
+
}
|
116
107
|
end
|
117
108
|
|
118
|
-
def
|
119
|
-
|
109
|
+
def parse_dpad(value)
|
110
|
+
{
|
111
|
+
:d_up => get_bool_decoded_value(value, 5, 0),
|
112
|
+
:d_down => get_bool_decoded_value(value, 4, 6),
|
113
|
+
:d_left => get_bool_decoded_value(value, 5, 1),
|
114
|
+
:d_right => get_bool_decoded_value(value, 4, 7)
|
115
|
+
}
|
120
116
|
end
|
121
117
|
|
122
|
-
def
|
123
|
-
|
124
|
-
:
|
125
|
-
:
|
126
|
-
:rx => ((get_value(value, 0) & 0xC0) >> 2) | ((get_value(value, 1) & 0xC0) >> 4) | (get_value(value, 2)[7]),
|
127
|
-
:ry => get_value(value, 2) & 0x1f,
|
128
|
-
:lt => ((get_value(value, 2) & 0x60) >> 3) | ((get_value(value, 3) & 0xC0) >> 6),
|
129
|
-
:rt => get_value(value, 3) & 0x1f,
|
130
|
-
:d_up => generate_bool(get_value(value, 5)[0]),
|
131
|
-
:d_down => generate_bool(get_value(value, 4)[6]),
|
132
|
-
:d_left => generate_bool(get_value(value, 5)[1]),
|
133
|
-
:d_right => generate_bool(get_value(value, 4)[7]),
|
134
|
-
:zr => generate_bool(get_value(value, 5)[2]),
|
135
|
-
:zl => generate_bool(get_value(value, 5)[7]),
|
136
|
-
:a => generate_bool(get_value(value, 5)[4]),
|
137
|
-
:b => generate_bool(get_value(value, 5)[6]),
|
138
|
-
:x => generate_bool(get_value(value, 5)[3]),
|
139
|
-
:y => generate_bool(get_value(value, 5)[5]),
|
140
|
-
:+ => generate_bool(get_value(value, 4)[2]),
|
141
|
-
:- => generate_bool(get_value(value, 4)[4]),
|
142
|
-
:h => generate_bool(get_value(value, 4)[3]),
|
118
|
+
def parse_zbuttons(value)
|
119
|
+
{
|
120
|
+
:zr => get_bool_decoded_value(value, 5, 2),
|
121
|
+
:zl => get_bool_decoded_value(value, 5, 7)
|
143
122
|
}
|
144
123
|
end
|
145
124
|
|
146
|
-
def
|
147
|
-
value
|
125
|
+
def get_bool_decoded_value(value, offset1, offset2)
|
126
|
+
generate_bool(decode_value(value, offset1)[offset2])
|
148
127
|
end
|
149
128
|
end
|
150
129
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Wii-based controller shared driver behaviors for Firmata
|
6
|
+
class Wiidriver < Driver
|
7
|
+
attr_reader :joystick, :data
|
8
|
+
|
9
|
+
def address; 0x52; end
|
10
|
+
|
11
|
+
def initialize(params={})
|
12
|
+
@joystick = get_defaults
|
13
|
+
@data = {}
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def start_driver
|
18
|
+
begin
|
19
|
+
listener = ->(value) { update(value) }
|
20
|
+
connection.on("i2c_reply", listener)
|
21
|
+
|
22
|
+
connection.i2c_config(0)
|
23
|
+
every(interval) do
|
24
|
+
connection.i2c_write_request(address, 0x40, 0x00)
|
25
|
+
p
|
26
|
+
connection.i2c_write_request(address, 0x00, 0x00)
|
27
|
+
p
|
28
|
+
connection.i2c_read_request(address, 6)
|
29
|
+
p
|
30
|
+
connection.read_and_process
|
31
|
+
end
|
32
|
+
|
33
|
+
super
|
34
|
+
rescue Exception => e
|
35
|
+
p "start driver"
|
36
|
+
p e.message
|
37
|
+
p e.backtrace.inspect
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def update(value)
|
42
|
+
if encrypted?(value)
|
43
|
+
Logger.error "Encrypted bytes from wii device!"
|
44
|
+
raise "Encrypted bytes from wii device!"
|
45
|
+
end
|
46
|
+
|
47
|
+
@data = parse(value)
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def get_defaults
|
53
|
+
{}
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse
|
57
|
+
{}
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_joystick_default_value(joystick_axis, default_value)
|
61
|
+
joystick[joystick_axis] = default_value if joystick[joystick_axis].nil?
|
62
|
+
end
|
63
|
+
|
64
|
+
def calculate_joystick_value(axis, origin)
|
65
|
+
data[axis] - joystick[origin]
|
66
|
+
end
|
67
|
+
|
68
|
+
def encrypted?(value)
|
69
|
+
[[0, 1], [2, 3], [4, 5]].all? {|a| get_value(value, a[0]) == get_value(value, a[1]) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def decode(x)
|
73
|
+
return ( x ^ 0x17 ) + 0x17
|
74
|
+
end
|
75
|
+
|
76
|
+
def decode_value(value, index)
|
77
|
+
decode(get_value(value, index))
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_value(value, index)
|
81
|
+
value[:data][index]
|
82
|
+
end
|
83
|
+
|
84
|
+
def generate_bool(value)
|
85
|
+
value == 0 ? true : false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# monkeypatches for Celluloid Actor class
|
2
|
+
module Celluloid
|
3
|
+
def timers
|
4
|
+
Actor.timers
|
5
|
+
end
|
6
|
+
|
7
|
+
class Actor
|
8
|
+
attr_accessor :timers
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def timers
|
12
|
+
actor = Thread.current[:celluloid_actor]
|
13
|
+
raise NotActorError, "not in actor scope" unless actor
|
14
|
+
actor.timers
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# monkeypatches for Timers & Timer classes used by Celluloid
|
2
|
+
class Timers
|
3
|
+
def initialize
|
4
|
+
@timers = SortedSet.new
|
5
|
+
@paused_timers = SortedSet.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def pause(timer = nil)
|
9
|
+
return pause_all if timer.nil?
|
10
|
+
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
11
|
+
@timers.delete timer
|
12
|
+
@paused_timers.add timer
|
13
|
+
end
|
14
|
+
|
15
|
+
def pause_all
|
16
|
+
@timers.each {|timer| timer.pause}
|
17
|
+
end
|
18
|
+
|
19
|
+
def continue(timer = nil)
|
20
|
+
return continue_all if timer.nil?
|
21
|
+
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
22
|
+
@paused_timers.delete timer
|
23
|
+
@timers.add timer
|
24
|
+
end
|
25
|
+
|
26
|
+
def continue_all
|
27
|
+
@paused_timers.each {|timer| timer.continue}
|
28
|
+
end
|
29
|
+
|
30
|
+
class Timer
|
31
|
+
# Pause this timer
|
32
|
+
def pause
|
33
|
+
@timers.pause self
|
34
|
+
end
|
35
|
+
|
36
|
+
# Continue this timer
|
37
|
+
def continue
|
38
|
+
@timers.continue self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/artoo/master.rb
CHANGED
@@ -9,8 +9,43 @@ module Artoo
|
|
9
9
|
@robots = bots
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def robot(name)
|
13
|
+
robots.find {|r| r.name == name}
|
14
|
+
end
|
15
|
+
|
16
|
+
def robot_devices(name)
|
17
|
+
robot(name).devices
|
18
|
+
end
|
19
|
+
|
20
|
+
def robot_device(name, device_id)
|
21
|
+
robot_devices(name)[device_id.intern]
|
22
|
+
end
|
23
|
+
|
24
|
+
def robot_connections(name)
|
25
|
+
robot(name).connections
|
26
|
+
end
|
27
|
+
|
28
|
+
def robot_connection(robot_id, connection_id)
|
29
|
+
robot_connections(robot_id)[connection_id.intern]
|
30
|
+
end
|
31
|
+
|
32
|
+
def start_work
|
33
|
+
robots.each {|r| r.async.work} unless Artoo::Robot.is_running?
|
34
|
+
end
|
35
|
+
|
36
|
+
def pause_work
|
37
|
+
robots.each {|r|
|
38
|
+
Logger.info "pausing #{r.name}"
|
39
|
+
r.async.pause_work
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def continue_work
|
44
|
+
robots.each {|r| r.async.continue_work}
|
45
|
+
end
|
46
|
+
|
47
|
+
def stop_work
|
48
|
+
#robots.each {|r| r.async.stop_work} unless !Artoo::Robot.is_running?
|
14
49
|
end
|
15
50
|
end
|
16
51
|
end
|
data/lib/artoo/robot.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
require 'celluloid/autostart'
|
1
2
|
require 'celluloid/io'
|
2
3
|
require 'multi_json'
|
4
|
+
require 'artoo/ext/timers'
|
5
|
+
require 'artoo/ext/actor'
|
3
6
|
|
4
7
|
require 'artoo/basic'
|
5
8
|
require 'artoo/connection'
|
@@ -10,6 +13,7 @@ require 'artoo/master'
|
|
10
13
|
require 'artoo/port'
|
11
14
|
require 'artoo/utility'
|
12
15
|
|
16
|
+
|
13
17
|
module Artoo
|
14
18
|
# The most important class used by Artoo is Robot. This represents the primary
|
15
19
|
# interface for interacting with a collection of physical computing capabilities.
|
@@ -29,7 +33,7 @@ module Artoo
|
|
29
33
|
end
|
30
34
|
|
31
35
|
class << self
|
32
|
-
attr_accessor :device_types, :working_code,
|
36
|
+
attr_accessor :device_types, :working_code, :running,
|
33
37
|
:use_api, :api_host, :api_port
|
34
38
|
|
35
39
|
def connection_types
|
@@ -80,6 +84,18 @@ module Artoo
|
|
80
84
|
# an array of existing instances
|
81
85
|
# or, a new instance can be created
|
82
86
|
def work!(robot=nil)
|
87
|
+
return if !test? && is_running?
|
88
|
+
prepare_robots(robot)
|
89
|
+
|
90
|
+
unless cli?
|
91
|
+
Celluloid::Actor[:api] = Api.new(self.api_host, self.api_port) if self.use_api
|
92
|
+
Celluloid::Actor[:master].start_work
|
93
|
+
self.running = true
|
94
|
+
sleep # sleep main thread, and let the work commence!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def prepare_robots(robot=nil)
|
83
99
|
if robot.respond_to?(:work)
|
84
100
|
robots = [robot]
|
85
101
|
elsif robot.kind_of?(Array)
|
@@ -88,17 +104,21 @@ module Artoo
|
|
88
104
|
robots = [self.new]
|
89
105
|
end
|
90
106
|
|
91
|
-
robots.each {|r| r.async.work}
|
92
|
-
|
93
107
|
Celluloid::Actor[:master] = Master.new(robots)
|
94
|
-
Celluloid::Actor[:api] = Api.new(self.api_host, self.api_port) if self.use_api
|
95
|
-
|
96
|
-
sleep # sleep main thread, and let the work commence!
|
97
108
|
end
|
98
109
|
|
99
110
|
def test?
|
100
111
|
ENV["ARTOO_TEST"] == 'true'
|
101
112
|
end
|
113
|
+
|
114
|
+
def cli?
|
115
|
+
ENV["ARTOO_CLI"] == 'true'
|
116
|
+
end
|
117
|
+
|
118
|
+
def is_running?
|
119
|
+
self.running ||= false
|
120
|
+
self.running == true
|
121
|
+
end
|
102
122
|
end
|
103
123
|
|
104
124
|
def safe_name
|
@@ -121,12 +141,22 @@ module Artoo
|
|
121
141
|
execute_working_code
|
122
142
|
end
|
123
143
|
|
144
|
+
def pause_work
|
145
|
+
Logger.info "Pausing work..."
|
146
|
+
current_instance.timers.pause
|
147
|
+
end
|
148
|
+
|
149
|
+
def continue_work
|
150
|
+
Logger.info "Continuing work..."
|
151
|
+
current_instance.timers.continue
|
152
|
+
end
|
153
|
+
|
124
154
|
def disconnect
|
125
155
|
connections.each {|k, c| c.async.disconnect}
|
126
156
|
end
|
127
157
|
|
128
158
|
def default_connection
|
129
|
-
connections
|
159
|
+
connections.values.first
|
130
160
|
end
|
131
161
|
|
132
162
|
def connection_types
|
@@ -153,6 +183,10 @@ module Artoo
|
|
153
183
|
MultiJson.dump(to_hash)
|
154
184
|
end
|
155
185
|
|
186
|
+
def inspect
|
187
|
+
"#<Robot #{object_id}>"
|
188
|
+
end
|
189
|
+
|
156
190
|
private
|
157
191
|
|
158
192
|
def initialize_connections(params={})
|
data/lib/artoo/version.rb
CHANGED
@@ -7,10 +7,5 @@ describe Artoo::Drivers::Wiiclassic do
|
|
7
7
|
@driver = Artoo::Drivers::Wiiclassic.new(:parent => @device)
|
8
8
|
end
|
9
9
|
|
10
|
-
it 'must
|
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
|
10
|
+
it 'must do things'
|
16
11
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
require 'artoo/drivers/wiidriver'
|
3
|
+
|
4
|
+
class Artoo::Drivers::Wiidriver
|
5
|
+
public :set_joystick_default_value, :calculate_joystick_value, :encrypted?,
|
6
|
+
:decode, :get_value, :generate_bool
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Artoo::Drivers::Wiidriver do
|
10
|
+
before do
|
11
|
+
@device = mock('device')
|
12
|
+
@driver = Artoo::Drivers::Wiidriver.new(:parent => @device)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'Artoo::Drivers::Wiidriver#set_joystick_default_value' do
|
16
|
+
val = "101"
|
17
|
+
@driver.joystick[:test_axis] = nil
|
18
|
+
@driver.set_joystick_default_value(:test_axis, val)
|
19
|
+
@driver.joystick[:test_axis].must_equal val
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'Artoo::Drivers::Wiidriver#calculate_joystick_value' do
|
23
|
+
@driver.data[:test_axis] = 8
|
24
|
+
@driver.joystick[:test_origin] = 5
|
25
|
+
@driver.calculate_joystick_value(:test_axis, :test_origin).must_equal 3
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'Artoo::Drivers::Wiidriver#encrypted?' do
|
29
|
+
value = {:data => [0, 0, 0, 0, 0, 0]}
|
30
|
+
@driver.encrypted?(value).must_equal true
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'Artoo::Drivers::Wiidriver#encrypted?' do
|
34
|
+
value = {:data => [1, 2, 3, 4, 5, 6]}
|
35
|
+
@driver.encrypted?(value).must_equal false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'Artoo::Drivers::Wiidriver#decode' do
|
39
|
+
@driver.decode(22).must_equal 24
|
40
|
+
@driver.decode(0).must_equal 46
|
41
|
+
@driver.decode(16).must_equal 30
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'Artoo::Drivers::Wiidriver#get_value' do
|
45
|
+
value = {:data => [1, 2, 3, 4, 5, 6], :other_data => [10, 20, 30, 40, 50, 60]}
|
46
|
+
@driver.get_value(value, 1).must_equal 2
|
47
|
+
@driver.get_value(value, 5).must_equal 6
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'Artoo::Drivers::Wiidriver#generate_bool' do
|
51
|
+
@driver.generate_bool(0).must_equal true
|
52
|
+
@driver.generate_bool(1).must_equal false
|
53
|
+
end
|
54
|
+
end
|
data/test/master_test.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/test_helper")
|
2
|
+
|
3
|
+
class MockRobot
|
4
|
+
attr_reader :name
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
def devices
|
11
|
+
["#{name}-device1", "#{name}-device2", "#{name}-device3"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def connections
|
15
|
+
["#{name}-connection1", "#{name}-connection2", "#{name}-connection3"]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Artoo::Master do
|
20
|
+
before do
|
21
|
+
@robots = []
|
22
|
+
|
23
|
+
@robot1 = MockRobot.new("robot1")
|
24
|
+
@robot2 = MockRobot.new("robot2")
|
25
|
+
@robot3 = MockRobot.new("robot3")
|
26
|
+
|
27
|
+
@robots << @robot1
|
28
|
+
@robots << @robot2
|
29
|
+
@robots << @robot3
|
30
|
+
|
31
|
+
@master = Artoo::Master.new(@robots)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'Artoo::Master#robot' do
|
35
|
+
@master.robot("robot2").must_equal @robot2
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'Artoo::Master#robot_devices' do
|
39
|
+
@master.robot_devices("robot2").first.must_equal "robot2-device1"
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'Artoo::Master#robot_connections' do
|
43
|
+
@master.robot_connections("robot2").last.must_equal "robot2-connection3"
|
44
|
+
end
|
45
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: artoo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ron Evans
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-
|
15
|
+
date: 2013-04-09 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: celluloid-io
|
@@ -20,14 +20,14 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: '0.
|
23
|
+
version: '0.13'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
28
|
- - ~>
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version: '0.
|
30
|
+
version: '0.13'
|
31
31
|
- !ruby/object:Gem::Dependency
|
32
32
|
name: reel
|
33
33
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,6 +84,20 @@ dependencies:
|
|
84
84
|
- - ~>
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '10.0'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: pry
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0.9'
|
94
|
+
type: :runtime
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0.9'
|
87
101
|
- !ruby/object:Gem::Dependency
|
88
102
|
name: minitest
|
89
103
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,6 +131,7 @@ email:
|
|
117
131
|
- artoo@hybridgroup.com
|
118
132
|
executables:
|
119
133
|
- retry.sh
|
134
|
+
- robi
|
120
135
|
- sphero.sh
|
121
136
|
extensions: []
|
122
137
|
extra_rdoc_files: []
|
@@ -160,6 +175,7 @@ files:
|
|
160
175
|
- api/public/partials/robot-index.html
|
161
176
|
- artoo.gemspec
|
162
177
|
- bin/retry.sh
|
178
|
+
- bin/robi
|
163
179
|
- bin/sphero.sh
|
164
180
|
- examples/ardrone.rb
|
165
181
|
- examples/ardrone_nav.rb
|
@@ -186,6 +202,7 @@ files:
|
|
186
202
|
- examples/sphero_multiple.rb
|
187
203
|
- examples/sphero_wiichuck.rb
|
188
204
|
- examples/wiichuck.rb
|
205
|
+
- examples/wiiclassic.rb
|
189
206
|
- lib/artoo.rb
|
190
207
|
- lib/artoo/adaptors/adaptor.rb
|
191
208
|
- lib/artoo/adaptors/ardrone.rb
|
@@ -217,7 +234,10 @@ files:
|
|
217
234
|
- lib/artoo/drivers/sphero.rb
|
218
235
|
- lib/artoo/drivers/wiichuck.rb
|
219
236
|
- lib/artoo/drivers/wiiclassic.rb
|
237
|
+
- lib/artoo/drivers/wiidriver.rb
|
220
238
|
- lib/artoo/events.rb
|
239
|
+
- lib/artoo/ext/actor.rb
|
240
|
+
- lib/artoo/ext/timers.rb
|
221
241
|
- lib/artoo/main.rb
|
222
242
|
- lib/artoo/master.rb
|
223
243
|
- lib/artoo/port.rb
|
@@ -244,6 +264,8 @@ files:
|
|
244
264
|
- test/drivers/sphero_test.rb
|
245
265
|
- test/drivers/wiichuck_test.rb
|
246
266
|
- test/drivers/wiiclassic_test.rb
|
267
|
+
- test/drivers/wiidriver_test.rb
|
268
|
+
- test/master_test.rb
|
247
269
|
- test/port_test.rb
|
248
270
|
- test/robot_test.rb
|
249
271
|
- test/test_helper.rb
|
@@ -267,32 +289,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
267
289
|
version: '0'
|
268
290
|
requirements: []
|
269
291
|
rubyforge_project: artoo
|
270
|
-
rubygems_version: 2.0.
|
292
|
+
rubygems_version: 2.0.3
|
271
293
|
signing_key:
|
272
294
|
specification_version: 4
|
273
295
|
summary: Ruby-based microframework for robotics
|
274
|
-
test_files:
|
275
|
-
- test/adaptors/adaptor_test.rb
|
276
|
-
- test/adaptors/ardrone_test.rb
|
277
|
-
- test/adaptors/firmata_test.rb
|
278
|
-
- test/adaptors/loopback_test.rb
|
279
|
-
- test/adaptors/sphero_test.rb
|
280
|
-
- test/api_test.rb
|
281
|
-
- test/artoo_test.rb
|
282
|
-
- test/connection_test.rb
|
283
|
-
- test/delegator_test.rb
|
284
|
-
- test/device_test.rb
|
285
|
-
- test/drivers/ardrone_navigation_test.rb
|
286
|
-
- test/drivers/ardrone_test.rb
|
287
|
-
- test/drivers/ardrone_video_test.rb
|
288
|
-
- test/drivers/driver_test.rb
|
289
|
-
- test/drivers/led_test.rb
|
290
|
-
- test/drivers/motor_test.rb
|
291
|
-
- test/drivers/servo_test.rb
|
292
|
-
- test/drivers/sphero_test.rb
|
293
|
-
- test/drivers/wiichuck_test.rb
|
294
|
-
- test/drivers/wiiclassic_test.rb
|
295
|
-
- test/port_test.rb
|
296
|
-
- test/robot_test.rb
|
297
|
-
- test/test_helper.rb
|
298
|
-
- test/utility_test.rb
|
296
|
+
test_files: []
|