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.
- data/Gemfile +3 -0
- data/Gemfile.lock +12 -0
- data/README.rdoc +176 -0
- data/Rakefile +31 -0
- data/examples/gps.rb +25 -0
- data/examples/interface_kit.rb +61 -0
- data/examples/lib/common.rb +51 -0
- data/examples/lib/console_table.rb +38 -0
- data/examples/list_all.rb +16 -0
- data/examples/spatial.rb +53 -0
- data/ext/phidgets_native/accelerometer_ruby.c +36 -0
- data/ext/phidgets_native/advancedservo_ruby.c +33 -0
- data/ext/phidgets_native/analog_ruby.c +34 -0
- data/ext/phidgets_native/bridge_ruby.c +32 -0
- data/ext/phidgets_native/device.c +68 -0
- data/ext/phidgets_native/device_ruby.c +404 -0
- data/ext/phidgets_native/encoder_ruby.c +34 -0
- data/ext/phidgets_native/extconf.rb +18 -0
- data/ext/phidgets_native/frequencycounter_ruby.c +32 -0
- data/ext/phidgets_native/gps.c +102 -0
- data/ext/phidgets_native/gps_ruby.c +212 -0
- data/ext/phidgets_native/interfacekit.c +203 -0
- data/ext/phidgets_native/interfacekit_ruby.c +507 -0
- data/ext/phidgets_native/ir_ruby.c +33 -0
- data/ext/phidgets_native/led_ruby.c +33 -0
- data/ext/phidgets_native/motorcontrol_ruby.c +32 -0
- data/ext/phidgets_native/phidgets_native.c +197 -0
- data/ext/phidgets_native/phidgets_native.h +320 -0
- data/ext/phidgets_native/phidgets_native_ruby.c +468 -0
- data/ext/phidgets_native/phsensor_ruby.c +32 -0
- data/ext/phidgets_native/rfid_ruby.c +31 -0
- data/ext/phidgets_native/servo_ruby.c +31 -0
- data/ext/phidgets_native/spatial.c +168 -0
- data/ext/phidgets_native/spatial_ruby.c +533 -0
- data/ext/phidgets_native/stepper_ruby.c +32 -0
- data/ext/phidgets_native/temperaturesensor_ruby.c +31 -0
- data/ext/phidgets_native/textlcd_ruby.c +31 -0
- data/ext/phidgets_native/textled_ruby.c +31 -0
- data/ext/phidgets_native/weightsensor_ruby.c +32 -0
- data/phidgets_native.gemspec +21 -0
- 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
|
+
}
|