remove script/cargo.py
[liba.git] / src / lib.rs
blob8b48a34ad78bd096370fbb715f660922cd01b5d7
1 /*!
2 An algorithm library based on C/C++
4 ## Installation
6 Add this to your `Cargo.toml`:
8 ```toml
9 [dependencies]
10 liba = "0.1"
11 ```
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"))]
20 pub type float = f64;
21 /// floating-point number stored using `f32`
22 #[cfg(feature = "float")]
23 pub type float = f32;
25 #[cfg(feature = "std")]
26 extern crate 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};
58 extern "C" {
59     fn a_u32_sqrt(x: u32) -> u16;
60     fn a_u64_sqrt(x: u64) -> u32;
63 /// square root of an unsigned integer
64 #[inline(always)]
65 pub fn u32_sqrt(x: u32) -> u16 {
66     unsafe { a_u32_sqrt(x) }
68 /// square root of an unsigned integer
69 #[inline(always)]
70 pub fn u64_sqrt(x: u64) -> u32 {
71     unsafe { a_u64_sqrt(x) }
74 extern "C" {
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}}`
80 #[inline(always)]
81 pub fn f32_rsqrt(x: f32) -> f32 {
82     unsafe { a_f32_rsqrt(x) }
84 /// reciprocal of square-root, `\frac{1}{\sqrt{x}}`
85 #[inline(always)]
86 pub fn f64_rsqrt(x: f64) -> f64 {
87     unsafe { a_f64_rsqrt(x) }
90 extern "C" {
91     fn a_float_push(p: *mut float, n: usize, x: float);
92     fn a_float_roll(p: *mut float, n: usize);
93     fn a_float_sum(p: *const float, n: usize) -> float;
94     fn a_float_sum1(p: *const float, n: usize) -> float;
95     fn a_float_sum2(p: *const float, n: usize) -> float;
96     fn a_float_mean(p: *const float, n: usize) -> float;
99 /// roll back the elements of a float array and save the value
100 #[inline(always)]
101 pub fn float_push(x: &mut [float], v: float) {
102     unsafe { a_float_push(x.as_mut_ptr(), x.len(), v) }
104 /// roll back the elements of a float array circularly
105 #[inline(always)]
106 pub fn float_roll(x: &mut [float]) {
107     unsafe { a_float_roll(x.as_mut_ptr(), x.len()) }
109 /// calculate the sum of a float array
110 #[inline(always)]
111 pub fn float_sum(x: &[float]) -> float {
112     unsafe { a_float_sum(x.as_ptr(), x.len()) }
114 /// calculate the absolute sum of a float array
115 #[inline(always)]
116 pub fn float_sum1(x: &[float]) -> float {
117     unsafe { a_float_sum1(x.as_ptr(), x.len()) }
119 /// calculate the sum of squares of a float array
120 #[inline(always)]
121 pub fn float_sum2(x: &[float]) -> float {
122     unsafe { a_float_sum2(x.as_ptr(), x.len()) }
124 /// calculate the mean of a float array
125 #[inline(always)]
126 pub fn float_mean(x: &[float]) -> float {
127     unsafe { a_float_mean(x.as_ptr(), x.len()) }
130 extern "C" {
131     fn a_hash_bkdr_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
132     fn a_hash_sdbm_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
135 /// a hash function whose prime number is 131
136 #[inline(always)]
137 pub fn hash_bkdr(block: &[u8], value: u32) -> u32 {
138     unsafe { a_hash_bkdr_(block.as_ptr(), block.len(), value) }
140 /// a hash function whose prime number is 65599
141 #[inline(always)]
142 pub fn hash_sdbm(block: &[u8], value: u32) -> u32 {
143     unsafe { a_hash_sdbm_(block.as_ptr(), block.len(), value) }
146 /// Cyclic Redundancy Check for 8 bits
147 #[repr(C)]
148 pub struct crc8 {
149     /// Cyclic Redundancy Check comparison table
150     pub table: [u8; 0x100],
153 extern "C" {
154     fn a_crc8m_init(table: *mut u8, poly: u8);
155     fn a_crc8l_init(table: *mut u8, poly: u8);
156     fn a_crc8(table: *const u8, pdate: *const u8, nbyte: usize, value: u8) -> u8;
159 impl crc8 {
160     /// initialize for MSB CRC-8
161     #[inline(always)]
162     pub fn new_msb(poly: u8) -> Self {
163         let mut ctx: Self = Self { table: [0; 0x100] };
164         unsafe { a_crc8m_init(ctx.table.as_mut_ptr(), poly) };
165         ctx
166     }
167     /// initialize for LSB CRC-8
168     #[inline(always)]
169     pub fn new_lsb(poly: u8) -> Self {
170         let mut ctx: Self = Self { table: [0; 0x100] };
171         unsafe { a_crc8l_init(ctx.table.as_mut_ptr(), poly) };
172         ctx
173     }
174     /// generate for MSB CRC-8
175     #[inline(always)]
176     pub fn gen_msb(&mut self, poly: u8) -> &mut Self {
177         unsafe { a_crc8m_init(self.table.as_mut_ptr(), poly) };
178         self
179     }
180     /// generate for LSB CRC-8
181     #[inline(always)]
182     pub fn gen_lsb(&mut self, poly: u8) -> &mut Self {
183         unsafe { a_crc8l_init(self.table.as_mut_ptr(), poly) };
184         self
185     }
186     /// calculate for CRC-8
187     #[inline(always)]
188     pub fn eval(self, block: &[u8], value: u8) -> u8 {
189         unsafe { a_crc8(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
190     }
193 /// Cyclic Redundancy Check for 16 bits
194 #[repr(C)]
195 pub struct crc16 {
196     /// Cyclic Redundancy Check comparison table
197     pub table: [u16; 0x100],
198     eval: unsafe extern "C" fn(*const u16, *const u8, usize, u16) -> u16,
201 extern "C" {
202     fn a_crc16m_init(table: *mut u16, poly: u16);
203     fn a_crc16l_init(table: *mut u16, poly: u16);
204     fn a_crc16m(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
205     fn a_crc16l(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
208 impl crc16 {
209     /// initialize for MSB CRC-16
210     #[inline(always)]
211     pub fn new_msb(poly: u16) -> Self {
212         let mut ctx: Self = Self {
213             table: [0; 0x100],
214             eval: a_crc16m,
215         };
216         unsafe { a_crc16m_init(ctx.table.as_mut_ptr(), poly) };
217         ctx
218     }
219     /// initialize for LSB CRC-16
220     #[inline(always)]
221     pub fn new_lsb(poly: u16) -> Self {
222         let mut ctx: Self = Self {
223             table: [0; 0x100],
224             eval: a_crc16l,
225         };
226         unsafe { a_crc16l_init(ctx.table.as_mut_ptr(), poly) };
227         ctx
228     }
229     /// generate for MSB CRC-16
230     #[inline(always)]
231     pub fn gen_msb(&mut self, poly: u16) -> &mut Self {
232         unsafe { a_crc16m_init(self.table.as_mut_ptr(), poly) };
233         self.eval = a_crc16m;
234         self
235     }
236     /// generate for LSB CRC-16
237     #[inline(always)]
238     pub fn gen_lsb(&mut self, poly: u16) -> &mut Self {
239         unsafe { a_crc16l_init(self.table.as_mut_ptr(), poly) };
240         self.eval = a_crc16l;
241         self
242     }
243     /// calculate for CRC-16
244     #[inline(always)]
245     pub fn eval(self, block: &[u8], value: u16) -> u16 {
246         unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
247     }
250 /// Cyclic Redundancy Check for 32 bits
251 #[repr(C)]
252 pub struct crc32 {
253     /// Cyclic Redundancy Check comparison table
254     pub table: [u32; 0x100],
255     eval: unsafe extern "C" fn(*const u32, *const u8, usize, u32) -> u32,
258 extern "C" {
259     fn a_crc32m_init(table: *mut u32, poly: u32);
260     fn a_crc32l_init(table: *mut u32, poly: u32);
261     fn a_crc32m(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
262     fn a_crc32l(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
265 impl crc32 {
266     /// initialize for MSB CRC-32
267     #[inline(always)]
268     pub fn new_msb(poly: u32) -> Self {
269         let mut ctx: Self = Self {
270             table: [0; 0x100],
271             eval: a_crc32m,
272         };
273         unsafe { a_crc32m_init(ctx.table.as_mut_ptr(), poly) };
274         ctx
275     }
276     /// initialize for LSB CRC-32
277     #[inline(always)]
278     pub fn new_lsb(poly: u32) -> Self {
279         let mut ctx: Self = Self {
280             table: [0; 0x100],
281             eval: a_crc32l,
282         };
283         unsafe { a_crc32l_init(ctx.table.as_mut_ptr(), poly) };
284         ctx
285     }
286     /// generate for MSB CRC-32
287     #[inline(always)]
288     pub fn gen_msb(&mut self, poly: u32) -> &mut Self {
289         unsafe { a_crc32m_init(self.table.as_mut_ptr(), poly) };
290         self.eval = a_crc32m;
291         self
292     }
293     /// generate for LSB CRC-32
294     #[inline(always)]
295     pub fn gen_lsb(&mut self, poly: u32) -> &mut Self {
296         unsafe { a_crc32l_init(self.table.as_mut_ptr(), poly) };
297         self.eval = a_crc32l;
298         self
299     }
300     /// calculate for CRC-32
301     #[inline(always)]
302     pub fn eval(self, block: &[u8], value: u32) -> u32 {
303         unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
304     }
307 /// Cyclic Redundancy Check for 64 bits
308 #[repr(C)]
309 pub struct crc64 {
310     /// Cyclic Redundancy Check comparison table
311     pub table: [u64; 0x100],
312     eval: unsafe extern "C" fn(*const u64, *const u8, usize, u64) -> u64,
315 extern "C" {
316     fn a_crc64m_init(table: *mut u64, poly: u64);
317     fn a_crc64l_init(table: *mut u64, poly: u64);
318     fn a_crc64m(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
319     fn a_crc64l(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
322 impl crc64 {
323     /// initialize for MSB CRC-64
324     #[inline(always)]
325     pub fn new_msb(poly: u64) -> Self {
326         let mut ctx: Self = Self {
327             table: [0; 0x100],
328             eval: a_crc64m,
329         };
330         unsafe { a_crc64m_init(ctx.table.as_mut_ptr(), poly) };
331         ctx
332     }
333     /// initialize for LSB CRC-64
334     #[inline(always)]
335     pub fn new_lsb(poly: u64) -> Self {
336         let mut ctx: Self = Self {
337             table: [0; 0x100],
338             eval: a_crc64l,
339         };
340         unsafe { a_crc64l_init(ctx.table.as_mut_ptr(), poly) };
341         ctx
342     }
343     /// generate for MSB CRC-64
344     #[inline(always)]
345     pub fn gen_msb(&mut self, poly: u64) -> &mut Self {
346         unsafe { a_crc64m_init(self.table.as_mut_ptr(), poly) };
347         self.eval = a_crc64m;
348         self
349     }
350     /// generate for LSB CRC-64
351     #[inline(always)]
352     pub fn gen_lsb(&mut self, poly: u64) -> &mut Self {
353         unsafe { a_crc64l_init(self.table.as_mut_ptr(), poly) };
354         self.eval = a_crc64l;
355         self
356     }
357     /// calculate for CRC-64
358     #[inline(always)]
359     pub fn eval(self, block: &[u8], value: u64) -> u64 {
360         unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
361     }
364 #[allow(clippy::excessive_precision)]
365 const TAU: float = 6.28318530717958647692528676655900577;
367 /// High Pass Filter
368 #[repr(C)]
369 pub struct hpf {
370     /// filter coefficient
371     pub alpha: float,
372     /// filter output
373     pub output: float,
374     /// filter input
375     pub input: float,
378 impl hpf {
379     /// initialize for High Pass Filter
380     #[inline(always)]
381     pub fn new(fc: float, ts: float) -> Self {
382         Self {
383             alpha: 1.0 / (TAU * fc * ts + 1.0),
384             output: 0.0,
385             input: 0.0,
386         }
387     }
388     /// generate for High Pass Filter
389     #[inline(always)]
390     pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
391         self.alpha = 1.0 / (TAU * fc * ts + 1.0);
392         self
393     }
394     /// calculate for High Pass Filter
395     #[inline(always)]
396     pub fn iter(&mut self, x: float) -> float {
397         self.output = self.alpha * (self.output + x - self.input);
398         self.input = x;
399         self.output
400     }
401     /// zeroing for High Pass Filter
402     #[inline(always)]
403     pub fn zero(&mut self) -> &mut Self {
404         self.output = 0.0;
405         self.input = 0.0;
406         self
407     }
410 #[allow(clippy::excessive_precision)]
411 const _1_TAU: float = 0.159154943091895335768883763372514362;
413 /// Low Pass Filter
414 #[repr(C)]
415 pub struct lpf {
416     /// filter coefficient
417     pub alpha: float,
418     /// filter output
419     pub output: float,
422 impl lpf {
423     /// initialize for Low Pass Filter
424     #[inline(always)]
425     pub fn new(fc: float, ts: float) -> Self {
426         Self {
427             alpha: ts / (_1_TAU / fc + ts),
428             output: 0.0,
429         }
430     }
431     /// generate for Low Pass Filter
432     #[inline(always)]
433     pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
434         self.alpha = ts / (_1_TAU / fc + ts);
435         self
436     }
437     /// calculate for Low Pass Filter
438     #[inline(always)]
439     pub fn iter(&mut self, x: float) -> float {
440         self.output *= 1.0 - self.alpha;
441         self.output += x * self.alpha;
442         self.output
443     }
444     /// zeroing for Low Pass Filter
445     #[inline(always)]
446     pub fn zero(&mut self) -> &mut Self {
447         self.output = 0.0;
448         self
449     }
452 /// membership function
453 pub mod mf {
454     use crate::c_int;
455     /// none
456     pub const NUL: c_int = 0;
457     /// gaussian membership function
458     pub const GAUSS: c_int = 1;
459     /// gaussian combination membership function
460     pub const GAUSS2: c_int = 2;
461     /// generalized bell-shaped membership function
462     pub const GBELL: c_int = 3;
463     /// sigmoidal membership function
464     pub const SIG: c_int = 4;
465     /// difference between two sigmoidal membership functions
466     pub const DSIG: c_int = 5;
467     /// product of two sigmoidal membership functions
468     pub const PSIG: c_int = 6;
469     /// trapezoidal membership function
470     pub const TRAP: c_int = 7;
471     /// triangular membership function
472     pub const TRI: c_int = 8;
473     /// linear s-shaped saturation membership function
474     pub const LINS: c_int = 9;
475     /// linear z-shaped saturation membership function
476     pub const LINZ: c_int = 10;
477     /// s-shaped membership function
478     pub const S: c_int = 11;
479     /// z-shaped membership function
480     pub const Z: c_int = 12;
481     /// pi-shaped membership function
482     pub const PI: c_int = 13;
484     use crate::float;
485     extern "C" {
486         fn a_mf_gauss(x: float, sigma: float, c: float) -> float;
487         fn a_mf_gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float;
488         fn a_mf_gbell(x: float, a: float, b: float, c: float) -> float;
489         fn a_mf_sig(x: float, a: float, c: float) -> float;
490         fn a_mf_dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
491         fn a_mf_psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
492         fn a_mf_trap(x: float, a: float, b: float, c: float, d: float) -> float;
493         fn a_mf_tri(x: float, a: float, b: float, c: float) -> float;
494         fn a_mf_lins(x: float, a: float, b: float) -> float;
495         fn a_mf_linz(x: float, a: float, b: float) -> float;
496         fn a_mf_s(x: float, a: float, b: float) -> float;
497         fn a_mf_z(x: float, a: float, b: float) -> float;
498         fn a_mf_pi(x: float, a: float, b: float, c: float, d: float) -> float;
499     }
501     /// gaussian membership function
502     #[inline(always)]
503     pub fn gauss(x: float, sigma: float, c: float) -> float {
504         unsafe { a_mf_gauss(x, sigma, c) }
505     }
506     /// gaussian combination membership function
507     #[inline(always)]
508     pub fn gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float {
509         unsafe { a_mf_gauss2(x, sigma1, c1, sigma2, c2) }
510     }
511     /// generalized bell-shaped membership function
512     #[inline(always)]
513     pub fn gbell(x: float, a: float, b: float, c: float) -> float {
514         unsafe { a_mf_gbell(x, a, b, c) }
515     }
516     /// sigmoidal membership function
517     #[inline(always)]
518     pub fn sig(x: float, a: float, c: float) -> float {
519         unsafe { a_mf_sig(x, a, c) }
520     }
521     /// difference between two sigmoidal membership functions
522     #[inline(always)]
523     pub fn dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
524         unsafe { a_mf_dsig(x, a1, c1, a2, c2) }
525     }
526     /// product of two sigmoidal membership functions
527     #[inline(always)]
528     pub fn psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
529         unsafe { a_mf_psig(x, a1, c1, a2, c2) }
530     }
531     /// trapezoidal membership function
532     #[inline(always)]
533     pub fn trap(x: float, a: float, b: float, c: float, d: float) -> float {
534         unsafe { a_mf_trap(x, a, b, c, d) }
535     }
536     /// triangular membership function
537     #[inline(always)]
538     pub fn tri(x: float, a: float, b: float, c: float) -> float {
539         unsafe { a_mf_tri(x, a, b, c) }
540     }
541     /// linear s-shaped saturation membership function
542     #[inline(always)]
543     pub fn lins(x: float, a: float, b: float) -> float {
544         unsafe { a_mf_lins(x, a, b) }
545     }
546     /// linear z-shaped saturation membership function
547     #[inline(always)]
548     pub fn linz(x: float, a: float, b: float) -> float {
549         unsafe { a_mf_linz(x, a, b) }
550     }
551     /// s-shaped membership function
552     #[inline(always)]
553     pub fn s(x: float, a: float, b: float) -> float {
554         unsafe { a_mf_s(x, a, b) }
555     }
556     /// z-shaped membership function
557     #[inline(always)]
558     pub fn z(x: float, a: float, b: float) -> float {
559         unsafe { a_mf_z(x, a, b) }
560     }
561     /// pi-shaped membership function
562     #[inline(always)]
563     pub fn pi(x: float, a: float, b: float, c: float, d: float) -> float {
564         unsafe { a_mf_pi(x, a, b, c, d) }
565     }
568 /// proportional integral derivative controller
569 #[repr(C)]
570 pub struct pid {
571     /// proportional constant
572     pub kp: float,
573     /// integral constant
574     pub ki: float,
575     /// derivative constant
576     pub kd: float,
577     /// maximum integral output
578     pub summax: float,
579     /// minimum integral output
580     pub summin: float,
581     /// controller integral output
582     pub sum: float,
583     /// maximum final output
584     pub outmax: float,
585     /// minimum final output
586     pub outmin: float,
587     /// controller final output
588     pub out: float,
589     /// cache variable
590     var: float,
591     /// cache feedback
592     pub fdb: float,
593     /// cache error
594     pub err: float,
597 impl Default for pid {
598     #[inline(always)]
599     fn default() -> Self {
600         Self {
601             kp: 0.0,
602             ki: 0.0,
603             kd: 0.0,
604             summax: float::INFINITY,
605             summin: -float::INFINITY,
606             sum: 0.0,
607             outmax: float::INFINITY,
608             outmin: -float::INFINITY,
609             out: 0.0,
610             var: 0.0,
611             fdb: 0.0,
612             err: 0.0,
613         }
614     }
617 extern "C" {
618     fn a_pid_set_kpid(ctx: *mut pid, kp: float, ki: float, kd: float);
619     fn a_pid_run(ctx: *mut pid, set: float, fdb: float) -> float;
620     fn a_pid_pos(ctx: *mut pid, set: float, fdb: float) -> float;
621     fn a_pid_inc(ctx: *mut pid, set: float, fdb: float) -> float;
622     fn a_pid_zero(ctx: *mut pid);
625 impl pid {
626     /// initialize for PID controller
627     #[inline(always)]
628     pub fn new() -> Self {
629         Self::default()
630     }
631     /// set proportional integral derivative constant for PID controller
632     #[inline(always)]
633     pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
634         unsafe { a_pid_set_kpid(self, kp, ki, kd) };
635         self
636     }
637     /// calculate for PID controller
638     #[inline(always)]
639     pub fn run(&mut self, set: float, fdb: float) -> float {
640         unsafe { a_pid_run(self, set, fdb) }
641     }
642     /// calculate for positional PID controller
643     #[inline(always)]
644     pub fn pos(&mut self, set: float, fdb: float) -> float {
645         unsafe { a_pid_pos(self, set, fdb) }
646     }
647     /// calculate for incremental PID controller
648     #[inline(always)]
649     pub fn inc(&mut self, set: float, fdb: float) -> float {
650         unsafe { a_pid_inc(self, set, fdb) }
651     }
652     /// zeroing for PID controller
653     #[inline(always)]
654     pub fn zero(&mut self) -> &mut Self {
655         unsafe { a_pid_zero(self) };
656         self
657     }
660 /// fuzzy PID controller operator
661 pub mod fuzzy {
662     use crate::c_uint;
663     /// min(a,b)
664     pub const CAP: c_uint = 1;
665     /// a*b
666     pub const CAP_ALGEBRA: c_uint = 2;
667     /// max(a+b-1,0)
668     pub const CAP_BOUNDED: c_uint = 3;
669     /// max(a,b)
670     pub const CUP: c_uint = 4;
671     /// a+b-a*b
672     pub const CUP_ALGEBRA: c_uint = 5;
673     /// min(a+b,1)
674     pub const CUP_BOUNDED: c_uint = 6;
675     /// sqrt(a,b)*sqrt(1-(1-a)*(1-b))
676     pub const EQU: c_uint = 0;
679 /// fuzzy proportional integral derivative controller
680 #[repr(C)]
681 pub struct pid_fuzzy {
682     /// proportional integral derivative controller
683     pub pid: pid,
684     me: *const float,
685     mec: *const float,
686     mkp: *const float,
687     mki: *const float,
688     mkd: *const float,
689     idx: *mut c_uint,
690     val: *mut float,
691     /// fuzzy relational operator
692     opr: extern "C" fn(float, float) -> float,
693     /// base proportional constant
694     pub kp: float,
695     /// base integral constant
696     pub ki: float,
697     /// base derivative constant
698     pub kd: float,
699     /// number of order in the square matrix
700     nrule: c_uint,
701     /// maximum number triggered by the rule
702     nfuzz: c_uint,
705 impl Default for pid_fuzzy {
706     #[inline(always)]
707     fn default() -> Self {
708         Self {
709             pid: pid::default(),
710             me: null(),
711             mec: null(),
712             mkp: null(),
713             mki: null(),
714             mkd: null(),
715             idx: null_mut(),
716             val: null_mut(),
717             opr: unsafe { a_pid_fuzzy_opr(fuzzy::EQU) },
718             kp: 0.0,
719             ki: 0.0,
720             kd: 0.0,
721             nrule: 0,
722             nfuzz: 0,
723         }
724     }
727 extern "C" {
728     fn a_pid_fuzzy_opr(opr: c_uint) -> extern "C" fn(float, float) -> float;
729     fn a_pid_fuzzy_set_opr(ctx: *mut pid_fuzzy, opr: c_uint);
730     fn a_pid_fuzzy_bfuzz(ctx: *const pid_fuzzy) -> *mut u8;
731     fn a_pid_fuzzy_set_bfuzz(ctx: *mut pid_fuzzy, ptr: *mut u8, num: usize);
732     fn a_pid_fuzzy_set_rule(
733         ctx: *mut pid_fuzzy,
734         num: c_uint,
735         me: *const float,
736         mec: *const float,
737         mkp: *const float,
738         mki: *const float,
739         mkd: *const float,
740     );
741     fn a_pid_fuzzy_set_kpid(ctx: *mut pid_fuzzy, kp: float, ki: float, kd: float);
742     fn a_pid_fuzzy_run(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
743     fn a_pid_fuzzy_pos(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
744     fn a_pid_fuzzy_inc(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
745     fn a_pid_fuzzy_zero(ctx: *mut pid_fuzzy);
748 impl pid_fuzzy {
749     /// initialize for fuzzy PID controller
750     #[inline(always)]
751     pub fn new() -> Self {
752         Self::default()
753     }
754     /// set fuzzy relational operator for fuzzy PID controller
755     #[inline(always)]
756     pub fn set_opr(&mut self, opr: c_uint) -> &mut Self {
757         unsafe { a_pid_fuzzy_set_opr(self, opr) };
758         self
759     }
760     /// compute size of memory block for fuzzy PID controller
761     #[inline(always)]
762     #[allow(non_snake_case)]
763     pub const fn BFUZZ(n: usize) -> usize {
764         size_of::<c_uint>() * n * 2 + size_of::<float>() * n * (2 + n)
765     }
766     /// get memory block for fuzzy PID controller
767     #[inline(always)]
768     pub fn bfuzz(&mut self) -> &mut [u8] {
769         unsafe { from_raw_parts_mut(a_pid_fuzzy_bfuzz(self), Self::BFUZZ(self.nfuzz as usize)) }
770     }
771     /// set memory block for fuzzy PID controller
772     #[inline(always)]
773     pub fn set_bfuzz(&mut self, ptr: &mut [u8], num: usize) -> &mut Self {
774         unsafe { a_pid_fuzzy_set_bfuzz(self, ptr.as_mut_ptr(), num) };
775         self
776     }
777     /// set rule base for fuzzy PID controller
778     #[inline(always)]
779     pub fn set_rule(
780         &mut self,
781         col: usize,
782         me: &[float],
783         mec: &[float],
784         mkp: &[float],
785         mki: &[float],
786         mkd: &[float],
787     ) -> &mut Self {
788         unsafe {
789             a_pid_fuzzy_set_rule(
790                 self,
791                 col as c_uint,
792                 me.as_ptr(),
793                 mec.as_ptr(),
794                 mkp.as_ptr(),
795                 mki.as_ptr(),
796                 mkd.as_ptr(),
797             )
798         };
799         self
800     }
801     /// set proportional integral derivative constant for fuzzy PID controller
802     #[inline(always)]
803     pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
804         unsafe { a_pid_fuzzy_set_kpid(self, kp, ki, kd) };
805         self
806     }
807     /// calculate for fuzzy PID controller
808     #[inline(always)]
809     pub fn run(&mut self, set: float, fdb: float) -> float {
810         unsafe { a_pid_fuzzy_run(self, set, fdb) }
811     }
812     /// calculate for positional fuzzy PID controller
813     #[inline(always)]
814     pub fn pos(&mut self, set: float, fdb: float) -> float {
815         unsafe { a_pid_fuzzy_pos(self, set, fdb) }
816     }
817     /// calculate for incremental fuzzy PID controller
818     #[inline(always)]
819     pub fn inc(&mut self, set: float, fdb: float) -> float {
820         unsafe { a_pid_fuzzy_inc(self, set, fdb) }
821     }
822     /// zeroing for fuzzy PID controller
823     #[inline(always)]
824     pub fn zero(&mut self) -> &mut Self {
825         unsafe { a_pid_fuzzy_zero(self) };
826         self
827     }
830 /// single neuron proportional integral derivative controller
831 #[repr(C)]
832 pub struct pid_neuro {
833     /// proportional integral derivative controller
834     pub pid: pid,
835     /// proportional coefficient
836     pub k: float,
837     /// proportional weight
838     pub wp: float,
839     /// integral weight
840     pub wi: float,
841     /// derivative weight
842     pub wd: float,
843     /// error change
844     pub ec: float,
847 impl Default for pid_neuro {
848     #[inline(always)]
849     fn default() -> Self {
850         Self {
851             pid: pid::default(),
852             k: 0.0,
853             wp: 0.0,
854             wi: 0.0,
855             wd: 0.0,
856             ec: 0.0,
857         }
858     }
861 extern "C" {
862     fn a_pid_neuro_set_kpid(ctx: *mut pid_neuro, k: float, kp: float, ki: float, kd: float);
863     fn a_pid_neuro_set_wpid(ctx: *mut pid_neuro, wp: float, wi: float, wd: float);
864     fn a_pid_neuro_run(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
865     fn a_pid_neuro_inc(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
866     fn a_pid_neuro_zero(ctx: *mut pid_neuro);
869 impl pid_neuro {
870     /// initialize for single neuron PID controller
871     #[inline(always)]
872     pub fn new() -> Self {
873         Self::default()
874     }
875     /// set proportional integral derivative constant for single neuron PID controller
876     #[inline(always)]
877     pub fn set_kpid(&mut self, k: float, kp: float, ki: float, kd: float) -> &mut Self {
878         unsafe { a_pid_neuro_set_kpid(self, k, kp, ki, kd) };
879         self
880     }
881     /// set proportional integral derivative weight for single neuron PID controller
882     #[inline(always)]
883     pub fn set_wpid(&mut self, wp: float, wi: float, wd: float) -> &mut Self {
884         unsafe { a_pid_neuro_set_wpid(self, wp, wi, wd) };
885         self
886     }
887     /// calculate for single neuron PID controller
888     #[inline(always)]
889     pub fn run(&mut self, set: float, fdb: float) -> float {
890         unsafe { a_pid_neuro_run(self, set, fdb) }
891     }
892     /// calculate for incremental single neuron PID controller
893     #[inline(always)]
894     pub fn inc(&mut self, set: float, fdb: float) -> float {
895         unsafe { a_pid_neuro_inc(self, set, fdb) }
896     }
897     /// zeroing for single neuron PID controller
898     #[inline(always)]
899     pub fn zero(&mut self) -> &mut Self {
900         unsafe { a_pid_neuro_zero(self) };
901         self
902     }
905 /// simple linear regression
906 #[repr(C)]
907 pub struct regress_simple {
908     /// regression coefficient
909     pub coef: float,
910     /// intercept
911     pub bias: float,
914 extern "C" {
915     fn a_regress_simple_eval(ctx: *const regress_simple, val: float) -> float;
916     fn a_regress_simple_evar(ctx: *const regress_simple, val: float) -> float;
917     fn a_regress_simple_ols_(
918         ctx: *mut regress_simple,
919         n: usize,
920         x: *const float,
921         y: *const float,
922         x_mean: float,
923         y_mean: float,
924     );
925     fn a_regress_simple_olsx(
926         ctx: *mut regress_simple,
927         n: usize,
928         x: *const float,
929         y: *const float,
930         x_mean: float,
931     );
932     fn a_regress_simple_olsy(
933         ctx: *mut regress_simple,
934         n: usize,
935         x: *const float,
936         y: *const float,
937         y_mean: float,
938     );
939     fn a_regress_simple_ols(ctx: *mut regress_simple, n: usize, x: *const float, y: *const float);
940     fn a_regress_simple_zero(ctx: *mut regress_simple);
943 impl regress_simple {
944     /// initialize for simple linear regression
945     #[inline(always)]
946     pub fn new(coef: float, bias: float) -> Self {
947         Self { coef, bias }
948     }
949     /// calculate predicted value for simple linear regression
950     #[inline(always)]
951     pub fn eval(&self, val: float) -> float {
952         unsafe { a_regress_simple_eval(self, val) }
953     }
954     /// calculate predicted value for simple linear regression
955     #[inline(always)]
956     pub fn evar(&self, val: float) -> float {
957         unsafe { a_regress_simple_evar(self, val) }
958     }
959     /// ordinary least squares for simple linear regression
960     #[inline(always)]
961     pub fn ols_(&mut self, x: &[float], y: &[float], x_mean: float, y_mean: float) -> &mut Self {
962         unsafe { a_regress_simple_ols_(self, x.len(), x.as_ptr(), y.as_ptr(), x_mean, y_mean) };
963         self
964     }
965     /// ordinary least squares for simple linear regression
966     #[inline(always)]
967     pub fn olsx(&mut self, x: &[float], y: &[float], x_mean: float) -> &mut Self {
968         unsafe { a_regress_simple_olsx(self, x.len(), x.as_ptr(), y.as_ptr(), x_mean) };
969         self
970     }
971     /// ordinary least squares for simple linear regression
972     #[inline(always)]
973     pub fn olsy(&mut self, x: &[float], y: &[float], y_mean: float) -> &mut Self {
974         unsafe { a_regress_simple_olsy(self, x.len(), x.as_ptr(), y.as_ptr(), y_mean) };
975         self
976     }
977     /// ordinary least squares for simple linear regression
978     #[inline(always)]
979     pub fn ols(&mut self, x: &[float], y: &[float]) -> &mut Self {
980         unsafe { a_regress_simple_ols(self, x.len(), x.as_ptr(), y.as_ptr()) };
981         self
982     }
983     /// zeroing for simple linear regression
984     #[inline(always)]
985     pub fn zero(&mut self) -> &mut Self {
986         unsafe { a_regress_simple_zero(self) };
987         self
988     }
991 /// transfer function
992 #[repr(C)]
993 pub struct tf {
994     /// input
995     input: *mut float,
996     /// output
997     output: *mut float,
998     /// numerator
999     num_p: *const float,
1000     /// denominator
1001     den_p: *const float,
1002     /// numerator number
1003     num_n: c_uint,
1004     /// denominator number
1005     den_n: c_uint,
1008 extern "C" {
1009     fn a_tf_set_num(ctx: *mut tf, num_n: c_uint, num_p: *const float, input: *mut float);
1010     fn a_tf_set_den(ctx: *mut tf, den_n: c_uint, den_p: *const float, output: *mut float);
1011     fn a_tf_init(
1012         ctx: *mut tf,
1013         num_n: c_uint,
1014         num_p: *const float,
1015         input: *mut float,
1016         den_n: c_uint,
1017         den_p: *const float,
1018         output: *mut float,
1019     );
1020     fn a_tf_iter(ctx: *const tf, x: float) -> float;
1021     fn a_tf_zero(ctx: *const tf);
1024 impl tf {
1025     /// initialize for transfer function
1026     #[inline(always)]
1027     pub fn new(num: &[float], input: &mut [float], den: &[float], output: &mut [float]) -> Self {
1028         let mut ctx: Self = Self {
1029             input: null_mut(),
1030             output: null_mut(),
1031             num_p: null(),
1032             den_p: null(),
1033             num_n: 0,
1034             den_n: 0,
1035         };
1036         unsafe {
1037             a_tf_init(
1038                 &mut ctx,
1039                 num.len() as c_uint,
1040                 num.as_ptr(),
1041                 input.as_mut_ptr(),
1042                 den.len() as c_uint,
1043                 den.as_ptr(),
1044                 output.as_mut_ptr(),
1045             )
1046         };
1047         ctx
1048     }
1049     /// calculate for transfer function
1050     #[inline(always)]
1051     pub fn iter(&mut self, x: float) -> float {
1052         unsafe { a_tf_iter(self, x) }
1053     }
1054     /// zeroing for transfer function
1055     #[inline(always)]
1056     pub fn zero(&mut self) -> &mut Self {
1057         unsafe { a_tf_zero(self) };
1058         self
1059     }
1060     /// get input for transfer function
1061     #[inline(always)]
1062     pub fn input(&self) -> &[float] {
1063         unsafe { from_raw_parts(self.input, self.num_n as usize) }
1064     }
1065     /// get numerator for transfer function
1066     #[inline(always)]
1067     pub fn num(&self) -> &[float] {
1068         unsafe { from_raw_parts(self.num_p, self.num_n as usize) }
1069     }
1070     /// set numerator for transfer function
1071     #[inline(always)]
1072     pub fn set_num(&mut self, num: &[float], input: &mut [float]) -> &mut Self {
1073         unsafe { a_tf_set_num(self, num.len() as c_uint, num.as_ptr(), input.as_mut_ptr()) };
1074         self
1075     }
1076     /// get output for transfer function
1077     #[inline(always)]
1078     pub fn output(&self) -> &[float] {
1079         unsafe { from_raw_parts(self.output, self.den_n as usize) }
1080     }
1081     /// get denominator for transfer function
1082     #[inline(always)]
1083     pub fn den(&self) -> &[float] {
1084         unsafe { from_raw_parts(self.den_p, self.den_n as usize) }
1085     }
1086     /// set denominator for transfer function
1087     #[inline(always)]
1088     pub fn set_den(&mut self, den: &[float], output: &mut [float]) -> &mut Self {
1089         unsafe { a_tf_set_den(self, den.len() as c_uint, den.as_ptr(), output.as_mut_ptr()) };
1090         self
1091     }
1094 /// bell-shaped velocity trajectory
1095 #[repr(C)]
1096 pub struct trajbell {
1097     /// total duration
1098     pub t: float,
1099     /// constant velocity phase
1100     pub tv: float,
1101     /// acceleration phase
1102     pub ta: float,
1103     /// deceleration phase
1104     pub td: float,
1105     /// time-interval in which the jerk is constant (j max or j min ) during the acceleration phase
1106     pub taj: float,
1107     /// time-interval in which the jerk is constant (j max or j min ) during the deceleration phase
1108     pub tdj: float,
1109     /// initial position
1110     pub p0: float,
1111     /// final position
1112     pub p1: float,
1113     /// initial velocity
1114     pub v0: float,
1115     /// final velocity
1116     pub v1: float,
1117     /// maximum velocity
1118     pub vm: float,
1119     /// maximum jerk
1120     pub jm: float,
1121     /// maximum acceleration
1122     pub am: float,
1123     /// maximum deceleration
1124     pub dm: float,
1127 impl Default for trajbell {
1128     #[inline(always)]
1129     fn default() -> Self {
1130         Self {
1131             t: 0.0,
1132             tv: 0.0,
1133             ta: 0.0,
1134             td: 0.0,
1135             taj: 0.0,
1136             tdj: 0.0,
1137             p0: 0.0,
1138             p1: 0.0,
1139             v0: 0.0,
1140             v1: 0.0,
1141             vm: 0.0,
1142             jm: 0.0,
1143             am: 0.0,
1144             dm: 0.0,
1145         }
1146     }
1149 extern "C" {
1150     fn a_trajbell_gen(
1151         ctx: *mut trajbell,
1152         jm: float,
1153         am: float,
1154         vm: float,
1155         p0: float,
1156         p1: float,
1157         v0: float,
1158         v1: float,
1159     ) -> float;
1160     fn a_trajbell_pos(ctx: *const trajbell, x: float) -> float;
1161     fn a_trajbell_vel(ctx: *const trajbell, x: float) -> float;
1162     fn a_trajbell_acc(ctx: *const trajbell, x: float) -> float;
1163     fn a_trajbell_jer(ctx: *const trajbell, x: float) -> float;
1166 impl trajbell {
1167     /// initialize for bell-shaped velocity trajectory
1168     #[inline(always)]
1169     pub fn new() -> Self {
1170         Self::default()
1171     }
1172     /// generate for bell-shaped velocity trajectory
1173     #[allow(clippy::too_many_arguments)]
1174     #[inline(always)]
1175     pub fn gen(
1176         &mut self,
1177         jm: float,
1178         am: float,
1179         vm: float,
1180         p0: float,
1181         p1: float,
1182         v0: float,
1183         v1: float,
1184     ) -> float {
1185         unsafe { a_trajbell_gen(self, jm, am, vm, p0, p1, v0, v1) }
1186     }
1187     /// calculate position for bell-shaped velocity trajectory
1188     #[inline(always)]
1189     pub fn pos(&mut self, x: float) -> float {
1190         unsafe { a_trajbell_pos(self, x) }
1191     }
1192     /// calculate velocity for bell-shaped velocity trajectory
1193     #[inline(always)]
1194     pub fn vel(&mut self, x: float) -> float {
1195         unsafe { a_trajbell_vel(self, x) }
1196     }
1197     /// calculate acceleration for bell-shaped velocity trajectory
1198     #[inline(always)]
1199     pub fn acc(&mut self, x: float) -> float {
1200         unsafe { a_trajbell_acc(self, x) }
1201     }
1202     /// calculate jerk for bell-shaped velocity trajectory
1203     #[inline(always)]
1204     pub fn jer(&mut self, x: float) -> float {
1205         unsafe { a_trajbell_jer(self, x) }
1206     }
1209 /// cubic polynomial trajectory
1210 #[repr(C)]
1211 pub struct trajpoly3 {
1212     /// coefficients of position
1213     pub p: [float; 4],
1214     /// coefficients of velocity
1215     pub v: [float; 3],
1216     /// coefficients of acceleration
1217     pub a: [float; 2],
1220 extern "C" {
1221     fn a_trajpoly3_gen(ctx: *mut trajpoly3, ts: float, p0: float, p1: float, v0: float, v1: float);
1222     fn a_trajpoly3_pos(ctx: *const trajpoly3, x: float) -> float;
1223     fn a_trajpoly3_vel(ctx: *const trajpoly3, x: float) -> float;
1224     fn a_trajpoly3_acc(ctx: *const trajpoly3, x: float) -> float;
1227 impl trajpoly3 {
1228     /// initialize for cubic polynomial trajectory
1229     #[inline(always)]
1230     pub fn new(ts: float, p0: float, p1: float, v0: float, v1: float) -> Self {
1231         let mut ctx: Self = Self {
1232             p: [0.0; 4],
1233             v: [0.0; 3],
1234             a: [0.0; 2],
1235         };
1236         unsafe { a_trajpoly3_gen(&mut ctx, ts, p0, p1, v0, v1) };
1237         ctx
1238     }
1239     /// generate for cubic polynomial trajectory
1240     #[inline(always)]
1241     pub fn gen(&mut self, ts: float, p0: float, p1: float, v0: float, v1: float) -> &mut Self {
1242         unsafe { a_trajpoly3_gen(self, ts, p0, p1, v0, v1) };
1243         self
1244     }
1245     /// calculate position for cubic polynomial trajectory
1246     #[inline(always)]
1247     pub fn pos(&mut self, x: float) -> float {
1248         unsafe { a_trajpoly3_pos(self, x) }
1249     }
1250     /// calculate velocity for cubic polynomial trajectory
1251     #[inline(always)]
1252     pub fn vel(&mut self, x: float) -> float {
1253         unsafe { a_trajpoly3_vel(self, x) }
1254     }
1255     /// calculate acceleration for cubic polynomial trajectory
1256     #[inline(always)]
1257     pub fn acc(&mut self, x: float) -> float {
1258         unsafe { a_trajpoly3_acc(self, x) }
1259     }
1262 /// quintic polynomial trajectory
1263 #[repr(C)]
1264 pub struct trajpoly5 {
1265     /// coefficients of position
1266     pub p: [float; 6],
1267     /// coefficients of velocity
1268     pub v: [float; 5],
1269     /// coefficients of acceleration
1270     pub a: [float; 4],
1273 extern "C" {
1274     fn a_trajpoly5_gen(
1275         ctx: *mut trajpoly5,
1276         ts: float,
1277         p0: float,
1278         p1: float,
1279         v0: float,
1280         v1: float,
1281         a0: float,
1282         a1: float,
1283     );
1284     fn a_trajpoly5_pos(ctx: *const trajpoly5, x: float) -> float;
1285     fn a_trajpoly5_vel(ctx: *const trajpoly5, x: float) -> float;
1286     fn a_trajpoly5_acc(ctx: *const trajpoly5, x: float) -> float;
1289 impl trajpoly5 {
1290     /// initialize for quintic polynomial trajectory
1291     #[allow(clippy::too_many_arguments)]
1292     #[inline(always)]
1293     pub fn new(
1294         ts: float,
1295         p0: float,
1296         p1: float,
1297         v0: float,
1298         v1: float,
1299         a0: float,
1300         a1: float,
1301     ) -> Self {
1302         let mut ctx: Self = Self {
1303             p: [0.0; 6],
1304             v: [0.0; 5],
1305             a: [0.0; 4],
1306         };
1307         unsafe { a_trajpoly5_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1) };
1308         ctx
1309     }
1310     /// generate for quintic polynomial trajectory
1311     #[allow(clippy::too_many_arguments)]
1312     #[inline(always)]
1313     pub fn gen(
1314         &mut self,
1315         ts: float,
1316         p0: float,
1317         p1: float,
1318         v0: float,
1319         v1: float,
1320         a0: float,
1321         a1: float,
1322     ) -> &mut Self {
1323         unsafe { a_trajpoly5_gen(self, ts, p0, p1, v0, v1, a0, a1) };
1324         self
1325     }
1326     /// calculate position for quintic polynomial trajectory
1327     #[inline(always)]
1328     pub fn pos(&mut self, x: float) -> float {
1329         unsafe { a_trajpoly5_pos(self, x) }
1330     }
1331     /// calculate velocity for quintic polynomial trajectory
1332     #[inline(always)]
1333     pub fn vel(&mut self, x: float) -> float {
1334         unsafe { a_trajpoly5_vel(self, x) }
1335     }
1336     /// calculate acceleration for quintic polynomial trajectory
1337     #[inline(always)]
1338     pub fn acc(&mut self, x: float) -> float {
1339         unsafe { a_trajpoly5_acc(self, x) }
1340     }
1343 /// hepta polynomial trajectory
1344 #[repr(C)]
1345 pub struct trajpoly7 {
1346     /// coefficients of position
1347     pub p: [float; 8],
1348     /// coefficients of velocity
1349     pub v: [float; 7],
1350     /// coefficients of acceleration
1351     pub a: [float; 6],
1352     /// coefficients of jerk
1353     pub j: [float; 5],
1356 extern "C" {
1357     fn a_trajpoly7_gen(
1358         ctx: *mut trajpoly7,
1359         ts: float,
1360         p0: float,
1361         p1: float,
1362         v0: float,
1363         v1: float,
1364         a0: float,
1365         a1: float,
1366         j0: float,
1367         j1: float,
1368     );
1369     fn a_trajpoly7_pos(ctx: *const trajpoly7, x: float) -> float;
1370     fn a_trajpoly7_vel(ctx: *const trajpoly7, x: float) -> float;
1371     fn a_trajpoly7_acc(ctx: *const trajpoly7, x: float) -> float;
1372     fn a_trajpoly7_jer(ctx: *const trajpoly7, x: float) -> float;
1375 impl trajpoly7 {
1376     /// initialize for hepta polynomial trajectory
1377     #[allow(clippy::too_many_arguments)]
1378     #[inline(always)]
1379     pub fn new(
1380         ts: float,
1381         p0: float,
1382         p1: float,
1383         v0: float,
1384         v1: float,
1385         a0: float,
1386         a1: float,
1387         j0: float,
1388         j1: float,
1389     ) -> Self {
1390         let mut ctx: Self = Self {
1391             p: [0.0; 8],
1392             v: [0.0; 7],
1393             a: [0.0; 6],
1394             j: [0.0; 5],
1395         };
1396         unsafe { a_trajpoly7_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1397         ctx
1398     }
1399     /// generate for hepta polynomial trajectory
1400     #[allow(clippy::too_many_arguments)]
1401     #[inline(always)]
1402     pub fn gen(
1403         &mut self,
1404         ts: float,
1405         p0: float,
1406         p1: float,
1407         v0: float,
1408         v1: float,
1409         a0: float,
1410         a1: float,
1411         j0: float,
1412         j1: float,
1413     ) -> &mut Self {
1414         unsafe { a_trajpoly7_gen(self, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1415         self
1416     }
1417     /// calculate position for hepta polynomial trajectory
1418     #[inline(always)]
1419     pub fn pos(&mut self, x: float) -> float {
1420         unsafe { a_trajpoly7_pos(self, x) }
1421     }
1422     /// calculate velocity for hepta polynomial trajectory
1423     #[inline(always)]
1424     pub fn vel(&mut self, x: float) -> float {
1425         unsafe { a_trajpoly7_vel(self, x) }
1426     }
1427     /// calculate acceleration for hepta polynomial trajectory
1428     #[inline(always)]
1429     pub fn acc(&mut self, x: float) -> float {
1430         unsafe { a_trajpoly7_acc(self, x) }
1431     }
1432     /// calculate jerk for hepta polynomial trajectory
1433     #[inline(always)]
1434     pub fn jer(&mut self, x: float) -> float {
1435         unsafe { a_trajpoly7_jer(self, x) }
1436     }
1439 /// trapezoidal velocity trajectory
1440 #[repr(C)]
1441 pub struct trajtrap {
1442     /// total duration
1443     pub t: float,
1444     /// initial position
1445     pub p0: float,
1446     /// final position
1447     pub p1: float,
1448     /// initial velocity
1449     pub v0: float,
1450     /// final velocity
1451     pub v1: float,
1452     /// constant velocity
1453     pub vc: float,
1454     /// time before constant velocity
1455     pub ta: float,
1456     /// time after constant velocity
1457     pub td: float,
1458     /// position before constant velocity
1459     pub pa: float,
1460     /// position after constant velocity
1461     pub pd: float,
1462     /// acceleration before constant velocity
1463     pub ac: float,
1464     /// acceleration after constant velocity
1465     pub de: float,
1468 impl Default for trajtrap {
1469     #[inline(always)]
1470     fn default() -> Self {
1471         Self {
1472             t: 0.0,
1473             p0: 0.0,
1474             p1: 0.0,
1475             v0: 0.0,
1476             v1: 0.0,
1477             vc: 0.0,
1478             ta: 0.0,
1479             td: 0.0,
1480             pa: 0.0,
1481             pd: 0.0,
1482             ac: 0.0,
1483             de: 0.0,
1484         }
1485     }
1488 extern "C" {
1489     fn a_trajtrap_gen(
1490         ctx: *mut trajtrap,
1491         vm: float,
1492         ac: float,
1493         de: float,
1494         p0: float,
1495         p1: float,
1496         v0: float,
1497         v1: float,
1498     ) -> float;
1499     fn a_trajtrap_pos(ctx: *const trajtrap, x: float) -> float;
1500     fn a_trajtrap_vel(ctx: *const trajtrap, x: float) -> float;
1501     fn a_trajtrap_acc(ctx: *const trajtrap, x: float) -> float;
1504 impl trajtrap {
1505     /// initialize for trapezoidal velocity trajectory
1506     #[inline(always)]
1507     pub fn new() -> Self {
1508         Self::default()
1509     }
1510     /// generate for trapezoidal velocity trajectory
1511     #[allow(clippy::too_many_arguments)]
1512     #[inline(always)]
1513     pub fn gen(
1514         &mut self,
1515         vm: float,
1516         ac: float,
1517         de: float,
1518         p0: float,
1519         p1: float,
1520         v0: float,
1521         v1: float,
1522     ) -> float {
1523         unsafe { a_trajtrap_gen(self, vm, ac, de, p0, p1, v0, v1) }
1524     }
1525     /// calculate position for trapezoidal velocity trajectory
1526     #[inline(always)]
1527     pub fn pos(&mut self, x: float) -> float {
1528         unsafe { a_trajtrap_pos(self, x) }
1529     }
1530     /// calculate velocity for trapezoidal velocity trajectory
1531     #[inline(always)]
1532     pub fn vel(&mut self, x: float) -> float {
1533         unsafe { a_trajtrap_vel(self, x) }
1534     }
1535     /// calculate acceleration for trapezoidal velocity trajectory
1536     #[inline(always)]
1537     pub fn acc(&mut self, x: float) -> float {
1538         unsafe { a_trajtrap_acc(self, x) }
1539     }
1542 /// version
1543 #[repr(C)]
1544 pub struct version {
1545     /// major number
1546     pub major: c_uint,
1547     /// minor number
1548     pub minor: c_uint,
1549     /// third number
1550     pub third: c_uint,
1551     /// extra number
1552     pub extra: c_uint,
1553     /// alphabet
1554     pub alpha: [u8; 4],
1557 impl Default for version {
1558     #[inline(always)]
1559     fn default() -> Self {
1560         Self {
1561             major: 0,
1562             minor: 0,
1563             third: 0,
1564             extra: 0,
1565             alpha: [b'.', 0, 0, 0],
1566         }
1567     }
1570 extern "C" {
1571     static a_version_major: c_uint;
1572     static a_version_minor: c_uint;
1573     static a_version_patch: c_uint;
1574     static a_version_tweak: u32;
1575     fn a_version_set_alpha(ctx: *mut version, alpha: *const u8);
1576     fn a_version_alpha(ctx: *const version, alpha: &mut [u8; 5]);
1577     fn a_version_parse(ctx: *mut version, ver: *const u8) -> c_uint;
1578     fn a_version_tostr(ctx: *const version, p: *mut u8, n: usize) -> c_int;
1579     fn a_version_cmp(ctx: *const version, rhs: *const version) -> c_int;
1580     fn a_version_lt(ctx: *const version, rhs: *const version) -> bool;
1581     fn a_version_gt(ctx: *const version, rhs: *const version) -> bool;
1582     fn a_version_le(ctx: *const version, rhs: *const version) -> bool;
1583     fn a_version_ge(ctx: *const version, rhs: *const version) -> bool;
1584     fn a_version_eq(ctx: *const version, rhs: *const version) -> bool;
1585     fn a_version_check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int;
1588 impl version {
1589     /// initialize for version
1590     #[inline(always)]
1591     pub fn new(major: c_uint, minor: c_uint, third: c_uint) -> Self {
1592         Self {
1593             major,
1594             minor,
1595             third,
1596             ..Default::default()
1597         }
1598     }
1599     /// set alphabet for version
1600     #[inline(always)]
1601     pub fn set_alpha(&mut self, alpha: &[u8]) {
1602         unsafe { a_version_set_alpha(self, alpha.as_ptr()) }
1603     }
1604     /// get alphabet for version
1605     #[inline(always)]
1606     pub fn alpha(&self, alpha: &mut [u8; 5]) {
1607         unsafe { a_version_alpha(self, alpha) }
1608     }
1609     /// parse version string to version
1610     #[inline(always)]
1611     pub fn parse(&mut self, ver: &str) -> c_uint {
1612         unsafe { a_version_parse(self, ver.as_ptr()) }
1613     }
1614     /// convert version to string
1615     #[inline(always)]
1616     pub fn tostr(&mut self, ver: &mut [u8]) -> c_int {
1617         unsafe { a_version_tostr(self, ver.as_mut_ptr(), ver.len()) }
1618     }
1619     /// algorithm library version check
1620     #[inline(always)]
1621     pub fn check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int {
1622         unsafe { a_version_check(major, minor, patch) }
1623     }
1624     /// algorithm library version major
1625     #[inline(always)]
1626     pub fn major() -> c_uint {
1627         unsafe { a_version_major }
1628     }
1629     /// algorithm library version minor
1630     #[inline(always)]
1631     pub fn minor() -> c_uint {
1632         unsafe { a_version_minor }
1633     }
1634     /// algorithm library version patch
1635     #[inline(always)]
1636     pub fn patch() -> c_uint {
1637         unsafe { a_version_patch }
1638     }
1639     /// algorithm library version tweak
1640     #[inline(always)]
1641     pub fn tweak() -> u32 {
1642         unsafe { a_version_tweak }
1643     }
1646 impl PartialOrd for version {
1647     #[inline(always)]
1648     fn partial_cmp(&self, other: &version) -> Option<Ordering> {
1649         let ok: c_int = unsafe { a_version_cmp(self, other) };
1650         if ok > 0 {
1651             return Some(Ordering::Greater);
1652         }
1653         if ok < 0 {
1654             return Some(Ordering::Less);
1655         }
1656         Some(Ordering::Equal)
1657     }
1658     #[inline(always)]
1659     fn lt(&self, other: &version) -> bool {
1660         unsafe { a_version_lt(self, other) }
1661     }
1662     #[inline(always)]
1663     fn gt(&self, other: &version) -> bool {
1664         unsafe { a_version_gt(self, other) }
1665     }
1666     #[inline(always)]
1667     fn le(&self, other: &version) -> bool {
1668         unsafe { a_version_le(self, other) }
1669     }
1670     #[inline(always)]
1671     fn ge(&self, other: &version) -> bool {
1672         unsafe { a_version_ge(self, other) }
1673     }
1676 impl PartialEq for version {
1677     #[inline(always)]
1678     fn eq(&self, other: &version) -> bool {
1679         unsafe { a_version_eq(self, other) }
1680     }