artoo 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +14 -25
- data/Gemfile.lock +9 -10
- data/README.md +7 -2
- data/artoo.gemspec +8 -0
- data/examples/ardrone.rb +2 -2
- data/examples/ardrone_nav.rb +3 -3
- data/examples/ardrone_nav_video_wii.rb +3 -3
- data/examples/ardrone_nav_wiiclassic.rb +2 -2
- data/examples/ardrone_wiiclassic.rb +57 -16
- data/examples/christmas_roomba.rb +18 -0
- data/examples/sphero_wiichuck.rb +28 -0
- data/examples/wiichuck.rb +12 -0
- data/lib/artoo/adaptors/adaptor.rb +7 -0
- data/lib/artoo/adaptors/roomba.rb +43 -0
- data/lib/artoo/basic.rb +79 -0
- data/lib/artoo/drivers/motor.rb +58 -0
- data/lib/artoo/drivers/roomba.rb +155 -0
- data/lib/artoo/drivers/servo.rb +49 -0
- data/lib/artoo/drivers/wiichuck.rb +86 -7
- data/lib/artoo/drivers/wiiclassic.rb +80 -76
- data/lib/artoo/events.rb +34 -0
- data/lib/artoo/robot.rb +25 -134
- data/lib/artoo/version.rb +1 -1
- data/test/drivers/motor_test.rb +40 -0
- data/test/drivers/servo_test.rb +45 -0
- data/test/drivers/wiiclassic_test.rb +6 -1
- metadata +120 -16
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# L293 or other H-bridge style motor driver behaviors for Firmata
|
6
|
+
class Motor < Driver
|
7
|
+
attr_reader :leg1_pin, :leg2_pin, :speed_pin, :current_speed
|
8
|
+
|
9
|
+
def initialize(params={})
|
10
|
+
super
|
11
|
+
|
12
|
+
raise "Invalid pins, please pass an array in format [leg1, leg2, speed]" unless (pin && pin.is_a?(Array) && pin.size == 3)
|
13
|
+
@leg1_pin = pin[0]
|
14
|
+
@leg2_pin = pin[1]
|
15
|
+
@speed_pin = pin[2]
|
16
|
+
@current_speed = 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def start_driver
|
20
|
+
every(interval) do
|
21
|
+
connection.read_and_process
|
22
|
+
end
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def forward(s)
|
28
|
+
set_legs(Firmata::Board::LOW, Firmata::Board::HIGH)
|
29
|
+
speed(s)
|
30
|
+
end
|
31
|
+
|
32
|
+
def backward(s)
|
33
|
+
set_legs(Firmata::Board::HIGH, Firmata::Board::LOW)
|
34
|
+
speed(s)
|
35
|
+
end
|
36
|
+
|
37
|
+
def stop
|
38
|
+
speed(0)
|
39
|
+
end
|
40
|
+
|
41
|
+
def speed(s)
|
42
|
+
raise "Motor speed must be an integer between 0-255" unless (s.is_a?(Numeric) && s >= 0 && s <= 255)
|
43
|
+
@current_speed = s
|
44
|
+
connection.set_pin_mode(speed_pin, Firmata::Board::PWM)
|
45
|
+
connection.analog_write(speed_pin, s)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def set_legs(l1, l2)
|
51
|
+
connection.set_pin_mode(leg1_pin, Firmata::Board::OUTPUT)
|
52
|
+
connection.digital_write(leg1_pin, l1)
|
53
|
+
connection.set_pin_mode(leg2_pin, Firmata::Board::OUTPUT)
|
54
|
+
connection.digital_write(leg2_pin, l2)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# The Roomba driver behaviors
|
6
|
+
class Roomba < Driver
|
7
|
+
|
8
|
+
STRAIGHT = 32768
|
9
|
+
CLOCKWISE = 65535
|
10
|
+
COUNTERCLOCKWISE = 1
|
11
|
+
MAX = 500
|
12
|
+
SLOW = 250
|
13
|
+
NEG = (65536 - 250)
|
14
|
+
ZERO = 0
|
15
|
+
|
16
|
+
B = 95
|
17
|
+
D = 98
|
18
|
+
G = 91
|
19
|
+
C = 96
|
20
|
+
A = 93
|
21
|
+
QUART = 16
|
22
|
+
HALF = 57
|
23
|
+
WHOLE = 114
|
24
|
+
START = 128
|
25
|
+
|
26
|
+
module Modes
|
27
|
+
FULL = 132
|
28
|
+
SAFE = 131
|
29
|
+
end
|
30
|
+
|
31
|
+
def start
|
32
|
+
send_bytes(START)
|
33
|
+
sleep 0.2
|
34
|
+
end
|
35
|
+
|
36
|
+
def safe_mode
|
37
|
+
start
|
38
|
+
send_bytes(Modes::SAFE)
|
39
|
+
sleep 0.1
|
40
|
+
end
|
41
|
+
|
42
|
+
def full_mode
|
43
|
+
start
|
44
|
+
send_bytes(Modes::FULL)
|
45
|
+
sleep 0.1
|
46
|
+
end
|
47
|
+
|
48
|
+
def forward(seconds, velocity = SLOW)
|
49
|
+
drive(velocity,STRAIGHT,seconds)
|
50
|
+
stop if seconds > 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def stop
|
54
|
+
drive(ZERO,STRAIGHT)
|
55
|
+
end
|
56
|
+
|
57
|
+
def fast_forward(seconds)
|
58
|
+
drive(MAX,STRAIGHT,seconds)
|
59
|
+
stop if seconds > 0
|
60
|
+
end
|
61
|
+
|
62
|
+
def backwards(seconds)
|
63
|
+
drive(NEG,STRAIGHT,seconds)
|
64
|
+
stop if seconds > 0
|
65
|
+
end
|
66
|
+
|
67
|
+
def nudge_left
|
68
|
+
turn_left(0.25)
|
69
|
+
end
|
70
|
+
|
71
|
+
def turn_left(seconds = 1)
|
72
|
+
drive(SLOW,COUNTERCLOCKWISE,seconds)
|
73
|
+
stop if seconds > 0
|
74
|
+
end
|
75
|
+
|
76
|
+
def turn_right(seconds = 1)
|
77
|
+
drive(SLOW,CLOCKWISE,seconds)
|
78
|
+
stop if seconds > 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def nudge_right
|
82
|
+
turn_right(0.25)
|
83
|
+
end
|
84
|
+
|
85
|
+
def turn_around
|
86
|
+
turn_left(1.6)
|
87
|
+
end
|
88
|
+
|
89
|
+
def beep
|
90
|
+
notes = [140,0,1,G,WHOLE]
|
91
|
+
connection.send_bytes(notes)
|
92
|
+
connection.send_bytes([141,0])
|
93
|
+
end
|
94
|
+
|
95
|
+
def sing_jingle_bells
|
96
|
+
song0 = [[B,QUART],[B,QUART],[B,HALF],
|
97
|
+
[B,QUART],[B,QUART],[B,HALF],
|
98
|
+
[B,QUART],[D,QUART],[G,QUART],[A,QUART],
|
99
|
+
[B,WHOLE]]
|
100
|
+
song1 = [[C,QUART],[C,QUART],[C,QUART],[C,QUART],
|
101
|
+
[C,QUART],[B,QUART],[B,HALF],
|
102
|
+
[B,QUART],[A,QUART],[A,QUART],[B,QUART],
|
103
|
+
[A,HALF],[D,HALF]]
|
104
|
+
song2 = [[B,QUART],[B,QUART],[B,HALF],
|
105
|
+
[B,QUART],[B,QUART],[B,HALF],
|
106
|
+
[B,QUART],[D,QUART],[G,QUART],[A,QUART],
|
107
|
+
[B,WHOLE]]
|
108
|
+
song3 = [[C,QUART],[C,QUART],[C,QUART],[C,QUART],
|
109
|
+
[C,QUART],[B,QUART],[B,QUART],[B,QUART],
|
110
|
+
[D,QUART],[D,QUART],[C,QUART],[A,QUART],
|
111
|
+
[G,WHOLE]]
|
112
|
+
|
113
|
+
note_group = song0.flatten.compact
|
114
|
+
l = note_group.length / 2
|
115
|
+
notes = [140,0,l] + note_group
|
116
|
+
connection.send_bytes(notes)
|
117
|
+
|
118
|
+
note_group = song1.flatten.compact
|
119
|
+
l = note_group.length / 2
|
120
|
+
notes = [140,1,l] + note_group
|
121
|
+
connection.send_bytes(notes)
|
122
|
+
|
123
|
+
note_group = song2.flatten.compact
|
124
|
+
l = note_group.length / 2
|
125
|
+
notes = [140,2,l] + note_group
|
126
|
+
connection.send_bytes(notes)
|
127
|
+
|
128
|
+
note_group = song3.flatten.compact
|
129
|
+
l = note_group.length / 2
|
130
|
+
notes = [140,3,l] + note_group
|
131
|
+
connection.send_bytes(notes)
|
132
|
+
|
133
|
+
connection.send_bytes([141,0])
|
134
|
+
sleep(7)
|
135
|
+
connection.send_bytes([141,1])
|
136
|
+
sleep(7)
|
137
|
+
connection.send_bytes([141,2])
|
138
|
+
sleep(7)
|
139
|
+
connection.send_bytes([141,3])
|
140
|
+
end
|
141
|
+
|
142
|
+
def drive(v,r,s = 0)
|
143
|
+
vH,vL = split_bytes(v)
|
144
|
+
rH,rL = split_bytes(r)
|
145
|
+
connection.send_bytes([137,vH,vL,rH,rL])
|
146
|
+
sleep(s) if s > 0
|
147
|
+
end
|
148
|
+
|
149
|
+
def split_bytes(num)
|
150
|
+
[num >> 8, num & 255]
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'artoo/drivers/driver'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Drivers
|
5
|
+
# Servo behaviors for Firmata
|
6
|
+
class Servo < Driver
|
7
|
+
attr_reader :current_angle
|
8
|
+
|
9
|
+
def initialize(params={})
|
10
|
+
super
|
11
|
+
|
12
|
+
@current_angle = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def start_driver
|
16
|
+
every(interval) do
|
17
|
+
connection.read_and_process
|
18
|
+
end
|
19
|
+
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def move(angle)
|
24
|
+
raise "Servo angle must be an integer between 0-180" unless (angle.is_a?(Numeric) && angle >= 0 && angle <= 180)
|
25
|
+
|
26
|
+
@current_angle = angle
|
27
|
+
connection.set_pin_mode(pin, Firmata::Board::SERVO)
|
28
|
+
connection.analog_write(pin, angle_to_span(angle))
|
29
|
+
end
|
30
|
+
|
31
|
+
def min
|
32
|
+
move(0)
|
33
|
+
end
|
34
|
+
|
35
|
+
def center
|
36
|
+
move(90)
|
37
|
+
end
|
38
|
+
|
39
|
+
def max
|
40
|
+
move(180)
|
41
|
+
end
|
42
|
+
|
43
|
+
# converts an angle to a span between 0-255
|
44
|
+
def angle_to_span(angle)
|
45
|
+
(angle * 255 / 180).to_i
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -4,26 +4,105 @@ module Artoo
|
|
4
4
|
module Drivers
|
5
5
|
# Wiichuck driver behaviors for Firmata
|
6
6
|
class Wiichuck < Driver
|
7
|
+
attr_reader :joystick
|
8
|
+
|
7
9
|
def address; 0x52; end
|
8
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
|
+
|
9
21
|
def start_driver
|
22
|
+
begin
|
10
23
|
listener = ->(value) { update(value) }
|
11
24
|
connection.on("i2c_reply", listener)
|
12
25
|
|
13
|
-
connection.i2c_config(
|
14
|
-
connection.i2c_request(address, 0x40, 0x00)
|
15
|
-
|
26
|
+
connection.i2c_config(0)
|
16
27
|
every(interval) do
|
17
|
-
connection.
|
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
|
18
34
|
connection.read_and_process
|
19
35
|
end
|
20
|
-
|
36
|
+
|
21
37
|
super
|
38
|
+
rescue Exception => e
|
39
|
+
p "start driver"
|
40
|
+
p e.message
|
41
|
+
p e.backtrace.inspect
|
42
|
+
end
|
43
|
+
|
22
44
|
end
|
23
45
|
|
24
46
|
def update(value)
|
25
|
-
|
47
|
+
begin
|
48
|
+
if encrypted?(value)
|
49
|
+
Logger.error "Encrypted bytes from wiichuck!"
|
50
|
+
return
|
51
|
+
end
|
52
|
+
|
53
|
+
data = parse_wiichuck(value)
|
54
|
+
|
55
|
+
adjust_origins(data)
|
56
|
+
update_buttons(data)
|
57
|
+
update_joystick(data)
|
58
|
+
|
59
|
+
rescue Exception => e
|
60
|
+
Logger.error "wiichuck update exception!"
|
61
|
+
Logger.error e.message
|
62
|
+
Logger.error e.backtrace.inspect
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def adjust_origins(data)
|
67
|
+
set_joystick_default_value(:sy_origin, data[:sy])
|
68
|
+
set_joystick_default_value(:sx_origin, data[:sx])
|
69
|
+
end
|
70
|
+
|
71
|
+
def set_joystick_default_value(joystick_axis, default_value)
|
72
|
+
joystick[joystick_axis] = default_value if joystick[joystick_axis].nil?
|
73
|
+
end
|
74
|
+
|
75
|
+
def update_buttons(data)
|
76
|
+
publish(event_topic_name("c_button")) if data[:c] == true
|
77
|
+
publish(event_topic_name("z_button")) if data[:z] == true
|
78
|
+
end
|
79
|
+
|
80
|
+
def update_joystick(data)
|
81
|
+
publish(event_topic_name("joystick"), {:x => data[:sx] - @joystick[:sx_origin], :y => data[:sy] - @joystick[:sy_origin]})
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def encrypted?(value)
|
87
|
+
value[:data][0] == value[:data][1] && value[:data][2] == value[:data][3] && value[:data][4] == value[:data][5]
|
88
|
+
end
|
89
|
+
|
90
|
+
def decode( x )
|
91
|
+
return ( x ^ 0x17 ) + 0x17
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_value(value, index)
|
95
|
+
decode(value[:data][index])
|
96
|
+
end
|
97
|
+
|
98
|
+
def parse_wiichuck(value)
|
99
|
+
return {
|
100
|
+
:sx => get_value(value, 0),
|
101
|
+
:sy => get_value(value, 1),
|
102
|
+
:z => (get_value(value, 5) & 0x01 == 0 ? true : false ),
|
103
|
+
:c => (get_value(value, 5) & 0x02 == 0 ? true : false )
|
104
|
+
}
|
26
105
|
end
|
27
106
|
end
|
28
107
|
end
|
29
|
-
end
|
108
|
+
end
|
@@ -2,26 +2,28 @@ require 'artoo/drivers/driver'
|
|
2
2
|
|
3
3
|
module Artoo
|
4
4
|
module Drivers
|
5
|
-
#
|
5
|
+
# Wiiclassic driver behaviors for Firmata
|
6
6
|
class Wiiclassic < Driver
|
7
|
+
attr_reader :joystick
|
8
|
+
|
7
9
|
def address; 0x52; end
|
8
10
|
|
9
11
|
INITIAL_DEFAULTS = {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
21
24
|
|
22
25
|
def start_driver
|
23
26
|
begin
|
24
|
-
@joystick = INITIAL_DEFAULTS
|
25
27
|
listener = ->(value) { update(value) }
|
26
28
|
connection.on("i2c_reply", listener)
|
27
29
|
|
@@ -47,70 +49,68 @@ module Artoo
|
|
47
49
|
|
48
50
|
def update(value)
|
49
51
|
begin
|
50
|
-
if value
|
52
|
+
if encrypted?(value)
|
51
53
|
Logger.error "Encrypted bytes from wiiclassic!"
|
52
54
|
return
|
53
55
|
end
|
54
56
|
|
55
57
|
data = parse_wiiclassic(value)
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
publish(event_topic_name("start_button")) if data[:+] == 0
|
63
|
-
publish(event_topic_name("select_button")) if data[:-] == 0
|
64
|
-
|
65
|
-
@joystick[:ly_origin] = data[:ly] if @joystick[:ly_origin].nil?
|
66
|
-
@joystick[:lx_origin] = data[:lx] if @joystick[:lx_origin].nil?
|
67
|
-
|
68
|
-
@joystick[:ry_origin] = data[:ry] if @joystick[:ry_origin].nil?
|
69
|
-
|
70
|
-
@joystick[:rt_origin] = data[:rt] if @joystick[:rt_origin].nil?
|
71
|
-
@joystick[:lt_origin] = data[:lt] if @joystick[:lt_origin].nil?
|
72
|
-
|
73
|
-
update_left_joystick
|
74
|
-
|
75
|
-
if data[:ry] > (@joystick[:ry_origin] + @joystick[:ry_offset])
|
76
|
-
publish(event_topic_name("ry_up"))
|
77
|
-
elsif data[:ry] < (@joystick[:ry_origin] - @joystick[:ry_offset])
|
78
|
-
publish(event_topic_name("ry_down"))
|
79
|
-
else
|
80
|
-
publish(event_topic_name("reset_altitude"))
|
81
|
-
end
|
82
|
-
|
83
|
-
if data[:rt] > (@joystick[:rt_origin] + @joystick[:rt_offset])
|
84
|
-
publish(event_topic_name("rotate_right"))
|
85
|
-
elsif data[:lt] > (@joystick[:lt_origin] + @joystick[:lt_offset])
|
86
|
-
publish(event_topic_name("rotate_left"))
|
87
|
-
else
|
88
|
-
publish(event_topic_name("reset_rotate"))
|
89
|
-
end
|
59
|
+
adjust_origins(data)
|
60
|
+
update_buttons(data)
|
61
|
+
update_left_joystick(data)
|
62
|
+
update_right_joystick(data)
|
63
|
+
update_triggers(data)
|
90
64
|
|
91
65
|
rescue Exception => e
|
92
|
-
|
93
|
-
|
94
|
-
|
66
|
+
Logger.error "wiiclassic update exception!"
|
67
|
+
Logger.error e.message
|
68
|
+
Logger.error e.backtrace.inspect
|
95
69
|
end
|
96
70
|
end
|
97
71
|
|
98
|
-
def
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
72
|
+
def adjust_origins(data)
|
73
|
+
set_joystick_default_value(:ly_origin, data[:ly])
|
74
|
+
set_joystick_default_value(:lx_origin, data[:lx])
|
75
|
+
set_joystick_default_value(:ry_origin, data[:ry])
|
76
|
+
set_joystick_default_value(:rx_origin, data[:rx])
|
77
|
+
set_joystick_default_value(:rt_origin, data[:rt])
|
78
|
+
set_joystick_default_value(:lt_origin, data[:lt])
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_joystick_default_value(joystick_axis, default_value)
|
82
|
+
joystick[joystick_axis] = default_value if joystick[joystick_axis].nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
def update_buttons(data)
|
86
|
+
publish(event_topic_name("a_button")) if data[:a] == true
|
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
|
93
|
+
end
|
94
|
+
|
95
|
+
def update_left_joystick(data)
|
96
|
+
publish(event_topic_name("left_joystick"), {:x => data[:lx] - @joystick[:lx_origin], :y => data[:ly] - @joystick[:ly_origin]})
|
97
|
+
end
|
98
|
+
|
99
|
+
def update_right_joystick(data)
|
100
|
+
publish(event_topic_name("right_joystick"), {:x => data[:rx] - @joystick[:rx_origin], :y => data[:ry] - @joystick[:ry_origin]})
|
101
|
+
end
|
102
|
+
|
103
|
+
def update_triggers(data)
|
104
|
+
publish(event_topic_name("right_trigger"), data[:rt] - @joystick[:rt_origin])
|
105
|
+
publish(event_topic_name("left_trigger"), data[:lt] - @joystick[:lt_origin])
|
110
106
|
end
|
111
107
|
|
112
108
|
private
|
113
109
|
|
110
|
+
def encrypted?(value)
|
111
|
+
value[:data][0] == value[:data][1] && value[:data][2] == value[:data][3] && value[:data][4] == value[:data][5]
|
112
|
+
end
|
113
|
+
|
114
114
|
def decode( x )
|
115
115
|
return ( x ^ 0x17 ) + 0x17
|
116
116
|
end
|
@@ -125,23 +125,27 @@ module Artoo
|
|
125
125
|
:ly => get_value(value, 1) & 0x3f,
|
126
126
|
:rx => ((get_value(value, 0) & 0xC0) >> 2) | ((get_value(value, 1) & 0xC0) >> 4) | (get_value(value, 2)[7]),
|
127
127
|
:ry => get_value(value, 2) & 0x1f,
|
128
|
-
:lt => ((get_value(value, 2) & 0x60) >> 3) | ((get_value(value, 3) &
|
128
|
+
:lt => ((get_value(value, 2) & 0x60) >> 3) | ((get_value(value, 3) & 0xC0) >> 6),
|
129
129
|
:rt => get_value(value, 3) & 0x1f,
|
130
|
-
:d_up => get_value(value, 5)[0],
|
131
|
-
:d_down => get_value(value, 4)[6],
|
132
|
-
:
|
133
|
-
:
|
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],
|
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]),
|
143
143
|
}
|
144
144
|
end
|
145
|
+
|
146
|
+
def generate_bool(value)
|
147
|
+
value == 0 ? true : false
|
148
|
+
end
|
145
149
|
end
|
146
150
|
end
|
147
151
|
end
|