artoo 0.1.2 → 0.1.3
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/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
|