1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
use core::ffi::c_uint;

pub const VISION_OBJECT_ERR_SIG: u16 = 255;
pub const VISION_FOV_WIDTH: c_uint = 316;
pub const VISION_FOV_HEIGHT: c_uint = 212;

pub const E_VISION_OBJECT_NORMAL: c_uint = 0;
pub const E_VISION_OBJECT_COLOR_CODE: c_uint = 1;
pub const E_VISION_OBJECT_LINE: c_uint = 2;
/**
 * This enumeration defines the different types of objects
 * that can be detected by the Vision Sensor
 */
pub type vision_object_type_e_t = c_uint;

/**
 * This structure contains the parameters used by the Vision Sensor
 * to detect objects.
 */
#[repr(packed, C)]
pub struct vision_signature_s_t {
    pub id: u8,
    pub _pad: [u8; 3],
    pub range: f32,
    pub u_min: i32,
    pub u_max: i32,
    pub u_mean: i32,
    pub v_min: i32,
    pub v_max: i32,
    pub v_mean: i32,
    pub rgb: u32,
    pub r#type: u32,
}

/**
 * Color codes are just signatures with multiple IDs and a different type.
 */
pub type vision_color_code_t = u16;

/**
 * This structure contains a descriptor of an object detected
 * by the Vision Sensor
 */
#[repr(packed, C)]
pub struct vision_object_s_t {
    pub signature: u16,
    pub r#type: vision_object_type_e_t,
    pub left_coord: i16,
    pub top_coord: i16,
    pub width: i16,
    pub height: i16,
    pub angle: i16,
    pub x_middle_coord: i16,
    pub y_middle_coord: i16,
}

pub const E_VISION_ZERO_TOPLEFT: c_uint = 0;
pub const E_VISION_ZERO_CENTER: c_uint = 1;
pub type vision_zero_e_t = c_uint;

