artoo 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +2 -2
- data/README.md +20 -0
- data/api/assets/javascripts/artoo/controllers/robot.js.coffee +5 -1
- data/api/public/core.js +7 -0
- data/api/public/partials/robot-detail.html +7 -7
- data/examples/ardrone.rb +2 -2
- data/examples/ardrone_nav.rb +2 -2
- data/examples/ardrone_nav_video_wii.rb +64 -0
- data/examples/ardrone_nav_wiiclassic.rb +61 -0
- data/examples/ardrone_wiiclassic.rb +48 -0
- data/examples/conway_sphero.rb +9 -7
- data/examples/firmata.rb +1 -1
- data/examples/firmata_button.rb +1 -1
- data/examples/sphero.rb +2 -2
- data/examples/sphero2.rb +26 -0
- data/examples/sphero_color.rb +1 -1
- data/examples/sphero_messages.rb +2 -2
- data/examples/sphero_multiple.rb +10 -15
- data/lib/artoo/drivers/sphero.rb +35 -33
- data/lib/artoo/drivers/wiiclassic.rb +47 -37
- data/lib/artoo/robot.rb +7 -7
- data/lib/artoo/version.rb +1 -1
- data/test/drivers/wiiclassic_test.rb +11 -0
- metadata +26 -16
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
artoo (0.1.
|
4
|
+
artoo (0.1.3)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -64,7 +64,7 @@ GEM
|
|
64
64
|
hybridgroup-argus (0.2.0)
|
65
65
|
hybridgroup-firmata (0.3.0)
|
66
66
|
event_spitter
|
67
|
-
hybridgroup-sphero (1.
|
67
|
+
hybridgroup-sphero (1.2.0)
|
68
68
|
listen (0.7.2)
|
69
69
|
lumberjack (1.0.2)
|
70
70
|
metaclass (0.0.1)
|
data/README.md
CHANGED
@@ -75,6 +75,26 @@ Artoo is conceptualy influenced by Sinatra (https://github.com/sinatra/sinatra)
|
|
75
75
|
|
76
76
|
Artoo provides a robust actor-based messaging architecture, that can support fully multi-threaded operation and high-concurrency, as long as it is supported by the Ruby version in which it is executing. To a large extent, this is due to being built on top of Celluloid (https://github.com/celluloid/celluloid) and Celluloid::IO (https://github.com/celluloid/celluloid-io).
|
77
77
|
|
78
|
+
## API:
|
79
|
+
|
80
|
+
Artoo includes a RESTful API to query the status of any robot running within a group, including the connection and device status, and device streaming data via websockets.
|
81
|
+
|
82
|
+
To activate the API, use the `api` command like this:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
require 'artoo'
|
86
|
+
|
87
|
+
connection :loop
|
88
|
+
device :passthru
|
89
|
+
api :host => '127.0.0.1', :port => '4321'
|
90
|
+
|
91
|
+
work do
|
92
|
+
puts "Hello from the API running at #{api_host}:#{api_port}..."
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
Once the robot or group is working, you can view the main API page at the host and port specified.
|
97
|
+
|
78
98
|
## Installing:
|
79
99
|
|
80
100
|
```ruby
|
@@ -1,3 +1,5 @@
|
|
1
|
+
window.driversWithOutput = ["Pinger", "Pinger2", "ardrone_navigation", "wiiclassic"]
|
2
|
+
|
1
3
|
@RobotIndexCtrl = ($scope, $http, $location, $route) ->
|
2
4
|
$http.get('/robots').success (data)->
|
3
5
|
$scope.robots = data
|
@@ -13,6 +15,9 @@
|
|
13
15
|
$scope.deviceDetail = data
|
14
16
|
device.console()
|
15
17
|
|
18
|
+
$scope.driverHasOutput = (driverId)->
|
19
|
+
true if $.inArray(driverId, window.driversWithOutput) != -1
|
20
|
+
|
16
21
|
device = console: ->
|
17
22
|
window.ws.close() if window.ws
|
18
23
|
window.ws = new WebSocket("ws://localhost:4321/robots/" + $scope.robot.name + "/devices/" + $scope.deviceDetail.name + "/events")
|
@@ -20,7 +25,6 @@
|
|
20
25
|
ws.onmessage = (evt)->
|
21
26
|
$(".console code").prepend(evt.data + "\n")
|
22
27
|
|
23
|
-
|
24
28
|
$scope.isConnected = (connection) ->
|
25
29
|
"connected" if connection && connection.connected
|
26
30
|
|
data/api/public/core.js
CHANGED
@@ -212,6 +212,8 @@ ngChange:rd,required:dc,ngRequired:dc,ngValue:ud}).directive(lb).directive(ec);a
|
|
212
212
|
}).call(this);
|
213
213
|
(function() {
|
214
214
|
|
215
|
+
window.driversWithOutput = ["Pinger", "Pinger2", "ardrone_navigation", "wiiclassic"];
|
216
|
+
|
215
217
|
this.RobotIndexCtrl = function($scope, $http, $location, $route) {
|
216
218
|
$http.get('/robots').success(function(data) {
|
217
219
|
return $scope.robots = data;
|
@@ -232,6 +234,11 @@ ngChange:rd,required:dc,ngRequired:dc,ngValue:ud}).directive(lb).directive(ec);a
|
|
232
234
|
return device.console();
|
233
235
|
});
|
234
236
|
};
|
237
|
+
$scope.driverHasOutput = function(driverId) {
|
238
|
+
if ($.inArray(driverId, window.driversWithOutput) !== -1) {
|
239
|
+
return true;
|
240
|
+
}
|
241
|
+
};
|
235
242
|
device = {
|
236
243
|
console: function() {
|
237
244
|
if (window.ws) {
|
@@ -22,22 +22,22 @@
|
|
22
22
|
|
23
23
|
<div class="container device details" ng-show='deviceDetail'>
|
24
24
|
<div class="row-fluid">
|
25
|
-
<div class="
|
26
|
-
|
25
|
+
<div class="span2">
|
26
|
+
<b><span class="name">{{deviceDetail.name}}</span></b>
|
27
|
+
</div>
|
28
|
+
<div class="span10">
|
27
29
|
<b>
|
28
|
-
<span class="name">{{deviceDetail.name}}</span>
|
29
|
-
{{device}}
|
30
30
|
<dl class="controls">
|
31
31
|
<span ng-show='deviceDetail.pin'>
|
32
32
|
<dt><i class="icon-fighter-jet"></i> </dt>
|
33
33
|
<dd>{{ deviceDetail.pin }}</dd>
|
34
34
|
</span>
|
35
35
|
<span ng-show='deviceDetail.driver'>
|
36
|
-
<dt><i class="icon-
|
36
|
+
<dt><i class="icon-hdd"></i></dt>
|
37
37
|
<dd>{{ deviceDetail.driver }}</dd>
|
38
38
|
</span>
|
39
39
|
<span ng-show='deviceDetail.adaptor'>
|
40
|
-
<dt><i class="icon-
|
40
|
+
<dt><i class="icon-resize-horizontal"></i></dt>
|
41
41
|
<dd>{{ deviceDetail.adaptor }}</dd>
|
42
42
|
</span>
|
43
43
|
<span ng-show='deviceDetail.connection'>
|
@@ -48,7 +48,7 @@
|
|
48
48
|
</b>
|
49
49
|
</div>
|
50
50
|
</div>
|
51
|
-
<div class="row-fluid content">
|
51
|
+
<div class="row-fluid content" ng-show="driverHasOutput( deviceDetail.driver )" >
|
52
52
|
<div class="console">
|
53
53
|
<code></code>
|
54
54
|
</div>
|
data/examples/ardrone.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
|
4
4
|
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
|
-
|
5
|
+
|
6
6
|
work do
|
7
7
|
drone.start
|
8
8
|
drone.take_off
|
data/examples/ardrone_nav.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
|
4
4
|
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
5
|
|
6
|
-
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.
|
6
|
+
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.43:5554'
|
7
7
|
device :nav, :driver => :ardrone_navigation, :connection => :navigation
|
8
8
|
|
9
9
|
work do
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'artoo'
|
2
|
+
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
|
4
|
+
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
|
+
|
6
|
+
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.43:5554'
|
7
|
+
device :nav, :driver => :ardrone_navigation, :connection => :navigation
|
8
|
+
|
9
|
+
connection :videodrone, :adaptor => :ardrone_video, :port => '192.168.1.43:5555'
|
10
|
+
device :video, :driver => :ardrone_video, :connection => :videodrone
|
11
|
+
|
12
|
+
connection :arduino, :adaptor => :firmata, :port => "8023"
|
13
|
+
device :classic, :driver => :wiiclassic, :connection => :arduino, :interval => 0.1
|
14
|
+
|
15
|
+
api :host => '127.0.0.1', :port => '8080'
|
16
|
+
|
17
|
+
work do
|
18
|
+
init_settings
|
19
|
+
|
20
|
+
on nav, :update => :nav_update
|
21
|
+
|
22
|
+
on classic, :a_button => proc { drone.take_off }
|
23
|
+
on classic, :b_button => proc { drone.hover }
|
24
|
+
on classic, :x_button => proc { drone.land }
|
25
|
+
on classic, :y_button => proc {
|
26
|
+
if @toggle_camera == 0
|
27
|
+
drone.bottom_camera
|
28
|
+
@toggle_camera = 1
|
29
|
+
else
|
30
|
+
drone.front_camera
|
31
|
+
@toggle_camera = 0
|
32
|
+
end
|
33
|
+
}
|
34
|
+
on classic, :home_button => proc { drone.emergency }
|
35
|
+
on classic, :start_button => proc { drone.start }
|
36
|
+
on classic, :select_button => proc { drone.stop }
|
37
|
+
on classic, :ry_up => proc { drone.up(@altitude_pitch) }
|
38
|
+
on classic, :ry_down => proc { drone.down(@altitude_pitch) }
|
39
|
+
on classic, :ly_up => proc { drone.forward(@fly_pitch) }
|
40
|
+
on classic, :ly_down => proc { drone.backward(@fly_pitch) }
|
41
|
+
on classic, :lx_right => proc { drone.right(@fly_pitch) }
|
42
|
+
on classic, :lx_left => proc { drone.left(@fly_pitch) }
|
43
|
+
on classic, :reset_pitch_roll => proc {
|
44
|
+
drone.left(0.0)
|
45
|
+
drone.forward(0.0)
|
46
|
+
}
|
47
|
+
on classic, :rotate_left => proc { drone.turn_left(@rotate_pitch) }
|
48
|
+
on classic, :rotate_right => proc { drone.turn_right(@rotate_pitch) }
|
49
|
+
on classic, :reset_rotate => proc { drone.turn_left(0.0) }
|
50
|
+
on classic, :reset_altitude => proc { drone.up(0.0) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def init_settings
|
54
|
+
@rotate_pitch = 0.5
|
55
|
+
@fly_pitch = 0.7
|
56
|
+
@altitude_pitch = 1
|
57
|
+
@toggle_camera = 0
|
58
|
+
end
|
59
|
+
|
60
|
+
def nav_update(*data)
|
61
|
+
data[1].drone_state.each do |name, val|
|
62
|
+
p "#{name}: #{val}"
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'artoo'
|
2
|
+
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
|
4
|
+
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
|
+
|
6
|
+
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.43:5554'
|
7
|
+
device :nav, :driver => :ardrone_navigation, :connection => :navigation
|
8
|
+
|
9
|
+
connection :arduino, :adaptor => :firmata, :port => "8023"
|
10
|
+
device :classic, :driver => :wiiclassic, :connection => :arduino, :interval => 0.1
|
11
|
+
|
12
|
+
api :host => 'localhost', :port => '8080'
|
13
|
+
|
14
|
+
work do
|
15
|
+
init_settings
|
16
|
+
|
17
|
+
on nav, :update => :nav_update
|
18
|
+
|
19
|
+
on classic, :a_button => proc { drone.take_off }
|
20
|
+
on classic, :b_button => proc { drone.hover }
|
21
|
+
on classic, :x_button => proc { drone.land }
|
22
|
+
on classic, :y_button => proc {
|
23
|
+
if @toggle_camera == 0
|
24
|
+
drone.bottom_camera
|
25
|
+
@toggle_camera = 1
|
26
|
+
else
|
27
|
+
drone.front_camera
|
28
|
+
@toggle_camera = 0
|
29
|
+
end
|
30
|
+
}
|
31
|
+
on classic, :home_button => proc { drone.emergency }
|
32
|
+
on classic, :start_button => proc { drone.start }
|
33
|
+
on classic, :select_button => proc { drone.stop }
|
34
|
+
on classic, :ry_up => proc { drone.up(@altitude_pitch) }
|
35
|
+
on classic, :ry_down => proc { drone.down(@altitude_pitch) }
|
36
|
+
on classic, :ly_up => proc { drone.forward(@fly_pitch) }
|
37
|
+
on classic, :ly_down => proc { drone.backward(@fly_pitch) }
|
38
|
+
on classic, :lx_right => proc { drone.right(@fly_pitch) }
|
39
|
+
on classic, :lx_left => proc { drone.left(@fly_pitch) }
|
40
|
+
on classic, :reset_pitch_roll => proc {
|
41
|
+
drone.left(0.0)
|
42
|
+
drone.forward(0.0)
|
43
|
+
}
|
44
|
+
on classic, :rotate_left => proc { drone.turn_left(@rotate_pitch) }
|
45
|
+
on classic, :rotate_right => proc { drone.turn_right(@rotate_pitch) }
|
46
|
+
on classic, :reset_rotate => proc { drone.turn_left(0.0) }
|
47
|
+
on classic, :reset_altitude => proc { drone.up(0.0) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def init_settings
|
51
|
+
@rotate_pitch = 0.5
|
52
|
+
@fly_pitch = 0.7
|
53
|
+
@altitude_pitch = 1
|
54
|
+
@toggle_camera = 0
|
55
|
+
end
|
56
|
+
|
57
|
+
def nav_update(*data)
|
58
|
+
data[1].drone_state.each do |name, val|
|
59
|
+
p "#{name}: #{val}"
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'artoo'
|
2
|
+
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
|
4
|
+
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
|
+
|
6
|
+
connection :arduino, :adaptor => :firmata, :port => "8023"
|
7
|
+
device :classic, :driver => :wiiclassic, :connection => :arduino, :interval => 0.1
|
8
|
+
|
9
|
+
work do
|
10
|
+
init_settings
|
11
|
+
|
12
|
+
on classic, :a_button => proc { drone.take_off }
|
13
|
+
on classic, :b_button => proc { drone.hover }
|
14
|
+
on classic, :x_button => proc { drone.land }
|
15
|
+
on classic, :y_button => proc {
|
16
|
+
if @toggle_camera == 0
|
17
|
+
drone.bottom_camera
|
18
|
+
@toggle_camera = 1
|
19
|
+
else
|
20
|
+
drone.front_camera
|
21
|
+
@toggle_camera = 0
|
22
|
+
end
|
23
|
+
}
|
24
|
+
on classic, :home_button => proc { drone.emergency }
|
25
|
+
on classic, :start_button => proc { drone.start }
|
26
|
+
on classic, :select_button => proc { drone.stop }
|
27
|
+
on classic, :ry_up => proc { drone.up(@altitude_pitch) }
|
28
|
+
on classic, :ry_down => proc { drone.down(@altitude_pitch) }
|
29
|
+
on classic, :ly_up => proc { drone.forward(@fly_pitch) }
|
30
|
+
on classic, :ly_down => proc { drone.backward(@fly_pitch) }
|
31
|
+
on classic, :lx_right => proc { drone.right(@fly_pitch) }
|
32
|
+
on classic, :lx_left => proc { drone.left(@fly_pitch) }
|
33
|
+
on classic, :reset_pitch_roll => proc {
|
34
|
+
drone.left(0.0)
|
35
|
+
drone.forward(0.0)
|
36
|
+
}
|
37
|
+
on classic, :rotate_left => proc { drone.turn_left(@rotate_pitch) }
|
38
|
+
on classic, :rotate_right => proc { drone.turn_right(@rotate_pitch) }
|
39
|
+
on classic, :reset_rotate => proc { drone.turn_left(0.0) }
|
40
|
+
on classic, :reset_altitude => proc { drone.up(0.0) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def init_settings
|
44
|
+
@rotate_pitch = 0.5
|
45
|
+
@fly_pitch = 0.7
|
46
|
+
@altitude_pitch = 1
|
47
|
+
@toggle_camera = 0
|
48
|
+
end
|
data/examples/conway_sphero.rb
CHANGED
@@ -4,6 +4,8 @@ class SpheroRobot < Artoo::Robot
|
|
4
4
|
connection :sphero, :adaptor => :sphero
|
5
5
|
device :sphero, :driver => :sphero
|
6
6
|
|
7
|
+
#api :host => '127.0.0.1', :port => '8080'
|
8
|
+
|
7
9
|
work do
|
8
10
|
birth
|
9
11
|
|
@@ -48,13 +50,13 @@ class SpheroRobot < Artoo::Robot
|
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
|
-
SPHEROS = {"4560" => "/dev/tty.Sphero-BRG-RN-SPP",
|
52
|
-
"4561" => "/dev/tty.Sphero-YBW-RN-SPP",
|
53
|
-
"4562" => "/dev/tty.Sphero-BWY-RN-SPP",
|
54
|
-
"4563" => "/dev/tty.Sphero-YRR-RN-SPP",
|
55
|
-
"4564" => "/dev/tty.Sphero-OBG-RN-SPP",
|
56
|
-
"4565" => "/dev/tty.Sphero-GOB-RN-SPP",
|
57
|
-
"4566" => "/dev/tty.Sphero-PYG-RN-SPP"}
|
53
|
+
SPHEROS = {"127.0.0.1:4560" => "/dev/tty.Sphero-BRG-RN-SPP",
|
54
|
+
"127.0.0.1:4561" => "/dev/tty.Sphero-YBW-RN-SPP",
|
55
|
+
"127.0.0.1:4562" => "/dev/tty.Sphero-BWY-RN-SPP",
|
56
|
+
"127.0.0.1:4563" => "/dev/tty.Sphero-YRR-RN-SPP",
|
57
|
+
"127.0.0.1:4564" => "/dev/tty.Sphero-OBG-RN-SPP",
|
58
|
+
"127.0.0.1:4565" => "/dev/tty.Sphero-GOB-RN-SPP",
|
59
|
+
"127.0.0.1:4566" => "/dev/tty.Sphero-PYG-RN-SPP"}
|
58
60
|
robots = []
|
59
61
|
SPHEROS.each_key {|p|
|
60
62
|
robots << SpheroRobot.new(:connections =>
|
data/examples/firmata.rb
CHANGED
data/examples/firmata_button.rb
CHANGED
data/examples/sphero.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :sphero, :adaptor => :sphero, :port => '4560'
|
3
|
+
connection :sphero, :adaptor => :sphero, :port => '127.0.0.1:4560'
|
4
4
|
device :sphero, :driver => :sphero
|
5
5
|
|
6
6
|
work do
|
7
7
|
every(3.seconds) do
|
8
8
|
puts "Rolling..."
|
9
|
-
sphero.roll
|
9
|
+
sphero.roll 90, rand(360)
|
10
10
|
end
|
11
11
|
end
|
data/examples/sphero2.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'artoo/robot'
|
2
|
+
|
3
|
+
class SpheroRobot < Artoo::Robot
|
4
|
+
connection :sphero, :adaptor => :sphero
|
5
|
+
device :sphero, :driver => :sphero
|
6
|
+
|
7
|
+
work do
|
8
|
+
@count = 1
|
9
|
+
every(3.seconds) do
|
10
|
+
sphero.set_color(@count % 2 == 0 ? :green : :blue)
|
11
|
+
@count += 1
|
12
|
+
sphero.roll 90, rand(360)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
SPHEROS = {"127.0.0.1:4560" => "/dev/tty.Sphero-BRG-RN-SPP",
|
18
|
+
"127.0.0.1:4561" => "/dev/tty.Sphero-YBW-RN-SPP"}
|
19
|
+
robots = []
|
20
|
+
SPHEROS.each_key {|p|
|
21
|
+
robots << SpheroRobot.new(:connections =>
|
22
|
+
{:sphero =>
|
23
|
+
{:port => p}})
|
24
|
+
}
|
25
|
+
|
26
|
+
SpheroRobot.work!(robots)
|
data/examples/sphero_color.rb
CHANGED
data/examples/sphero_messages.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :sphero, :adaptor => :sphero, :port => '4560'
|
3
|
+
connection :sphero, :adaptor => :sphero, :port => '127.0.0.1:4560'
|
4
4
|
device :sphero, :driver => :sphero
|
5
5
|
|
6
6
|
work do
|
@@ -9,7 +9,7 @@ work do
|
|
9
9
|
|
10
10
|
every(3.seconds) do
|
11
11
|
puts "Rolling..."
|
12
|
-
sphero.roll
|
12
|
+
sphero.roll 90, rand(360)
|
13
13
|
unless sphero.collisions.empty?
|
14
14
|
puts "----------"
|
15
15
|
sphero.collisions.each do |c|
|
data/examples/sphero_multiple.rb
CHANGED
@@ -4,31 +4,26 @@ class SpheroRobot < Artoo::Robot
|
|
4
4
|
connection :sphero, :adaptor => :sphero
|
5
5
|
device :sphero, :driver => :sphero
|
6
6
|
|
7
|
+
#api :host => '127.0.0.1', :port => '8080'
|
8
|
+
|
7
9
|
work do
|
8
10
|
@count = 1
|
9
11
|
|
10
|
-
every(
|
12
|
+
every(3.seconds) do
|
11
13
|
sphero.set_color(@count % 2 == 0 ? :white : :blue)
|
12
14
|
@count += 1
|
13
|
-
end
|
14
|
-
|
15
|
-
every(3.seconds) do
|
16
15
|
sphero.roll 90, rand(360)
|
17
16
|
end
|
18
|
-
|
19
|
-
after(60.seconds) do
|
20
|
-
sphero.stop
|
21
|
-
end
|
22
17
|
end
|
23
18
|
end
|
24
19
|
|
25
|
-
SPHEROS = {"4560" => "/dev/tty.Sphero-BRG-RN-SPP",
|
26
|
-
"4561" => "/dev/tty.Sphero-YBW-RN-SPP",
|
27
|
-
"4562" => "/dev/tty.Sphero-BWY-RN-SPP",
|
28
|
-
"4563" => "/dev/tty.Sphero-YRR-RN-SPP",
|
29
|
-
"4564" => "/dev/tty.Sphero-OBG-RN-SPP",
|
30
|
-
"4565" => "/dev/tty.Sphero-GOB-RN-SPP",
|
31
|
-
"4566" => "/dev/tty.Sphero-PYG-RN-SPP"}
|
20
|
+
SPHEROS = {"127.0.0.1:4560" => "/dev/tty.Sphero-BRG-RN-SPP",
|
21
|
+
"127.0.0.1:4561" => "/dev/tty.Sphero-YBW-RN-SPP",
|
22
|
+
"127.0.0.1:4562" => "/dev/tty.Sphero-BWY-RN-SPP",
|
23
|
+
"127.0.0.1:4563" => "/dev/tty.Sphero-YRR-RN-SPP",
|
24
|
+
"127.0.0.1:4564" => "/dev/tty.Sphero-OBG-RN-SPP",
|
25
|
+
"127.0.0.1:4565" => "/dev/tty.Sphero-GOB-RN-SPP",
|
26
|
+
"127.0.0.1:4566" => "/dev/tty.Sphero-PYG-RN-SPP"}
|
32
27
|
robots = []
|
33
28
|
SPHEROS.each_key {|p|
|
34
29
|
robots << SpheroRobot.new(:connections =>
|
data/lib/artoo/drivers/sphero.rb
CHANGED
@@ -4,54 +4,56 @@ module Artoo
|
|
4
4
|
module Drivers
|
5
5
|
# The Sphero driver behaviors
|
6
6
|
class Sphero < Driver
|
7
|
+
RED = [255, 0, 0]
|
8
|
+
GREEN = [0, 255, 0]
|
9
|
+
YELLOW = [255, 255, 0]
|
10
|
+
BLUE = [0, 0, 255]
|
11
|
+
WHITE = [255, 255, 255]
|
12
|
+
|
7
13
|
def detect_collisions(params={})
|
8
14
|
connection.configure_collision_detection 0x01, 0x20, 0x20, 0x20, 0x20, 0x50
|
9
15
|
end
|
10
16
|
|
11
17
|
def clear_collisions
|
12
|
-
|
13
|
-
messages.clear if messages
|
18
|
+
responses.clear if responses = messages
|
14
19
|
end
|
15
20
|
|
16
21
|
def collisions
|
17
|
-
messages
|
18
|
-
return nil unless messages
|
19
|
-
messages.select {|m| m.is_a?(::Sphero::Response::CollisionDetected)}
|
22
|
+
matching_response_types messages, ::Sphero::Response::CollisionDetected
|
20
23
|
end
|
21
24
|
|
22
25
|
def power_notifications
|
23
|
-
messages
|
24
|
-
return nil unless messages
|
25
|
-
messages.select {|m| m.is_a?(::Sphero::Response::PowerNotification)}
|
26
|
+
matching_response_types messages, ::Sphero::Response::PowerNotification
|
26
27
|
end
|
27
28
|
|
28
29
|
def sensor_data
|
29
|
-
messages
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
when :
|
42
|
-
|
43
|
-
|
44
|
-
return 0, 255, 0
|
45
|
-
when :yellow
|
46
|
-
return 255, 255, 0
|
47
|
-
when :blue
|
48
|
-
return 0, 0, 255
|
49
|
-
when :white
|
50
|
-
return 255, 255, 255
|
51
|
-
else
|
52
|
-
return r, g, b
|
30
|
+
matching_response_types messages, ::Sphero::Response::SensorData
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_color(*colors)
|
34
|
+
connection.rgb(*color(colors))
|
35
|
+
end
|
36
|
+
|
37
|
+
def color(*colors)
|
38
|
+
case colors.first
|
39
|
+
when :red then RED
|
40
|
+
when :green then GREEN
|
41
|
+
when :yellow then YELLOW
|
42
|
+
when :blue then BLUE
|
43
|
+
when :white then WHITE
|
44
|
+
else colors
|
53
45
|
end
|
54
46
|
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def matching_response_types(responses, respone_klass)
|
51
|
+
responses.select { |m| m.is_a? respone_klass } if responses
|
52
|
+
end
|
53
|
+
|
54
|
+
def messages
|
55
|
+
connection.async_messages
|
56
|
+
end
|
55
57
|
end
|
56
58
|
end
|
57
|
-
end
|
59
|
+
end
|
@@ -6,9 +6,7 @@ module Artoo
|
|
6
6
|
class Wiiclassic < Driver
|
7
7
|
def address; 0x52; end
|
8
8
|
|
9
|
-
|
10
|
-
begin
|
11
|
-
@joystick = {
|
9
|
+
INITIAL_DEFAULTS = {
|
12
10
|
:ry_offset => 8,
|
13
11
|
:ry_origin => nil,
|
14
12
|
:ly_offset => 20,
|
@@ -20,6 +18,10 @@ module Artoo
|
|
20
18
|
:rt_offset => 5,
|
21
19
|
:lt_offset => 5
|
22
20
|
}
|
21
|
+
|
22
|
+
def start_driver
|
23
|
+
begin
|
24
|
+
@joystick = INITIAL_DEFAULTS
|
23
25
|
listener = ->(value) { update(value) }
|
24
26
|
connection.on("i2c_reply", listener)
|
25
27
|
|
@@ -45,13 +47,13 @@ module Artoo
|
|
45
47
|
|
46
48
|
def update(value)
|
47
49
|
begin
|
48
|
-
#Logger.info "value[:data] #{value[:data].inspect}"
|
49
50
|
if value[:data][0] == value[:data][1] && value[:data][2] == value[:data][3] && value[:data][4] == value[:data][5]
|
50
|
-
|
51
|
-
|
51
|
+
Logger.error "Encrypted bytes from wiiclassic!"
|
52
|
+
return
|
52
53
|
end
|
54
|
+
|
53
55
|
data = parse_wiiclassic(value)
|
54
|
-
|
56
|
+
|
55
57
|
publish(event_topic_name("a_button")) if data[:a] == 0
|
56
58
|
publish(event_topic_name("b_button")) if data[:b] == 0
|
57
59
|
publish(event_topic_name("x_button")) if data[:x] == 0
|
@@ -68,17 +70,7 @@ module Artoo
|
|
68
70
|
@joystick[:rt_origin] = data[:rt] if @joystick[:rt_origin].nil?
|
69
71
|
@joystick[:lt_origin] = data[:lt] if @joystick[:lt_origin].nil?
|
70
72
|
|
71
|
-
|
72
|
-
publish(event_topic_name("ly_up"))
|
73
|
-
elsif data[:ly] < (@joystick[:ly_origin] - @joystick[:ly_offset])
|
74
|
-
publish(event_topic_name("ly_down"))
|
75
|
-
elsif data[:lx] > (@joystick[:lx_origin] + @joystick[:lx_offset])
|
76
|
-
publish(event_topic_name("lx_right"))
|
77
|
-
elsif data[:lx] < (@joystick[:lx_origin] - @joystick[:lx_offset])
|
78
|
-
publish(event_topic_name("lx_left"))
|
79
|
-
else
|
80
|
-
publish(event_topic_name("reset_pitch_roll"))
|
81
|
-
end
|
73
|
+
update_left_joystick
|
82
74
|
|
83
75
|
if data[:ry] > (@joystick[:ry_origin] + @joystick[:ry_offset])
|
84
76
|
publish(event_topic_name("ry_up"))
|
@@ -103,33 +95,51 @@ module Artoo
|
|
103
95
|
end
|
104
96
|
end
|
105
97
|
|
98
|
+
def update_left_joystick
|
99
|
+
if data[:ly] > (@joystick[:ly_origin] + @joystick[:ly_offset])
|
100
|
+
publish(event_topic_name("ly_up"))
|
101
|
+
elsif data[:ly] < (@joystick[:ly_origin] - @joystick[:ly_offset])
|
102
|
+
publish(event_topic_name("ly_down"))
|
103
|
+
elsif data[:lx] > (@joystick[:lx_origin] + @joystick[:lx_offset])
|
104
|
+
publish(event_topic_name("lx_right"))
|
105
|
+
elsif data[:lx] < (@joystick[:lx_origin] - @joystick[:lx_offset])
|
106
|
+
publish(event_topic_name("lx_left"))
|
107
|
+
else
|
108
|
+
publish(event_topic_name("reset_pitch_roll")) # TODO: rename something not so drone specfic
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
106
112
|
private
|
107
113
|
|
108
114
|
def decode( x )
|
109
115
|
return ( x ^ 0x17 ) + 0x17
|
110
116
|
end
|
111
117
|
|
118
|
+
def get_value(value, index)
|
119
|
+
decode(value[:data][index])
|
120
|
+
end
|
121
|
+
|
112
122
|
def parse_wiiclassic(value)
|
113
123
|
return {
|
114
|
-
:lx =>
|
115
|
-
:ly =>
|
116
|
-
:rx => ((
|
117
|
-
:ry =>
|
118
|
-
:lt => ((
|
119
|
-
:rt =>
|
120
|
-
:d_up =>
|
121
|
-
:d_down =>
|
122
|
-
:D_left =>
|
123
|
-
:D_right =>
|
124
|
-
:zr =>
|
125
|
-
:zl =>
|
126
|
-
:a =>
|
127
|
-
:b =>
|
128
|
-
:x =>
|
129
|
-
:y =>
|
130
|
-
:+ =>
|
131
|
-
:- =>
|
132
|
-
:h =>
|
124
|
+
:lx => get_value(value, 0) & 0x3f,
|
125
|
+
:ly => get_value(value, 1) & 0x3f,
|
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) & 0xE0) >> 6),
|
129
|
+
:rt => get_value(value, 3) & 0x1f,
|
130
|
+
:d_up => get_value(value, 5)[0],
|
131
|
+
:d_down => get_value(value, 4)[6],
|
132
|
+
:D_left => get_value(value, 5)[1],
|
133
|
+
:D_right => get_value(value, 4)[7],
|
134
|
+
:zr => get_value(value, 5)[2],
|
135
|
+
:zl => get_value(value, 5)[7],
|
136
|
+
:a => get_value(value, 5)[4],
|
137
|
+
:b => get_value(value, 5)[6],
|
138
|
+
:x => get_value(value, 5)[3],
|
139
|
+
:y => get_value(value, 5)[5],
|
140
|
+
:+ => get_value(value, 4)[2],
|
141
|
+
:- => get_value(value, 4)[4],
|
142
|
+
:h => get_value(value, 4)[3],
|
133
143
|
}
|
134
144
|
end
|
135
145
|
end
|
data/lib/artoo/robot.rb
CHANGED
@@ -133,13 +133,13 @@ module Artoo
|
|
133
133
|
|
134
134
|
# Taken from Sinatra codebase
|
135
135
|
CALLERS_TO_IGNORE = [ # :nodoc:
|
136
|
-
/lib\/artoo.*\.rb$/,
|
137
|
-
/^\(.*\)$/,
|
138
|
-
/rubygems\/
|
139
|
-
/active_support/,
|
140
|
-
/bundler(\/runtime)?\.rb/,
|
141
|
-
/<internal:/,
|
142
|
-
/src\/kernel\/bootstrap\/[A-Z]/
|
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
143
|
]
|
144
144
|
|
145
145
|
# Taken from Sinatra codebase
|
data/lib/artoo/version.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
require 'artoo/drivers/wiiclassic'
|
3
|
+
|
4
|
+
describe Artoo::Drivers::Wiiclassic do
|
5
|
+
before do
|
6
|
+
@device = mock('device')
|
7
|
+
@driver = Artoo::Drivers::Wiiclassic.new(:parent => @device)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'must do things'
|
11
|
+
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: artoo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
4
|
+
version: 0.1.3
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ron Evans
|
@@ -10,10 +10,10 @@ authors:
|
|
10
10
|
- Ari Lerner
|
11
11
|
- Mario Ricalde
|
12
12
|
- Daniel Fischer
|
13
|
-
autorequire:
|
13
|
+
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2013-02-
|
16
|
+
date: 2013-02-26 00:00:00.000000000 Z
|
17
17
|
dependencies: []
|
18
18
|
description: Ruby-based microframework for robotics
|
19
19
|
email:
|
@@ -24,7 +24,7 @@ executables:
|
|
24
24
|
extensions: []
|
25
25
|
extra_rdoc_files: []
|
26
26
|
files:
|
27
|
-
-
|
27
|
+
- .gitignore
|
28
28
|
- Gemfile
|
29
29
|
- Gemfile.lock
|
30
30
|
- Guardfile
|
@@ -66,7 +66,10 @@ files:
|
|
66
66
|
- examples/ardrone.rb
|
67
67
|
- examples/ardrone_nav.rb
|
68
68
|
- examples/ardrone_nav_video.rb
|
69
|
+
- examples/ardrone_nav_video_wii.rb
|
70
|
+
- examples/ardrone_nav_wiiclassic.rb
|
69
71
|
- examples/ardrone_video.rb
|
72
|
+
- examples/ardrone_wiiclassic.rb
|
70
73
|
- examples/conway_sphero.rb
|
71
74
|
- examples/firmata.rb
|
72
75
|
- examples/firmata_button.rb
|
@@ -77,6 +80,7 @@ files:
|
|
77
80
|
- examples/hello_multiple.rb
|
78
81
|
- examples/notifications.rb
|
79
82
|
- examples/sphero.rb
|
83
|
+
- examples/sphero2.rb
|
80
84
|
- examples/sphero_color.rb
|
81
85
|
- examples/sphero_firmata.rb
|
82
86
|
- examples/sphero_messages.rb
|
@@ -130,34 +134,39 @@ files:
|
|
130
134
|
- test/drivers/led_test.rb
|
131
135
|
- test/drivers/sphero_test.rb
|
132
136
|
- test/drivers/wiichuck_test.rb
|
137
|
+
- test/drivers/wiiclassic_test.rb
|
133
138
|
- test/port_test.rb
|
134
139
|
- test/robot_test.rb
|
135
140
|
- test/test_helper.rb
|
136
141
|
- test/utility_test.rb
|
137
142
|
homepage: https://github.com/hybridgroup/artoo
|
138
143
|
licenses: []
|
139
|
-
post_install_message:
|
144
|
+
post_install_message:
|
140
145
|
rdoc_options: []
|
141
146
|
require_paths:
|
142
147
|
- lib
|
143
148
|
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
144
150
|
requirements:
|
145
|
-
- -
|
151
|
+
- - ! '>='
|
146
152
|
- !ruby/object:Gem::Version
|
147
|
-
version:
|
148
|
-
|
149
|
-
|
153
|
+
version: '0'
|
154
|
+
segments:
|
155
|
+
- 0
|
156
|
+
hash: -4461140220613461358
|
150
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
none: false
|
151
159
|
requirements:
|
152
|
-
- -
|
160
|
+
- - ! '>='
|
153
161
|
- !ruby/object:Gem::Version
|
154
|
-
version:
|
155
|
-
|
156
|
-
|
162
|
+
version: '0'
|
163
|
+
segments:
|
164
|
+
- 0
|
165
|
+
hash: -4461140220613461358
|
157
166
|
requirements: []
|
158
167
|
rubyforge_project: artoo
|
159
|
-
rubygems_version: 1.8.
|
160
|
-
signing_key:
|
168
|
+
rubygems_version: 1.8.25
|
169
|
+
signing_key:
|
161
170
|
specification_version: 3
|
162
171
|
summary: Ruby-based microframework for robotics
|
163
172
|
test_files:
|
@@ -178,6 +187,7 @@ test_files:
|
|
178
187
|
- test/drivers/led_test.rb
|
179
188
|
- test/drivers/sphero_test.rb
|
180
189
|
- test/drivers/wiichuck_test.rb
|
190
|
+
- test/drivers/wiiclassic_test.rb
|
181
191
|
- test/port_test.rb
|
182
192
|
- test/robot_test.rb
|
183
193
|
- test/test_helper.rb
|