brick-pi 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d3978e422e7aef842b14c7fa85775465b3de0c2b
4
- data.tar.gz: e4a48cd6cf90ef8fb77ebe2ec3a0a884580ebecb
3
+ metadata.gz: 403b67c29e0a5deac1e7fa65c2e28f6547c8fdfa
4
+ data.tar.gz: c156cc0857f29fa08d56c65f2138ca85a8a0348f
5
5
  SHA512:
6
- metadata.gz: 73681522c98b6d7c0536730f95d51992d0279ee45d39d093485c95b77a7e9c890459882525adc3b66fb1b902c70b01bc45de98274d44695e4d711c2bc5cd44fc
7
- data.tar.gz: 78ef2add72b15a2c63038406c74d6946d83b2df7b5ba586cddbfae2bab5838517ca59cd0a5d85d6c1f96c5d1f08b391e08733fe1b1845e009c4ee87c124624fd
6
+ metadata.gz: 5734a423bea697b0665431865f834b257368f630f2a5ad0ef478c29e00b03d8b854260c0c034c6d84af52e7bfa61b57ee861b2419cf9fcadf2781fb0be182141
7
+ data.tar.gz: 018446a9b9269f5b20a7ee68fe6af86c3719a886ced5db8ba4d5fcc8c37b17934a115e72dd5c93337de06c13d0ee8924ea6e4058cdec9c6146bb16b409e9ec4e
data/README.md CHANGED
@@ -43,28 +43,29 @@ Here's a quick & dirty script to spin a motor:
43
43
  require 'brick_pi'
44
44
 
45
45
  # Create a bot with a motor on port A
46
- bot = BrickPi.create do |bot|
47
- bot.motor :port_A
48
- end
49
-
50
- # Get this party started
51
- bot.start do
52
- schedule do
53
- # Set the speed for a motor, on a scale of 0 - 100
54
- bot.motor_A.spin 50
55
-
56
- # Run the motor for 1 second
57
- sleep 1
46
+ class HelloBot < BrickPi::Bot
47
+ motor :port_A
58
48
 
59
- # Stop a single motor
60
- bot.motor_A.stop
49
+ # Declare a property to adjust speed at any time
50
+ property :motor_speed do |value|
51
+ # This `motor :port_A` to `@motor_A` mapping is yucky, sorry bout that
52
+ @motor_A.spin value
61
53
  end
62
54
  end
55
+
56
+ # Get this party started
57
+ bot = HelloBot.new
58
+ bot.motor_speed = 80
59
+ bot.start
60
+ sleep 2
61
+ bot.motor_speed - -80
62
+ sleep 2
63
+ bot.stop
63
64
  ```
64
65
 
65
- Once your bot is started, you can change the speed or direction of the motors at any time with the `Motor#spin` method.
66
+ Once your bot is started, you can change the speed or direction of the motors at any time.
66
67
 
67
- Here's a really yucky script I hacked together to let you drive a 2-tracked vehicle with an iCade 8-Bitty (which is basically a bluetooth keyboard that looks like an NES controller).
68
+ Here's a custom bot class and quick script to let you drive a 2-tracked vehicle with an iCade 8-Bitty (which is basically a bluetooth keyboard that looks like an NES controller).
68
69
 
69
70
  It requires the Highline gem, so on the BrickPi you'll need to run `gem install highline`.
70
71
 
@@ -75,92 +76,88 @@ include HighLine::SystemExtensions
75
76
  HighLine::SystemExtensions.raw_no_echo_mode
76
77
 
77
78
  # Create a bot with two motors
78
- bot = BrickPi.create do |bot|
79
- bot.motor :port_A
80
- bot.motor :port_B
81
- bot.ultrasonic_sensor :port_3
82
- end
83
-
84
- bot.singleton_class.class_eval do
79
+ class DemoBot < BrickPi::Bot
85
80
  attr_accessor :speed
86
-
87
- def move_forward
88
- schedule do |op|
89
- motor_A.spin speed
90
- motor_B.spin speed
91
- end
81
+ motor :port_A
82
+ motor :port_B
83
+ ultrasonic_sensor :port_3
84
+
85
+ # A property is always settable and gettable, even while things are running.
86
+ property :forward_speed do |value|
87
+ @motor_A.spin value
88
+ @motor_B.spin value
92
89
  end
