akshayrawat-rmotion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,6 @@
1
+ Ruby bindings to the Unimotion library. Reads output from the Apple Sudden Motion Sensors.
2
+
3
+ X is left/right tilt, Y is forward/back, and Z is the change in G force.
4
+ iBook/Powerbook 1G = ~50, positive force = left, towards you, down
5
+ High-res Powerbook 1G = ~50, positive force = right, away from you, up
6
+ MacBook [Pro] 1G = ~250, positive force = left, towards you, down
@@ -0,0 +1,17 @@
1
+ ######################################################################
2
+
3
+ # Copyright 2008 by Akshay Rawat (projectsatakshaydotcc).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+
10
+ ######################################################################
11
+
12
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/rubyturtles")
13
+
14
+ require File.dirname(__FILE__) + "/../../lib/rmotion"
15
+ require 'tkturtle'
16
+ require 'turtle'
17
+ require 'turtle_patch'
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- ruby -*-
3
+
4
+ # Copyright 2001 by Jim Weirich (jweirich@one.net).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+
11
+ require 'tk'
12
+ require 'turtle'
13
+ require 'singleton'
14
+
15
+ ######################################################################
16
+ # Main module for implementing turtle graphics.
17
+ #
18
+ # This file adds a TK based canvas and world for TK turtle graphics.
19
+ #
20
+ module TurtleGraphics
21
+
22
+ ######################################################################
23
+ # Canvas used to adapt a turtle to a TK Canvas Object.
24
+ #
25
+ class TkTurtleCanvas
26
+
27
+ def initialize(tkcanvas)
28
+ @canvas = tkcanvas
29
+ end
30
+
31
+ ## Draw a line from the start point to the end point. Return an ID
32
+ # used to reference the line later.
33
+ def draw_line(p1, p2)
34
+ x1, y1 = transform(p1)
35
+ x2, y2 = transform(p2)
36
+ TkcLine.new(@canvas, x1, y1, x2, y2)
37
+ end
38
+
39
+ ## Erase the line represented by _id_.
40
+ def erase_line(id)
41
+ id.destroy
42
+ end
43
+
44
+ IconShape = [[5,0],[-5,0],[0,15]]
45
+
46
+ ## Display the turtle icon. Return an icon ID used to reference
47
+ # the ID later.
48
+ def show_icon(heading, position)
49
+ tx, ty = transform(position)
50
+ angle = heading * Math::PI/180
51
+ points = IconShape.map { |x,y|
52
+ [ tx + x * Math.cos(angle) + y * Math.sin(angle),
53
+ ty + x * Math.sin(angle) - y * Math.cos(angle)
54
+ ]
55
+ }
56
+ (0...3).collect { |i|
57
+ TkcLine.new(@canvas,
58
+ points[i][0], points[i][1],
59
+ points[(i+1)%3][0], points[(i+1)%3][1])
60
+ }
61
+ end
62
+
63
+ ## Hide the icon represented by _id_.
64
+ def hide_icon(icon)
65
+ icon.each { |widget| widget.destroy }
66
+ end
67
+
68
+ private # --------------------------------------------------------
69
+
70
+ ## Transform a point in turtle graphics to a TK canvas point.
71
+ def transform(point)
72
+ [point[0]+250, 250-point[1]]
73
+ end
74
+ end
75
+
76
+
77
+ ######################################################################
78
+ # A TK based turtle world.
79
+ #
80
+ class TkWorld < TurtleGraphics::TurtleWorld
81
+ include Singleton
82
+
83
+ ## The canvas to be used for TK graphics. We will auto create the
84
+ # canvas if it is not already defined.
85
+ def canvas
86
+ @canvas ||= create_canvas
87
+ end
88
+
89
+ private
90
+
91
+ ## Create a TK canvas object.
92
+ def create_canvas
93
+ root = TkRoot.new { title "TK Turtle World" }
94
+ c = TkCanvas.new(root) {
95
+ height 500
96
+ width 500
97
+ }
98
+ c.pack
99
+ @canvas = TkTurtleCanvas.new(c)
100
+ @thread = Thread.new { Tk.mainloop }
101
+ @canvas
102
+ end
103
+
104
+ end
105
+ end
106
+
107
+ ## Use the TK world object by default.
108
+ Turtle.world = TurtleGraphics::TkWorld.instance
@@ -0,0 +1,328 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- ruby -*-
3
+
4
+ # Copyright 2001 by Jim Weirich (jweirich@one.net).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+
11
+ ######################################################################
12
+ # Main module for implementing turtle graphics.
13
+ #
14
+ module TurtleGraphics
15
+
16
+ include Math
17
+
18
+ ######################################################################
19
+ # Abbreviated commands for interactive turtles. This makes using
20
+ # turtles in IRB a little easier.
21
+ #
22
+ module TurtleAbbreviations
23
+ def fd(n=10); forward(n); end
24
+ def bk(n=10); back(n); end
25
+ def t(a); turn(a); end
26
+ def rt; right; end
27
+ def lt; left; end
28
+ def hd; hide; end
29
+ def sh; show; end
30
+ def pu; penup; end
31
+ def pd; pendown; end
32
+ def hm; home; end
33
+ end
34
+
35
+
36
+ ######################################################################
37
+ # Universal canvas object that does absolutely nothing. We use this
38
+ # canvas by default if a real graphical canvas hasn't been defined.
39
+ #
40
+ class DefaultCanvas
41
+
42
+ ## Draw a line from the start point to the end point. Return an ID
43
+ # used to reference the line later.
44
+ def draw_line(start_point, end_point); nil; end
45
+
46
+ ## Erase the line represented by _id_.
47
+ def erase_line(id); end
48
+
49
+ ## Display the turtle icon. Return an icon ID used to reference
50
+ # the ID later.
51
+ def show_icon(heading, position); nil; end
52
+
53
+ ## Hide the icon represented by _id_.
54
+ def hide_icon(id); end
55
+ end
56
+
57
+
58
+ ######################################################################
59
+ # Turtle objects. Turtle objects respond to relative movement
60
+ # commands (e.g. forward, backward, turn), as well as a few commands
61
+ # to control the pen.
62
+ #
63
+ class Turtle
64
+
65
+ include TurtleAbbreviations
66
+ attr_reader :heading
67
+
68
+ DEG2RAD = Math::PI/180
69
+
70
+ # Class Methods --------------------------------------------------
71
+
72
+ class << self
73
+ ## The world to use for newly created turtles.
74
+ def world
75
+ @world ||= TurtleWorld.new
76
+ end
77
+
78
+ ## Set the world.
79
+ def world=(new_world)
80
+ @world = new_world
81
+ end
82
+ end
83
+
84
+ # Creation ---------------------------------------------------------
85
+
86
+ def initialize
87
+ @canvas = self.class.world.canvas
88
+ @position = [0,0]
89
+ @penup = true
90
+ @hidden = true
91
+ @lines = []
92
+ self.heading = 0
93
+ Turtle.world.add(self)
94
+ show
95
+ end
96
+
97
+ # Queries ----------------------------------------------------------
98
+
99
+ ## Is the turtle hidden?
100
+ def hidden?
101
+ @hidden
102
+ end
103
+
104
+ ## Is the pen up?
105
+ def penup?
106
+ @penup
107
+ end
108
+
109
+ ## Array containing the X/Y position of the turtle.
110
+ def position
111
+ @position.dup
112
+ end
113
+
114
+ # Basic Movement ---------------------------------------------------
115
+
116
+ ## Set the position of turtle.
117
+ def position=(new_position)
118
+ old_position = @position
119
+ move_turtle {
120
+ @position = new_position
121
+ if not penup?
122
+ @lines << @canvas.draw_line(old_position, position)
123
+ end
124
+ }
125
+ @position
126
+ end
127
+
128
+ ## Set the heading of the turtle. Zero is straight up.
129
+ def heading=(value)
130
+ while value < 0
131
+ value += 360
132
+ end
133
+ move_turtle { @heading = (value % 360) }
134
+ value
135
+ end
136
+
137
+ # Movement ---------------------------------------------------------
138
+
139
+ ## Send the turtle home.
140
+ def home
141
+ self.position = [0,0]
142
+ self.heading = 0
143
+ end
144
+
145
+ ## Move the turtle forward.
146
+ def forward(amount)
147
+ dx = amount * Math.sin(@heading*DEG2RAD)
148
+ dy = amount * Math.cos(@heading*DEG2RAD)
149
+ self.position = [@position[0]+dx, @position[1]+dy]
150
+ end
151
+
152
+ ## Move the turtle backwards.
153
+ def backward(amount)
154
+ forward(-amount)
155
+ end
156
+
157
+ ## Turn the turtle. Positive degrees turns to the right.
158
+ def turn(degrees)
159
+ self.heading = @heading + degrees
160
+ end
161
+
162
+ ## Turn 90 degrees to the left.
163
+ def left
164
+ turn(-90)
165
+ end
166
+
167
+ ## Turn 90 degrees to the right.
168
+ def right
169
+ turn(90)
170
+ end
171
+
172
+ # Drawing ----------------------------------------------------------
173
+
174
+ ## Hide the turtle icon.
175
+ def hide
176
+ move_turtle { @hidden = true }
177
+ nil
178
+ end
179
+
180
+ ## Show the turtle icon.
181
+ def show
182
+ move_turtle { @hidden = false }
183
+ nil
184
+ end
185
+
186
+ ## Left the pen off the drawing surface.
187
+ def penup
188
+ @penup = true
189
+ nil
190
+ end
191
+
192
+ ## Set the pen down on the drawing surface.
193
+ def pendown
194
+ @penup = false
195
+ nil
196
+ end
197
+
198
+ ## Erase all the lines drawn by this turtle.
199
+ def clear
200
+ @lines.each { |lineid| @canvas.erase_line(lineid) }
201
+ @lines = []
202
+ end
203
+
204
+ # Other ------------------------------------------------------------
205
+
206
+ def inspect
207
+ "Turtle(#{@heading},[#{@position.join(',')}])"
208
+ end
209
+
210
+ private # ----------------------------------------------------------
211
+
212
+ ## Move the turtle. Make sure the icon is hidden before the turtle
213
+ # is moved.
214
+ def move_turtle
215
+ @canvas.hide_icon(@icon) if ! hidden?
216
+ yield
217
+ @icon = @canvas.show_icon(heading, position) if ! hidden?
218
+ end
219
+ end
220
+
221
+
222
+ ######################################################################
223
+ # A composite of many turtles. A composite turtle controls a number
224
+ # of other turtles. Turtle commands are sent to each of its
225
+ # sub-turtles.
226
+ #
227
+ class CompositeTurtle < Turtle
228
+ include TurtleAbbreviations
229
+ include Enumerable
230
+
231
+ attr_reader :turtles
232
+
233
+ def initialize(turtles=nil)
234
+ @turtles = turtles
235
+ @turtles ||= Array.new
236
+ end
237
+
238
+ def add(turtle)
239
+ @turtles << turtle
240
+ end
241
+
242
+ def each(&block)
243
+ @turtles.each(&block)
244
+ end
245
+
246
+ def [](index)
247
+ @turtles[index]
248
+ end
249
+
250
+ def size
251
+ @turtles.size
252
+ end
253
+
254
+ # Turtle Protocol ------------------------------------------------
255
+
256
+ def forward(n)
257
+ @turtles.each { |t| t.forward(n) }
258
+ end
259
+
260
+ def backward(n)
261
+ @turtles.each { |t| t.backward(n) }
262
+ end
263
+
264
+ def turn(a)
265
+ @turtles.each { |t| t.turn(a) }
266
+ end
267
+
268
+ def right
269
+ @turtles.each { |t| t.right }
270
+ end
271
+
272
+ def left
273
+ @turtles.each { |t| t.left }
274
+ end
275
+
276
+ def hide
277
+ @turtles.each { |t| t.hide }
278
+ end
279
+
280
+ def show
281
+ @turtles.each { |t| t.show }
282
+ end
283
+
284
+ def penup
285
+ @turtles.each { |t| t.penup }
286
+ end
287
+
288
+ def pendown
289
+ @turtles.each { |t| t.pendown }
290
+ end
291
+
292
+ def home
293
+ @turtles.each { |t| t.home }
294
+ end
295
+ end
296
+
297
+
298
+ ######################################################################
299
+ # World in which turtles can move and exist. A turtle world defines
300
+ # the environment where turtles move. The world sets up the drawing
301
+ # canvas used to display the turtles. A composite turtle
302
+ # representing all the turtles defined in the world is also
303
+ # available.
304
+ #
305
+ class TurtleWorld
306
+ attr_reader :all
307
+ attr_writer :canvas
308
+
309
+ def initialize
310
+ @all = CompositeTurtle.new
311
+ end
312
+
313
+ ## Add a turtle to the world.
314
+ def add(turtle)
315
+ @all.add(turtle)
316
+ end
317
+
318
+ ## Canvas used for drawing. Lazy initialization is recommended.
319
+ def canvas
320
+ @canvas ||= DefaultCanvas.new
321
+ end
322
+
323
+ end
324
+ end
325
+
326
+ # Export only the Turtle Class
327
+
328
+ Turtle = TurtleGraphics::Turtle
@@ -0,0 +1,26 @@
1
+ ######################################################################
2
+
3
+ # Copyright 2008 by Akshay Rawat (projectsatakshaydotcc).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+
10
+ ######################################################################
11
+
12
+ module TurtleGraphics
13
+
14
+ class TkTurtleCanvas
15
+ def update_title(title)
16
+ @canvas.root.title=title
17
+ end
18
+ end
19
+
20
+ class Turtle
21
+ def say(text)
22
+ @canvas.update_title(text)
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + "/../lib/rmotion"
2
+ require 'test/unit'
3
+
4
+ class Readings < Test::Unit::TestCase
5
+
6
+ include RMotion
7
+
8
+ def test_should_detect_coordinates_and_sms_type
9
+ sms_type = detect_sms()
10
+ coordinates = read_sms_raw(sms_type[:code])
11
+
12
+ assert_equal(sms_type, {:code=> 4, :description=> :MacBookPro})
13
+ assert_equal(coordinates.size,3)
14
+
15
+ printf("Apple Motion Sensor Type: %s \n", sms_type[:description])
16
+
17
+ loop do
18
+ coordinates = read_sms_raw(sms_type[:code])
19
+ printf("Coordinates: X: %d Y: %d Z: %d \n", coordinates[0], coordinates[1], coordinates[2])
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,31 @@
1
+ ######################################################################
2
+
3
+ # Copyright 2008 by Akshay Rawat (projectsatakshaydotcc).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+
10
+ ######################################################################
11
+
12
+ require File.dirname(__FILE__) + "/lib/examples_init"
13
+
14
+ class TurtleBeach
15
+ include RMotion, TurtleGraphics
16
+
17
+ def initialize
18
+ @turtle = TurtleGraphics::Turtle.new()
19
+ @type = detect_sms()
20
+ loop { move() }
21
+ end
22
+
23
+ def move()
24
+ r = read_sms(@type[:code])
25
+ @turtle.say("X: #{r[0]}, Y:#{r[1]}, G:#{r[2]}")
26
+ @turtle.position= r
27
+ end
28
+
29
+ end
30
+
31
+ TurtleBeach.new
Binary file
@@ -0,0 +1,75 @@
1
+ ######################################################################
2
+
3
+ # Copyright 2008 by Akshay Rawat (projectsatakshaydotcc).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+
10
+ ######################################################################
11
+
12
+ require 'dl/import'
13
+
14
+ module RMotion extend DL::Importable
15
+ LIBUNIMOTION = DL.dlopen(File.dirname(__FILE__) + "/libUniMotion.dylib")
16
+ SYM = {
17
+ :detect_sms => LIBUNIMOTION['detect_sms','I'],
18
+ :read_sms_raw => LIBUNIMOTION['read_sms_raw','IIiii'],
19
+ :read_sms_real => LIBUNIMOTION['read_sms_real', 'IIddd'],
20
+ :read_sms => LIBUNIMOTION['read_sms', 'IIiii'],
21
+ :read_sms_scaled => LIBUNIMOTION['read_sms_scaled', 'IIiii']
22
+ }
23
+
24
+ SMS_TYPES = {
25
+ 0=> :unknown,
26
+ 1=> :PowerBook,
27
+ 2=> :IBook,
28
+ 3=> :highrespb,
29
+ 4=> :MacBookPro
30
+ }
31
+
32
+ def detect_sms()
33
+ sms_type = SYM[:detect_sms].call()
34
+ {:code=> sms_type.first, :description=> SMS_TYPES[sms_type.first]}
35
+ end
36
+
37
+ # raw, unmodified values
38
+ def read_sms_raw(type=nil)
39
+ type = detect_sms() if type.nil?
40
+ result = SYM[:read_sms_raw].call(type,1,1,1)
41
+ coordinates(result)
42
+ end
43
+
44
+ # real (1.0 = 1G) values (requires calibration data)
45
+ # note that this is the preferred API as it need not change with new machines
46
+ # if no "scale" calibration data exists defaults will be used based on the
47
+ # machine type
48
+ def read_sms_real(type=nil)
49
+ type = detect_sms() if type.nil?
50
+ result = SYM[:read_sms_real].call(type,1.0,1.0,1.0)
51
+ coordinates(result)
52
+ end
53
+
54
+ # calibrated" values (same as raw if no calibration data exists)
55
+ def read_sms(type=nil)
56
+ type = detect_sms() if type.nil?
57
+ result = SYM[:read_sms].call(type,1.0,1.0,1.0)
58
+ coordinates(result)
59
+ end
60
+
61
+ # scaled values, like real but easier to handle
62
+ # this reverses the backwards polarity of x and increases the range of the
63
+ # older machines to match the MacBook [Pro] sensor
64
+ def read_sms_scaled(type=nil)
65
+ type = detect_sms() if type.nil?
66
+ result = SYM[:read_sms_scaled].call(type,1.0,1.0,1.0)
67
+ coordinates(result)
68
+ end
69
+
70
+ private
71
+ def coordinates(result)
72
+ result[1][1..3]
73
+ end
74
+
75
+ end
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "rmotion"
3
+ s.version = "0.0.1"
4
+ s.date = "2008-04-26"
5
+ s.summary = "RMotion is a ruby library which allows you to read the output of Sudden Motion Sensors on your Apple laptop"
6
+ s.email = "project@akshay.cc"
7
+ s.homepage = "http://github.com/akshayrawat/rmotion"
8
+ s.description = "RMotion is a ruby library which allows you to read the output of Sudden Motion Sensors on your Apple laptop"
9
+ s.has_rdoc = false
10
+ s.authors = ["Akshay Rawat"]
11
+ s.files = ["README", "rmotion.gemspec", "lib/rmotion.rb", "lib/libUniMotion.dylib", "examples/readings.rb", "examples/turtlebeach.rb", "examples/lib/examples_init.rb", "examples/lib/rubyturtles/tkturtle.rb", "examples/lib/rubyturtles/turtle.rb", "examples/lib/rubyturtles/turtle_patch.rb"]
12
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: akshayrawat-rmotion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Akshay Rawat
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-04-26 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: RMotion is a ruby library which allows you to read the output of Sudden Motion Sensors on your Apple laptop
17
+ email: project@akshay.cc
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README
26
+ - rmotion.gemspec
27
+ - lib/rmotion.rb
28
+ - lib/libUniMotion.dylib
29
+ - examples/readings.rb
30
+ - examples/turtlebeach.rb
31
+ - examples/lib/examples_init.rb
32
+ - examples/lib/rubyturtles/tkturtle.rb
33
+ - examples/lib/rubyturtles/turtle.rb
34
+ - examples/lib/rubyturtles/turtle_patch.rb
35
+ has_rdoc: false
36
+ homepage: http://github.com/akshayrawat/rmotion
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.0.1
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: RMotion is a ruby library which allows you to read the output of Sudden Motion Sensors on your Apple laptop
61
+ test_files: []
62
+