phidgets_native 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -22,16 +22,16 @@ Presumably most other UNIX variants will work just fine. Probably win32/win64
22
22
  will not.
23
23
 
24
24
  ==Supported Devices
25
- As of this version, we currently only support the following phidgets:
25
+ As of the most recent version of this library, we support the following phidgets:
26
26
  * Phidget Spatial
27
27
  * Phidget GPS
28
28
  * Phidget Interface Kit
29
- There will soon be support for the "Phidget Servo" phidget. If you have a phidget
30
- that's not on our current compatibility list, either get me a copy of the phidget
31
- to work with at my desk, or check out the existing modules for a reference in
32
- setting up your own class, and push your changes to my repo. Most of the difficult
33
- work is done, and you'll find plenty of stubs to work with for nearly all the
34
- available phidgets.
29
+ * Phidget Advanced Servo
30
+ If you have a phidget that's not on the compatibility list, either buy me a copy
31
+ of the phidget you need support for, or check out the existing modules for a
32
+ reference in setting up your own class, and push your changes to my repo. Most
33
+ of the difficult work is done, and you'll find plenty of stubs to work with for
34
+ nearly all the available phidgets.
35
35
 
36
36
  =Why not Phidgets-FFI?
37
37
  Though encompassing, Phidgets-FFI is seemingly quite buggy, and a bit slow. Particularly
@@ -60,7 +60,7 @@ is attached. If the device is disconnected and reconnected, your phidget object
60
60
  will automatically re-register its handlers with the device, and continue to
61
61
  function as if the device were never disconnected to begin with. Keep in mind that
62
62
  any attributes relating to the device's capabilities (mostly those in the
63
- Phidget::Device class, though there are things like the axial extents in the
63
+ PhidgetsNative::Device class, though there are things like the axial extents in the
64
64
  spatial object) will be 'cached' from the previous connection. "State" attributes
