akshayrawat-rmotion 0.0.1

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.
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
+