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