orbita3d_c_api/controller.rs
1//! C API for the controller module of the Orbita3D library.
2use std::{ffi::CStr, sync::Mutex};
3
4use motor_toolbox_rs::PID;
5use once_cell::sync::Lazy;
6use orbita3d_controller::Orbita3dController;
7
8use crate::sync_map::SyncMap;
9use env_logger;
10// use log::debug;
11static UID: Lazy<Mutex<u32>> = Lazy::new(|| Mutex::new(0));
12static CONTROLLER: Lazy<SyncMap<u32, Orbita3dController>> = Lazy::new(SyncMap::new);
13
14fn print_error(e: Box<dyn std::error::Error>) {
15 // eprintln!("[ORBITA_3D] {:?}", e);
16 log::debug!("[ORBITA_3D] Error: {:?}", e);
17}
18
19#[no_mangle]
20#[allow(clippy::not_unsafe_ptr_arg_deref)]
21/// Create the Orbita3dController from a config file.
22///
23/// # Arguments
24/// * configfile: *const libc::c_char - The path to the config file.
25/// * uid: *mut u32 - The unique identifier of the controller.
26/// # Returns
27/// * i32 - 0 if the controller was created successfully, 1 otherwise.
28pub extern "C" fn orbita3d_controller_from_config(
29 configfile: *const libc::c_char,
30 uid: &mut u32,
31) -> i32 {
32 let configfile = unsafe { CStr::from_ptr(configfile) }.to_str().unwrap();
33
34 let _ = env_logger::try_init();
35
36 match Orbita3dController::with_config(configfile) {
37 Ok(controller) => {
38 *uid = get_available_uid();
39 CONTROLLER.insert(*uid, controller);
40 0
41 }
42 Err(e) => {
43 print_error(e);
44 1
45 }
46 }
47}
48
49#[no_mangle]
50/// Check if controller is activated (are the motors on)
51///
52/// # Arguments
53/// * uid: u32 - The unique identifier of the controller.
54/// * is_on: *mut bool - The result of the check.
55/// # Returns
56/// * i32 - 0 if the controller is activated, 1 otherwise.
57pub extern "C" fn orbita3d_is_torque_on(uid: u32, is_on: &mut bool) -> i32 {
58 match CONTROLLER.get_mut(&uid).unwrap().is_torque_on() {
59 Ok(torque) => {
60 *is_on = torque;
61 0
62 }
63 Err(e) => {
64 print_error(e);
65 1
66 }
67 }
68}
69
70#[no_mangle]
71/// Enable the controller (turn on the motors)
72///
73/// # Arguments
74/// * uid: u32 - The unique identifier of the controller.
75/// * reset_target: bool - Reset the target orientation to the current orientation.
76/// # Returns
77/// * i32 - 0 if the controller was enabled successfully, 1 otherwise.
78pub extern "C" fn orbita3d_enable_torque(uid: u32, reset_target: bool) -> i32 {
79 match CONTROLLER
80 .get_mut(&uid)
81 .unwrap()
82 .enable_torque(reset_target)
83 {
84 Ok(_) => 0,
85 Err(e) => {
86 print_error(e);
87 1
88 }
89 }
90}
91
92#[no_mangle]
93/// Disable the controller (turn off the motors)
94///
95/// # Arguments
96/// * uid: u32 - The unique identifier of the controller.
97/// # Returns
98/// * i32 - 0 if the controller was disabled successfully, 1 otherwise.
99pub extern "C" fn orbita3d_disable_torque(uid: u32) -> i32 {
100 match CONTROLLER.get_mut(&uid).unwrap().disable_torque() {
101 Ok(_) => 0,
102 Err(e) => {
103 print_error(e);
104 1
105 }
106 }
107}
108
109#[no_mangle]
110/// Get the current orientation of the platform (quaternion)
111///
112/// # Arguments
113/// * uid: u32 - The unique identifier of the controller.
114/// * orientation: *mut [f64; 4] - The current orientation of the platform.
115/// # Returns
116/// * i32 - 0 if the orientation was retrieved successfully, 1 otherwise.
117pub extern "C" fn orbita3d_get_current_orientation(uid: u32, orientation: &mut [f64; 4]) -> i32 {
118 match CONTROLLER.get_mut(&uid).unwrap().get_current_orientation() {
119 Ok(ori) => {
120 *orientation = ori;
121 0
122 }
123 Err(e) => {
124 print_error(e);
125 1
126 }
127 }
128}
129
130#[no_mangle]
131/// Get the current orientation of the platform (roll, pitch, yaw)
132///
133/// # Arguments
134/// * uid: u32 - The unique identifier of the controller.
135/// * rpy: *mut [f64; 3] - The current orientation of the platform.
136/// # Returns
137/// * i32 - 0 if the orientation was retrieved successfully, 1 otherwise.
138pub extern "C" fn orbita3d_get_current_rpy_orientation(uid: u32, rpy: &mut [f64; 3]) -> i32 {
139 match CONTROLLER
140 .get_mut(&uid)
141 .unwrap()
142 .get_current_rpy_orientation()
143 {
144 Ok(ori) => {
145 *rpy = ori;
146 0
147 }
148 Err(e) => {
149 print_error(e);
150 1
151 }
152 }
153}
154
155#[no_mangle]
156/// Get the current velocity of the platform
157///
158/// # Arguments
159/// * uid: u32 - The unique identifier of the controller.
160/// * velocity: *mut [f64; 3] - The current velocity of the platform.
161/// # Returns
162/// * i32 - 0 if the velocity was retrieved successfully, 1 otherwise.
163pub extern "C" fn orbita3d_get_current_velocity(uid: u32, velocity: &mut [f64; 3]) -> i32 {
164 match CONTROLLER.get_mut(&uid).unwrap().get_current_velocity() {
165 Ok(vel) => {
166 *velocity = vel;
167 0
168 }
169 Err(e) => {
170 print_error(e);
171 1
172 }
173 }
174}
175
176#[no_mangle]
177/// Get the current torque applied by the actuator
178///
179/// # Arguments
180/// * uid: u32 - The unique identifier of the controller.
181/// * torque: *mut [f64; 3] - The current torque applied to the platform.
182/// # Returns
183/// * i32 - 0 if the torque was retrieved successfully, 1 otherwise.
184pub extern "C" fn orbita3d_get_current_torque(uid: u32, torque: &mut [f64; 3]) -> i32 {
185 match CONTROLLER.get_mut(&uid).unwrap().get_current_torque() {
186 Ok(tor) => {
187 *torque = tor;
188 0
189 }
190 Err(e) => {
191 print_error(e);
192 1
193 }
194 }
195}
196
197#[no_mangle]
198/// Get the current target orientation of the platform (quaternion)
199///
200/// # Arguments
201/// * uid: u32 - The unique identifier of the controller.
202/// * orientation: *mut [f64; 4] - The current target orientation of the platform.
203/// # Returns
204/// * i32 - 0 if the orientation was retrieved successfully, 1 otherwise.
205pub extern "C" fn orbita3d_get_target_orientation(uid: u32, orientation: &mut [f64; 4]) -> i32 {
206 match CONTROLLER.get_mut(&uid).unwrap().get_target_orientation() {
207 Ok(ori) => {
208 *orientation = ori;
209 0
210 }
211 Err(e) => {
212 print_error(e);
213 1
214 }
215 }
216}
217
218#[no_mangle]
219/// Get the current target orientation of the platform (roll, pitch, yaw)
220///
221/// # Arguments
222/// * uid: u32 - The unique identifier of the controller.
223/// * rpy: *mut [f64; 3] - The current target orientation of the platform.
224/// # Returns
225/// * i32 - 0 if the orientation was retrieved successfully, 1 otherwise.
226pub extern "C" fn orbita3d_get_target_rpy_orientation(uid: u32, rpy: &mut [f64; 3]) -> i32 {
227 match CONTROLLER
228 .get_mut(&uid)
229 .unwrap()
230 .get_target_rpy_orientation()
231 {
232 Ok(ori) => {
233 *rpy = ori;
234 0
235 }
236 Err(e) => {
237 print_error(e);
238 1
239 }
240 }
241}
242
243#[no_mangle]
244/// Set the target orientation of the platform (quaternion)
245///
246/// # Arguments
247/// * uid: u32 - The unique identifier of the controller.
248/// * orientation: *const [f64; 4] - The target orientation of the platform.
249/// # Returns
250/// * i32 - 0 if the orientation was set successfully, 1 otherwise.
251pub extern "C" fn orbita3d_set_target_orientation(uid: u32, orientation: &[f64; 4]) -> i32 {
252 match CONTROLLER
253 .get_mut(&uid)
254 .unwrap()
255 .set_target_orientation(*orientation)
256 {
257 Ok(_) => 0,
258 Err(e) => {
259 print_error(e);
260 1
261 }
262 }
263}
264
265#[no_mangle]
266/// Set the target orientation of the platform (roll, pitch, yaw)
267///
268/// # Arguments
269/// * uid: u32 - The unique identifier of the controller.
270/// * rpy: *const [f64; 3] - The target orientation of the platform.
271/// # Returns
272/// * i32 - 0 if the orientation was set successfully, 1 otherwise.
273pub extern "C" fn orbita3d_set_target_rpy_orientation(uid: u32, rpy: &[f64; 3]) -> i32 {
274 match CONTROLLER
275 .get_mut(&uid)
276 .unwrap()
277 .set_target_rpy_orientation(*rpy)
278 {
279 Ok(_) => 0,
280 Err(e) => {
281 print_error(e);
282 1
283 }
284 }
285}
286
287#[no_mangle]
288/// Set the tatget orientation and return the current orientation (quaternion)
289///
290/// # Arguments
291/// * uid: u32 - The unique identifier of the controller.
292/// * orientation: *const [f64; 4] - The target orientation of the platform.
293/// * feedback: *mut [f64; 10] - The feedback of the controller.
294/// # Returns
295/// * i32 - 0 if the orientation was set successfully, 1 otherwise.
296pub extern "C" fn orbita3d_set_target_orientation_fb(
297 uid: u32,
298 orientation: &[f64; 4],
299 // feedback: &mut [f64; 10],
300 feedback: &mut [f64; 4],
301) -> i32 {
302 match CONTROLLER
303 .get_mut(&uid)
304 .unwrap()
305 .set_target_orientation_fb(*orientation)
306 {
307 Ok(fb) => {
308 feedback[0] = fb.orientation[0]; //FIXME: I don't know how to include the struct definition in the C bindings...
309 feedback[1] = fb.orientation[1];
310 feedback[2] = fb.orientation[2];
311 feedback[3] = fb.orientation[3];
312 // feedback[4] = fb.velocity[0];
313 // feedback[5] = fb.velocity[1];
314 // feedback[6] = fb.velocity[2];
315 // feedback[7] = fb.torque[0];
316 // feedback[8] = fb.torque[1];
317 // feedback[9] = fb.torque[2];
318 0
319 }
320 Err(e) => {
321 print_error(e);
322 1
323 }
324 }
325}
326
327#[no_mangle]
328/// Set the tatget orientation and return the current orientation (roll, pitch, yaw)
329///
330/// # Arguments
331/// * uid: u32 - The unique identifier of the controller.
332/// * rpy: *const [f64; 3] - The target orientation of the platform.
333/// * feedback: *mut [f64; 10] - The feedback of the controller.
334/// # Returns
335/// * i32 - 0 if the orientation was set successfully, 1 otherwise.
336pub extern "C" fn orbita3d_set_target_rpy_orientation_fb(
337 uid: u32,
338 rpy: &[f64; 3],
339 // feedback: &mut [f64; 10],
340 feedback: &mut [f64; 3],
341) -> i32 {
342 match CONTROLLER
343 .get_mut(&uid)
344 .unwrap()
345 .set_target_rpy_orientation_fb(*rpy)
346 {
347 Ok(fb) => {
348 feedback[0] = fb[0];
349 feedback[1] = fb[1];
350 feedback[2] = fb[2];
351 0
352 }
353 Err(e) => {
354 print_error(e);
355 1
356 }
357 }
358}
359
360#[no_mangle]
361/// Get the current velocity of the motors (0 - 1.0)
362///
363/// # Arguments
364/// * uid: u32 - The unique identifier of the controller.
365/// * velocity: *mut [f64; 3] - The current velocity of the motors.
366/// # Returns
367/// * i32 - 0 if the velocity was retrieved successfully, 1 otherwise.
368pub extern "C" fn orbita3d_get_raw_motors_velocity_limit(uid: u32, limit: &mut [f64; 3]) -> i32 {
369 match CONTROLLER
370 .get_mut(&uid)
371 .unwrap()
372 .get_raw_motors_velocity_limit()
373 {
374 Ok(lim) => {
375 *limit = lim;
376 0
377 }
378 Err(e) => {
379 print_error(e);
380 1
381 }
382 }
383}
384
385#[no_mangle]
386/// Set the current velocity of the motors (0 - 1.0)
387///
388/// # Arguments
389/// * uid: u32 - The unique identifier of the controller.
390/// * velocity: *const [f64; 3] - The current velocity of the motors.
391/// # Returns
392/// * i32 - 0 if the velocity was set successfully, 1 otherwise.
393pub extern "C" fn orbita3d_set_raw_motors_velocity_limit(uid: u32, limit: &[f64; 3]) -> i32 {
394 match CONTROLLER
395 .get_mut(&uid)
396 .unwrap()
397 .set_raw_motors_velocity_limit(*limit)
398 {
399 Ok(_) => 0,
400 Err(e) => {
401 print_error(e);
402 1
403 }
404 }
405}
406
407#[no_mangle]
408/// Get the current torque limit of the motors (0 - 1.0)
409///
410/// # Arguments
411/// * uid: u32 - The unique identifier of the controller.
412/// * limit: *mut [f64; 3] - The current torque limit of the motors.
413/// # Returns
414/// * i32 - 0 if the torque limit was retrieved successfully, 1 otherwise.
415pub extern "C" fn orbita3d_get_raw_motors_torque_limit(uid: u32, limit: &mut [f64; 3]) -> i32 {
416 match CONTROLLER
417 .get_mut(&uid)
418 .unwrap()
419 .get_raw_motors_torque_limit()
420 {
421 Ok(lim) => {
422 *limit = lim;
423 0
424 }
425 Err(e) => {
426 print_error(e);
427 1
428 }
429 }
430}
431
432#[no_mangle]
433/// Set the current torque limit of the motors (0 - 1.0)
434///
435/// # Arguments
436/// * uid: u32 - The unique identifier of the controller.
437/// * limit: *const [f64; 3] - The current torque limit of the motors.
438/// # Returns
439/// * i32 - 0 if the torque limit was set successfully, 1 otherwise.
440pub extern "C" fn orbita3d_set_raw_motors_torque_limit(uid: u32, limit: &[f64; 3]) -> i32 {
441 match CONTROLLER
442 .get_mut(&uid)
443 .unwrap()
444 .set_raw_motors_torque_limit(*limit)
445 {
446 Ok(_) => 0,
447 Err(e) => {
448 print_error(e);
449 1
450 }
451 }
452}
453
454#[no_mangle]
455/// Get the current PID gains of the motors
456///
457/// # Arguments
458/// * uid: u32 - The unique identifier of the controller.
459/// * gains: *mut [[f64; 3]; 3] - The current PID gains of the motors.
460/// # Returns
461/// * i32 - 0 if the PID gains were retrieved successfully, 1 otherwise.
462pub extern "C" fn orbita3d_get_raw_motors_pid_gains(uid: u32, gains: &mut [[f64; 3]; 3]) -> i32 {
463 match CONTROLLER.get_mut(&uid).unwrap().get_raw_motors_pid_gains() {
464 Ok([pid_top, pid_middle, pid_bottom]) => {
465 gains[0][0] = pid_top.p;
466 gains[0][1] = pid_top.i;
467 gains[0][2] = pid_top.d;
468 gains[1][0] = pid_middle.p;
469 gains[1][1] = pid_middle.i;
470 gains[1][2] = pid_middle.d;
471 gains[2][0] = pid_bottom.p;
472 gains[2][1] = pid_bottom.i;
473 gains[2][2] = pid_bottom.d;
474
475 0
476 }
477 Err(e) => {
478 print_error(e);
479 1
480 }
481 }
482}
483
484#[no_mangle]
485/// Set the current PID gains of the motors
486///
487/// # Arguments
488/// * uid: u32 - The unique identifier of the controller.
489/// * gains: *const [[f64; 3]; 3] - The current PID gains of the motors.
490/// # Returns
491/// * i32 - 0 if the PID gains were set successfully, 1 otherwise.
492pub extern "C" fn orbita3d_set_raw_motors_pid_gains(uid: u32, gains: &[[f64; 3]; 3]) -> i32 {
493 match CONTROLLER.get_mut(&uid).unwrap().set_raw_motors_pid_gains([
494 PID {
495 p: gains[0][0],
496 i: gains[0][1],
497 d: gains[0][2],
498 },
499 PID {
500 p: gains[1][0],
501 i: gains[1][1],
502 d: gains[1][2],
503 },
504 PID {
505 p: gains[2][0],
506 i: gains[2][1],
507 d: gains[2][2],
508 },
509 ]) {
510 Ok(_) => 0,
511 Err(e) => {
512 print_error(e);
513 1
514 }
515 }
516}
517
518#[no_mangle]
519/// Get the raw motor current of the actuators
520///
521/// # Arguments
522/// * uid: u32 - The unique identifier of the controller.
523/// * current: *mut [f64; 3] - The current of the motors.
524/// # Returns
525/// * i32 - 0 if the current was retrieved successfully, 1 otherwise.
526pub extern "C" fn orbita3d_get_raw_motors_current(
527 uid: u32,
528 raw_motors_current: &mut [f64; 3],
529) -> u32 {
530 match CONTROLLER.get_mut(&uid).unwrap().get_raw_motors_current() {
531 Ok(c) => {
532 *raw_motors_current = c;
533 0
534 }
535 Err(e) => {
536 print_error(e);
537 1
538 }
539 }
540}
541
542#[no_mangle]
543/// Get the raw motor velocity of the actuators
544///
545/// # Arguments
546/// * uid: u32 - The unique identifier of the controller.
547/// * raw_motors_velocity: *mut [f64; 3] - The velocity of the motors.
548/// # Returns
549/// * i32 - 0 if the velocity was retrieved successfully, 1 otherwise.
550pub extern "C" fn orbita3d_get_raw_motors_velocity(
551 uid: u32,
552 raw_motors_velocity: &mut [f64; 3],
553) -> u32 {
554 match CONTROLLER.get_mut(&uid).unwrap().get_raw_motors_velocity() {
555 Ok(v) => {
556 *raw_motors_velocity = v;
557 0
558 }
559 Err(e) => {
560 print_error(e);
561 1
562 }
563 }
564}
565
566#[no_mangle]
567/// Get the raw motor position of the actuators
568///
569/// # Arguments
570/// * uid: u32 - The unique identifier of the controller.
571/// * raw_motors_position: *mut [f64; 3] - The position of the motors.
572/// # Returns
573/// * i32 - 0 if the position was retrieved successfully, 1 otherwise.
574pub extern "C" fn orbita3d_get_raw_motors_position(
575 uid: u32,
576 raw_motors_position: &mut [f64; 3],
577) -> u32 {
578 match CONTROLLER.get_mut(&uid).unwrap().get_raw_motors_positions() {
579 Ok(p) => {
580 *raw_motors_position = p;
581 0
582 }
583 Err(e) => {
584 print_error(e);
585 1
586 }
587 }
588}
589
590#[no_mangle]
591/// Get the state of the board (BoardState - u8)
592/// - See more info [here](../../poulpe_ethercat_controller/register/enum.BoardStatus.html)
593///
594/// # Arguments
595/// * uid: u32 - The unique identifier of the controller.
596/// * state: *mut u8 - The state of the board.
597/// # Returns
598/// * i32 - 0 if the state was retrieved successfully, 1 otherwise.
599pub extern "C" fn orbita3d_get_board_state(uid: u32, state: &mut u8) -> i32 {
600 match CONTROLLER.get_mut(&uid).unwrap().get_board_state() {
601 Ok(s) => {
602 *state = s;
603 0
604 }
605 Err(e) => {
606 print_error(e);
607 1
608 }
609 }
610}
611
612#[no_mangle]
613/// Set the state of the board (BoardState - u8)
614/// - See more info [here](../../poulpe_ethercat_controller/register/enum.BoardStatus.html)
615///
616/// # Arguments
617/// * uid: u32 - The unique identifier of the controller.
618/// * state: *const u8 - The state of the board.
619/// # Returns
620/// * i32 - 0 if the state was set successfully, 1 otherwise.
621pub extern "C" fn orbita3d_set_board_state(uid: u32, state: &u8) -> i32 {
622 match CONTROLLER.get_mut(&uid).unwrap().set_board_state(*state) {
623 Ok(_) => 0,
624 Err(e) => {
625 print_error(e);
626 1
627 }
628 }
629}
630
631#[no_mangle]
632/// Get the raw axis sensors values
633///
634/// # Arguments
635/// * uid: u32 - The unique identifier of the controller.
636/// * axis: *mut [f64; 3] - The axis sensors values.
637/// # Returns
638/// * i32 - 0 if the axis sensors values were retrieved successfully, 1 otherwise.
639pub extern "C" fn orbita3d_get_axis_sensors(uid: u32, axis: &mut [f64; 3]) -> i32 {
640 match CONTROLLER.get_mut(&uid).unwrap().get_axis_sensors() {
641 Ok(a) => {
642 *axis = a;
643 0
644 }
645 Err(e) => {
646 print_error(e);
647 1
648 }
649 }
650}
651
652#[no_mangle]
653/// Get the raw axis sensor zeros
654///
655/// # Arguments
656/// * uid: u32 - The unique identifier of the controller.
657/// * axis: *mut [f64; 3] - The axis sensor zeros.
658/// # Returns
659/// * i32 - 0 if the axis sensor zeros were retrieved successfully, 1 otherwise.
660pub extern "C" fn orbita3d_get_axis_sensor_zeros(uid: u32, axis: &mut [f64; 3]) -> i32 {
661 match CONTROLLER.get_mut(&uid).unwrap().get_axis_sensor_zeros() {
662 Ok(a) => {
663 *axis = a;
664 0
665 }
666 Err(e) => {
667 print_error(e);
668 1
669 }
670 }
671}
672
673#[no_mangle]
674/// Get the raw motor temperatures
675///
676/// # Arguments
677/// * uid: u32 - The unique identifier of the controller.
678/// * temp: *mut [f64; 3] - The motor temperatures.
679/// # Returns
680/// * i32 - 0 if the motor temperatures were retrieved successfully, 1 otherwise.
681pub extern "C" fn orbita3d_get_motor_temperatures(uid: u32, temp: &mut [f64; 3]) -> i32 {
682 match CONTROLLER.get_mut(&uid).unwrap().get_motor_temperatures() {
683 Ok(t) => {
684 *temp = t;
685 0
686 }
687 Err(e) => {
688 print_error(e);
689 1
690 }
691 }
692}
693
694#[no_mangle]
695/// Get the raw board temperatures
696///
697/// # Arguments
698/// * uid: u32 - The unique identifier of the controller.
699/// * temp: *mut [f64; 3] - The board temperatures.
700/// # Returns
701/// * i32 - 0 if the board temperatures were retrieved successfully, 1 otherwise.
702pub extern "C" fn orbita3d_get_board_temperatures(uid: u32, temp: &mut [f64; 3]) -> i32 {
703 match CONTROLLER.get_mut(&uid).unwrap().get_board_temperatures() {
704 Ok(t) => {
705 *temp = t;
706 0
707 }
708 Err(e) => {
709 print_error(e);
710 1
711 }
712 }
713}
714
715#[no_mangle]
716/// Get the error codes
717/// - see more info [here](../../poulpe_ethercat_controller/state_machine/struct.ErrorFlags.html)
718///
719/// # Arguments
720/// * uid: u32 - The unique identifier of the controller.
721/// * error: *mut [i32; 3] - The error codes.
722/// # Returns
723/// * i32 - 0 if the error codes were retrieved successfully, 1 otherwise.
724pub extern "C" fn orbita3d_get_error_codes(uid: u32, error: &mut [i32; 3]) -> i32 {
725 match CONTROLLER.get_mut(&uid).unwrap().get_error_codes() {
726 Ok(c) => {
727 *error = c;
728 0
729 }
730 Err(e) => {
731 print_error(e);
732 1
733 }
734 }
735}
736
737#[no_mangle]
738/// Get the control mode ( CiA402 control mode - u8) : 1 - Profile Position Mode, 3 - Profile Velocity Mode, 4 - Profile Torque Mode
739/// - See more info [here](../../poulpe_ethercat_controller/state_machine/enum.CiA402ModeOfOperation.html)
740///
741/// # Arguments
742/// * uid: u32 - The unique identifier of the controller.
743/// * mode: *mut u8 - The control mode.
744/// # Returns
745/// * i32 - 0 if the control mode was retrieved successfully, 1 otherwise.
746pub extern "C" fn orbita3d_get_control_mode(uid: u32, mode: &mut u8) -> i32 {
747 match CONTROLLER.get_mut(&uid).unwrap().get_control_mode() {
748 Ok(m) => {
749 *mode = m[0];
750 0
751 }
752 Err(e) => {
753 print_error(e);
754 1
755 }
756 }
757}
758
759#[no_mangle]
760/// Set the control mode ( CiA402 control mode - u8) : 1 - Profile Position Mode, 3 - Profile Velocity Mode, 4 - Profile Torque Mode
761/// - See more info [here](../../poulpe_ethercat_controller/state_machine/enum.CiA402ModeOfOperation.html)
762///
763/// # Arguments
764/// * uid: u32 - The unique identifier of the controller.
765/// * mode: *const u8 - The control mode.
766/// # Returns
767/// * i32 - 0 if the control mode was set successfully, 1 otherwise.
768pub extern "C" fn orbita3d_set_control_mode(uid: u32, mode: &u8) -> i32 {
769 match CONTROLLER
770 .get_mut(&uid)
771 .unwrap()
772 .set_control_mode([*mode, *mode, *mode])
773 {
774 Ok(_) => 0,
775 Err(e) => {
776 print_error(e);
777 1
778 }
779 }
780}
781
782#[no_mangle]
783/// Send the emergency stop signal to the controller
784///
785/// # Arguments
786/// * uid: u32 - The unique identifier of the controller.
787/// # Returns
788/// * i32 - 0 if the emergency stop signal was sent successfully, 1 otherwise.
789pub extern "C" fn orbita3d_emergency_stop(uid: u32) -> i32 {
790 CONTROLLER.get_mut(&uid).unwrap().emergency_stop();
791 0
792}
793
794/// Get the next available unique identifier
795fn get_available_uid() -> u32 {
796 let mut uid = UID.lock().unwrap();
797 *uid += 1;
798 *uid
799}