brick-pi 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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