phidgets_native 0.1.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.
Files changed (41) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +12 -0
  3. data/README.rdoc +176 -0
  4. data/Rakefile +31 -0
  5. data/examples/gps.rb +25 -0
  6. data/examples/interface_kit.rb +61 -0
  7. data/examples/lib/common.rb +51 -0
  8. data/examples/lib/console_table.rb +38 -0
  9. data/examples/list_all.rb +16 -0
  10. data/examples/spatial.rb +53 -0
  11. data/ext/phidgets_native/accelerometer_ruby.c +36 -0
  12. data/ext/phidgets_native/advancedservo_ruby.c +33 -0
  13. data/ext/phidgets_native/analog_ruby.c +34 -0
  14. data/ext/phidgets_native/bridge_ruby.c +32 -0
  15. data/ext/phidgets_native/device.c +68 -0
  16. data/ext/phidgets_native/device_ruby.c +404 -0
  17. data/ext/phidgets_native/encoder_ruby.c +34 -0
  18. data/ext/phidgets_native/extconf.rb +18 -0
  19. data/ext/phidgets_native/frequencycounter_ruby.c +32 -0
  20. data/ext/phidgets_native/gps.c +102 -0
  21. data/ext/phidgets_native/gps_ruby.c +212 -0
  22. data/ext/phidgets_native/interfacekit.c +203 -0
  23. data/ext/phidgets_native/interfacekit_ruby.c +507 -0
  24. data/ext/phidgets_native/ir_ruby.c +33 -0
  25. data/ext/phidgets_native/led_ruby.c +33 -0
  26. data/ext/phidgets_native/motorcontrol_ruby.c +32 -0
  27. data/ext/phidgets_native/phidgets_native.c +197 -0
  28. data/ext/phidgets_native/phidgets_native.h +320 -0
  29. data/ext/phidgets_native/phidgets_native_ruby.c +468 -0
  30. data/ext/phidgets_native/phsensor_ruby.c +32 -0
  31. data/ext/phidgets_native/rfid_ruby.c +31 -0
  32. data/ext/phidgets_native/servo_ruby.c +31 -0
  33. data/ext/phidgets_native/spatial.c +168 -0
  34. data/ext/phidgets_native/spatial_ruby.c +533 -0
  35. data/ext/phidgets_native/stepper_ruby.c +32 -0
  36. data/ext/phidgets_native/temperaturesensor_ruby.c +31 -0
  37. data/ext/phidgets_native/textlcd_ruby.c +31 -0
  38. data/ext/phidgets_native/textled_ruby.c +31 -0
  39. data/ext/phidgets_native/weightsensor_ruby.c +32 -0
  40. data/phidgets_native.gemspec +21 -0
  41. metadata +96 -0