93
90
 
94
- def move_backward
95
- schedule do
96
- motor_A.spin 0 - speed
97
- motor_B.spin 0 - speed
98
- end
91
+ # Properties are applied in order. Since it comes second, this trumps forward_speed.
92
+ property :rotation_speed do |value|
93
+ @motor_A.spin -1 * value
94
+ @motor_B.spin value
99
95
  end
100
96
 
101
97
  def turn_left
102
- schedule do
103
- motor_A.spin speed
104
- motor_B.spin 0 - speed
105
- end
98
+ self.rotation_speed = -1 * speed
106
99
  end
107
100
 
108
101
  def turn_right
109
- schedule do
110
- motor_A.spin 0 - speed
111
- motor_B.spin speed
112
- end
102
+ self.rotation_speed = speed
103
+ end
104
+
105
+ def move_forward
106
+ # Since rotation speed trumps forward speed, you need to EXTERMINATE it.
107
+ self.rotation_speed = nil
108
+ self.forward_speed = speed
109
+ end
110
+
111
+ def move_backward
112
+ self.rotation_speed = nil
113
+ self.forward_speed = -1 * speed
113
114
  end
114
115
 
115
116
  def increase_speed
116
- schedule do
117
- if speed >=0 && speed <= 80
118
- self.speed += 20
119
- end
117
+ if speed >=0 && speed <= 80
118
+ self.speed += 20
120
119
  end
121
120
  end
122
121
 
123
122
  def decrease_speed
124
- schedule do
125
- if speed > 20 && speed <= 100
126
- self.speed -= 20
127
- end
123
+ if speed > 20 && speed <= 100
124
+ self.speed -= 20
128
125
  end
129
126
  end
130
127
 
131
128
  def stop_motors
132
- schedule do
133
- motor_A.stop
134
- motor_B.stop
135
- end
129
+ self.rotation_speed = nil
130
+ self.forward_speed = 0
136
131
  end
137
132
 
138
133
  end
139
134
 
140
- bot.start do
141
- bot.speed = 60
142
- loop do
143
- unless bot.sensor_3.distance == 0
144
- puts "*****SENSOR DISTANCE:*****"
145
- puts bot.sensor_3.distance
146
- end
147
- char = HighLine::SystemExtensions.get_character
148
- case char.chr
149
- when 'w'
150
- bot.move_forward
151
- when 'd'
152
- bot.turn_left
153
- when 'a'
154
- bot.turn_right
155
- when 'x'
156
- bot.move_backward
157
- when 'o'
158
- bot.increase_speed
159
- when 'l'
160
- bot.decrease_speed
161
- when 'e', 'c', 'z', 'q'
162
- bot.stop_motors
163
- end
135
+ @bot = DemoBot.new
136
+ @bot.start
137
+ @bot.speed = 60
138
+ puts "bot ready!"
139
+
140
+ loop do
141
+ unless @bot.sensor_3.distance == 0
142
+ print "SENSOR DISTANCE: "
143
+ puts @bot.sensor_3.distance
144
+ end
145
+ char = HighLine::SystemExtensions.get_character
146
+ case char.chr
147
+ when 'w'
148
+ @bot.move_forward
149
+ when 'd'
150
+ @bot.turn_left
151
+ when 'a'
152
+ @bot.turn_right
153
+ when 'x'
154
+ @bot.move_backward
155
+ when 'o'
156
+ @bot.increase_speed
157
+ when 'l'
158
+ @bot.decrease_speed
159
+ when 'e', 'c', 'z', 'q'
160
+ @bot.stop_motors
164
161
  end
165
162
  end
166
163
  ```
@@ -170,12 +167,12 @@ end
170
167
  You can read values from sensors by doing something like this:
171
168
 
172
169
  ```
173
- bot = BrickPi.create do |bot|
174
- bot.touch_sensor :port_1
175
- end
176
- bot.run do
177
- bot.sensor_1.read
170
+ class SensorBot = BrickPi::Bot
171
+ touch_sensor :port_1
178
172
  end
