2 An algorithm library based on C/C++
6 Add this to your `Cargo.toml`:
14 #![warn(missing_docs)]
15 #![allow(non_camel_case_types)]
16 #![cfg_attr(not(feature = "std"), no_std)]
18 /// floating-point number stored using `f64`
19 #[cfg(not(feature = "float"))]
21 /// floating-point number stored using `f32`
22 #[cfg(feature = "float")]
25 #[cfg(feature = "std")]
28 #[cfg(not(feature = "std"))]
29 pub use core::ffi::c_int;
30 #[cfg(feature = "std")]
31 pub use std::os::raw::c_int;
33 #[cfg(not(feature = "std"))]
34 pub use core::ffi::c_uint;
35 #[cfg(feature = "std")]
36 pub use std::os::raw::c_uint;
38 #[cfg(not(feature = "std"))]
39 use core::mem::size_of;
40 #[cfg(feature = "std")]
41 use std::mem::size_of;
43 #[cfg(not(feature = "std"))]
44 use core::cmp::Ordering;
45 #[cfg(feature = "std")]
46 use std::cmp::Ordering;
48 #[cfg(not(feature = "std"))]
49 use core::ptr::{null, null_mut};
50 #[cfg(feature = "std")]
51 use std::ptr::{null, null_mut};
53 #[cfg(not(feature = "std"))]
54 use core::slice::{from_raw_parts, from_raw_parts_mut};
55 #[cfg(feature = "std")]
56 use std::slice::{from_raw_parts, from_raw_parts_mut};
59 fn a_u32_sqrt(x: u32) -> u16;
60 fn a_u64_sqrt(x: u64) -> u32;
63 /// square root of an unsigned integer
65 pub fn u32_sqrt(x: u32) -> u16 {
66 unsafe { a_u32_sqrt(x) }
68 /// square root of an unsigned integer
70 pub fn u64_sqrt(x: u64) -> u32 {
71 unsafe { a_u64_sqrt(x) }
75 fn a_f32_rsqrt(x: f32) -> f32;
76 fn a_f64_rsqrt(x: f64) -> f64;
79 /// reciprocal of square-root, `\frac{1}{\sqrt{x}}`
81 pub fn f32_rsqrt(x: f32) -> f32 {
82 unsafe { a_f32_rsqrt(x) }
84 /// reciprocal of square-root, `\frac{1}{\sqrt{x}}`
86 pub fn f64_rsqrt(x: f64) -> f64 {
87 unsafe { a_f64_rsqrt(x) }
91 fn a_hash_bkdr_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
92 fn a_hash_sdbm_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
95 /// a hash function whose prime number is 131
97 pub fn hash_bkdr(block: &[u8], value: u32) -> u32 {
98 unsafe { a_hash_bkdr_(block.as_ptr(), block.len(), value) }
100 /// a hash function whose prime number is 65599
102 pub fn hash_sdbm(block: &[u8], value: u32) -> u32 {
103 unsafe { a_hash_sdbm_(block.as_ptr(), block.len(), value) }
106 /// Cyclic Redundancy Check for 8 bits
109 /// Cyclic Redundancy Check comparison table
110 pub table: [u8; 0x100],
114 fn a_crc8m_init(table: *mut u8, poly: u8);
115 fn a_crc8l_init(table: *mut u8, poly: u8);
116 fn a_crc8(table: *const u8, pdate: *const u8, nbyte: usize, value: u8) -> u8;
120 /// initialize for MSB CRC-8
122 pub fn new_msb(poly: u8) -> Self {
123 let mut ctx: Self = Self { table: [0; 0x100] };
124 unsafe { a_crc8m_init(ctx.table.as_mut_ptr(), poly) };
127 /// initialize for LSB CRC-8
129 pub fn new_lsb(poly: u8) -> Self {
130 let mut ctx: Self = Self { table: [0; 0x100] };
131 unsafe { a_crc8l_init(ctx.table.as_mut_ptr(), poly) };
134 /// generate for MSB CRC-8
136 pub fn gen_msb(&mut self, poly: u8) -> &mut Self {
137 unsafe { a_crc8m_init(self.table.as_mut_ptr(), poly) };
140 /// generate for LSB CRC-8
142 pub fn gen_lsb(&mut self, poly: u8) -> &mut Self {
143 unsafe { a_crc8l_init(self.table.as_mut_ptr(), poly) };
146 /// calculate for CRC-8
148 pub fn eval(self, block: &[u8], value: u8) -> u8 {
149 unsafe { a_crc8(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
153 /// Cyclic Redundancy Check for 16 bits
156 /// Cyclic Redundancy Check comparison table
157 pub table: [u16; 0x100],
158 eval: unsafe extern "C" fn(*const u16, *const u8, usize, u16) -> u16,
162 fn a_crc16m_init(table: *mut u16, poly: u16);
163 fn a_crc16l_init(table: *mut u16, poly: u16);
164 fn a_crc16m(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
165 fn a_crc16l(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
169 /// initialize for MSB CRC-16
171 pub fn new_msb(poly: u16) -> Self {
172 let mut ctx: Self = Self {
176 unsafe { a_crc16m_init(ctx.table.as_mut_ptr(), poly) };
179 /// initialize for LSB CRC-16
181 pub fn new_lsb(poly: u16) -> Self {
182 let mut ctx: Self = Self {
186 unsafe { a_crc16l_init(ctx.table.as_mut_ptr(), poly) };
189 /// generate for MSB CRC-16
191 pub fn gen_msb(&mut self, poly: u16) -> &mut Self {
192 unsafe { a_crc16m_init(self.table.as_mut_ptr(), poly) };
193 self.eval = a_crc16m;
196 /// generate for LSB CRC-16
198 pub fn gen_lsb(&mut self, poly: u16) -> &mut Self {
199 unsafe { a_crc16l_init(self.table.as_mut_ptr(), poly) };
200 self.eval = a_crc16l;
203 /// calculate for CRC-16
205 pub fn eval(self, block: &[u8], value: u16) -> u16 {
206 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
210 /// Cyclic Redundancy Check for 32 bits
213 /// Cyclic Redundancy Check comparison table
214 pub table: [u32; 0x100],
215 eval: unsafe extern "C" fn(*const u32, *const u8, usize, u32) -> u32,
219 fn a_crc32m_init(table: *mut u32, poly: u32);
220 fn a_crc32l_init(table: *mut u32, poly: u32);
221 fn a_crc32m(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
222 fn a_crc32l(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
226 /// initialize for MSB CRC-32
228 pub fn new_msb(poly: u32) -> Self {
229 let mut ctx: Self = Self {
233 unsafe { a_crc32m_init(ctx.table.as_mut_ptr(), poly) };
236 /// initialize for LSB CRC-32
238 pub fn new_lsb(poly: u32) -> Self {
239 let mut ctx: Self = Self {
243 unsafe { a_crc32l_init(ctx.table.as_mut_ptr(), poly) };
246 /// generate for MSB CRC-32
248 pub fn gen_msb(&mut self, poly: u32) -> &mut Self {
249 unsafe { a_crc32m_init(self.table.as_mut_ptr(), poly) };
250 self.eval = a_crc32m;
253 /// generate for LSB CRC-32
255 pub fn gen_lsb(&mut self, poly: u32) -> &mut Self {
256 unsafe { a_crc32l_init(self.table.as_mut_ptr(), poly) };
257 self.eval = a_crc32l;
260 /// calculate for CRC-32
262 pub fn eval(self, block: &[u8], value: u32) -> u32 {
263 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
267 /// Cyclic Redundancy Check for 64 bits
270 /// Cyclic Redundancy Check comparison table
271 pub table: [u64; 0x100],
272 eval: unsafe extern "C" fn(*const u64, *const u8, usize, u64) -> u64,
276 fn a_crc64m_init(table: *mut u64, poly: u64);
277 fn a_crc64l_init(table: *mut u64, poly: u64);
278 fn a_crc64m(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
279 fn a_crc64l(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
283 /// initialize for MSB CRC-64
285 pub fn new_msb(poly: u64) -> Self {
286 let mut ctx: Self = Self {
290 unsafe { a_crc64m_init(ctx.table.as_mut_ptr(), poly) };
293 /// initialize for LSB CRC-64
295 pub fn new_lsb(poly: u64) -> Self {
296 let mut ctx: Self = Self {
300 unsafe { a_crc64l_init(ctx.table.as_mut_ptr(), poly) };
303 /// generate for MSB CRC-64
305 pub fn gen_msb(&mut self, poly: u64) -> &mut Self {
306 unsafe { a_crc64m_init(self.table.as_mut_ptr(), poly) };
307 self.eval = a_crc64m;
310 /// generate for LSB CRC-64
312 pub fn gen_lsb(&mut self, poly: u64) -> &mut Self {
313 unsafe { a_crc64l_init(self.table.as_mut_ptr(), poly) };
314 self.eval = a_crc64l;
317 /// calculate for CRC-64
319 pub fn eval(self, block: &[u8], value: u64) -> u64 {
320 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
324 #[allow(clippy::excessive_precision)]
325 const TAU: float = 6.28318530717958647692528676655900577;
330 /// filter coefficient
339 /// initialize for High Pass Filter
341 pub fn new(fc: float, ts: float) -> Self {
343 alpha: 1.0 / (TAU * fc * ts + 1.0),
348 /// generate for High Pass Filter
350 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
351 self.alpha = 1.0 / (TAU * fc * ts + 1.0);
354 /// calculate for High Pass Filter
356 pub fn iter(&mut self, x: float) -> float {
357 self.output = self.alpha * (self.output + x - self.input);
361 /// zeroing for High Pass Filter
363 pub fn zero(&mut self) -> &mut Self {
370 #[allow(clippy::excessive_precision)]
371 const _1_TAU: float = 0.159154943091895335768883763372514362;
376 /// filter coefficient
383 /// initialize for Low Pass Filter
385 pub fn new(fc: float, ts: float) -> Self {
387 alpha: ts / (_1_TAU / fc + ts),
391 /// generate for Low Pass Filter
393 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
394 self.alpha = ts / (_1_TAU / fc + ts);
397 /// calculate for Low Pass Filter
399 pub fn iter(&mut self, x: float) -> float {
400 self.output *= 1.0 - self.alpha;
401 self.output += x * self.alpha;
404 /// zeroing for Low Pass Filter
406 pub fn zero(&mut self) -> &mut Self {
412 /// membership function
416 pub const NUL: c_int = 0;
417 /// gaussian membership function
418 pub const GAUSS: c_int = 1;
419 /// gaussian combination membership function
420 pub const GAUSS2: c_int = 2;
421 /// generalized bell-shaped membership function
422 pub const GBELL: c_int = 3;
423 /// sigmoidal membership function
424 pub const SIG: c_int = 4;
425 /// difference between two sigmoidal membership functions
426 pub const DSIG: c_int = 5;
427 /// product of two sigmoidal membership functions
428 pub const PSIG: c_int = 6;
429 /// trapezoidal membership function
430 pub const TRAP: c_int = 7;
431 /// triangular membership function
432 pub const TRI: c_int = 8;
433 /// linear s-shaped saturation membership function
434 pub const LINS: c_int = 9;
435 /// linear z-shaped saturation membership function
436 pub const LINZ: c_int = 10;
437 /// s-shaped membership function
438 pub const S: c_int = 11;
439 /// z-shaped membership function
440 pub const Z: c_int = 12;
441 /// pi-shaped membership function
442 pub const PI: c_int = 13;
446 fn a_mf_gauss(x: float, sigma: float, c: float) -> float;
447 fn a_mf_gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float;
448 fn a_mf_gbell(x: float, a: float, b: float, c: float) -> float;
449 fn a_mf_sig(x: float, a: float, c: float) -> float;
450 fn a_mf_dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
451 fn a_mf_psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
452 fn a_mf_trap(x: float, a: float, b: float, c: float, d: float) -> float;
453 fn a_mf_tri(x: float, a: float, b: float, c: float) -> float;
454 fn a_mf_lins(x: float, a: float, b: float) -> float;
455 fn a_mf_linz(x: float, a: float, b: float) -> float;
456 fn a_mf_s(x: float, a: float, b: float) -> float;
457 fn a_mf_z(x: float, a: float, b: float) -> float;
458 fn a_mf_pi(x: float, a: float, b: float, c: float, d: float) -> float;
461 /// gaussian membership function
463 pub fn gauss(x: float, sigma: float, c: float) -> float {
464 unsafe { a_mf_gauss(x, sigma, c) }
466 /// gaussian combination membership function
468 pub fn gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float {
469 unsafe { a_mf_gauss2(x, sigma1, c1, sigma2, c2) }
471 /// generalized bell-shaped membership function
473 pub fn gbell(x: float, a: float, b: float, c: float) -> float {
474 unsafe { a_mf_gbell(x, a, b, c) }
476 /// sigmoidal membership function
478 pub fn sig(x: float, a: float, c: float) -> float {
479 unsafe { a_mf_sig(x, a, c) }
481 /// difference between two sigmoidal membership functions
483 pub fn dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
484 unsafe { a_mf_dsig(x, a1, c1, a2, c2) }
486 /// product of two sigmoidal membership functions
488 pub fn psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
489 unsafe { a_mf_psig(x, a1, c1, a2, c2) }
491 /// trapezoidal membership function
493 pub fn trap(x: float, a: float, b: float, c: float, d: float) -> float {
494 unsafe { a_mf_trap(x, a, b, c, d) }
496 /// triangular membership function
498 pub fn tri(x: float, a: float, b: float, c: float) -> float {
499 unsafe { a_mf_tri(x, a, b, c) }
501 /// linear s-shaped saturation membership function
503 pub fn lins(x: float, a: float, b: float) -> float {
504 unsafe { a_mf_lins(x, a, b) }
506 /// linear z-shaped saturation membership function
508 pub fn linz(x: float, a: float, b: float) -> float {
509 unsafe { a_mf_linz(x, a, b) }
511 /// s-shaped membership function
513 pub fn s(x: float, a: float, b: float) -> float {
514 unsafe { a_mf_s(x, a, b) }
516 /// z-shaped membership function
518 pub fn z(x: float, a: float, b: float) -> float {
519 unsafe { a_mf_z(x, a, b) }
521 /// pi-shaped membership function
523 pub fn pi(x: float, a: float, b: float, c: float, d: float) -> float {
524 unsafe { a_mf_pi(x, a, b, c, d) }
528 /// proportional integral derivative controller
531 /// proportional constant
533 /// integral constant
535 /// derivative constant
537 /// maximum integral output
539 /// minimum integral output
541 /// controller integral output
543 /// maximum final output
545 /// minimum final output
547 /// controller final output
557 impl Default for pid {
559 fn default() -> Self {
564 summax: float::INFINITY,
565 summin: -float::INFINITY,
567 outmax: float::INFINITY,
568 outmin: -float::INFINITY,
578 fn a_pid_set_kpid(ctx: *mut pid, kp: float, ki: float, kd: float);
579 fn a_pid_run(ctx: *mut pid, set: float, fdb: float) -> float;
580 fn a_pid_pos(ctx: *mut pid, set: float, fdb: float) -> float;
581 fn a_pid_inc(ctx: *mut pid, set: float, fdb: float) -> float;
582 fn a_pid_zero(ctx: *mut pid);
586 /// initialize for PID controller
588 pub fn new() -> Self {
591 /// set proportional integral derivative constant for PID controller
593 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
594 unsafe { a_pid_set_kpid(self, kp, ki, kd) };
597 /// calculate for PID controller
599 pub fn run(&mut self, set: float, fdb: float) -> float {
600 unsafe { a_pid_run(self, set, fdb) }
602 /// calculate for positional PID controller
604 pub fn pos(&mut self, set: float, fdb: float) -> float {
605 unsafe { a_pid_pos(self, set, fdb) }
607 /// calculate for incremental PID controller
609 pub fn inc(&mut self, set: float, fdb: float) -> float {
610 unsafe { a_pid_inc(self, set, fdb) }
612 /// zeroing for PID controller
614 pub fn zero(&mut self) -> &mut Self {
615 unsafe { a_pid_zero(self) };
620 /// fuzzy PID controller operator
624 pub const CAP: c_uint = 1;
626 pub const CAP_ALGEBRA: c_uint = 2;
628 pub const CAP_BOUNDED: c_uint = 3;
630 pub const CUP: c_uint = 4;
632 pub const CUP_ALGEBRA: c_uint = 5;
634 pub const CUP_BOUNDED: c_uint = 6;
635 /// sqrt(a,b)*sqrt(1-(1-a)*(1-b))
636 pub const EQU: c_uint = 0;
639 /// fuzzy proportional integral derivative controller
641 pub struct pid_fuzzy {
642 /// proportional integral derivative controller
651 /// fuzzy relational operator
652 opr: extern "C" fn(float, float) -> float,
653 /// base proportional constant
655 /// base integral constant
657 /// base derivative constant
659 /// number of order in the square matrix
661 /// maximum number triggered by the rule
665 impl Default for pid_fuzzy {
667 fn default() -> Self {
677 opr: unsafe { a_pid_fuzzy_opr(fuzzy::EQU) },
688 fn a_pid_fuzzy_opr(opr: c_uint) -> extern "C" fn(float, float) -> float;
689 fn a_pid_fuzzy_set_opr(ctx: *mut pid_fuzzy, opr: c_uint);
690 fn a_pid_fuzzy_bfuzz(ctx: *const pid_fuzzy) -> *mut u8;
691 fn a_pid_fuzzy_set_bfuzz(ctx: *mut pid_fuzzy, ptr: *mut u8, num: usize);
692 fn a_pid_fuzzy_set_rule(
701 fn a_pid_fuzzy_set_kpid(ctx: *mut pid_fuzzy, kp: float, ki: float, kd: float);
702 fn a_pid_fuzzy_run(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
703 fn a_pid_fuzzy_pos(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
704 fn a_pid_fuzzy_inc(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
705 fn a_pid_fuzzy_zero(ctx: *mut pid_fuzzy);
709 /// initialize for fuzzy PID controller
711 pub fn new() -> Self {
714 /// set fuzzy relational operator for fuzzy PID controller
716 pub fn set_opr(&mut self, opr: c_uint) -> &mut Self {
717 unsafe { a_pid_fuzzy_set_opr(self, opr) };
720 /// compute size of memory block for fuzzy PID controller
722 #[allow(non_snake_case)]
723 pub const fn BFUZZ(n: usize) -> usize {
724 size_of::<c_uint>() * n * 2 + size_of::<float>() * n * (2 + n)
726 /// get memory block for fuzzy PID controller
728 pub fn bfuzz(&mut self) -> &mut [u8] {
729 unsafe { from_raw_parts_mut(a_pid_fuzzy_bfuzz(self), Self::BFUZZ(self.nfuzz as usize)) }
731 /// set memory block for fuzzy PID controller
733 pub fn set_bfuzz(&mut self, ptr: &mut [u8], num: usize) -> &mut Self {
734 unsafe { a_pid_fuzzy_set_bfuzz(self, ptr.as_mut_ptr(), num) };
737 /// set rule base for fuzzy PID controller
749 a_pid_fuzzy_set_rule(
761 /// set proportional integral derivative constant for fuzzy PID controller
763 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
764 unsafe { a_pid_fuzzy_set_kpid(self, kp, ki, kd) };
767 /// calculate for fuzzy PID controller
769 pub fn run(&mut self, set: float, fdb: float) -> float {
770 unsafe { a_pid_fuzzy_run(self, set, fdb) }
772 /// calculate for positional fuzzy PID controller
774 pub fn pos(&mut self, set: float, fdb: float) -> float {
775 unsafe { a_pid_fuzzy_pos(self, set, fdb) }
777 /// calculate for incremental fuzzy PID controller
779 pub fn inc(&mut self, set: float, fdb: float) -> float {
780 unsafe { a_pid_fuzzy_inc(self, set, fdb) }
782 /// zeroing for fuzzy PID controller
784 pub fn zero(&mut self) -> &mut Self {
785 unsafe { a_pid_fuzzy_zero(self) };
790 /// single neuron proportional integral derivative controller
792 pub struct pid_neuro {
793 /// proportional integral derivative controller
795 /// proportional coefficient
797 /// proportional weight
801 /// derivative weight
807 impl Default for pid_neuro {
809 fn default() -> Self {
822 fn a_pid_neuro_set_kpid(ctx: *mut pid_neuro, k: float, kp: float, ki: float, kd: float);
823 fn a_pid_neuro_set_wpid(ctx: *mut pid_neuro, wp: float, wi: float, wd: float);
824 fn a_pid_neuro_run(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
825 fn a_pid_neuro_inc(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
826 fn a_pid_neuro_zero(ctx: *mut pid_neuro);
830 /// initialize for single neuron PID controller
832 pub fn new() -> Self {
835 /// set proportional integral derivative constant for single neuron PID controller
837 pub fn set_kpid(&mut self, k: float, kp: float, ki: float, kd: float) -> &mut Self {
838 unsafe { a_pid_neuro_set_kpid(self, k, kp, ki, kd) };
841 /// set proportional integral derivative weight for single neuron PID controller
843 pub fn set_wpid(&mut self, wp: float, wi: float, wd: float) -> &mut Self {
844 unsafe { a_pid_neuro_set_wpid(self, wp, wi, wd) };
847 /// calculate for single neuron PID controller
849 pub fn run(&mut self, set: float, fdb: float) -> float {
850 unsafe { a_pid_neuro_run(self, set, fdb) }
852 /// calculate for incremental single neuron PID controller
854 pub fn inc(&mut self, set: float, fdb: float) -> float {
855 unsafe { a_pid_neuro_inc(self, set, fdb) }
857 /// zeroing for single neuron PID controller
859 pub fn zero(&mut self) -> &mut Self {
860 unsafe { a_pid_neuro_zero(self) };
865 /// transfer function
878 /// denominator number
883 fn a_tf_set_num(ctx: *mut tf, num_n: c_uint, num_p: *const float, input: *mut float);
884 fn a_tf_set_den(ctx: *mut tf, den_n: c_uint, den_p: *const float, output: *mut float);
894 fn a_tf_iter(ctx: *const tf, x: float) -> float;
895 fn a_tf_zero(ctx: *const tf);
899 /// initialize for transfer function
901 pub fn new(num: &[float], input: &mut [float], den: &[float], output: &mut [float]) -> Self {
902 let mut ctx: Self = Self {
923 /// calculate for transfer function
925 pub fn iter(&mut self, x: float) -> float {
926 unsafe { a_tf_iter(self, x) }
928 /// zeroing for transfer function
930 pub fn zero(&mut self) -> &mut Self {
931 unsafe { a_tf_zero(self) };
934 /// get input for transfer function
936 pub fn input(&self) -> &[float] {
937 unsafe { from_raw_parts(self.input, self.num_n as usize) }
939 /// get numerator for transfer function
941 pub fn num(&self) -> &[float] {
942 unsafe { from_raw_parts(self.num_p, self.num_n as usize) }
944 /// set numerator for transfer function
946 pub fn set_num(&mut self, num: &[float], input: &mut [float]) -> &mut Self {
947 unsafe { a_tf_set_num(self, num.len() as c_uint, num.as_ptr(), input.as_mut_ptr()) };
950 /// get output for transfer function
952 pub fn output(&self) -> &[float] {
953 unsafe { from_raw_parts(self.output, self.den_n as usize) }
955 /// get denominator for transfer function
957 pub fn den(&self) -> &[float] {
958 unsafe { from_raw_parts(self.den_p, self.den_n as usize) }
960 /// set denominator for transfer function
962 pub fn set_den(&mut self, den: &[float], output: &mut [float]) -> &mut Self {
963 unsafe { a_tf_set_den(self, den.len() as c_uint, den.as_ptr(), output.as_mut_ptr()) };
968 /// bell-shaped velocity trajectory
970 pub struct trajbell {
973 /// constant velocity phase
975 /// acceleration phase
977 /// deceleration phase
979 /// time-interval in which the jerk is constant (j max or j min ) during the acceleration phase
981 /// time-interval in which the jerk is constant (j max or j min ) during the deceleration phase
995 /// maximum acceleration
997 /// maximum deceleration
1001 impl Default for trajbell {
1003 fn default() -> Self {
1034 fn a_trajbell_pos(ctx: *const trajbell, x: float) -> float;
1035 fn a_trajbell_vel(ctx: *const trajbell, x: float) -> float;
1036 fn a_trajbell_acc(ctx: *const trajbell, x: float) -> float;
1037 fn a_trajbell_jer(ctx: *const trajbell, x: float) -> float;
1041 /// initialize for bell-shaped velocity trajectory
1043 pub fn new() -> Self {
1046 /// generate for bell-shaped velocity trajectory
1047 #[allow(clippy::too_many_arguments)]
1059 unsafe { a_trajbell_gen(self, jm, am, vm, p0, p1, v0, v1) }
1061 /// calculate position for bell-shaped velocity trajectory
1063 pub fn pos(&mut self, x: float) -> float {
1064 unsafe { a_trajbell_pos(self, x) }
1066 /// calculate velocity for bell-shaped velocity trajectory
1068 pub fn vel(&mut self, x: float) -> float {
1069 unsafe { a_trajbell_vel(self, x) }
1071 /// calculate acceleration for bell-shaped velocity trajectory
1073 pub fn acc(&mut self, x: float) -> float {
1074 unsafe { a_trajbell_acc(self, x) }
1076 /// calculate jerk for bell-shaped velocity trajectory
1078 pub fn jer(&mut self, x: float) -> float {
1079 unsafe { a_trajbell_jer(self, x) }
1083 /// cubic polynomial trajectory
1085 pub struct trajpoly3 {
1086 /// coefficients of position
1088 /// coefficients of velocity
1090 /// coefficients of acceleration
1095 fn a_trajpoly3_gen(ctx: *mut trajpoly3, ts: float, p0: float, p1: float, v0: float, v1: float);
1096 fn a_trajpoly3_pos(ctx: *const trajpoly3, x: float) -> float;
1097 fn a_trajpoly3_vel(ctx: *const trajpoly3, x: float) -> float;
1098 fn a_trajpoly3_acc(ctx: *const trajpoly3, x: float) -> float;
1102 /// initialize for cubic polynomial trajectory
1104 pub fn new(ts: float, p0: float, p1: float, v0: float, v1: float) -> Self {
1105 let mut ctx: Self = Self {
1110 unsafe { a_trajpoly3_gen(&mut ctx, ts, p0, p1, v0, v1) };
1113 /// generate for cubic polynomial trajectory
1115 pub fn gen(&mut self, ts: float, p0: float, p1: float, v0: float, v1: float) -> &mut Self {
1116 unsafe { a_trajpoly3_gen(self, ts, p0, p1, v0, v1) };
1119 /// calculate position for cubic polynomial trajectory
1121 pub fn pos(&mut self, x: float) -> float {
1122 unsafe { a_trajpoly3_pos(self, x) }
1124 /// calculate velocity for cubic polynomial trajectory
1126 pub fn vel(&mut self, x: float) -> float {
1127 unsafe { a_trajpoly3_vel(self, x) }
1129 /// calculate acceleration for cubic polynomial trajectory
1131 pub fn acc(&mut self, x: float) -> float {
1132 unsafe { a_trajpoly3_acc(self, x) }
1136 /// quintic polynomial trajectory
1138 pub struct trajpoly5 {
1139 /// coefficients of position
1141 /// coefficients of velocity
1143 /// coefficients of acceleration
1149 ctx: *mut trajpoly5,
1158 fn a_trajpoly5_pos(ctx: *const trajpoly5, x: float) -> float;
1159 fn a_trajpoly5_vel(ctx: *const trajpoly5, x: float) -> float;
1160 fn a_trajpoly5_acc(ctx: *const trajpoly5, x: float) -> float;
1164 /// initialize for quintic polynomial trajectory
1165 #[allow(clippy::too_many_arguments)]
1176 let mut ctx: Self = Self {
1181 unsafe { a_trajpoly5_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1) };
1184 /// generate for quintic polynomial trajectory
1185 #[allow(clippy::too_many_arguments)]
1197 unsafe { a_trajpoly5_gen(self, ts, p0, p1, v0, v1, a0, a1) };
1200 /// calculate position for quintic polynomial trajectory
1202 pub fn pos(&mut self, x: float) -> float {
1203 unsafe { a_trajpoly5_pos(self, x) }
1205 /// calculate velocity for quintic polynomial trajectory
1207 pub fn vel(&mut self, x: float) -> float {
1208 unsafe { a_trajpoly5_vel(self, x) }
1210 /// calculate acceleration for quintic polynomial trajectory
1212 pub fn acc(&mut self, x: float) -> float {
1213 unsafe { a_trajpoly5_acc(self, x) }
1217 /// hepta polynomial trajectory
1219 pub struct trajpoly7 {
1220 /// coefficients of position
1222 /// coefficients of velocity
1224 /// coefficients of acceleration
1226 /// coefficients of jerk
1232 ctx: *mut trajpoly7,
1243 fn a_trajpoly7_pos(ctx: *const trajpoly7, x: float) -> float;
1244 fn a_trajpoly7_vel(ctx: *const trajpoly7, x: float) -> float;
1245 fn a_trajpoly7_acc(ctx: *const trajpoly7, x: float) -> float;
1246 fn a_trajpoly7_jer(ctx: *const trajpoly7, x: float) -> float;
1250 /// initialize for hepta polynomial trajectory
1251 #[allow(clippy::too_many_arguments)]
1264 let mut ctx: Self = Self {
1270 unsafe { a_trajpoly7_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1273 /// generate for hepta polynomial trajectory
1274 #[allow(clippy::too_many_arguments)]
1288 unsafe { a_trajpoly7_gen(self, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1291 /// calculate position for hepta polynomial trajectory
1293 pub fn pos(&mut self, x: float) -> float {
1294 unsafe { a_trajpoly7_pos(self, x) }
1296 /// calculate velocity for hepta polynomial trajectory
1298 pub fn vel(&mut self, x: float) -> float {
1299 unsafe { a_trajpoly7_vel(self, x) }
1301 /// calculate acceleration for hepta polynomial trajectory
1303 pub fn acc(&mut self, x: float) -> float {
1304 unsafe { a_trajpoly7_acc(self, x) }
1306 /// calculate jerk for hepta polynomial trajectory
1308 pub fn jer(&mut self, x: float) -> float {
1309 unsafe { a_trajpoly7_jer(self, x) }
1313 /// trapezoidal velocity trajectory
1315 pub struct trajtrap {
1318 /// initial position
1322 /// initial velocity
1326 /// constant velocity
1328 /// time before constant velocity
1330 /// time after constant velocity
1332 /// position before constant velocity
1334 /// position after constant velocity
1336 /// acceleration before constant velocity
1338 /// acceleration after constant velocity
1342 impl Default for trajtrap {
1344 fn default() -> Self {
1373 fn a_trajtrap_pos(ctx: *const trajtrap, x: float) -> float;
1374 fn a_trajtrap_vel(ctx: *const trajtrap, x: float) -> float;
1375 fn a_trajtrap_acc(ctx: *const trajtrap, x: float) -> float;
1379 /// initialize for trapezoidal velocity trajectory
1381 pub fn new() -> Self {
1384 /// generate for trapezoidal velocity trajectory
1385 #[allow(clippy::too_many_arguments)]
1397 unsafe { a_trajtrap_gen(self, vm, ac, de, p0, p1, v0, v1) }
1399 /// calculate position for trapezoidal velocity trajectory
1401 pub fn pos(&mut self, x: float) -> float {
1402 unsafe { a_trajtrap_pos(self, x) }
1404 /// calculate velocity for trapezoidal velocity trajectory
1406 pub fn vel(&mut self, x: float) -> float {
1407 unsafe { a_trajtrap_vel(self, x) }
1409 /// calculate acceleration for trapezoidal velocity trajectory
1411 pub fn acc(&mut self, x: float) -> float {
1412 unsafe { a_trajtrap_acc(self, x) }
1418 pub struct version {
1431 impl Default for version {
1433 fn default() -> Self {
1439 alpha: [b'.', 0, 0, 0],
1445 static a_version_major: c_uint;
1446 static a_version_minor: c_uint;
1447 static a_version_patch: c_uint;
1448 static a_version_tweak: u32;
1449 fn a_version_set_alpha(ctx: *mut version, alpha: *const u8);
1450 fn a_version_alpha(ctx: *const version, alpha: &mut [u8; 5]);
1451 fn a_version_parse(ctx: *mut version, ver: *const u8) -> c_uint;
1452 fn a_version_tostr(ctx: *const version, p: *mut u8, n: usize) -> c_int;
1453 fn a_version_cmp(ctx: *const version, rhs: *const version) -> c_int;
1454 fn a_version_lt(ctx: *const version, rhs: *const version) -> bool;
1455 fn a_version_gt(ctx: *const version, rhs: *const version) -> bool;
1456 fn a_version_le(ctx: *const version, rhs: *const version) -> bool;
1457 fn a_version_ge(ctx: *const version, rhs: *const version) -> bool;
1458 fn a_version_eq(ctx: *const version, rhs: *const version) -> bool;
1459 fn a_version_check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int;
1463 /// initialize for version
1465 pub fn new(major: c_uint, minor: c_uint, third: c_uint) -> Self {
1470 ..Default::default()
1473 /// set alphabet for version
1475 pub fn set_alpha(&mut self, alpha: &[u8]) {
1476 unsafe { a_version_set_alpha(self, alpha.as_ptr()) }
1478 /// get alphabet for version
1480 pub fn alpha(&self, alpha: &mut [u8; 5]) {
1481 unsafe { a_version_alpha(self, alpha) }
1483 /// parse version string to version
1485 pub fn parse(&mut self, ver: &str) -> c_uint {
1486 unsafe { a_version_parse(self, ver.as_ptr()) }
1488 /// convert version to string
1490 pub fn tostr(&mut self, ver: &mut [u8]) -> c_int {
1491 unsafe { a_version_tostr(self, ver.as_mut_ptr(), ver.len()) }
1493 /// algorithm library version check
1495 pub fn check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int {
1496 unsafe { a_version_check(major, minor, patch) }
1498 /// algorithm library version major
1500 pub fn major() -> c_uint {
1501 unsafe { a_version_major }
1503 /// algorithm library version minor
1505 pub fn minor() -> c_uint {
1506 unsafe { a_version_minor }
1508 /// algorithm library version patch
1510 pub fn patch() -> c_uint {
1511 unsafe { a_version_patch }
1513 /// algorithm library version tweak
1515 pub fn tweak() -> u32 {
1516 unsafe { a_version_tweak }
1520 impl PartialOrd for version {
1522 fn partial_cmp(&self, other: &version) -> Option<Ordering> {
1523 let ok: c_int = unsafe { a_version_cmp(self, other) };
1525 return Some(Ordering::Greater);
1528 return Some(Ordering::Less);
1530 Some(Ordering::Equal)
1533 fn lt(&self, other: &version) -> bool {
1534 unsafe { a_version_lt(self, other) }
1537 fn gt(&self, other: &version) -> bool {
1538 unsafe { a_version_gt(self, other) }
1541 fn le(&self, other: &version) -> bool {
1542 unsafe { a_version_le(self, other) }
1545 fn ge(&self, other: &version) -> bool {
1546 unsafe { a_version_ge(self, other) }
1550 impl PartialEq for version {
1552 fn eq(&self, other: &version) -> bool {
1553 unsafe { a_version_eq(self, other) }