@@ -0,0 +1,168 @@
1
+ #include "phidgets_native.h"
2
+
3
+ void spatial_on_free(void *type_info) {
4
+ SpatialInfo *spatial_info = type_info;
5
+ if (spatial_info->acceleration)
6
+ xfree(spatial_info->acceleration);
7
+ if (spatial_info->acceleration_min)
8
+ xfree(spatial_info->acceleration_min);
9
+ if (spatial_info->acceleration_max)
10
+ xfree(spatial_info->acceleration_max);
11
+ if (spatial_info->gyroscope)
12
+ xfree(spatial_info->gyroscope);
13
+ if (spatial_info->gyroscope_min)
14
+ xfree(spatial_info->gyroscope_min);
15
+ if (spatial_info->gyroscope_max)
16
+ xfree(spatial_info->gyroscope_max);
17
+ if (spatial_info->compass)
18
+ xfree(spatial_info->compass);
19
+ if (spatial_info->compass_min)
20
+ xfree(spatial_info->compass_min);
21
+ if (spatial_info->compass_max)
22
+ xfree(spatial_info->compass_max);
23
+ if (spatial_info->sample_rate)
24
+ sample_free(spatial_info->sample_rate);
25
+ if (spatial_info)
26
+ xfree(spatial_info);
27
+
28
+ return;
29
+ }
30
+
31
+ int spatial_set_compass_correction_by_array(CPhidgetSpatialHandle phid, double *cc) {
32
+ return report(CPhidgetSpatial_setCompassCorrectionParameters( phid,
33
+ cc[0], cc[1], cc[2], cc[3], cc[4], cc[5], cc[6], cc[7], cc[8], cc[9],
34
+ cc[10], cc[11], cc[12] ));
35
+ }
36
+
37
+ int CCONV spatial_on_attach(CPhidgetHandle phid, void *userptr) {
38
+ PhidgetInfo *info = userptr;
39
+ SpatialInfo *spatial_info = info->type_info;
40
+
41
+ // Accelerometer Attributes:
42
+ report(CPhidgetSpatial_getAccelerationAxisCount((CPhidgetSpatialHandle)phid, &spatial_info->accelerometer_axes));
43
+ report(CPhidgetSpatial_getGyroAxisCount((CPhidgetSpatialHandle)phid, &spatial_info->gyro_axes));
44
+ report(CPhidgetSpatial_getCompassAxisCount((CPhidgetSpatialHandle)phid, &spatial_info->compass_axes));
45
+ report(CPhidgetSpatial_getDataRateMax((CPhidgetSpatialHandle)phid, &spatial_info->data_rate_max));
46
+ report(CPhidgetSpatial_getDataRateMin((CPhidgetSpatialHandle)phid, &spatial_info->data_rate_min));
47
+
48
+ // Dealloc if we're alloc'd, this will prevent memory leaks on device re-attachment:
49
+ if (spatial_info->acceleration) xfree(spatial_info->acceleration);
50
+ if (spatial_info->acceleration_min) xfree(spatial_info->acceleration_min);
51
+ if (spatial_info->acceleration_max) xfree(spatial_info->acceleration_max);
52
+ if (spatial_info->compass) xfree(spatial_info->compass);
53
+ if (spatial_info->compass_min) xfree(spatial_info->compass_min);
54
+ if (spatial_info->compass_max) xfree(spatial_info->compass_max);
55
+ if (spatial_info->gyroscope) xfree(spatial_info->gyroscope);
56
+ if (spatial_info->gyroscope_min) xfree(spatial_info->gyroscope_min);
57
+ if (spatial_info->gyroscope_max) xfree(spatial_info->gyroscope_max);
58
+
59
+ // Allocate space for our extents:
60
+ spatial_info->acceleration = ALLOC_N(double, spatial_info->accelerometer_axes);
61
+ spatial_info->acceleration_min = ALLOC_N(double, spatial_info->accelerometer_axes);
62
+ spatial_info->acceleration_max = ALLOC_N(double, spatial_info->accelerometer_axes);
63
+ spatial_info->compass = ALLOC_N(double, spatial_info->compass_axes);
64
+ spatial_info->compass_min = ALLOC_N(double, spatial_info->compass_axes);
65
+ spatial_info->compass_max = ALLOC_N(double, spatial_info->compass_axes);
66
+ spatial_info->gyroscope = ALLOC_N(double, spatial_info->gyro_axes);
67
+ spatial_info->gyroscope_min = ALLOC_N(double, spatial_info->gyro_axes);
68
+ spatial_info->gyroscope_max = ALLOC_N(double, spatial_info->gyro_axes);
69
+
70
+ // Accelerometer
71
+ for(int i=0; i < spatial_info->accelerometer_axes; i++) {
72
+ report(CPhidgetSpatial_getAccelerationMin((CPhidgetSpatialHandle)phid, i, &spatial_info->acceleration_min[i]));
73
+ report(CPhidgetSpatial_getAccelerationMax((CPhidgetSpatialHandle)phid, i, &spatial_info->acceleration_max[i]));
74
+ }
75
+
76
+ for(int i=0; i < spatial_info->compass_axes; i++) {
77
+ report(CPhidgetSpatial_getMagneticFieldMin((CPhidgetSpatialHandle)phid, i, &spatial_info->compass_min[i]));
78
+ report(CPhidgetSpatial_getMagneticFieldMax((CPhidgetSpatialHandle)phid, i, &spatial_info->compass_max[i]));
79
+ }
80
+
81
+ for(int i=0; i < spatial_info->gyro_axes; i++) {
82
+ report(CPhidgetSpatial_getAngularRateMin((CPhidgetSpatialHandle)phid, i, &spatial_info->gyroscope_min[i]));
83
+ report(CPhidgetSpatial_getAngularRateMax((CPhidgetSpatialHandle)phid, i, &spatial_info->gyroscope_max[i]));
84
+ }
85
+
86
+ // Set the data rate for the spatial events in milliseconds.
87
+ // Note that 1000/16 = 62.5 Hz
88
+ report(CPhidgetSpatial_setDataRate((CPhidgetSpatialHandle)phid, spatial_info->data_rate));
89
+
90
+ // Strictly speaking, this is entirely optional:
91
+ if (spatial_info->is_compass_correction_known)
92
+ spatial_set_compass_correction_by_array( (CPhidgetSpatialHandle)phid,
93
+ spatial_info->compass_correction);
94
+
95
+ return 0;
96
+ }
97
+
98
+
99
+ int CCONV spatial_on_detach(CPhidgetHandle phidget, void *userptr) {
100
+ PhidgetInfo *info = userptr;
101
+ SpatialInfo *spatial_info = info->type_info;
102
+
103
+ // These would be misleading to report if there's no device:
104
+ memset(spatial_info->acceleration, 0, sizeof(double) * spatial_info->accelerometer_axes);
105
+ memset(spatial_info->gyroscope, 0, sizeof(double) * spatial_info->gyro_axes);
106
+ memset(spatial_info->compass, 0, sizeof(double) * spatial_info->compass_axes);
107
+
108
+ spatial_info->last_microsecond = 0;
109
+ spatial_info->is_acceleration_known = false;
110
+ spatial_info->is_gyroscope_known = false;
111
+ spatial_info->is_compass_known = false;
112
+
113
+ sample_zero(spatial_info->sample_rate);
114
+
115
+ return 0;
116
+ }
117
+
118
+ //callback that will run at datarate
119
+ //data - array of spatial event data structures that holds the spatial data packets that were sent in this event
120
+ //count - the number of spatial data event packets included in this event
121
+ int CCONV spatial_on_data(CPhidgetSpatialHandle spatial, void *userptr, CPhidgetSpatial_SpatialEventDataHandle *data, int count)
122
+ {
123
+ PhidgetInfo *info = userptr;
124
+ SpatialInfo *spatial_info = info->type_info;
125
+
126
+ int i;
127
+ for(i = 0; i < count; i++) {
128
+ sample_tick(spatial_info->sample_rate, &data[i]->timestamp);
129
+
130
+ // Set the values to where they need to be:
131
+ for(int j=0; j < spatial_info->accelerometer_axes; j++)
132
+ spatial_info->acceleration[j] = data[i]->acceleration[j];
133
+
134
+ spatial_info->is_acceleration_known = true;
135
+
136
+ // Sometimes the compass will return nonesense in the form of this constant
137
+ // I'm fairly certain that simply checking the first element of the array
138
+ // will suffice, and when this is the case, we just keep the prior values:
139
+ if (data[i]->magneticField[0] == PUNK_DBL)
140
+ spatial_info->is_compass_known = false;
141
+ else {
142
+ for(int j=0; j < spatial_info->compass_axes; j++)
143
+ spatial_info->compass[j] = data[i]->magneticField[j];
144
+
145
+ spatial_info->is_compass_known = true;
146
+ }
147
+
148
+ // Gyros get handled slightly different:
149
+ // NOTE: Other people may have a better way to do this, but this is the method
150
+ // I grabbed from the phidget sample. Maybe I should report these in radians...
151
+ double timestamp = data[i]->timestamp.seconds + data[i]->timestamp.microseconds/MICROSECONDS_IN_SECOND;
152
+
153
+ if (spatial_info->last_microsecond > 0) {
154
+ double timechange = timestamp - spatial_info->last_microsecond;
155
+
156
+ for(int j=0; j < spatial_info->gyro_axes; j++)
157
+ spatial_info->gyroscope[j] += data[i]->angularRate[j] * timechange;
158
+ }
159
+
160
+ spatial_info->is_gyroscope_known = true;
161
+
162
+ // We'll need this on the next go around:
163
+ spatial_info->last_microsecond = timestamp;
164
+ }
165
+
166
+ return 0;
167
+ }
168
+
@@ -0,0 +1,533 @@
1
+ #include "phidgets_native.h"
2
+
3
+ const char MSG_COMPASS_CORRECTION_NOT_ARRAY[] = "compass correction must be a 13 element array";
4
+ const char MSG_COMPASS_CORRECTION_MUST_BE_FLOAT[] = "compass correction elements must be float or fixnum";
5
+ const char MSG_DATA_RATE_MUST_BE_NUM[] = "data rate must be fixnum";
6
+
7
+ /*
8
+ * Document-class: PhidgetsNative::Spatial < PhidgetsNative::Device
9
+ *
10
+ * This class provides functionality specific to the "Spatial" device class.
11
+ * Primarily, this includes reporting of acceleration, compass, and orientation
12
+ * vectors.
13
+ */
14
+
15
+ void Init_phidgets_native_spatial(VALUE m_Phidget) {
16
+ VALUE c_Device = rb_const_get(m_Phidget, rb_intern("Device"));
17
+
18
+ VALUE c_Spatial = rb_define_class_under(m_Phidget,"Spatial",c_Device);
19
+
20
+ /*
21
+ * Document-method: new
22
+ * call-seq:
23
+ * new(serial_number)
24
+ *
25
+ * All phidget objects are created from the device serial number. Serial numbers
26
+ * are required to be Fixnums (aka "unsigned integers").
27
+ */
28
+ rb_define_method(c_Spatial, "initialize", spatial_initialize, 1);
29
+
30
+ /*
31
+ * Document-method: close
32
+ * call-seq:
33
+ * close -> nil
34
+ *
35
+ * This method will unregister the phidget event handlers, and free up all
36
+ * API resources associated with the phidget. This is an optional, but useful
37
+ * way to remove the object's overhead before the GC kicks in and actually
38
+ * frees the resource.
39
+ */
40
+ rb_define_method(c_Spatial, "close", spatial_close, 0);
41
+
42
+ /*
43
+ * Document-method: sample_rate
44
+ * call-seq:
45
+ * sample_rate -> FixNum
46
+ *
47
+ * For most Phidgets, an event handler processes the device state changes at
48
+ * some regular interval. For these devices, this method will return the rate
49
+ * of state changes measured in Hz.
50
+ */
51
+ rb_define_method(c_Spatial, "sample_rate", spatial_sample_rate, 0);
52
+
53
+ /*
54
+ * Document-method: accelerometer_axes
55
+ * call-seq:
56
+ * accelerometer_axes -> Fixnum
57
+ *
58
+ * This method returns the number of axis reported by the accelerometer. This
59
+ * number comes from the
60
+ * CPhidgetSpatial_getAccelerationAxisCount[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
61
+ * function.
62
+ */
63
+ rb_define_method(c_Spatial, "accelerometer_axes", spatial_accelerometer_axes, 0);
64
+
65
+ /*
66
+ * Document-method: compass_axes
67
+ * call-seq:
68
+ * compass_axes -> Fixnum
69
+ *
70
+ * This method returns the number of axis reported by the compass. This
71
+ * number comes from the
72
+ * CPhidgetSpatial_getCompassAxisCount[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
73
+ * function.
74
+ */
75
+ rb_define_method(c_Spatial, "compass_axes", spatial_compass_axes, 0);
76
+
77
+ /*
78
+ * Document-method: gyro_axes
79
+ * call-seq:
80
+ * gyro_axes -> Fixnum
81
+ *
82
+ * This method returns the number of axis reported by the gyroscope. This
83
+ * number comes from the
84
+ * CPhidgetSpatial_getGyroAxisCount[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
85
+ * function.
86
+ */
87
+ rb_define_method(c_Spatial, "gyro_axes", spatial_gyro_axes, 0);
88
+
89
+ /*
90
+ * Document-method: gyro_min
91
+ * call-seq:
92
+ * gyro_min -> Array
93
+ *
94
+ * This method returns an array of Float(s) which represent the minimal value
95
+ * that an axis will report during a sample interval. These values come from the
96
+ * CPhidgetSpatial_getAngularRateMin[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
97
+ * function.
98
+ */
99
+ rb_define_method(c_Spatial, "gyro_min", spatial_gyro_min, 0);
100
+
101
+ /*
102
+ * Document-method: gyro_max
103
+ * call-seq:
104
+ * gyro_max -> Array
105
+ *
106
+ * This method returns an array of Float(s) which represent the maximal value
107
+ * that an axis will report during a sample interval. These values come from the
108
+ * CPhidgetSpatial_getAngularRateMax[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
109
+ * function.
110
+ */
111
+ rb_define_method(c_Spatial, "gyro_max", spatial_gyro_max, 0);
112
+
113
+ /*
114
+ * Document-method: accelerometer_min
115
+ * call-seq:
116
+ * accelerometer_min -> Array
117
+ *
118
+ * This method returns an array of Float(s) which represent the minimal value
119
+ * that an axis will report during a sample interval. These values come from the
120
+ * CPhidgetSpatial_getAccelerationMin[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
121
+ * function.
122
+ */
123
+ rb_define_method(c_Spatial, "accelerometer_min", spatial_accelerometer_min, 0);
124
+
125
+ /*
126
+ * Document-method: accelerometer_max
127
+ * call-seq:
128
+ * accelerometer_max -> Array
129
+ *
130
+ * This method returns an array of Float(s) which represent the maximal value
131
+ * that an axis will report during a sample interval. These values come from the
132
+ * CPhidgetSpatial_getAccelerationMax[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
133
+ * function.
134
+ */
135
+ rb_define_method(c_Spatial, "accelerometer_max", spatial_accelerometer_max, 0);
136
+
137
+ /*
138
+ * Document-method: compass_min
139
+ * call-seq:
140
+ * compass_min -> Array
141
+ *
142
+ * This method returns an array of Float(s) which represent the minimal value
143
+ * that an axis will report during a sample interval. These values come from the
144
+ * CPhidgetSpatial_getMagneticFieldMin[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
145
+ * function.
146
+ */
147
+ rb_define_method(c_Spatial, "compass_min", spatial_compass_min, 0);
148
+
149
+ /*
150
+ * Document-method: compass_max
151
+ * call-seq:
152
+ * compass_max -> Array
153
+ *
154
+ * This method returns an array of Float(s) which represent the maximal value
155
+ * that an axis will report during a sample interval. These values come from the
156
+ * CPhidgetSpatial_getMagneticFieldMax[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
157
+ * function.
158
+ */
159
+ rb_define_method(c_Spatial, "compass_max", spatial_compass_max, 0);
160
+
161
+ /*
162
+ * Document-method: gyro
163
+ * call-seq:
164
+ * gyro -> Array
165
+ *
166
+ * This method returns an array of Float(s) which represent the normalized value
167
+ * of each axis on the gyro in degrees (0-359.9). These values are calculated
168
+ * by accumulating the delta measurements which are reported inside the
169
+ * CPhidgetSpatial_set_OnSpatialData_Handler[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
170
+ * event handler.
171
+ *
172
+ * NOTE: There's probably better algorithms to calculate this value than the
173
+ * one being used by this library. The algorithm used was merely the one found
174
+ * in the phidget-provided examples. Feel free to submit your algorithm for
175
+ * inclusion in this library if you know of a better way to do this.
176
+ */
177
+ rb_define_method(c_Spatial, "gyro", spatial_gyro, 0);
178
+
179
+ /*
180
+ * Document-method: compass
181
+ * call-seq:
182
+ * compass -> Array
183
+ *
184
+ * This method returns an array of Float(s) which represent the relative magnetic
185
+ * attraction of each axis. These values are merely those which were most
186
+ * recently reported via the
187
+ * CPhidgetSpatial_set_OnSpatialData_Handler[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
188
+ * event handler.
189
+ *
190
+ * NOTE: Sometimes the phidget library won't have values to report on this
191
+ * measurement due to "EPHIDGET_UNKNOWNVAL" errors. When we come up against
192
+ * this case, we return the last values that were reported successfully.
193
+ *
194
+ * NOTE: You probably want this value in degrees. This is difficult, primarily
195
+ * due to the pre-requisite of knowing what the cross-product is of the ground
196
+ * plane (aka, the ground's surface normal). I might add a 'bad estimate'
197
+ * of this vector in a future version of the library. E-mail the author if you
198
+ * need some sample code based on the accelerometer's inverse vector.
199
+ */
200
+ rb_define_method(c_Spatial, "compass", spatial_compass, 0);
201
+
202
+ /*
203
+ * Document-method: accelerometer
204
+ * call-seq:
205
+ * accelerometer -> Array
206
+ *
207
+ * This method returns an array of Float(s) which represent the accelerometer
208
+ * magnitude of each axis, in meters per second. These values are merely those
209
+ * which were most recently reported via the
210
+ * CPhidgetSpatial_set_OnSpatialData_Handler[http://www.phidgets.com/documentation/web/cdoc/group__phidspatial.html]
211
+ * event handler.
212
+ */
213
+ rb_define_method(c_Spatial, "accelerometer", spatial_accelerometer, 0);
214
+
215
+ /*
216
+ * Document-method: zero_gyro!
217
+ * call-seq:
218
+ * zero_gyro! -> nil
219
+ *
220
+ * Zero's the gyro values, and reference point. Once this method is executed
221
+ * it takes approximately two seconds for the gyro to zero, and start returning
222
+ * its offsets. This method zero's out the current gyro state vector and calls the
223
+ * CPhidgetSpatial_zeroGyro[http://www.phidgets.com/documentation/web/cdoc/group__phidcommon.html]
224
+ * function.
225
+ */
226
+ rb_define_method(c_Spatial, "zero_gyro!", spatial_zero_gyro, 0);
227
+
228
+ /*
229
+ * Document-method: reset_compass_correction!
230
+ * call-seq:
231
+ * reset_compass_correction! -> nil
232
+ *
233
+ * Zero's the compass correction parameters. This method calls the
234
+ * CPhidgetSpatial_resetCompassCorrectionParameters[http://www.phidgets.com/documentation/web/cdoc/group__phidcommon.html]
235
+ * function.
236
+ */
237
+ rb_define_method(c_Spatial, "reset_compass_correction!", spatial_reset_compass_correction, 0);
238
+
239
+ /*
240
+ * Document-method: compass_correction=
241
+ * call-seq:
242
+ * compass_correction=( Array correction_parameters ) -> Array
243
+ *
244
+ * This method expects a thirteen digit array of Floats, which are passed to the
245
+ * CPhidgetSpatial_setCompassCorrectionParameters[http://www.phidgets.com/documentation/web/cdoc/group__phidcommon.html]
246
+ * function. It returns the provided array.
247
+ */
248
+ rb_define_method(c_Spatial, "compass_correction=", spatial_compass_correction_set, 1);
249
+
250
+ /*
251
+ * Document-method: compass_correction
252
+ * call-seq:
253
+ * compass_correction -> Array
254
+ *
255
+ * This method returns the current compass_correction parameters, which were
256
+ * previously supplied to the compass_correction= method. If no such corrections
257
+ * were supplied, the return is nil.
258
+ */
259
+ rb_define_method(c_Spatial, "compass_correction", spatial_compass_correction_get, 0);
260
+
261
+ /*
262
+ * Document-method: data_rate_min
263
+ * call-seq:
264
+ * data_rate_min -> Fixnum
265
+ *
266
+ * This method returns a Fixnum which represents the minimaly supported data rate
267
+ * that is supported by the library. This value comes direct from the
268
+ * CPhidgetSpatial_getDataRateMin[http://www.phidgets.com/documentation/web/cdoc/group__phidcommon.html]
269
+ * function.
270
+ *
271
+ * NOTE: Keep in mind that the higher the value, the "lower" the rate.
272
+ */
273
+ rb_define_method(c_Spatial, "data_rate_min", spatial_data_rate_min, 0);
274
+
275
+ /*
276
+ * Document-method: data_rate_max
277
+ * call-seq:
278
+ * data_rate_max -> Fixnum
279
+ *
280
+ * This method returns a Fixnum which represents the maximum supported data rate
281
+ * that is supported by the library. This value comes direct from the
282
+ * CPhidgetSpatial_getDataRateMax[http://www.phidgets.com/documentation/web/cdoc/group__phidcommon.html]
283
+ * function.
284
+ *
285
+ * NOTE: Keep in mind that the lower the value, the "higher" the rate.
286
+ */
287
+ rb_define_method(c_Spatial, "data_rate_max", spatial_data_rate_max, 0);
288
+
289
+ /*
290
+ * Document-method: data_rate=
291
+ * call-seq:
292
+ * data_rate=( FixNum rate_in_ms ) -> FixNum
293
+ *
294
+ * This method expects a FixNum, which is passed to the
295
+ * CPhidgetSpatial_setDataRate[http://www.phidgets.com/documentation/web/cdoc/group__phidcommon.html]
296
+ * function. This value is the number of milliseconds between device sampling
297
+ * reports, and it defaults to 16.
298
+ *
299
+ * NOTE: For the case of 16, the data_rate as would be measured in Hz is 62.5: 1000/16 = 62.5 Hz
300
+ */
301
+ rb_define_method(c_Spatial, "data_rate=", spatial_data_rate_set, 1);
302
+
303
+ /*
304
+ * Document-method: data_rate
305
+ * call-seq:
306
+ * data_rate -> FixNum
307
+ *
308
+ * This method returns the current data_rate as was previously supplied to the
309
+ * data_rate= method. If no such rate was supplied, then this method returns
310
+ * the default rate, which is 16.
311
+ */
312
+ rb_define_method(c_Spatial, "data_rate", spatial_data_rate_get, 0);
313
+
314
+
315
+ }
316
+
317
+ VALUE spatial_initialize(VALUE self, VALUE serial) {
318
+ PhidgetInfo *info = device_info(self);
319
+
320
+ SpatialInfo *spatial_info = ALLOC(SpatialInfo);
321
+ memset(spatial_info, 0, sizeof(SpatialInfo));
322
+
323
+ spatial_info->data_rate = DEFAULT_SPATIAL_DATA_RATE;
324
+ spatial_info->sample_rate = sample_create();
325
+
326
+ // Setup a spatial handle
327
+ CPhidgetSpatialHandle spatial = 0;
328
+ ensure(CPhidgetSpatial_create(&spatial));
329
+ ensure(CPhidgetSpatial_set_OnSpatialData_Handler(spatial, spatial_on_data, info));
330
+
331
+ info->handle = (CPhidgetHandle)spatial;
332
+ info->on_type_attach = spatial_on_attach;
333
+ info->on_type_detach = spatial_on_detach;
334
+ info->on_type_free = spatial_on_free;
335
+ info->type_info = spatial_info;
336
+
337
+ return rb_call_super(1, &serial);
338
+ }
339
+
340
+ VALUE spatial_close(VALUE self) {
341
+ PhidgetInfo *info = device_info(self);
342
+
343
+ ensure(CPhidgetSpatial_set_OnSpatialData_Handler((CPhidgetSpatialHandle)info->handle, NULL, NULL));
344
+
345
+ return rb_call_super(0,NULL);
346
+ }
347
+
348
+ VALUE spatial_sample_rate(VALUE self) {
349
+ SpatialInfo *spatial_info = device_type_info(self);
350
+
351
+ return INT2FIX(spatial_info->sample_rate->in_hz);
352
+ }
353
+
354
+ VALUE spatial_accelerometer_axes(VALUE self) {
355
+ SpatialInfo *spatial_info = device_type_info(self);
356
+
357
+ return (spatial_info->accelerometer_axes) ?
358
+ INT2FIX(spatial_info->accelerometer_axes) : Qnil;
359
+ }
360
+
361
+ VALUE spatial_compass_axes(VALUE self) {
362
+ SpatialInfo *spatial_info = device_type_info(self);
363
+
364
+ return (spatial_info->compass_axes) ? INT2FIX(spatial_info->compass_axes) : Qnil;
365
+ }
366
+
367
+ VALUE spatial_gyro_axes(VALUE self) {
368
+ SpatialInfo *spatial_info = device_type_info(self);
369
+
370
+ return (spatial_info->gyro_axes) ? INT2FIX(spatial_info->gyro_axes) : Qnil;
371
+ }
372
+
373
+ VALUE spatial_accelerometer(VALUE self) {
374
+ SpatialInfo *spatial_info = device_type_info(self);
375
+
376
+ return (spatial_info->is_acceleration_known) ?
377
+ double_array_to_rb(spatial_info->acceleration, spatial_info->accelerometer_axes) :
378
+ Qnil;
379
+ }
380
+
381
+ VALUE spatial_accelerometer_min(VALUE self) {
382
+ SpatialInfo *spatial_info = device_type_info(self);
383
+
384
+ return double_array_to_rb(spatial_info->acceleration_min, spatial_info->accelerometer_axes);
385
+ }
386
+
387
+ VALUE spatial_accelerometer_max(VALUE self) {
388
+ SpatialInfo *spatial_info = device_type_info(self);
389
+
390
+ return double_array_to_rb(spatial_info->acceleration_max, spatial_info->accelerometer_axes);
391
+ }
392
+
393
+ VALUE spatial_gyro(VALUE self) {
394
+ SpatialInfo *spatial_info = device_type_info(self);
395
+
396
+ if (!spatial_info->is_gyroscope_known) return Qnil;
397
+
398
+ double *gyroscope_in_degrees;
399
+ VALUE ret;
400
+
401
+ gyroscope_in_degrees = ALLOC_N(double, spatial_info->gyro_axes);
402
+ for(int i=0; i < spatial_info->gyro_axes; i++)
403
+ gyroscope_in_degrees[i] = fmod(spatial_info->gyroscope[i], DEGREES_IN_CIRCLE);
404
+
405
+ ret = double_array_to_rb(gyroscope_in_degrees, spatial_info->gyro_axes);
406
+ xfree(gyroscope_in_degrees);
407
+
408
+ return ret;
409
+ }
410
+
411
+ VALUE spatial_gyro_min(VALUE self) {
412
+ SpatialInfo *spatial_info = device_type_info(self);
413
+
414
+ return double_array_to_rb(spatial_info->gyroscope_min, spatial_info->gyro_axes);
415
+ }
416
+
417
+ VALUE spatial_gyro_max(VALUE self) {
418
+ SpatialInfo *spatial_info = device_type_info(self);
419
+
420
+ return double_array_to_rb(spatial_info->gyroscope_max, spatial_info->gyro_axes);
421
+ }
422
+
423
+ VALUE spatial_compass(VALUE self) {
424
+ SpatialInfo *spatial_info = device_type_info(self);
425
+
426
+ return (spatial_info->is_compass_known) ?
427
+ double_array_to_rb(spatial_info->compass, spatial_info->compass_axes) :
428
+ Qnil;
429
+ }
430
+
431
+ VALUE spatial_compass_min(VALUE self) {
432
+ SpatialInfo *spatial_info = device_type_info(self);
433
+
434
+ return double_array_to_rb(spatial_info->compass_min, spatial_info->compass_axes);
435
+ }
436
+
437
+ VALUE spatial_compass_max(VALUE self) {
438
+ SpatialInfo *spatial_info = device_type_info(self);
439
+
440
+ return double_array_to_rb(spatial_info->compass_max, spatial_info->compass_axes);
441
+ }
442
+
443
+ VALUE spatial_zero_gyro(VALUE self) {
444
+ PhidgetInfo *info = device_info(self);
445
+ SpatialInfo *spatial_info = info->type_info;
446
+
447
+ ensure(CPhidgetSpatial_zeroGyro((CPhidgetSpatialHandle) info->handle));
448
+ memset(spatial_info->gyroscope, 0, sizeof(double) * spatial_info->gyro_axes);
449
+
450
+ return Qnil;
451
+ }
452
+
453
+ VALUE spatial_reset_compass_correction(VALUE self) {
454
+ PhidgetInfo *info = device_info(self);
455
+ SpatialInfo *spatial_info = info->type_info;
456
+
457
+ ensure(CPhidgetSpatial_resetCompassCorrectionParameters((CPhidgetSpatialHandle) info->handle));
458
+ memset(spatial_info->compass_correction, 0, sizeof(double) * COMPASS_CORRECTION_LENGTH );
459
+ spatial_info->is_compass_correction_known = false;
460
+
461
+ return Qnil;
462
+ }
463
+
464
+ VALUE spatial_compass_correction_set(VALUE self, VALUE compass_correction) {
465
+ PhidgetInfo *info = device_info(self);
466
+ SpatialInfo *spatial_info = info->type_info;
467
+
468
+ if ( (TYPE(compass_correction) != T_ARRAY) || (RARRAY_LEN(compass_correction) != COMPASS_CORRECTION_LENGTH) ) {
469
+ rb_raise(rb_eTypeError, MSG_COMPASS_CORRECTION_NOT_ARRAY);
470
+ return Qnil;
471
+ } else {
472
+ for (int i=0; i<RARRAY_LEN(compass_correction); i++) {
473
+ VALUE cc_element = rb_ary_entry(compass_correction, i);
474
+
475
+ if ( TYPE(cc_element) == T_FLOAT)
476
+ spatial_info->compass_correction[i] = NUM2DBL(cc_element);
477
+ else {
478
+ rb_raise(rb_eTypeError, MSG_COMPASS_CORRECTION_MUST_BE_FLOAT);
479
+ return Qnil;
480
+ }
481
+ }
482
+
483
+ spatial_info->is_compass_correction_known = true;
484
+ if (info->is_attached)
485
+ spatial_set_compass_correction_by_array(
486
+ (CPhidgetSpatialHandle)info->handle, spatial_info->compass_correction);
487
+ }
488
+
489
+ return compass_correction;
490
+ }
491
+
492
+ VALUE spatial_compass_correction_get(VALUE self) {
493
+ SpatialInfo *spatial_info = device_type_info(self);
494
+
495
+ return (spatial_info->is_compass_correction_known) ?
496
+ double_array_to_rb(spatial_info->compass_correction, COMPASS_CORRECTION_LENGTH) : Qnil;
497
+ }
498
+
499
+ VALUE spatial_data_rate_max(VALUE self) {
500
+ SpatialInfo *spatial_info = device_type_info(self);
501
+
502
+ return (spatial_info->data_rate_max) ? INT2FIX(spatial_info->data_rate_max) : Qnil;
503
+ }
504
+
505
+ VALUE spatial_data_rate_min(VALUE self) {
506
+ SpatialInfo *spatial_info = device_type_info(self);
507
+
508
+ return (spatial_info->data_rate_min) ? INT2FIX(spatial_info->data_rate_min) : Qnil;
509
+ }
510
+
511
+ VALUE spatial_data_rate_set(VALUE self, VALUE data_rate) {
512
+ PhidgetInfo *info = device_info(self);
513
+ SpatialInfo *spatial_info = info->type_info;
514
+
515
+ if ( TYPE(data_rate) != T_FIXNUM ) {
516
+ rb_raise(rb_eTypeError, MSG_DATA_RATE_MUST_BE_NUM);
517
+ return Qnil;
518
+ } else {
519
+ spatial_info->data_rate = FIX2INT(data_rate);
520
+
521
+ if (info->is_attached)
522
+ ensure(CPhidgetSpatial_setDataRate((CPhidgetSpatialHandle)info->handle,
523
+ spatial_info->data_rate));
524
+ }
525
+
526
+ return data_rate;
527
+ }
528
+
529
+ VALUE spatial_data_rate_get(VALUE self) {
530
+ SpatialInfo *spatial_info = device_type_info(self);
531
+
532
+ return INT2FIX(spatial_info->data_rate);
533
+ }