173
+
174
+ bot = DemoBot.new
175
+ bot.sensor_1.read
179
176
  ```
180
177
 
181
178
  See the scripts in the `examples` directory for more details.
@@ -194,4 +191,3 @@ See the scripts in the `examples` directory for more details.
194
191
  I use HuBoard to manage GitHub issues. It's pretty awesome, check it out here:
195
192
 
196
193
  https://huboard.com/tehviking/brick_pi_ruby/
197
-
@@ -1,6 +1,5 @@
1
1
  require "brick_pi/version"
2
2
  require "brick_pi/native"
3
- require "brick_pi/configuration"
4
3
  require "brick_pi/bot"
5
4
  require "brick_pi/motor"
6
5
  require "brick_pi/sensor"
@@ -3,9 +3,6 @@ include BrickPi
3
3
 
4
4
  module BrickPi
5
5
  class Bot
6
-
7
- include BrickPi::Configuration
8
-
9
6
  attr_accessor :motor_A, :motor_B, :motor_C, :motor_D
10
7
  attr_accessor :sensor_1, :sensor_2, :sensor_3, :sensor_4
11
8
 
@@ -13,7 +10,9 @@ module BrickPi
13
10
  Native.BrickPiSetup()
14
11
  Native::Address[0] = 1
15
12
  Native::Address[1] = 2
16
- @queue = Queue.new
13
+ self.class.initializers.each do |initializer|
14
+ instance_eval &initializer
15
+ end
17
16
  end
18
17
 
19
18
  def start
@@ -23,35 +22,100 @@ module BrickPi
23
22
  Native.BrickPiSetTimeout()
24
23
  Thread.new do
25
24
  until @stop do
25
+ tick()
26
26
  Native.BrickPiUpdateValues()
27
27
  sleep 50/1000
28
28
  end
29
29
  end
30
- Thread.new do
31
- until @stop do
32
- code = @queue.pop
33
- begin
34
- code.call
35
- rescue => e
36
- $stderr.puts e.message
37
- $stderr.puts e.backtrace.join("\n")
30
+ end
31
+
32
+ def tick
33
+ self.class.devices.each { |d| d.zero }
34
+ self.class.properties.each { |p| p.apply self }
35
+ rescue Exception => e
36
+ $stderr.puts e.message
37
+ $stderr.puts e.backtrace.join "\n"
38
+ end
39
+
40
+ def stop
41
+ @stop = true
42
+ end
43
+
44
+ class << self
45
+ attr_reader :properties, :devices, :initializers
46
+
47
+ def property(name, &body)
48
+ @properties ||= []
49
+ @properties << Property.new(name, body)
50
+ send(:attr_accessor, name)
51
+ end
52
+
53
+ def device(device)
54
+ device.tap do
55
+ @devices ||= []
56
+ @devices << device
57
+ end
58
+ end
59
+
60
+ def initializer(&body)
61
+ @initializers ||= []
62
+ @initializers << body
63
+ end
64
+
65
+ def motor(port)
66
+ initializer do
67
+ case port
68
+ when :port_A
69
+ @motor_A = self.class.device BrickPi::Motor.new(Native::PORT_A)
70
+ when :port_B
71
+ @motor_B = self.class.device BrickPi::Motor.new(Native::PORT_B)
72
+ when :port_C
73
+ @motor_C = self.class.device BrickPi::Motor.new(Native::PORT_C)
74
+ when :port_D
75
+ @motor_D = self.class.device BrickPi::Motor.new(Native::PORT_D)
38
76
  end
39
77
  end
40
78
  end
41
- Thread.new do
42
- yield
43
- end.join
44
- stop
45
- end
46
79
 
47
- def stop
48
- schedule do
49
- @stop = true
80
+ def sensor(port, sensor_type)
81
+ initializer do
82
+ case port
83
+ when :port_1
84
+ @sensor_1 = self.class.device BrickPi::Sensor.new(:port_1, sensor_type)
85
+ when :port_2
86
+ @sensor_2 = self.class.device BrickPi::Sensor.new(:port_2, sensor_type)
87
+ when :port_3
88
+ @sensor_3 = self.class.device BrickPi::Sensor.new(:port_3, sensor_type)
89
+ when :port_4
90
+ @sensor_4 = self.class.device BrickPi::Sensor.new(:port_4, sensor_type)
91
+ end
92
+ end
93
+ end
94
+
95
+ def touch_sensor(port)
96
+ sensor(port, :touch)
97
+ end
98
+
99
+ def ultrasonic_sensor(port)
100
+ sensor(port, :ultrasonic)
101
+ end
102
+
103
+ def color_sensor(port)
104
+ sensor(port, :color)
50
105
  end
51
106
  end
52
107
 
53
- def schedule(&block)
54
- @queue.push block
108
+ class Property
109
+ def initialize(name, body)
110
+ @name, @body = name, body
111
+ end
112
+
113
+ def apply(bot)
114
+ value = bot.send(@name)
115
+ if !value.nil?
116
+ bot.instance_exec(value, &@body)
117
+ end
118
+ end
55
119
  end
56
120
  end
57
121
  end
@@ -8,7 +8,6 @@ module BrickPi
8
8
  def spin(speed)
9
9
  speed = [-100, [100, speed].min].max
10
10
  motor_speed = (speed * 2.55).round
11
- puts motor_speed
12
11
  Native::MotorSpeed[@port] = motor_speed
13
12
  end
14
13
 
@@ -21,5 +20,7 @@ module BrickPi
21
20
  def stop
22
21
  spin 0
23
22
  end
23
+
24
+ alias_method :zero, :stop
24
25
  end
25
26
  end
@@ -39,5 +39,8 @@ module BrickPi
39
39
  read if @sensor_type == :ultrasonic
40
40
  end
41
41
 
42
+ def zero
43
+ end
44
+
42
45
  end
43
46
  end
@@ -1,3 +1,3 @@
1
1
  module BrickPi
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brick-pi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Hays
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-16 00:00:00.000000000 Z
12
+ date: 2014-09-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -80,7 +80,6 @@ files:
80
80
  - ext/brick_pi/tick.h
81
81
  - lib/brick_pi.rb
82
82
  - lib/brick_pi/bot.rb
83
- - lib/brick_pi/configuration.rb
84
83
  - lib/brick_pi/motor.rb
85
84
  - lib/brick_pi/sensor.rb
86
85
  - lib/brick_pi/version.rb
@@ -1,55 +0,0 @@
1
- module BrickPi
2
-
3
- def self.create &block
4
- bot = BrickPi::Bot.new
5
- bot.configure &block
6
- bot
7
- end
8
-
9
- module Configuration
10
-
11
- def configure &block
12
- yield self
13
- end
14
-
15
- def motor(port)
16
- case port
17
- when :port_A
18
- @motor_A = BrickPi::Motor.new(Native::PORT_A)
19
- when :port_B
20
- @motor_B = BrickPi::Motor.new(Native::PORT_B)
21
- when :port_C
22
- @motor_C = BrickPi::Motor.new(Native::PORT_C)
23
- when :port_D
24
- @motor_D = BrickPi::Motor.new(Native::PORT_D)
25
- end
26
- end
27
-
28
- def sensor(port, sensor_type)
29
- case port
30
- when :port_1
31
- @sensor_1 = BrickPi::Sensor.new(:port_1, sensor_type)
32
- when :port_2
33
- @sensor_2 = BrickPi::Sensor.new(:port_2, sensor_type)
34
- when :port_3
35
- @sensor_3 = BrickPi::Sensor.new(:port_3, sensor_type)
36
- when :port_4
37
- @sensor_4 = BrickPi::Sensor.new(:port_4, sensor_type)
38
- end
39
- end
40
-
41
- def touch_sensor(port)
42
- sensor(port, :touch)
43
- end
44
-
45
- def ultrasonic_sensor(port)
46
- sensor(port, :ultrasonic)
47
- end
48
-
49
- def color_sensor(port)
50
- sensor(port, :color)
51
- end
52
-
53
- end
54
-
55
- end