65
65
  (such as the spatial's accelerometer output) will return nil or 0.
66
66
 
@@ -68,7 +68,7 @@ In practice, if you need an event-driven model for your code, you can almost cer
68
68
  get by using a ruby thread with a polling loop, like so:
69
69
 
70
70
  is_fixed_last = false
71
- @poller = Thread.new(Phidget::GPS(12345)) do |gps|
71
+ @poller = Thread.new(PhidgetsNative::GPS(12345)) do |gps|
72
72
  gps.wait_for_attachment(10000)
73
73
 
74
74
  begin
@@ -91,8 +91,8 @@ latest Phidget driver for your system.
91
91
  We also recommend that you read the following reference materials:
92
92
  * {General Phidget Programming}[http://www.phidgets.com/docs/General_Phidget_Programming]
93
93
  * The {User Guide}[http://www.phidgets.com/docs/Category:UserGuide] for your device
94
- * {RubyDoc API Documentation}[http://rubydoc.info/gems/phidgets_native/frames]
95
- * {Ruby code samples}[https://github.com/kreynolds/phidgets_native/tree/master/examples]
94
+ * {RubyDoc API Documentation}[http://rubydoc.info/github/brighton36/phidgets_native/master/frames]
95
+ * {Ruby code samples}[https://github.com/brighton36/phidgets_native/tree/master/examples]
96
96
 
97
97
  The RubyDoc API manual contains calls and events for every type of Phidget and
98
98
  can be used as a reference. You can find a high level discussion about programming
@@ -136,7 +136,7 @@ will reserve the device until closed. This prevents any other instances from
136
136
  retrieving data from the Phidget, including other programs.
137
137
 
138
138
  ==Standard accessors
139
- All devices support the accessors defined in the Phidget::Device class from which
139
+ All devices support the accessors defined in the PhidgetsNative::Device class from which
140
140
  they inherit.
141
141
 
142
142
  ==A note about device availability
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require '%s/lib/common' % File.dirname(__FILE__)
5
+
6
+ additional_attribs = [
7
+ %w(Motor\ Count motor_count),
8
+ %w(Acceleration\ Max acceleration_max),
9
+ %w(Acceleration\ Min acceleration_min),
10
+ %w(Velocity\ Max velocity_max),
11
+ %w(Velocity\ Min velocity_min)
12
+ ]
13
+
14
+ phidgets_example_for(PhidgetsNative::AdvancedServo, additional_attribs) do |servo|
15
+ servo.acceleration 0, servo.acceleration_max[0]
16
+ servo.velocity_limit 0, servo.velocity_max[0]
17
+ # NOTE that these doesn't seem to be supported on all servo types
18
+ servo.position_max 0, 220
19
+ servo.position_min 0, 0
20
+ # /NOTE
21
+ servo.servo_type 0, :default
22
+ servo.speed_ramping 0, false
23
+ servo.engaged 0, true
24
+
25
+ servo_range = servo.position_max(0) - servo.position_min(0)
26
+ servo_middle = servo.position_min(0) + servo_range/2
27
+ servo_left = servo.position_min(0) + servo_middle - servo_range / 4
28
+ servo_right = servo.position_min(0) + servo_middle + servo_range / 4
29
+
30
+ servo.position 0, servo_middle
31
+
32
+ puts "\nServo-specific Attributes:"
33
+ ConsoleTable.new([
34
+ 'Servo Offset', 'Acceleration Max', 'Acceleration Min','Velocity Limit', 'Position Max', 'Position Min',
35
+ 'Speed_Ramping?', 'Engaged?', 'Stopped?', 'Servo Type' ]).output do
36
+ (0...servo.motor_count).collect do |i|
37
+ ([i, servo.acceleration_max[i], servo.acceleration_min[i]]+%w(
38
+ velocity_limit position_max position_min speed_ramping? engaged?
39
+ stopped? servo_type).collect{|attr|
40
+ begin
41
+ servo.send(attr, i)
42
+ rescue PhidgetsNative::UnknownValError
43
+ nil
44
+ end
45
+ }).collect(&:inspect)
46
+ end
47
+ end
48
+
49
+ puts "\nPolled Values:"
50
+ i = 0
51
+ ConsoleTable.new([
52
+ 'Sample Rates',
53
+ 'Currents',
54
+ 'Positions',
55
+ 'Velocities'
56
+ ]).output(:header => (i == 0), :separator => false) do |columns|
57
+ i+=1
58
+
59
+ servo.position 0, (i % 2 == 0) ? servo_left : servo_right if (i != 0)
60
+ [ [servo.sample_rates, servo.currents, servo.positions, servo.velocities].collect(&:inspect) ]
61
+ end while sleep(3)
62
+ end
@@ -32,6 +32,9 @@ phidgets_example_for(PhidgetsNative::InterfaceKit, additional_attribs) do |ifkit
32
32
  end
33
33
  end
34
34
 
35
+ # Set the ratiometric state
36
+ ifkit.ratiometric = false
37
+
35
38
  # Test sensor_raw
36
39
  puts "Raw Analog sensor values:"
37
40
  ConsoleTable.new((0...ifkit.sensor_count).collect{|i| "Sensor #{i}"}).output do
@@ -50,8 +53,6 @@ phidgets_example_for(PhidgetsNative::InterfaceKit, additional_attribs) do |ifkit
50
53
  ]).output(:header => (i == 0), :separator => false) do |columns|
51
54
  i+=1
52
55
 
53
- #TODO Test the ratiometric set at some point
54
-
55
56
  [ [ifkit.input_sample_rates, ifkit.sensor_sample_rates, ifkit.ratiometric?.inspect,
56
57
  ifkit.sensors.inspect]+[ifkit.inputs, ifkit.outputs].collect{ |bools|
57
58
  (bools.kind_of? Array) ?
@@ -0,0 +1,112 @@
1
+ #include "phidgets_native.h"
2
+
3
+ int CCONV advancedservo_on_attach(CPhidgetHandle phid, void *userptr) {
4
+ PhidgetInfo *info = userptr;
5
+ AdvancedServoInfo *servo_info = info->type_info;
6
+ CPhidgetAdvancedServoHandle advancedservo = (CPhidgetAdvancedServoHandle) phid;
7
+
8
+ report(CPhidgetAdvancedServo_getMotorCount(advancedservo, &servo_info->motor_count));
9
+ servo_info->is_motor_count_known = true;
10
+
11
+ if (servo_info->motor_count != servo_info->motor_count_prior) {
12
+ if(servo_info->acceleration_min) xfree(servo_info->acceleration_min);
13
+ if(servo_info->acceleration_max) xfree(servo_info->acceleration_max);
14
+ if(servo_info->velocity_min) xfree(servo_info->velocity_min);
15
+ if(servo_info->velocity_max) xfree(servo_info->velocity_max);
16
+ if(servo_info->sample_rates) xfree(servo_info->sample_rates);
17
+
18
+ servo_info->acceleration_max = ALLOC_N(double, servo_info->motor_count);
19
+ servo_info->acceleration_min = ALLOC_N(double, servo_info->motor_count);
20
+ servo_info->velocity_min = ALLOC_N(double, servo_info->motor_count);
21
+ servo_info->velocity_max = ALLOC_N(double, servo_info->motor_count);
22
+ servo_info->sample_rates = ALLOC_N(SampleRate, servo_info->motor_count);
23
+
24
+ memset(servo_info->sample_rates, 0, sizeof(SampleRate) * servo_info->motor_count);
25
+
26
+ for (int i=0; i < servo_info->motor_count; i++) {
27
+ report(CPhidgetAdvancedServo_getAccelerationMax(advancedservo,i,&servo_info->acceleration_max[i]));
28
+ report(CPhidgetAdvancedServo_getAccelerationMin(advancedservo,i,&servo_info->acceleration_min[i]));
29
+ report(CPhidgetAdvancedServo_getVelocityMax(advancedservo,i,&servo_info->velocity_max[i]));
30
+ report(CPhidgetAdvancedServo_getVelocityMin(advancedservo,i,&servo_info->velocity_min[i]));
31
+ }
32
+ }
33
+
34
+ servo_info->current = ALLOC_N(double, servo_info->motor_count);
35
+ servo_info->position = ALLOC_N(double, servo_info->motor_count);
36
+ servo_info->velocity = ALLOC_N(double, servo_info->motor_count);
37
+
38
+ memset(servo_info->current, 0, sizeof(double) * servo_info->motor_count);
39
+ memset(servo_info->position, 0, sizeof(double) * servo_info->motor_count);
40
+ memset(servo_info->velocity, 0, sizeof(double) * servo_info->motor_count);
41
+
42
+ return 0;
43
+ }
44
+
45
+ int CCONV advancedservo_on_detach(CPhidgetHandle phid, void *userptr) {
46
+ PhidgetInfo *info = userptr;
47
+ AdvancedServoInfo *servo_info = info->type_info;
48
+
49
+ servo_info->motor_count_prior = servo_info->motor_count;
50
+
51
+ if(servo_info->current) xfree(servo_info->current);
52
+ if(servo_info->position) xfree(servo_info->position);
53
+ if(servo_info->velocity) xfree(servo_info->velocity);
54
+
55
+ servo_info->current = 0;
56
+ servo_info->position = 0;
57
+ servo_info->velocity = 0;
58
+
59
+ memset(servo_info->sample_rates, 0, sizeof(SampleRate) * servo_info->motor_count);
60
+
61
+ return 0;
62
+ }
63
+
64
+ void advancedservo_on_free(void *type_info) {
65
+ AdvancedServoInfo *servo_info = type_info;
66
+
67
+ if(servo_info->sample_rates) xfree(servo_info->sample_rates);
68
+ if(servo_info->acceleration_min) xfree(servo_info->acceleration_min);
69
+ if(servo_info->acceleration_max) xfree(servo_info->acceleration_max);
70
+ if(servo_info->velocity_min) xfree(servo_info->velocity_min);
71
+ if(servo_info->velocity_max) xfree(servo_info->velocity_max);
72
+ if(servo_info->current) xfree(servo_info->current);
73
+ if(servo_info->position) xfree(servo_info->position);
74
+ if(servo_info->velocity) xfree(servo_info->velocity);
75
+ if (servo_info) xfree(servo_info);
76
+
77
+ return;
78
+ }
79
+
80
+ int CCONV advancedservo_on_velocity_change(CPhidgetAdvancedServoHandle phid, void *userptr, int index, double velocity) {
81
+ PhidgetInfo *info = userptr;
82
+ AdvancedServoInfo *servo_info = info->type_info;
83
+
84
+ sample_tick(&servo_info->sample_rates[index], NULL);
85
+
86
+ if (servo_info->velocity) servo_info->velocity[index] = velocity;
87
+
88
+ return 0;
89
+ }
90
+
91
+ int CCONV advancedservo_on_position_change(CPhidgetAdvancedServoHandle phid, void *userptr, int index, double position) {
92
+ PhidgetInfo *info = userptr;
93
+ AdvancedServoInfo *servo_info = info->type_info;
94
+
95
+ sample_tick(&servo_info->sample_rates[index], NULL);
96
+
97
+ if (servo_info->position) servo_info->position[index] = position;
98
+
99
+ return 0;
100
+ }
101
+
102
+ int CCONV advancedservo_on_current_change(CPhidgetAdvancedServoHandle phid, void *userptr, int index, double current) {
103
+ PhidgetInfo *info = userptr;
104
+ AdvancedServoInfo *servo_info = info->type_info;
105
+
106
+ sample_tick(&servo_info->sample_rates[index], NULL);
107
+
108
+ if (servo_info->current) servo_info->current[index] = current;
109
+
110
+ return 0;
111
+ }
112
+
@@ -1,5 +1,15 @@
1
1
  #include "phidgets_native.h"
2
2
 
3
+ const char MSG_INDEX_MUST_BE_FIXNUM[] = "servo index must be fixnum";
4
+ const char MSG_VALUE_MUST_BE_FLOAT[] = "value must be a floating point number";
5
+ const char MSG_VALUE_MUST_BE_BOOL[] = "value must be either true or false";
6
+ const char MSG_SERVO_MIN_US_MUST_BE_FLOAT[] = "min_us must be a floating point number";
7
+ const char MSG_SERVO_MAX_US_MUST_BE_FLOAT[] = "max_us must be a floating point number";
8
+ const char MSG_SERVO_DEGREES_MUST_BE_FLOAT[] = "degrees_us must be a floating point number";
9
+ const char MSG_SERVO_VELOCITY_MAX_MUST_BE_FLOAT[] = "velocity_max must be a floating point number";
10
+ const char MSG_TYPE_MUST_BE_SYMBOL[] = "type must be a symbol";
11
+ const char MSG_UNRECOGNIZED_SERVO_TYPE[] = "unrecognized servo type, double check your spelling and/or revisit the rdoc";
12
+
3
13
  /*
4
14
  * Document-class: PhidgetsNative::AdvancedServo < PhidgetsNative::Device
5
15
  *
@@ -22,12 +32,828 @@ void Init_phidgets_native_advancedservo(VALUE m_Phidget) {
22
32
  * are required to be Fixnums (aka "unsigned integers").
23
33
  */
24
34
  rb_define_method(c_AdvancedServo, "initialize", advancedservo_initialize, 1);
35
+
36
+ /*
37
+ * Document-method: motor_count
38
+ * call-seq:
39
+ * motor_count -> Fixnum
40
+ *
41
+ * Returns an integer which represents the number of motor interfaces provided
42
+ * by this advanced servo controller, or nil if the device has yet to be connected.
43
+ */
44
+ rb_define_method(c_AdvancedServo, "motor_count", advancedservo_motor_count, 0);
45
+
46
+ /*
47
+ * Document-method: sample_rates
48
+ * call-seq:
49
+ * sample_rates -> Array
50
+ *
51
+ * The advancedservo object tracks the sample rate of each servo individually.
52
+ * This method returns an array containing the sample rates of each servo
53
+ */
54
+ rb_define_method(c_AdvancedServo, "sample_rates", advancedservo_sample_rates, 0);
55
+
56
+ /*
57
+ * Document-method: acceleration_max
58
+ * call-seq:
59
+ * acceleration_max -> Array
60
+ *
61
+ * Returns an array of Floats which specify the maximum acceleration value that can
62
+ * be configured on each servo, or nil if the device has yet to be connected.
63
+ */
64
+ rb_define_method(c_AdvancedServo, "acceleration_max", advancedservo_acceleration_max, 0);
65
+
66
+ /*
67
+ * Document-method: acceleration_min
68
+ * call-seq:
69
+ * acceleration_min -> Array
70
+ *
71
+ * Returns an array of Floats which specify the minimum acceleration value that can
72
+ * be configured on each servo, or nil if the device has yet to be connected.
73
+ */
74
+ rb_define_method(c_AdvancedServo, "acceleration_min", advancedservo_acceleration_min, 0);
75
+
76
+ /*
77
+ * Document-method: velocity_max
78
+ * call-seq:
79
+ * velocity_max -> Array
80
+ *
81
+ * Returns an array of Floats which specify the maximum velocity value that can
82
+ * be configured on each servo, or nil if the device has yet to be connected.
83
+ */
84
+ rb_define_method(c_AdvancedServo, "velocity_max", advancedservo_velocity_max, 0);
85
+
86
+ /*
87
+ * Document-method: velocity_min
88
+ * call-seq:
89
+ * velocity_min -> Array
90
+ *
91
+ * Returns an array of Floats which specify the minimum velocity value that can
92
+ * be configured on each servo, or nil if the device is disconnected.
93
+ */
94
+ rb_define_method(c_AdvancedServo, "velocity_min", advancedservo_velocity_min, 0);
95
+
96
+ /*
97
+ * Document-method: currents
98
+ * call-seq:
99
+ * currents -> Array
100
+ *
101
+ * Returns an array of Floats which represent the current draw of each servo
102
+ * attached to the system, or nil if the device is disconnected.
103
+ */
104
+ rb_define_method(c_AdvancedServo, "currents", advancedservo_currents, 0);
105
+
106
+ /*
107
+ * Document-method: positions
108
+ * call-seq:
109
+ * positions -> Array
110
+ *
111
+ * Returns an array of Floats which represent the positions of each servo
112
+ * attached to the system, or nil if the device has yet to be connected.
113
+ */
114
+ rb_define_method(c_AdvancedServo, "positions", advancedservo_positions, 0);
115
+
116
+ /*
117
+ * Document-method: velocities
118
+ * call-seq:
119
+ * velocities -> Array
120
+ *
121
+ * Returns an array of Floats which represent the velocities of each servo
122
+ * attached to the system, or nil if the device is disconnected.
123
+ */
124
+ rb_define_method(c_AdvancedServo, "velocities", advancedservo_velocities, 0);
125
+
126
+ /*
127
+ * Document-method: acceleration
128
+ * call-seq:
129
+ * acceleration(Fixnum index, Float value = nil) -> Float
130
+ *
131
+ * If a value is passed, the acceleration of a servo is set to the specified
132
+ * value at the provided index.
133
+ * Returns a float representing the "acceleration" of the servo at the provided
134
+ * index. This value comes directly from the
135
+ * CPhidgetAdvancedServo_getAcceleration[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
136
+ * function.
137
+ */
138
+ rb_define_method(c_AdvancedServo, "acceleration", advancedservo_acceleration, -1);
139
+
140
+ /*
141
+ * Document-method: velocity_limit
142
+ * call-seq:
143
+ * velocity_limit(Fixnum index, Float value = nil) -> Float
144
+ *
145
+ * If a value is passed, the velocity_limit of a servo is set to the specified
146
+ * value at the provided index.
147
+ * Returns a float representing the "velocity limit" of the servo at the provided
148
+ * index. This value comes directly from the
149
+ * CPhidgetAdvancedServo_getVelocityLimit[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
150
+ * function.
151
+ */
152
+ rb_define_method(c_AdvancedServo, "velocity_limit", advancedservo_velocity_limit, -1);
153
+
154
+ /*
155
+ * Document-method: position
156
+ * call-seq:
157
+ * position(Fixnum index, Float value = nil) -> Float
158
+ *
159
+ * Sets the servo position of the servo at the provided index.
160
+ * Returns the passed position. This value comes directly from the
161
+ * CPhidgetAdvancedServo_setPosition[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
162
+ * function.
163
+ */
164
+ rb_define_method(c_AdvancedServo, "position", advancedservo_position_set, 2);
165
+
166
+ /*
167
+ * Document-method: position_max
168
+ * call-seq:
169
+ * position_max(Fixnum index, Float value = nil) -> Float
170
+ *
171
+ * If a value is passed, the position_max of a servo is set to the specified
172
+ * value at the provided index.
173
+ * Returns a float representing the "maximum position" of the servo at the provided
174
+ * index. This value comes directly from the
175
+ * CPhidgetAdvancedServo_getPositionMax[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
176
+ * function.
177
+ */
178
+ rb_define_method(c_AdvancedServo, "position_max", advancedservo_position_max, -1);
179
+
180
+ /*
181
+ * Document-method: position_min
182
+ * call-seq:
183
+ * position_min(Fixnum index, Float value = nil) -> Float
184
+ *
185
+ * If a value is passed, the position_min of a servo is set to the specified
186
+ * value at the provided index.
187
+ * Returns a float representing the "minimum position" of the servo at the provided
188
+ * index. This value comes directly from the
189
+ * CPhidgetAdvancedServo_getPositionMin[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
190
+ * function.
191
+ */
192
+ rb_define_method(c_AdvancedServo, "position_min", advancedservo_position_min, -1);
193
+
194
+ /*
195
+ * Document-method: servo_type
196
+ * call-seq:
197
+ * servo_type(Fixnum index, Float value = nil) -> Symbol
198
+ *
199
+ * If a value is passed, the type of servo is set to the specified
200
+ * value at the provided index.
201
+ * Returns a symbol indicating the model/type of the servo at the provided
202
+ * index. This value comes directly from the
203
+ * CPhidgetAdvancedServo_getServoType[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
204
+ * function.
205
+ *
206
+ * Currently, the following servo types are returned:
207
+ * * :default
208
+ * * :raw_us_mode
209
+ * * :hitec_hs322hd
210
+ * * :hitec_hs5245mg
211
+ * * :hitec_805bb
212
+ * * :hitec_hs422
213
+ * * :towerpro_mg90
214
+ * * :hitec_hsr1425cr
215
+ * * :hitec_hs785hb
216
+ * * :hitec_hs485hb
217
+ * * :hitec_hs645mg
218
+ * * :hitec_815bb
219
+ * * :firgelli_l12_30_50_06_r
220
+ * * :firgelli_l12_50_100_06_r
221
+ * * :firgelli_l12_50_210_06_r
222
+ * * :firgelli_l12_100_50_06_r
223
+ * * :firgelli_l12_100_100_06_r
224
+ * * :springrc_sm_s2313m
225
+ * * :springrc_sm_s3317m
226
+ * * :springrc_sm_s3317sr
227
+ * * :springrc_sm_s4303r
228
+ * * :springrc_sm_s4315m
229
+ * * :springrc_sm_s4315r
230
+ * * :springrc_sm_s4505b
231
+ * * :unknown
232
+ *
233
+ * NOTE: Servo types cannot be set to :unknown, though :unknown is possibly
234
+ * returned if an unrecognized servo type is returned by the phidget libraries.
235
+ */
236
+ rb_define_method(c_AdvancedServo, "servo_type", advancedservo_servo_type, -1);
237
+
238
+ /*
239
+ * Document-method: speed_ramping?
240
+ * call-seq:
241
+ * speed_ramping?(Fixnum index) -> Boolean
242
+ *
243
+ * Returns either true or false, depending on whether the servo at the provided
244
+ * index is configured to speed ramp. This value comes directly from the
245
+ * CPhidgetAdvancedServo_getSpeedRampingOn[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
246
+ * function.
247
+ */
248
+ rb_define_method(c_AdvancedServo, "speed_ramping?", advancedservo_is_speed_ramping, 1);
249
+
250
+ /*
251
+ * Document-method: engaged?
252
+ * call-seq:
253
+ * engaged?(Fixnum index) -> Boolean
254
+ *
255
+ * Returns either true or false, depending on whether the servo at the provided
256
+ * index is engaged (aka - whether the motor is powered or not). This value
257
+ * comes directly from the
258
+ * CPhidgetAdvancedServo_getEngaged[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
259
+ * function.
260
+ */
261
+ rb_define_method(c_AdvancedServo, "engaged?", advancedservo_is_engaged, 1);
262
+
263
+ /*
264
+ * Document-method: stopped?
265
+ * call-seq:
266
+ * stopped?(Fixnum index) -> Boolean
267
+ *
268
+ * Returns either true or false, depending on whether the servo at the provided
269
+ * index is stopped (aka - whether the motor is currently moving or not). This
270
+ * value comes directly from the
271
+ * CPhidgetAdvancedServo_getStopped[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
272
+ * function.
273
+ */
274
+ rb_define_method(c_AdvancedServo, "stopped?", advancedservo_is_stopped, 1);
275
+
276
+
277
+ /*
278
+ * Document-method: speed_ramping
279
+ * call-seq:
280
+ * speed_ramping(Fixnum index, Boolean) -> Boolean
281
+ *
282
+ * Sets the "speed ramping" of the servo at the provided index.
283
+ * This value is sent directly to the
284
+ * CPhidgetAdvancedServo_setSpeedRampingOn[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
285
+ * function.
286
+ */
287
+ rb_define_method(c_AdvancedServo, "speed_ramping", advancedservo_speed_ramping_set, 2);
288
+
289
+ /*
290
+ * Document-method: engaged
291
+ * call-seq:
292
+ * engaged(Fixnum index, Boolean) -> Boolean
293
+ *
294
+ * Sets the "engagement" of the servo at the provided index.
295
+ * This value is sent directly to the
296
+ * CPhidgetAdvancedServo_setEngaged[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
297
+ * function.
298
+ */
299
+ rb_define_method(c_AdvancedServo, "engaged", advancedservo_engaged_set, 2);
300
+
301
+ /*
302
+ * Document-method: servo_parameters
303
+ * call-seq:
304
+ * servo_parameters(Fixnum index, Float min_us, Float max_us, Float degrees, Float velocity_max) -> Qnil
305
+ *
306
+ * Sets the "servo parameters" of the servo at the provided index.
307
+ * This value is sent directly to the
308
+ * CPhidgetAdvancedServo_setServoParameters[http://www.phidgets.com/documentation/web/cdoc/group__phidadvservo.html]
309
+ * function.
310
+ */
311
+ rb_define_method(c_AdvancedServo, "servo_parameters", advancedservo_servo_parameters_set, 5);
25
312
  }
26
313
 
27
314
  VALUE advancedservo_initialize(VALUE self, VALUE serial) {
28
315
  PhidgetInfo *info = device_info(self);
316
+
317
+ AdvancedServoInfo *servo_info = ALLOC(AdvancedServoInfo);
318
+ memset(servo_info, 0, sizeof(AdvancedServoInfo));
319
+ servo_info->is_motor_count_known = false;
320
+
29
321
  CPhidgetAdvancedServoHandle advancedservo = 0;
30
322
  ensure(CPhidgetAdvancedServo_create(&advancedservo));
323
+
31
324
  info->handle = (CPhidgetHandle)advancedservo;
325
+ info->on_type_attach = advancedservo_on_attach;
326
+ info->on_type_detach = advancedservo_on_detach;
327
+ info->on_type_free = advancedservo_on_free;
328
+ info->type_info = servo_info;
329
+
330
+ ensure(CPhidgetAdvancedServo_set_OnVelocityChange_Handler(advancedservo, advancedservo_on_velocity_change, info));
331
+ ensure(CPhidgetAdvancedServo_set_OnPositionChange_Handler(advancedservo, advancedservo_on_position_change, info));
332
+ ensure(CPhidgetAdvancedServo_set_OnCurrentChange_Handler(advancedservo, advancedservo_on_current_change, info));
333
+
32
334
  return rb_call_super(1, &serial);
33
335
  }
336
+
337
+ VALUE advancedservo_close(VALUE self) {
338
+ PhidgetInfo *info = device_info(self);
339
+
340
+ ensure(CPhidgetAdvancedServo_set_OnVelocityChange_Handler((CPhidgetAdvancedServoHandle)info->handle, NULL, NULL));
341
+ ensure(CPhidgetAdvancedServo_set_OnPositionChange_Handler((CPhidgetAdvancedServoHandle)info->handle, NULL, NULL));
342
+ ensure(CPhidgetAdvancedServo_set_OnCurrentChange_Handler((CPhidgetAdvancedServoHandle)info->handle, NULL, NULL));
343
+
344
+ return rb_call_super(0,NULL);
345
+ }
346
+
347
+ VALUE advancedservo_motor_count(VALUE self) {
348
+ AdvancedServoInfo *servo_info = device_type_info(self);
349
+
350
+ return (servo_info->is_motor_count_known) ?
351
+ INT2FIX(servo_info->motor_count) : Qnil;
352
+ }
353
+
354
+ VALUE advancedservo_sample_rates(VALUE self) {
355
+ AdvancedServoInfo *servo_info = device_type_info(self);
356
+
357
+ if (!servo_info->is_motor_count_known) return Qnil;
358
+
359
+ int *rates_in_hz = ALLOC_N(int, servo_info->motor_count);
360
+ for(int i=0; i<servo_info->motor_count; i++)
361
+ rates_in_hz[i] = servo_info->sample_rates[i].in_hz;
362
+
363
+ VALUE ret = int_array_to_rb(rates_in_hz, servo_info->motor_count);
364
+
365
+ xfree(rates_in_hz);
366
+
367
+ return ret;
368
+ }
369
+
370
+ VALUE advancedservo_acceleration_max(VALUE self) {
371
+ AdvancedServoInfo *servo_info = device_type_info(self);
372
+
373
+ return (servo_info->is_motor_count_known) ?
374
+ double_array_to_rb(servo_info->acceleration_max, servo_info->motor_count) : Qnil;
375
+ }
376
+
377
+ VALUE advancedservo_acceleration_min(VALUE self) {
378
+ AdvancedServoInfo *servo_info = device_type_info(self);
379
+
380
+ return (servo_info->is_motor_count_known) ?
381
+ double_array_to_rb(servo_info->acceleration_min, servo_info->motor_count) : Qnil;
382
+ }
383
+
384
+ VALUE advancedservo_velocity_max(VALUE self) {
385
+ AdvancedServoInfo *servo_info = device_type_info(self);
386
+
387
+ return (servo_info->is_motor_count_known) ?
388
+ double_array_to_rb(servo_info->velocity_max, servo_info->motor_count) : Qnil;
389
+ }
390
+
391
+ VALUE advancedservo_velocity_min(VALUE self) {
392
+ AdvancedServoInfo *servo_info = device_type_info(self);
393
+
394
+ return (servo_info->is_motor_count_known) ?
395
+ double_array_to_rb(servo_info->velocity_min, servo_info->motor_count) : Qnil;
396
+ }
397
+
398
+ VALUE advancedservo_currents(VALUE self) {
399
+ AdvancedServoInfo *servo_info = device_type_info(self);
400
+
401
+ return (servo_info->current) ?
402
+ double_array_to_rb(servo_info->current, servo_info->motor_count) : Qnil;
403
+ }
404
+
405
+ VALUE advancedservo_positions(VALUE self) {
406
+ AdvancedServoInfo *servo_info = device_type_info(self);
407
+
408
+ return (servo_info->position) ?
409
+ double_array_to_rb(servo_info->position, servo_info->motor_count) : Qnil;
410
+ }
411
+
412
+ VALUE advancedservo_velocities(VALUE self) {
413
+ AdvancedServoInfo *servo_info = device_type_info(self);
414
+
415
+ return (servo_info->velocity) ?
416
+ double_array_to_rb(servo_info->velocity, servo_info->motor_count) : Qnil;
417
+ }
418
+
419
+ VALUE advancedservo_acceleration(int argc, VALUE* argv, VALUE self) {
420
+ VALUE index;
421
+ VALUE value;
422
+
423
+ rb_scan_args(argc, argv, "11", &index, &value);
424
+
425
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
426
+
427
+ int index_int = FIX2INT(index);
428
+ double value_dbl;
429
+
430
+ PhidgetInfo *info = device_info(self);
431
+
432
+ if (!info->is_attached) return Qnil;
433
+
434
+ if(NIL_P(value)) {
435
+ // It's a get request:
436
+ ensure(CPhidgetAdvancedServo_getAcceleration(
437
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &value_dbl ));
438
+
439
+ } else {
440
+ // Set request
441
+ if ( (TYPE(value) != T_FLOAT) && (TYPE(value) != T_FIXNUM) )
442
+ rb_raise(rb_eTypeError, MSG_VALUE_MUST_BE_FLOAT);
443
+
444
+ value_dbl = NUM2DBL(value);
445
+
446
+ ensure(CPhidgetAdvancedServo_setAcceleration(
447
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, value_dbl ));
448
+ }
449
+
450
+ return DBL2NUM(value_dbl);
451
+ }
452
+
453
+ VALUE advancedservo_velocity_limit(int argc, VALUE* argv, VALUE self) {
454
+ VALUE index;
455
+ VALUE value;
456
+
457
+ rb_scan_args(argc, argv, "11", &index, &value);
458
+
459
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
460
+
461
+ int index_int = FIX2INT(index);
462
+ double value_dbl;
463
+
464
+ PhidgetInfo *info = device_info(self);
465
+
466
+ if (!info->is_attached) return Qnil;
467
+
468
+ if(NIL_P(value)) {
469
+ // It's a get request:
470
+ ensure(CPhidgetAdvancedServo_getVelocityLimit(
471
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &value_dbl ));
472
+
473
+ } else {
474
+ // Set request
475
+ if ( (TYPE(value) != T_FLOAT) && (TYPE(value) != T_FIXNUM) )
476
+ rb_raise(rb_eTypeError, MSG_VALUE_MUST_BE_FLOAT);
477
+
478
+ value_dbl = NUM2DBL(value);
479
+
480
+ ensure(CPhidgetAdvancedServo_setVelocityLimit(
481
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, value_dbl ));
482
+ }
483
+
484
+ return DBL2NUM(value_dbl);
485
+ }
486
+
487
+ VALUE advancedservo_position_max(int argc, VALUE* argv, VALUE self) {
488
+ VALUE index;
489
+ VALUE value;
490
+
491
+ rb_scan_args(argc, argv, "11", &index, &value);
492
+
493
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
494
+
495
+ int index_int = FIX2INT(index);
496
+ double value_dbl;
497
+
498
+ PhidgetInfo *info = device_info(self);
499
+
500
+ if (!info->is_attached) return Qnil;
501
+
502
+ if(NIL_P(value)) {
503
+ // It's a get request:
504
+ ensure(CPhidgetAdvancedServo_getPositionMax(
505
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &value_dbl ));
506
+
507
+ } else {
508
+ // Set request
509
+ if ( (TYPE(value) != T_FLOAT) && (TYPE(value) != T_FIXNUM) )
510
+ rb_raise(rb_eTypeError, MSG_VALUE_MUST_BE_FLOAT);
511
+
512
+ value_dbl = NUM2DBL(value);
513
+ ensure(CPhidgetAdvancedServo_setPositionMax(
514
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, value_dbl ));
515
+ }
516
+
517
+ return DBL2NUM(value_dbl);
518
+ }
519
+
520
+ VALUE advancedservo_position_min(int argc, VALUE* argv, VALUE self) {
521
+ VALUE index;
522
+ VALUE value;
523
+
524
+ rb_scan_args(argc, argv, "11", &index, &value);
525
+
526
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
527
+
528
+ int index_int = FIX2INT(index);
529
+ double value_dbl;
530
+
531
+ PhidgetInfo *info = device_info(self);
532
+
533
+ if (!info->is_attached) return Qnil;
534
+
535
+ if(NIL_P(value)) {
536
+ // It's a get request:
537
+ ensure(CPhidgetAdvancedServo_getPositionMin(
538
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &value_dbl ));
539
+
540
+ } else {
541
+ // Set request
542
+ if ( (TYPE(value) != T_FLOAT) && (TYPE(value) != T_FIXNUM) )
543
+ rb_raise(rb_eTypeError, MSG_VALUE_MUST_BE_FLOAT);
544
+
545
+ value_dbl = NUM2DBL(value);
546
+
547
+ ensure(CPhidgetAdvancedServo_setPositionMin(
548
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, value_dbl ));
549
+ }
550
+
551
+ return DBL2NUM(value_dbl);
552
+ }
553
+
554
+ VALUE advancedservo_is_speed_ramping(VALUE self, VALUE index) {
555
+ PhidgetInfo *info = device_info(self);
556
+
557
+ if (!info->is_attached) return Qnil;
558
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
559
+
560
+ int index_int = FIX2INT(index);
561
+
562
+ int is_ret;
563
+ ensure(CPhidgetAdvancedServo_getSpeedRampingOn(
564
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &is_ret ));
565
+
566
+ return (is_ret == PTRUE) ? Qtrue : Qfalse;
567
+ }
568
+
569
+ VALUE advancedservo_is_engaged(VALUE self, VALUE index) {
570
+ PhidgetInfo *info = device_info(self);
571
+
572
+ if (!info->is_attached) return Qnil;
573
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
574
+
575
+ int index_int = FIX2INT(index);
576
+
577
+ int is_ret;
578
+ ensure(CPhidgetAdvancedServo_getEngaged(
579
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &is_ret ));
580
+
581
+ return (is_ret == PTRUE) ? Qtrue : Qfalse;
582
+ }
583
+
584
+ VALUE advancedservo_is_stopped(VALUE self, VALUE index) {
585
+ PhidgetInfo *info = device_info(self);
586
+
587
+ if (!info->is_attached) return Qnil;
588
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
589
+
590
+ int index_int = FIX2INT(index);
591
+
592
+ int is_ret;
593
+ ensure(CPhidgetAdvancedServo_getStopped(
594
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &is_ret ));
595
+
596
+ return (is_ret == PTRUE) ? Qtrue : Qfalse;
597
+ }
598
+
599
+
600
+ VALUE advancedservo_position_set(VALUE self, VALUE index, VALUE value) {
601
+ PhidgetInfo *info = device_info(self);
602
+
603
+ if (!info->is_attached) return Qnil;
604
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
605
+ if ( (TYPE(value) != T_FLOAT) && (TYPE(value) != T_FIXNUM) )
606
+ rb_raise(rb_eTypeError, MSG_VALUE_MUST_BE_FLOAT);
607
+
608
+ int index_int = FIX2INT(index);
609
+ double value_dbl = NUM2DBL(value);
610
+
611
+ double ret;
612
+ ensure(CPhidgetAdvancedServo_setPosition(
613
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, value_dbl ));
614
+
615
+ return DBL2NUM(value_dbl);
616
+ }
617
+
618
+ VALUE advancedservo_speed_ramping_set(VALUE self, VALUE index, VALUE value) {
619
+ PhidgetInfo *info = device_info(self);
620
+
621
+ if (!info->is_attached) return Qnil;
622
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
623
+
624
+
625
+ int index_int = FIX2INT(index);
626
+ int value_int;
627
+
628
+ if (TYPE(value) == T_TRUE)
629
+ value_int = PTRUE;
630
+ else if (TYPE(value) == T_FALSE)
631
+ value_int = PFALSE;
632
+ else
633
+ rb_raise(rb_eTypeError, MSG_VALUE_MUST_BE_BOOL);
634
+
635
+ ensure(CPhidgetAdvancedServo_setSpeedRampingOn(
636
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, value_int ));
637
+
638
+ return (value_int == PTRUE) ? Qtrue : Qfalse;
639
+ }
640
+
641
+ VALUE advancedservo_engaged_set(VALUE self, VALUE index, VALUE value) {
642
+ PhidgetInfo *info = device_info(self);
643
+
644
+ if (!info->is_attached) return Qnil;
645
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
646
+
647
+ int index_int = FIX2INT(index);
648
+ int value_int;
649
+
650
+ if (TYPE(value) == T_TRUE)
651
+ value_int = PTRUE;
652
+ else if (TYPE(value) == T_FALSE)
653
+ value_int = PFALSE;
654
+ else
655
+ rb_raise(rb_eTypeError, MSG_VALUE_MUST_BE_BOOL);
656
+
657
+ ensure(CPhidgetAdvancedServo_setEngaged(
658
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, value_int ));
659
+
660
+ return (value_int == PTRUE) ? Qtrue : Qfalse;
661
+ }
662
+
663
+ VALUE advancedservo_servo_parameters_set(VALUE self, VALUE index, VALUE min_us, VALUE max_us, VALUE degrees, VALUE velocity_max) {
664
+ PhidgetInfo *info = device_info(self);
665
+
666
+ if (!info->is_attached) return Qnil;
667
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
668
+
669
+ if ( (TYPE(min_us) != T_FLOAT) && (TYPE(min_us) != T_FIXNUM) )
670
+ rb_raise(rb_eTypeError, MSG_SERVO_MIN_US_MUST_BE_FLOAT);
671
+
672
+ if ( (TYPE(max_us) != T_FLOAT) && (TYPE(max_us) != T_FIXNUM) )
673
+ rb_raise(rb_eTypeError, MSG_SERVO_MAX_US_MUST_BE_FLOAT);
674
+
675
+ if ( (TYPE(degrees) != T_FLOAT) && (TYPE(degrees) != T_FIXNUM) )
676
+ rb_raise(rb_eTypeError, MSG_SERVO_DEGREES_MUST_BE_FLOAT);
677
+
678
+ if ( (TYPE(velocity_max) != T_FLOAT) && (TYPE(velocity_max) != T_FIXNUM) )
679
+ rb_raise(rb_eTypeError, MSG_SERVO_VELOCITY_MAX_MUST_BE_FLOAT);
680
+
681
+ int index_int = FIX2INT(index);
682
+ double min_us_dbl = NUM2DBL(min_us);
683
+ double max_us_dbl = NUM2DBL(max_us);
684
+ double degrees_dbl = NUM2DBL(degrees);
685
+ double velocity_max_dbl = NUM2DBL(velocity_max);
686
+
687
+ ensure(CPhidgetAdvancedServo_setServoParameters(
688
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, min_us_dbl, max_us_dbl,
689
+ degrees_dbl, velocity_max_dbl ));
690
+
691
+ return Qnil;
692
+ }
693
+
694
+ VALUE advancedservo_servo_type(int argc, VALUE* argv, VALUE self) {
695
+ VALUE index;
696
+ VALUE value;
697
+
698
+ rb_scan_args(argc, argv, "11", &index, &value);
699
+
700
+ if (TYPE(index) != T_FIXNUM) rb_raise(rb_eTypeError, MSG_INDEX_MUST_BE_FIXNUM);
701
+
702
+ int index_int = FIX2INT(index);
703
+
704
+ PhidgetInfo *info = device_info(self);
705
+
706
+ if (!info->is_attached) return Qnil;
707
+
708
+ VALUE ret;
709
+ if(NIL_P(value)) {
710
+ // It's a get request:
711
+ CPhidget_ServoType servo_type;
712
+ ensure(CPhidgetAdvancedServo_getServoType(
713
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, &servo_type ));
714
+
715
+ switch(servo_type) {
716
+ case PHIDGET_SERVO_DEFAULT:
717
+ ret = ID2SYM(rb_intern("default"));
718
+ break;
719
+ case PHIDGET_SERVO_RAW_us_MODE:
720
+ ret = ID2SYM(rb_intern("raw_us_mode"));
721
+ break;
722
+ case PHIDGET_SERVO_HITEC_HS322HD:
723
+ ret = ID2SYM(rb_intern("hitec_hs322hd"));
724
+ break;
725
+ case PHIDGET_SERVO_HITEC_HS5245MG:
726
+ ret = ID2SYM(rb_intern("hitec_hs5245mg"));
727
+ break;
728
+ case PHIDGET_SERVO_HITEC_805BB:
729
+ ret = ID2SYM(rb_intern("hitec_805bb"));
730
+ break;
731
+ case PHIDGET_SERVO_HITEC_HS422:
732
+ ret = ID2SYM(rb_intern("hitec_hs422"));
733
+ break;
734
+ case PHIDGET_SERVO_TOWERPRO_MG90:
735
+ ret = ID2SYM(rb_intern("towerpro_mg90"));
736
+ break;
737
+ case PHIDGET_SERVO_HITEC_HSR1425CR:
738
+ ret = ID2SYM(rb_intern("hitec_hsr1425cr"));
739
+ break;
740
+ case PHIDGET_SERVO_HITEC_HS785HB:
741
+ ret = ID2SYM(rb_intern("hitec_hs785hb"));
742
+ break;
743
+ case PHIDGET_SERVO_HITEC_HS485HB:
744
+ ret = ID2SYM(rb_intern("hitec_hs485hb"));
745
+ break;
746
+ case PHIDGET_SERVO_HITEC_HS645MG:
747
+ ret = ID2SYM(rb_intern("hitec_hs645mg"));
748
+ break;
749
+ case PHIDGET_SERVO_HITEC_815BB:
750
+ ret = ID2SYM(rb_intern("hitec_815bb"));
751
+ break;
752
+ case PHIDGET_SERVO_FIRGELLI_L12_30_50_06_R:
753
+ ret = ID2SYM(rb_intern("firgelli_l12_30_50_06_r"));
754
+ break;
755
+ case PHIDGET_SERVO_FIRGELLI_L12_50_100_06_R:
756
+ ret = ID2SYM(rb_intern("firgelli_l12_50_100_06_r"));
757
+ break;
758
+ case PHIDGET_SERVO_FIRGELLI_L12_50_210_06_R:
759
+ ret = ID2SYM(rb_intern("firgelli_l12_50_210_06_r"));
760
+ break;
761
+ case PHIDGET_SERVO_FIRGELLI_L12_100_50_06_R:
762
+ ret = ID2SYM(rb_intern("firgelli_l12_100_50_06_r"));
763
+ break;
764
+ case PHIDGET_SERVO_FIRGELLI_L12_100_100_06_R:
765
+ ret = ID2SYM(rb_intern("firgelli_l12_100_100_06_r"));
766
+ break;
767
+ case PHIDGET_SERVO_SPRINGRC_SM_S2313M:
768
+ ret = ID2SYM(rb_intern("springrc_sm_s2313m"));
769
+ break;
770
+ case PHIDGET_SERVO_SPRINGRC_SM_S3317M:
771
+ ret = ID2SYM(rb_intern("springrc_sm_s3317m"));
772
+ break;
773
+ case PHIDGET_SERVO_SPRINGRC_SM_S3317SR:
774
+ ret = ID2SYM(rb_intern("springrc_sm_s3317sr"));
775
+ break;
776
+ case PHIDGET_SERVO_SPRINGRC_SM_S4303R:
777
+ ret = ID2SYM(rb_intern("springrc_sm_s4303r"));
778
+ break;
779
+ case PHIDGET_SERVO_SPRINGRC_SM_S4315M:
780
+ ret = ID2SYM(rb_intern("springrc_sm_s4315m"));
781
+ break;
782
+ case PHIDGET_SERVO_SPRINGRC_SM_S4315R:
783
+ ret = ID2SYM(rb_intern("springrc_sm_s4315r"));
784
+ break;
785
+ case PHIDGET_SERVO_SPRINGRC_SM_S4505B:
786
+ ret = ID2SYM(rb_intern("springrc_sm_s4505b"));
787
+ break;
788
+ default:
789
+ ret = ID2SYM(rb_intern("unknown"));
790
+ break;
791
+ }
792
+
793
+ } else {
794
+ // Set request
795
+ if (TYPE(value) != T_SYMBOL) rb_raise(rb_eTypeError, MSG_TYPE_MUST_BE_SYMBOL);
796
+
797
+ ID type_id = SYM2ID(value);
798
+
799
+ CPhidget_ServoType phidget_type;
800
+
801
+ if (rb_intern("default") == type_id)
802
+ phidget_type = PHIDGET_SERVO_DEFAULT;
803
+ else if (rb_intern("raw_us_mode") == type_id)
804
+ phidget_type = PHIDGET_SERVO_RAW_us_MODE;
805
+ else if (rb_intern("hitec_hs322hd") == type_id)
806
+ phidget_type = PHIDGET_SERVO_HITEC_HS322HD;
807
+ else if (rb_intern("hitec_hs5245mg") == type_id)
808
+ phidget_type = PHIDGET_SERVO_HITEC_HS5245MG;
809
+ else if (rb_intern("hitec_805bb") == type_id)
810
+ phidget_type = PHIDGET_SERVO_HITEC_805BB;
811
+ else if (rb_intern("hitec_hs422") == type_id)
812
+ phidget_type = PHIDGET_SERVO_HITEC_HS422;
813
+ else if (rb_intern("towerpro_mg90") == type_id)
814
+ phidget_type = PHIDGET_SERVO_TOWERPRO_MG90;
815
+ else if (rb_intern("hitec_hsr1425cr") == type_id)
816
+ phidget_type = PHIDGET_SERVO_HITEC_HSR1425CR;
817
+ else if (rb_intern("hitec_hs785hb") == type_id)
818
+ phidget_type = PHIDGET_SERVO_HITEC_HS785HB;
819
+ else if (rb_intern("hitec_hs485hb") == type_id)
820
+ phidget_type = PHIDGET_SERVO_HITEC_HS485HB;
821
+ else if (rb_intern("hitec_hs645mg") == type_id)
822
+ phidget_type = PHIDGET_SERVO_HITEC_HS645MG;
823
+ else if (rb_intern("hitec_815bb") == type_id)
824
+ phidget_type = PHIDGET_SERVO_HITEC_815BB;
825
+ else if (rb_intern("firgelli_l12_30_50_06_r") == type_id)
826
+ phidget_type = PHIDGET_SERVO_FIRGELLI_L12_30_50_06_R;
827
+ else if (rb_intern("firgelli_l12_50_100_06_r") == type_id)
828
+ phidget_type = PHIDGET_SERVO_FIRGELLI_L12_50_100_06_R;
829
+ else if (rb_intern("firgelli_l12_50_210_06_r") == type_id)
830
+ phidget_type = PHIDGET_SERVO_FIRGELLI_L12_50_210_06_R;
831
+ else if (rb_intern("firgelli_l12_100_50_06_r") == type_id)
832
+ phidget_type = PHIDGET_SERVO_FIRGELLI_L12_100_50_06_R;
833
+ else if (rb_intern("firgelli_l12_100_100_06_r") == type_id)
834
+ phidget_type = PHIDGET_SERVO_FIRGELLI_L12_100_100_06_R;
835
+ else if (rb_intern("springrc_sm_s2313m") == type_id)
836
+ phidget_type = PHIDGET_SERVO_SPRINGRC_SM_S2313M;
837
+ else if (rb_intern("springrc_sm_s3317m") == type_id)
838
+ phidget_type = PHIDGET_SERVO_SPRINGRC_SM_S3317M;
839
+ else if (rb_intern("springrc_sm_s3317sr") == type_id)
840
+ phidget_type = PHIDGET_SERVO_SPRINGRC_SM_S3317SR;
841
+ else if (rb_intern("springrc_sm_s4303r") == type_id)
842
+ phidget_type = PHIDGET_SERVO_SPRINGRC_SM_S4303R;
843
+ else if (rb_intern("springrc_sm_s4315m") == type_id)
844
+ phidget_type = PHIDGET_SERVO_SPRINGRC_SM_S4315M;
845
+ else if (rb_intern("springrc_sm_s4315r") == type_id)
846
+ phidget_type = PHIDGET_SERVO_SPRINGRC_SM_S4315R;
847
+ else if (rb_intern("springrc_sm_s4505b") == type_id)
848
+ phidget_type = PHIDGET_SERVO_SPRINGRC_SM_S4505B;
849
+ else
850
+ rb_raise(rb_eTypeError, MSG_UNRECOGNIZED_SERVO_TYPE);
851
+
852
+ ensure(CPhidgetAdvancedServo_setServoType(
853
+ (CPhidgetAdvancedServoHandle)info->handle, index_int, phidget_type ));
854
+
855
+ ret = value;
856
+ }
857
+
858
+ return ret;
859
+ }
@@ -18,27 +18,36 @@ int CCONV interfacekit_on_attach(CPhidgetHandle phid, void *userptr) {
18
18
  ifkit_info->digital_input_states = ALLOC_N(int, ifkit_info->digital_input_count);
19
19
  ifkit_info->analog_input_states = ALLOC_N(int, ifkit_info->analog_input_count);
20
20
 
21
- // Allocate our data_rate-related collections
21
+ if (ifkit_info->digital_input_count_prior != ifkit_info->digital_input_count) {
22
+ if(ifkit_info->digital_sample_rates) xfree(ifkit_info->digital_sample_rates);
23
+
24
+ ifkit_info->digital_sample_rates = ALLOC_N(SampleRate, ifkit_info->digital_input_count);
25
+
26
+ memset(ifkit_info->digital_sample_rates, 0, sizeof(SampleRate) * ifkit_info->digital_input_count);
27
+ }
28
+
29
+ if (ifkit_info->digital_output_count_prior != ifkit_info->digital_output_count) {
30
+ if(ifkit_info->digital_output_states) xfree(ifkit_info->digital_output_states);
31
+
32
+ ifkit_info->digital_output_states = ALLOC_N(int, ifkit_info->digital_output_count);
33
+
34
+ memset(ifkit_info->digital_output_states, 0, sizeof(int) * ifkit_info->digital_output_count);
35
+ }
36
+
22
37
  if (ifkit_info->analog_input_count_prior != ifkit_info->analog_input_count) {
23
38
  if(ifkit_info->data_rates) xfree(ifkit_info->data_rates);
24
39
  if(ifkit_info->data_rates_max) xfree(ifkit_info->data_rates_max);
25
40
  if(ifkit_info->data_rates_min) xfree(ifkit_info->data_rates_min);
26
41
  if(ifkit_info->sensor_change_triggers) xfree(ifkit_info->sensor_change_triggers);
27
- if(ifkit_info->digital_sample_rates) xfree(ifkit_info->digital_sample_rates);
28
42
  if(ifkit_info->analog_sample_rates) xfree(ifkit_info->analog_sample_rates);
29
- if(ifkit_info->digital_output_states) xfree(ifkit_info->digital_output_states);
30
43
 
31
44
  ifkit_info->data_rates = ALLOC_N(int, ifkit_info->analog_input_count);
32
45
  ifkit_info->data_rates_max = ALLOC_N(int, ifkit_info->analog_input_count);
33
46
  ifkit_info->data_rates_min = ALLOC_N(int, ifkit_info->analog_input_count);
34
47
  ifkit_info->sensor_change_triggers = ALLOC_N(int, ifkit_info->analog_input_count);
35
- ifkit_info->digital_output_states = ALLOC_N(int, ifkit_info->digital_output_count);
36
48
 
37
- ifkit_info->digital_sample_rates = ALLOC_N(SampleRate, ifkit_info->digital_input_count);
38
49
  ifkit_info->analog_sample_rates = ALLOC_N(SampleRate, ifkit_info->analog_input_count);
39
50
 
40
- memset(ifkit_info->digital_output_states, 0, sizeof(int) * ifkit_info->digital_output_count);
41
- memset(ifkit_info->digital_sample_rates, 0, sizeof(SampleRate) * ifkit_info->digital_input_count);
42
51
  memset(ifkit_info->analog_sample_rates, 0, sizeof(SampleRate) * ifkit_info->analog_input_count);
43
52
 
44
53
  for(int i=0;i<ifkit_info->analog_input_count;i++) {
@@ -90,6 +99,8 @@ int CCONV interfacekit_on_detach(CPhidgetHandle phid, void *userptr) {
90
99
 
91
100
  // This is used to determine whethere to preserve the allocated memory on reattach:
92
101
  ifkit_info->analog_input_count_prior = ifkit_info->analog_input_count;
102
+ ifkit_info->digital_input_count_prior = ifkit_info->digital_input_count;
103
+ ifkit_info->digital_output_count_prior = ifkit_info->digital_output_count;
93
104
 
94
105
  // Free the polled resources:
95
106
  xfree(ifkit_info->digital_input_states);
@@ -262,15 +262,15 @@ VALUE interfacekit_initialize(VALUE self, VALUE serial) {
262
262
  CPhidgetInterfaceKitHandle interfacekit = 0;
263
263
  ensure(CPhidgetInterfaceKit_create(&interfacekit));
264
264
 
265
- ensure(CPhidgetInterfaceKit_set_OnInputChange_Handler(interfacekit, interfacekit_on_digital_change, info));
266
- ensure(CPhidgetInterfaceKit_set_OnSensorChange_Handler(interfacekit, interfacekit_on_analog_change, info));
267
-
268
265
  info->handle = (CPhidgetHandle)interfacekit;
269
266
  info->on_type_attach = interfacekit_on_attach;
270
267
  info->on_type_detach = interfacekit_on_detach;
271
268
  info->on_type_free = interfacekit_on_free;
272
269
  info->type_info = ifkit_info;
273
270
 
271
+ ensure(CPhidgetInterfaceKit_set_OnInputChange_Handler(interfacekit, interfacekit_on_digital_change, info));
272
+ ensure(CPhidgetInterfaceKit_set_OnSensorChange_Handler(interfacekit, interfacekit_on_analog_change, info));
273
+
274
274
  return rb_call_super(1, &serial);
275
275
  }
276
276
 
@@ -286,6 +286,8 @@ VALUE interfacekit_close(VALUE self) {
286
286
  VALUE interfacekit_sensor_sample_rates(VALUE self) {
287
287
  InterfaceKitInfo *ifkit_info = device_type_info(self);
288
288
 
289
+ if (!ifkit_info->is_analog_input_count_known) return Qnil;
290
+
289
291
  int *rates_in_hz = ALLOC_N(int, ifkit_info->analog_input_count);
290
292
  for(int i=0; i<ifkit_info->analog_input_count; i++)
291
293
  rates_in_hz[i] = ifkit_info->analog_sample_rates[i].in_hz;
@@ -300,7 +302,9 @@ VALUE interfacekit_sensor_sample_rates(VALUE self) {
300
302
  VALUE interfacekit_input_sample_rates(VALUE self) {
301
303
  InterfaceKitInfo *ifkit_info = device_type_info(self);
302
304
 
303
- int *rates_in_hz = ALLOC_N(int, ifkit_info->analog_input_count);
305
+ if (!ifkit_info->is_digital_input_count_known) return Qnil;
306
+
307
+ int *rates_in_hz = ALLOC_N(int, ifkit_info->digital_input_count);
304
308
  for(int i=0; i<ifkit_info->digital_input_count; i++)
305
309
  rates_in_hz[i] = ifkit_info->digital_sample_rates[i].in_hz;
306
310
 
@@ -139,6 +139,8 @@ typedef struct interfacekit_info {
139
139
  // I use it to determine whether the input counts have changed between device
140
140
  // plug events.
141
141
  int analog_input_count_prior;
142
+ int digital_input_count_prior;
143
+ int digital_output_count_prior;
142
144
 
143
145
  bool is_ratiometric;
144
146
  int rationmetric_changed_usec;
@@ -158,6 +160,24 @@ typedef struct interfacekit_info {
158
160
 
159
161
  } InterfaceKitInfo;
160
162
 
163
+ typedef struct advancedservo_info {
164
+ SampleRate *sample_rates;
165
+
166
+ bool is_motor_count_known;
167
+ int motor_count;
168
+ int motor_count_prior;
169
+
170
+ double *acceleration_max;
171
+ double *acceleration_min;
172
+ double *velocity_max;
173
+ double *velocity_min;
174
+
175
+ double *current;
176
+ double *position;
177
+ double *velocity;
178
+
179
+ } AdvancedServoInfo;
180
+
161
181
  void Init_phidgets_native();
162
182
  void Init_phidgets_native_module();
163
183
  void Init_phidgets_native_device(VALUE m_Phidget);
@@ -200,7 +220,7 @@ VALUE phidget_disable_logging(VALUE class);
200
220
  VALUE phidget_log(VALUE class, VALUE log_level, VALUE message);
201
221
  VALUE phidget_all(VALUE class);
202
222
 
203
- // Phidget::Device
223
+ // PhidgetsNative::Device
204
224
  PhidgetInfo *device_info(VALUE self);
205
225
  void *device_type_info(VALUE self);
206
226
  void device_free(PhidgetInfo *info);
@@ -221,7 +241,7 @@ VALUE device_label(VALUE self);
221
241
  VALUE device_serial_number(VALUE self);
222
242
  VALUE device_version(VALUE self);
223
243
 
224
- // Phidget::Spatial
244
+ // PhidgetsNative::Spatial
225
245
  void spatial_on_free(void *type_info);
226
246
  int CCONV spatial_on_attach(CPhidgetHandle phid, void *userptr);
227
247
  int CCONV spatial_on_detach(CPhidgetHandle phid, void *userptr);
@@ -255,7 +275,7 @@ VALUE spatial_data_rate_max(VALUE self);
255
275
  VALUE spatial_data_rate_set(VALUE self, VALUE data_rate);
256
276
  VALUE spatial_data_rate_get(VALUE self);
257
277
 
258
- // Phidget::InterfaceKit
278
+ // PhidgetsNative::InterfaceKit
259
279
  void interfacekit_on_free(void *type_info);
260
280
  int CCONV interfacekit_on_attach(CPhidgetHandle phid, void *userptr);
261
281
  int CCONV interfacekit_on_detach(CPhidgetHandle phid, void *userptr);
@@ -283,7 +303,7 @@ VALUE interfacekit_output_set(VALUE self, VALUE index, VALUE is_on);
283
303
  VALUE interfacekit_data_rate_set(VALUE self, VALUE index, VALUE rate);
284
304
  VALUE interfacekit_change_trigger_set(VALUE self, VALUE index, VALUE rate_thresh);
285
305
 
286
- // Phidget::Gps
306
+ // PhidgetsNative::Gps
287
307
  void gps_on_free(void *type_info);
288
308
  int CCONV gps_on_attach(CPhidgetHandle phid, void *userptr);
289
309
  int CCONV gps_on_detach(CPhidgetHandle phidget, void *userptr);
@@ -300,6 +320,38 @@ VALUE gps_velocity(VALUE self);
300
320
  VALUE gps_is_fixed(VALUE self);
301
321
  VALUE gps_now_at_utc(VALUE self);
302
322
 
323
+ // PhidgetsNative::AdvancedServo
324
+ void advancedservo_on_free(void *type_info);
325
+ int CCONV advancedservo_on_attach(CPhidgetHandle phid, void *userptr);
326
+ int CCONV advancedservo_on_detach(CPhidgetHandle phid, void *userptr);
327
+ int CCONV advancedservo_on_velocity_change(CPhidgetAdvancedServoHandle phid, void *userPtr, int index, double velocity);
328
+ int CCONV advancedservo_on_position_change(CPhidgetAdvancedServoHandle phid, void *userPtr, int index, double position);
329
+ int CCONV advancedservo_on_current_change(CPhidgetAdvancedServoHandle phid, void *userPtr, int index, double current);
330
+ VALUE advancedservo_initialize(VALUE self, VALUE serial);
331
+ VALUE advancedservo_close(VALUE self);
332
+ VALUE advancedservo_motor_count(VALUE self);
333
+ VALUE advancedservo_sample_rates(VALUE self);
334
+ VALUE advancedservo_acceleration_max(VALUE self);
335
+ VALUE advancedservo_acceleration_min(VALUE self);
336
+ VALUE advancedservo_velocity_max(VALUE self);
337
+ VALUE advancedservo_velocity_min(VALUE self);
338
+ VALUE advancedservo_currents(VALUE self);
339
+ VALUE advancedservo_positions(VALUE self);
340
+ VALUE advancedservo_velocities(VALUE self);
341
+ VALUE advancedservo_acceleration(int argc, VALUE* argv, VALUE self);
342
+ VALUE advancedservo_velocity_limit(int argc, VALUE* argv, VALUE self);
343
+ VALUE advancedservo_position_max(int argc, VALUE* argv, VALUE self);
344
+ VALUE advancedservo_position_min(int argc, VALUE* argv, VALUE self);
345
+ VALUE advancedservo_servo_type(int argc, VALUE* argv, VALUE self);
346
+ VALUE advancedservo_position_set(VALUE self, VALUE index, VALUE value);
347
+ VALUE advancedservo_is_speed_ramping(VALUE self, VALUE index);
348
+ VALUE advancedservo_speed_ramping_set(VALUE self, VALUE index, VALUE value);
349
+ VALUE advancedservo_is_engaged(VALUE self, VALUE index);
350
+ VALUE advancedservo_engaged_set(VALUE self, VALUE index, VALUE value);
351
+ VALUE advancedservo_is_stopped(VALUE self, VALUE index);
352
+ VALUE advancedservo_servo_parameters_set(VALUE self, VALUE index, VALUE min_us, VALUE max_us, VALUE degrees, VALUE velocity_max);
353
+
354
+
303
355
  // Stub initializers:
304
356
  VALUE accelerometer_initialize(VALUE self, VALUE serial);
305
357
  VALUE advancedservo_initialize(VALUE self, VALUE serial);
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "phidgets_native"
3
- s.version = "0.1.0"
3
+ s.version = "0.2.0"
4
4
  s.summary = "Native C-extension gem for the Phidgets library in ruby"
5
5
  s.author = "Chris DeRose"
6
6
  s.description = s.summary
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phidgets_native
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-24 00:00:00.000000000 Z
12
+ date: 2013-08-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
16
- requirement: &70343382636480 !ruby/object:Gem::Requirement
16
+ requirement: &70163161506660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70343382636480
24
+ version_requirements: *70163161506660
25
25
  description: Native C-extension gem for the Phidgets library in ruby
26
26
  email: cderose@derosetechnologies.com
27
27
  executables: []
@@ -30,6 +30,7 @@ extensions:
30
30
  extra_rdoc_files: []
31
31
  files:
32
32
  - ext/phidgets_native/accelerometer_ruby.c
33
+ - ext/phidgets_native/advancedservo.c
33
34
  - ext/phidgets_native/advancedservo_ruby.c
34
35
  - ext/phidgets_native/analog_ruby.c
35
36
  - ext/phidgets_native/bridge_ruby.c
@@ -58,6 +59,7 @@ files:
58
59
  - ext/phidgets_native/weightsensor_ruby.c
59
60
  - ext/phidgets_native/phidgets_native.h
60
61
  - ext/phidgets_native/extconf.rb
62
+ - examples/advancedservo.rb
61
63
  - examples/gps.rb
62
64
  - examples/interface_kit.rb
63
65
  - examples/list_all.rb