artoo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +25 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +144 -0
- data/Guardfile +15 -0
- data/LICENSE +13 -0
- data/README.md +97 -0
- data/Rakefile +11 -0
- data/api/assets/compass.rb +25 -0
- data/api/assets/javascripts/artoo/controllers/robot.js.coffee +27 -0
- data/api/assets/javascripts/artoo/routes.js.coffee +23 -0
- data/api/assets/javascripts/core.js.coffee +6 -0
- data/api/assets/javascripts/vendor/angular.min.js +161 -0
- data/api/assets/javascripts/vendor/bootstrap.min.js +6 -0
- data/api/assets/javascripts/vendor/jquery.min.js +5 -0
- data/api/assets/stylesheets/artoo/_core.css.scss +3 -0
- data/api/assets/stylesheets/artoo/_font-awesome.scss +534 -0
- data/api/assets/stylesheets/artoo/_variables.scss +8 -0
- data/api/assets/stylesheets/core.scss +70 -0
- data/api/public/core.css +9848 -0
- data/api/public/core.js +259 -0
- data/api/public/favicon.ico +0 -0
- data/api/public/font/FontAwesome.otf +0 -0
- data/api/public/font/fontawesome-webfont.eot +0 -0
- data/api/public/font/fontawesome-webfont.svg +284 -0
- data/api/public/font/fontawesome-webfont.ttf +0 -0
- data/api/public/font/fontawesome-webfont.woff +0 -0
- data/api/public/html5shiv.js +8 -0
- data/api/public/images/devices/ardrone.jpg +0 -0
- data/api/public/images/devices/arduino.jpg +0 -0
- data/api/public/images/devices/sphero.png +0 -0
- data/api/public/images/glyphicons-halflings-white.png +0 -0
- data/api/public/images/glyphicons-halflings.png +0 -0
- data/api/public/index.html +36 -0
- data/api/public/partials/robot-detail.html +111 -0
- data/api/public/partials/robot-device-detail.html +0 -0
- data/api/public/partials/robot-index.html +26 -0
- data/artoo.gemspec +21 -0
- data/bin/retry.sh +8 -0
- data/bin/sphero.sh +8 -0
- data/examples/ardrone.rb +12 -0
- data/examples/ardrone_nav.rb +22 -0
- data/examples/ardrone_nav_video.rb +33 -0
- data/examples/ardrone_video.rb +22 -0
- data/examples/conway_sphero.rb +65 -0
- data/examples/firmata.rb +13 -0
- data/examples/firmata_button.rb +9 -0
- data/examples/hello.rb +12 -0
- data/examples/hello_api.rb +9 -0
- data/examples/hello_api_multiple.rb +25 -0
- data/examples/hello_modular.rb +16 -0
- data/examples/hello_multiple.rb +22 -0
- data/examples/notifications.rb +9 -0
- data/examples/sphero.rb +11 -0
- data/examples/sphero_color.rb +13 -0
- data/examples/sphero_firmata.rb +17 -0
- data/examples/sphero_messages.rb +22 -0
- data/examples/sphero_multiple.rb +33 -0
- data/examples/wiiclassic.rb +94 -0
- data/lib/artoo.rb +3 -0
- data/lib/artoo/adaptors/adaptor.rb +54 -0
- data/lib/artoo/adaptors/ardrone.rb +32 -0
- data/lib/artoo/adaptors/ardrone_navigation.rb +26 -0
- data/lib/artoo/adaptors/ardrone_video.rb +27 -0
- data/lib/artoo/adaptors/firmata.rb +25 -0
- data/lib/artoo/adaptors/loopback.rb +8 -0
- data/lib/artoo/adaptors/sphero.rb +46 -0
- data/lib/artoo/api.rb +48 -0
- data/lib/artoo/api_route_helpers.rb +197 -0
- data/lib/artoo/connection.rb +70 -0
- data/lib/artoo/delegator.rb +49 -0
- data/lib/artoo/device.rb +61 -0
- data/lib/artoo/device_event_client.rb +27 -0
- data/lib/artoo/drivers/ardrone.rb +9 -0
- data/lib/artoo/drivers/ardrone_navigation.rb +21 -0
- data/lib/artoo/drivers/ardrone_video.rb +22 -0
- data/lib/artoo/drivers/button.rb +40 -0
- data/lib/artoo/drivers/driver.rb +48 -0
- data/lib/artoo/drivers/led.rb +37 -0
- data/lib/artoo/drivers/passthru.rb +9 -0
- data/lib/artoo/drivers/pinger.rb +19 -0
- data/lib/artoo/drivers/pinger2.rb +18 -0
- data/lib/artoo/drivers/sphero.rb +57 -0
- data/lib/artoo/drivers/wiichuck.rb +29 -0
- data/lib/artoo/drivers/wiiclassic.rb +137 -0
- data/lib/artoo/main.rb +32 -0
- data/lib/artoo/master.rb +16 -0
- data/lib/artoo/port.rb +51 -0
- data/lib/artoo/robot.rb +299 -0
- data/lib/artoo/utility.rb +39 -0
- data/lib/artoo/version.rb +5 -0
- data/test/adaptors/adaptor_test.rb +18 -0
- data/test/adaptors/ardrone_test.rb +24 -0
- data/test/adaptors/firmata_test.rb +25 -0
- data/test/adaptors/loopback_test.rb +18 -0
- data/test/adaptors/sphero_test.rb +24 -0
- data/test/api_test.rb +61 -0
- data/test/artoo_test.rb +12 -0
- data/test/connection_test.rb +28 -0
- data/test/delegator_test.rb +71 -0
- data/test/device_test.rb +41 -0
- data/test/drivers/ardrone_navigation_test.rb +11 -0
- data/test/drivers/ardrone_test.rb +11 -0
- data/test/drivers/ardrone_video_test.rb +11 -0
- data/test/drivers/driver_test.rb +21 -0
- data/test/drivers/led_test.rb +52 -0
- data/test/drivers/sphero_test.rb +54 -0
- data/test/drivers/wiichuck_test.rb +11 -0
- data/test/port_test.rb +33 -0
- data/test/robot_test.rb +96 -0
- data/test/test_helper.rb +8 -0
- data/test/utility_test.rb +27 -0
- metadata +185 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Artoo
|
2
|
+
# The Artoo::DeviceEventClient class is how a websocket client can subscribe
|
3
|
+
# to event notifications for a specific device.
|
4
|
+
# Example: ardrone nav data
|
5
|
+
class DeviceEventClient
|
6
|
+
include Celluloid
|
7
|
+
include Celluloid::Notifications
|
8
|
+
include Celluloid::Logger
|
9
|
+
|
10
|
+
attr_reader :topic
|
11
|
+
|
12
|
+
def initialize(websocket, topic)
|
13
|
+
@topic = topic
|
14
|
+
info "Streaming #{@topic} to websocket..."
|
15
|
+
@socket = websocket
|
16
|
+
subscribe(@topic, :notify_event)
|
17
|
+
end
|
18
|
+
|
19
|
+
def notify_event(topic, *data)
|
20
|
+
# TODO: send which topic sent the notification
|
21
|
+
@socket << data.last.to_s
|
22
|
+
rescue Reel::SocketError, Errno::EPIPE
|
23
|
+
info "Device event notification #{topic} websocket disconnected"
|
24
|
+
terminate
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Ardrone navigation driver behaviors
|
6
|
+
class ArdroneNavigation < Driver
|
7
|
+
def start_driver
|
8
|
+
every(interval) do
|
9
|
+
handle_update
|
10
|
+
end
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def handle_update
|
16
|
+
navdata = connection.receive_data
|
17
|
+
publish(event_topic_name("update"), navdata)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Ardrone video driver behaviors
|
6
|
+
class ArdroneVideo < Driver
|
7
|
+
def start_driver
|
8
|
+
every(interval) do
|
9
|
+
handle_frame
|
10
|
+
end
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def handle_frame(*params)
|
16
|
+
frame = connection.video_parser.get_frame
|
17
|
+
publish(event_topic_name("update"), "frame", frame)
|
18
|
+
publish(event_topic_name("frame"), frame)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Button driver behaviors for Firmata
|
6
|
+
class Button < Driver
|
7
|
+
DOWN = 1
|
8
|
+
UP = 0
|
9
|
+
|
10
|
+
def is_pressed?
|
11
|
+
(@is_pressed ||= false) == true
|
12
|
+
end
|
13
|
+
|
14
|
+
def start_driver
|
15
|
+
listener = ->(value) { update(value) }
|
16
|
+
connection.on("digital-read-#{pin}", listener)
|
17
|
+
connection.set_pin_mode(pin, Firmata::Board::INPUT)
|
18
|
+
connection.toggle_pin_reporting(pin)
|
19
|
+
|
20
|
+
every(interval) do
|
21
|
+
connection.read_and_process
|
22
|
+
end
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def update(value)
|
28
|
+
if value == DOWN
|
29
|
+
@is_pressed = true
|
30
|
+
publish(event_topic_name("update"), "push", value)
|
31
|
+
publish(event_topic_name("push"), value)
|
32
|
+
else
|
33
|
+
@is_pressed = false
|
34
|
+
publish(event_topic_name("update"), "release", value)
|
35
|
+
publish(event_topic_name("release"), value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Artoo
|
2
|
+
module Drivers
|
3
|
+
# The Driver class is the base class used to
|
4
|
+
# implement behavior for a specific kind of hardware devices. Examples
|
5
|
+
# would be an Arduino, a Sphero, or an ARDrone.
|
6
|
+
#
|
7
|
+
# Derive a class from this class, in order to implement behavior
|
8
|
+
# for a new type of hardware device.
|
9
|
+
class Driver
|
10
|
+
include Celluloid
|
11
|
+
include Celluloid::Notifications
|
12
|
+
|
13
|
+
attr_reader :parent
|
14
|
+
|
15
|
+
def initialize(params={})
|
16
|
+
@parent = params[:parent]
|
17
|
+
end
|
18
|
+
|
19
|
+
def connection
|
20
|
+
parent.connection
|
21
|
+
end
|
22
|
+
|
23
|
+
def pin
|
24
|
+
parent.pin
|
25
|
+
end
|
26
|
+
|
27
|
+
def interval
|
28
|
+
parent.interval
|
29
|
+
end
|
30
|
+
|
31
|
+
def start_driver
|
32
|
+
Logger.info "Starting driver '#{self.class.name}'..."
|
33
|
+
end
|
34
|
+
|
35
|
+
def event_topic_name(event)
|
36
|
+
parent.event_topic_name(event)
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method_name, *arguments, &block)
|
40
|
+
connection.send(method_name, *arguments, &block)
|
41
|
+
rescue Exception => e
|
42
|
+
Logger.error e.message
|
43
|
+
Logger.error e.backtrace.inspect
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# The LED driver behaviors
|
6
|
+
class Led < Driver
|
7
|
+
def is_on?
|
8
|
+
(@is_on ||= false) == true
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_off?
|
12
|
+
(@is_on ||= false) == false
|
13
|
+
end
|
14
|
+
|
15
|
+
def on
|
16
|
+
@is_on = true
|
17
|
+
connection.set_pin_mode(pin, Firmata::Board::OUTPUT)
|
18
|
+
connection.digital_write(pin, Firmata::Board::HIGH)
|
19
|
+
end
|
20
|
+
|
21
|
+
def off
|
22
|
+
@is_on = false
|
23
|
+
connection.set_pin_mode(pin, Firmata::Board::OUTPUT)
|
24
|
+
connection.digital_write(pin, Firmata::Board::LOW)
|
25
|
+
end
|
26
|
+
|
27
|
+
def toggle
|
28
|
+
is_off? ? on : off
|
29
|
+
end
|
30
|
+
|
31
|
+
def brightness(level=0)
|
32
|
+
connection.set_pin_mode(pin, Firmata::Board::PWM)
|
33
|
+
connection.analog_write(pin, level)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Pings itself
|
6
|
+
class Pinger < Driver
|
7
|
+
def start_driver
|
8
|
+
@count = 1
|
9
|
+
every(interval) do
|
10
|
+
publish(event_topic_name("update"), "alive", @count)
|
11
|
+
publish(event_topic_name("alive"), @count)
|
12
|
+
@count += 1
|
13
|
+
end
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Pings itself
|
6
|
+
class Pinger2 < Driver
|
7
|
+
def start_driver
|
8
|
+
every(interval) do
|
9
|
+
@count = rand(100000)
|
10
|
+
publish(event_topic_name("update"), "alive", @count)
|
11
|
+
publish(event_topic_name("alive"), @count)
|
12
|
+
end
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# The Sphero driver behaviors
|
6
|
+
class Sphero < Driver
|
7
|
+
def detect_collisions(params={})
|
8
|
+
connection.configure_collision_detection 0x01, 0x20, 0x20, 0x20, 0x20, 0x50
|
9
|
+
end
|
10
|
+
|
11
|
+
def clear_collisions
|
12
|
+
messages = connection.async_messages
|
13
|
+
messages.clear if messages
|
14
|
+
end
|
15
|
+
|
16
|
+
def collisions
|
17
|
+
messages = connection.async_messages
|
18
|
+
return nil unless messages
|
19
|
+
messages.select {|m| m.is_a?(::Sphero::Response::CollisionDetected)}
|
20
|
+
end
|
21
|
+
|
22
|
+
def power_notifications
|
23
|
+
messages = connection.async_messages
|
24
|
+
return nil unless messages
|
25
|
+
messages.select {|m| m.is_a?(::Sphero::Response::PowerNotification)}
|
26
|
+
end
|
27
|
+
|
28
|
+
def sensor_data
|
29
|
+
messages = connection.async_messages
|
30
|
+
return nil unless messages
|
31
|
+
messages.select {|m| m.is_a?(::Sphero::Response::SensorData)}
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_color(r, g=nil, b=nil)
|
35
|
+
r, g, b = color(r, g, b)
|
36
|
+
connection.rgb(r, g, b)
|
37
|
+
end
|
38
|
+
|
39
|
+
def color(r, g=nil, b=nil)
|
40
|
+
case r
|
41
|
+
when :red
|
42
|
+
return 255, 0, 0
|
43
|
+
when :green
|
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
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Wiichuck driver behaviors for Firmata
|
6
|
+
class Wiichuck < Driver
|
7
|
+
def address; 0x52; end
|
8
|
+
|
9
|
+
def start_driver
|
10
|
+
listener = ->(value) { update(value) }
|
11
|
+
connection.on("i2c_reply", listener)
|
12
|
+
|
13
|
+
connection.i2c_config(10)
|
14
|
+
connection.i2c_request(address, 0x40, 0x00)
|
15
|
+
|
16
|
+
every(interval) do
|
17
|
+
connection.i2c_request(address, 0x00)
|
18
|
+
connection.read_and_process
|
19
|
+
end
|
20
|
+
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def update(value)
|
25
|
+
publish("#{parent.name}_update", value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Wiichuck driver behaviors for Firmata
|
6
|
+
class Wiiclassic < Driver
|
7
|
+
def address; 0x52; end
|
8
|
+
|
9
|
+
def start_driver
|
10
|
+
begin
|
11
|
+
@joystick = {
|
12
|
+
:ry_offset => 8,
|
13
|
+
:ry_origin => nil,
|
14
|
+
:ly_offset => 20,
|
15
|
+
:lx_offset => 20,
|
16
|
+
:ly_origin => nil,
|
17
|
+
:lx_origin => nil,
|
18
|
+
:rt_origin => nil,
|
19
|
+
:lt_origin => nil,
|
20
|
+
:rt_offset => 5,
|
21
|
+
:lt_offset => 5
|
22
|
+
}
|
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
|
+
|
46
|
+
def update(value)
|
47
|
+
begin
|
48
|
+
#Logger.info "value[:data] #{value[:data].inspect}"
|
49
|
+
if value[:data][0] == value[:data][1] && value[:data][2] == value[:data][3] && value[:data][4] == value[:data][5]
|
50
|
+
# Logger.error "Encrypted bytes from wiiclassic"
|
51
|
+
break
|
52
|
+
end
|
53
|
+
data = parse_wiiclassic(value)
|
54
|
+
#publish(event_topic_name("_a_button") if data[:a] == 0
|
55
|
+
publish(event_topic_name("a_button")) if data[:a] == 0
|
56
|
+
publish(event_topic_name("b_button")) if data[:b] == 0
|
57
|
+
publish(event_topic_name("x_button")) if data[:x] == 0
|
58
|
+
publish(event_topic_name("y_button")) if data[:y] == 0
|
59
|
+
publish(event_topic_name("home_button")) if data[:h] == 0
|
60
|
+
publish(event_topic_name("start_button")) if data[:+] == 0
|
61
|
+
publish(event_topic_name("select_button")) if data[:-] == 0
|
62
|
+
|
63
|
+
@joystick[:ly_origin] = data[:ly] if @joystick[:ly_origin].nil?
|
64
|
+
@joystick[:lx_origin] = data[:lx] if @joystick[:lx_origin].nil?
|
65
|
+
|
66
|
+
@joystick[:ry_origin] = data[:ry] if @joystick[:ry_origin].nil?
|
67
|
+
|
68
|
+
@joystick[:rt_origin] = data[:rt] if @joystick[:rt_origin].nil?
|
69
|
+
@joystick[:lt_origin] = data[:lt] if @joystick[:lt_origin].nil?
|
70
|
+
|
71
|
+
if data[:ly] > (@joystick[:ly_origin] + @joystick[:ly_offset])
|
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
|
82
|
+
|
83
|
+
if data[:ry] > (@joystick[:ry_origin] + @joystick[:ry_offset])
|
84
|
+
publish(event_topic_name("ry_up"))
|
85
|
+
elsif data[:ry] < (@joystick[:ry_origin] - @joystick[:ry_offset])
|
86
|
+
publish(event_topic_name("ry_down"))
|
87
|
+
else
|
88
|
+
publish(event_topic_name("reset_altitude"))
|
89
|
+
end
|
90
|
+
|
91
|
+
if data[:rt] > (@joystick[:rt_origin] + @joystick[:rt_offset])
|
92
|
+
publish(event_topic_name("rotate_right"))
|
93
|
+
elsif data[:lt] > (@joystick[:lt_origin] + @joystick[:lt_offset])
|
94
|
+
publish(event_topic_name("rotate_left"))
|
95
|
+
else
|
96
|
+
publish(event_topic_name("reset_rotate"))
|
97
|
+
end
|
98
|
+
|
99
|
+
rescue Exception => e
|
100
|
+
p "wiiclassic update exception!"
|
101
|
+
p e.message
|
102
|
+
p e.backtrace.inspect
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def decode( x )
|
109
|
+
return ( x ^ 0x17 ) + 0x17
|
110
|
+
end
|
111
|
+
|
112
|
+
def parse_wiiclassic(value)
|
113
|
+
return {
|
114
|
+
:lx => decode(value[:data][0]) & 0x3f,
|
115
|
+
:ly => decode(value[:data][1]) & 0x3f,
|
116
|
+
:rx => ((decode(value[:data][0]) & 0xC0) >> 2) | ((decode(value[:data][1]) & 0xC0) >> 4) | (decode(value[:data][2])[7]),
|
117
|
+
:ry => decode(value[:data][2]) & 0x1f,
|
118
|
+
:lt => ((decode(value[:data][2]) & 0x60) >> 3) | ((decode(value[:data][3]) & 0xE0) >> 6),
|
119
|
+
:rt => decode(value[:data][3]) & 0x1f,
|
120
|
+
:d_up => decode(value[:data][5])[0],
|
121
|
+
:d_down => decode(value[:data][4])[6],
|
122
|
+
:D_left => decode(value[:data][5])[1],
|
123
|
+
:D_right => decode(value[:data][4])[7],
|
124
|
+
:zr => decode(value[:data][5])[2],
|
125
|
+
:zl => decode(value[:data][5])[7],
|
126
|
+
:a => decode(value[:data][5])[4],
|
127
|
+
:b => decode(value[:data][5])[6],
|
128
|
+
:x => decode(value[:data][5])[3],
|
129
|
+
:y => decode(value[:data][5])[5],
|
130
|
+
:+ => decode(value[:data][4])[2],
|
131
|
+
:- => decode(value[:data][4])[4],
|
132
|
+
:h => decode(value[:data][4])[3],
|
133
|
+
}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|