extern "C" {
    /**
    Clears the vision sensor LED color, resetting it back to its default behavior,
    displaying the most prominent object signature color.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
           The V5 port number from 1-21

    \return 1 if the operation was successful or PROS_ERR if the operation
    failed, setting errno.
    */
    pub fn vision_clear_led(port: u8) -> i32;
    /**
    Creates a signature from the vision sensor utility

    \param id
           The signature ID
    \param u_min
           Minimum value on U axis
    \param u_max
           Maximum value on U axis
    \param u_mean
           Mean value on U axis
    \param v_min
           Minimum value on V axis
    \param v_max
           Maximum value on V axis
    \param v_mean
           Mean value on V axis
    \param range
           Scale factor
    \param type
           Signature type

    \return A vision_signature_s_t that can be set using vision_set_signature
    */
    pub fn vision_signature_from_utility(
        id: i32,
        u_min: i32,
        u_max: i32,
        u_mean: i32,
        v_min: i32,
        v_max: i32,
        v_mean: i32,
        range: f32,
        r#type: i32,
    ) -> vision_signature_s_t;
    /**
    Creates a color code that represents a combination of the given signature
    IDs. If fewer than 5 signatures are to be a part of the color code, pass 0
    for the additional function parameters.

    This function uses the following values of errno when an error state is
    reached:
    EINVAL - Fewer than two signatures have been provided or one of the
             signatures is out of its [1-7] range (or 0 when omitted).

    \param port
           The V5 port number from 1-21
    \param sig_id1
           The first signature id [1-7] to add to the color code
    \param sig_id2
           The second signature id [1-7] to add to the color code
    \param sig_id3
           The third signature id [1-7] to add to the color code
    \param sig_id4
           The fourth signature id [1-7] to add to the color code
    \param sig_id5
           The fifth signature id [1-7] to add to the color code

    \return A vision_color_code_t object containing the color code information.
    */
    pub fn vision_create_color_code(
        port: u8,
        sig_id1: u32,
        sig_id2: u32,
        sig_id3: u32,
        sig_id4: u32,
        sig_id5: u32,
    ) -> vision_color_code_t;
    /**
    Gets the nth largest object according to size_id.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor
    EDOM - size_id is greater than the number of available objects.
    EHOSTDOWN - Reading the vision sensor failed for an unknown reason.

    \param port
           The V5 port number from 1-21
    \param size_id
           The object to read from a list roughly ordered by object size
           (0 is the largest item, 1 is the second largest, etc.)

    \return The vision_object_s_t object corresponding to the given size id, or
    PROS_ERR if an error occurred.
    */
    pub fn vision_get_by_size(port: u8, size_id: u32) -> vision_object_s_t;
    /**
    Gets the nth largest object of the given signature according to size_id.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor
    EINVAL - sig_id is outside the range [1-8]
    EDOM - size_id is greater than the number of available objects.
    EAGAIN - Reading the vision sensor failed for an unknown reason.

    \param port
           The V5 port number from 1-21
    \param size_id
           The object to read from a list roughly ordered by object size
           (0 is the largest item, 1 is the second largest, etc.)
    \param signature
           The signature ID [1-7] for which an object will be returned.

    \return The vision_object_s_t object corresponding to the given signature and
    size_id, or PROS_ERR if an error occurred.
    */
    pub fn vision_get_by_sig(port: u8, size_id: u32, sig_id: u32) -> vision_object_s_t;
    /**
    Gets the nth largest object of the given color code according to size_id.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor
    EAGAIN - Reading the vision sensor failed for an unknown reason.

    \param port
           The V5 port number from 1-21
    \param size_id
           The object to read from a list roughly ordered by object size
           (0 is the largest item, 1 is the second largest, etc.)
    \param color_code
           The vision_color_code_t for which an object will be returned

    \return The vision_object_s_t object corresponding to the given color code
    and size_id, or PROS_ERR if an error occurred.
    */
    pub fn vision_get_by_code(
        port: u8,
        size_id: u32,
        code: vision_color_code_t,
    ) -> vision_object_s_t;
    /**
    Gets the exposure parameter of the Vision Sensor. See
    https://pros.cs.purdue.edu/v5/tutorials/topical/vision.html#exposure-setting
    for more details.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
           The V5 port number from 1-21

    \return The current exposure setting from [0,150], PROS_ERR if an error
    occurred
    */
    pub fn vision_get_exposure(port: u8) -> i32;
    /**
    Gets the number of objects currently detected by the Vision Sensor.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
           The V5 port number from 1-21

    \return The number of objects detected on the specified vision sensor.
    Returns PROS_ERR if the port was invalid or an error occurred.
    */
    pub fn vision_get_object_count(port: u8) -> i32;
    /**
    Get the white balance parameter of the Vision Sensor.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
                The V5 port number from 1-21

    \return The current RGB white balance setting of the sensor
    */
    pub fn vision_get_white_balance(port: u8) -> i32;
    /**
    Prints the contents of the signature as an initializer list to the terminal.

    \param sig
           The signature for which the contents will be printed

    \return 1 if no errors occurred, PROS_ERR otherwise
    */
    pub fn vision_print_signature(sig: vision_signature_s_t) -> i32;
    /**
    Reads up to object_count object descriptors into object_arr.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21), or
             fewer than object_count number of objects were found.
    ENODEV - The port cannot be configured as a vision sensor
    EDOM - size_id is greater than the number of available objects.

    \param port
           The V5 port number from 1-21
    \param size_id
           The object to read from a list roughly ordered by object size
           (0 is the largest item, 1 is the second largest, etc.)
    \param object_count
           The number of objects to read
    \param[out] object_arr
                A pointer to copy the objects into

    \return The number of object signatures copied. This number will be less than
    object_count if there are fewer objects detected by the vision sensor.
    Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects
    than size_id were found. All objects in object_arr that were not found are
    given VISION_OBJECT_ERR_SIG as their signature.
    */
    pub fn vision_read_by_size(
        port: u8,
        size_id: u32,
        object_count: u32,
        object_arr: *mut vision_object_s_t,
    ) -> i32;
    /**
    Reads up to object_count object descriptors into object_arr.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21), or
             fewer than object_count number of objects were found.
    ENODEV - The port cannot be configured as a vision sensor
    EDOM - size_id is greater than the number of available objects.

    \param port
           The V5 port number from 1-21
    \param object_count
           The number of objects to read
    \param size_id
           The object to read from a list roughly ordered by object size
           (0 is the largest item, 1 is the second largest, etc.)
    \param signature
           The signature ID [1-7] for which objects will be returned.
    \param[out] object_arr
                A pointer to copy the objects into

    \return The number of object signatures copied. This number will be less than
    object_count if there are fewer objects detected by the vision sensor.
    Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects
    than size_id were found. All objects in object_arr that were not found are
    given VISION_OBJECT_ERR_SIG as their signature.
    */
    pub fn vision_read_by_sig(
        port: u8,
        size_id: u32,
        sig_id: u32,
        object_count: u32,
        object_arr: *mut vision_object_s_t,
    ) -> i32;
    /**
    Reads up to object_count object descriptors into object_arr.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21), or
             fewer than object_count number of objects were found.
    ENODEV - The port cannot be configured as a vision sensor

    \param port
           The V5 port number from 1-21
    \param object_count
           The number of objects to read
    \param size_id
           The object to read from a list roughly ordered by object size
           (0 is the largest item, 1 is the second largest, etc.)
    \param color_code
           The vision_color_code_t for which objects will be returned
    \param[out] object_arr
                A pointer to copy the objects into

    \return The number of object signatures copied. This number will be less than
    object_count if there are fewer objects detected by the vision sensor.
    Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects
    than size_id were found. All objects in object_arr that were not found are
    given VISION_OBJECT_ERR_SIG as their signature.
    */
    pub fn vision_read_by_code(
        port: u8,
        size_id: u32,
        code: vision_color_code_t,
        object_count: u32,
        object_arr: *mut vision_object_s_t,
    ) -> i32;
    /**
    Gets the object detection signature with the given id number.

    \param port
           The V5 port number from 1-21
    \param signature_id
           The signature id to read

    \return A vision_signature_s_t containing information about the signature.
    */
    pub fn vision_get_signature(port: u8, signature_id: u8) -> vision_signature_s_t;
    /**
    Stores the supplied object detection signature onto the vision sensor.

    NOTE: This saves the signature in volatile memory, and the signature will be
    lost as soon as the sensor is powered down.

    \param port
           The V5 port number from 1-21
    \param signature_id
           The signature id to store into
    \param[in] signature_ptr
               A pointer to the signature to save

    \return 1 if no errors occurred, PROS_ERR otherwise
    */
    pub fn vision_set_signature(
        port: u8,
        signature_id: u8,
        signature_ptr: *const vision_signature_s_t,
    ) -> i32;
    /**
    Enables/disables auto white-balancing on the Vision Sensor.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor
    EINVAL - enable was not 0 or 1

    \param port
                The V5 port number from 1-21
    \param enabled
                Pass 0 to disable, 1 to enable

    \return 1 if the operation was successful or PROS_ERR if the operation
    failed, setting errno.
    */
    pub fn vision_set_auto_white_balance(port: u8, enable: u8) -> i32;
    /**
    Sets the exposure parameter of the Vision Sensor. See
    https://pros.cs.purdue.edu/v5/tutorials/topical/vision.html#exposure-setting
    for more details.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
           The V5 port number from 1-21
    \param percent
           The new exposure setting from [0,150]

    \return 1 if the operation was successful or PROS_ERR if the operation
    failed, setting errno.
    */
    pub fn vision_set_exposure(port: u8, exposure: u8) -> i32;
    /**
    Sets the vision sensor LED color, overriding the automatic behavior.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
           The V5 port number from 1-21
    \param rgb
           An RGB code to set the LED to

    \return 1 if the operation was successful or PROS_ERR if the operation
    failed, setting errno.
    */
    pub fn vision_set_led(port: u8, rgb: i32) -> i32;
    /**
    Sets the white balance parameter of the Vision Sensor.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
                The V5 port number from 1-21
    \param rgb
           The new RGB white balance setting of the sensor

    \return 1 if the operation was successful or PROS_ERR if the operation
    failed, setting errno.
    */
    pub fn vision_set_white_balance(port: u8, rgb: i32) -> i32;
    /**
    Sets the (0,0) coordinate for the Field of View.

    This will affect the coordinates returned for each request for a
    vision_object_s_t from the sensor, so it is recommended that this function
    only be used to configure the sensor at the beginning of its use.

    This function uses the following values of errno when an error state is
    reached:
    ENXIO - The given value is not within the range of V5 ports (1-21).
    ENODEV - The port cannot be configured as a vision sensor

    \param port
                The V5 port number from 1-21
    \param zero_point
           One of vision_zero_e_t to set the (0,0) coordinate for the FOV

    \return 1 if the operation was successful or PROS_ERR if the operation
    failed, setting errno.
    */
    pub fn vision_set_zero_point(port: u8, zero_point: vision_zero_e_t) -> i32;
    /**
    Sets the Wi-Fi mode of the Vision sensor

    This functions uses the following values of errno when an error state is
    reached:
    ENXIO - The given port is not within the range of V5 ports (1-21)
    EACCESS - Another resource is currently trying to access the port

    \param port
           The V5 port number from 1-21
    \param enable
           Disable Wi-Fi on the Vision sensor if 0, enable otherwise (e.g. 1)

    \return 1 if the operation was successful or PROS_ERR if the operation
    failed, setting errno.
    */
    pub fn vision_set_wifi_mode(port: u8, mode: u8) -> i32;
}