#![warn(missing_docs)]
#![allow(non_camel_case_types)]
#![cfg_attr(not(features = "std"), no_std)]
pub type int = core::ffi::c_int;
pub type uint = core::ffi::c_uint;
#[cfg(not(feature = "float"))]
pub type float = f64;
#[cfg(feature = "float")]
pub type float = f32;
extern "C" {
fn a_u32_sqrt(x: u32) -> u16;
fn a_u64_sqrt(x: u64) -> u32;
}
#[inline(always)]
pub fn u32_sqrt(x: u32) -> u16 {
unsafe { a_u32_sqrt(x) }
}
#[inline(always)]
pub fn u64_sqrt(x: u64) -> u32 {
unsafe { a_u64_sqrt(x) }
}
extern "C" {
fn a_f32_rsqrt(x: f32) -> f32;
fn a_f64_rsqrt(x: f64) -> f64;
}
#[inline(always)]
pub fn f32_rsqrt(x: f32) -> f32 {
unsafe { a_f32_rsqrt(x) }
}
#[inline(always)]
pub fn f64_rsqrt(x: f64) -> f64 {
unsafe { a_f64_rsqrt(x) }
}
extern "C" {
fn a_hash_bkdr_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
fn a_hash_sdbm_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
}
#[inline(always)]
pub fn hash_bkdr(block: &[u8], value: u32) -> u32 {
unsafe { a_hash_bkdr_(block.as_ptr(), block.len(), value) }
}
#[inline(always)]
pub fn hash_sdbm(block: &[u8], value: u32) -> u32 {
unsafe { a_hash_sdbm_(block.as_ptr(), block.len(), value) }
}
mod test {
extern crate std;
#[test]
fn usqrt() {
std::println!("{}", crate::u32_sqrt(u32::MAX));
std::println!("{}", crate::u64_sqrt(u64::MAX));
}
#[test]
fn rsqrt() {
std::println!("1/sqrt({})={}", 4, crate::f32_rsqrt(4.0));
std::println!("1/sqrt({})={}", 4, crate::f64_rsqrt(4.0));
}
#[test]
fn hash() {
let text: [u8; 10] = *b"0123456789";
std::println!("{}", crate::hash_bkdr(&text, 0));
std::println!("{}", crate::hash_sdbm(&text, 0));
}
}
#[repr(C)]
pub struct crc8 {
pub table: [u8; 0x100],
}
extern "C" {
fn a_crc8m_init(table: *mut u8, poly: u8);
fn a_crc8l_init(table: *mut u8, poly: u8);
fn a_crc8(table: *const u8, pdate: *const u8, nbyte: usize, value: u8) -> u8;
}
impl crc8 {
#[inline(always)]
pub fn new_msb(poly: u8) -> Self {
let mut ctx: Self = Self { table: [0; 0x100] };
unsafe { a_crc8m_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn new_lsb(poly: u8) -> Self {
let mut ctx: Self = Self { table: [0; 0x100] };
unsafe { a_crc8l_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn gen_msb(&mut self, poly: u8) -> &mut Self {
unsafe { a_crc8m_init(self.table.as_mut_ptr(), poly) };
self
}
#[inline(always)]
pub fn gen_lsb(&mut self, poly: u8) -> &mut Self {
unsafe { a_crc8l_init(self.table.as_mut_ptr(), poly) };
self
}
#[inline(always)]
pub fn eval(self, block: &[u8], value: u8) -> u8 {
unsafe { a_crc8(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
}
}
#[test]
fn crc8() {
extern crate std;
{
let ctx = crate::crc8::new_msb(0x07);
assert_eq!(ctx.eval(b"0123456789", 0), 0x45);
}
{
let ctx = crate::crc8::new_lsb(0x31);
assert_eq!(ctx.eval(b"0123456789", 0), 0x75);
}
}
#[repr(C)]
pub struct crc16 {
pub table: [u16; 0x100],
eval: unsafe extern "C" fn(*const u16, *const u8, usize, u16) -> u16,
}
extern "C" {
fn a_crc16m_init(table: *mut u16, poly: u16);
fn a_crc16l_init(table: *mut u16, poly: u16);
fn a_crc16m(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
fn a_crc16l(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
}
impl crc16 {
#[inline(always)]
pub fn new_msb(poly: u16) -> Self {
let mut ctx: Self = Self {
table: [0; 0x100],
eval: a_crc16m,
};
unsafe { a_crc16m_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn new_lsb(poly: u16) -> Self {
let mut ctx: Self = Self {
table: [0; 0x100],
eval: a_crc16l,
};
unsafe { a_crc16l_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn gen_msb(&mut self, poly: u16) -> &mut Self {
unsafe { a_crc16m_init(self.table.as_mut_ptr(), poly) };
self.eval = a_crc16m;
self
}
#[inline(always)]
pub fn gen_lsb(&mut self, poly: u16) -> &mut Self {
unsafe { a_crc16l_init(self.table.as_mut_ptr(), poly) };
self.eval = a_crc16l;
self
}
#[inline(always)]
pub fn eval(self, block: &[u8], value: u16) -> u16 {
unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
}
}
#[test]
fn crc16() {
extern crate std;
{
let ctx = crate::crc16::new_msb(0x1021);
assert_eq!(ctx.eval(b"0123456789", 0), 0x9C58);
}
{
let ctx = crate::crc16::new_lsb(0x8005);
assert_eq!(ctx.eval(b"0123456789", 0), 0x443D);
}
}
#[repr(C)]
pub struct crc32 {
pub table: [u32; 0x100],
eval: unsafe extern "C" fn(*const u32, *const u8, usize, u32) -> u32,
}
extern "C" {
fn a_crc32m_init(table: *mut u32, poly: u32);
fn a_crc32l_init(table: *mut u32, poly: u32);
fn a_crc32m(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
fn a_crc32l(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
}
impl crc32 {
#[inline(always)]
pub fn new_msb(poly: u32) -> Self {
let mut ctx: Self = Self {
table: [0; 0x100],
eval: a_crc32m,
};
unsafe { a_crc32m_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn new_lsb(poly: u32) -> Self {
let mut ctx: Self = Self {
table: [0; 0x100],
eval: a_crc32l,
};
unsafe { a_crc32l_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn gen_msb(&mut self, poly: u32) -> &mut Self {
unsafe { a_crc32m_init(self.table.as_mut_ptr(), poly) };
self.eval = a_crc32m;
self
}
#[inline(always)]
pub fn gen_lsb(&mut self, poly: u32) -> &mut Self {
unsafe { a_crc32l_init(self.table.as_mut_ptr(), poly) };
self.eval = a_crc32l;
self
}
#[inline(always)]
pub fn eval(self, block: &[u8], value: u32) -> u32 {
unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
}
}
#[test]
fn crc32() {
extern crate std;
{
let ctx = crate::crc32::new_msb(0x1EDC6F41);
assert_eq!(ctx.eval(b"0123456789", 0), 0x512B456E);
}
{
let ctx = crate::crc32::new_lsb(0x04C11DB7);
assert_eq!(ctx.eval(b"0123456789", 0), 0x450EAFB0);
}
}
#[repr(C)]
pub struct crc64 {
pub table: [u64; 0x100],
eval: unsafe extern "C" fn(*const u64, *const u8, usize, u64) -> u64,
}
extern "C" {
fn a_crc64m_init(table: *mut u64, poly: u64);
fn a_crc64l_init(table: *mut u64, poly: u64);
fn a_crc64m(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
fn a_crc64l(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
}
impl crc64 {
#[inline(always)]
pub fn new_msb(poly: u64) -> Self {
let mut ctx: Self = Self {
table: [0; 0x100],
eval: a_crc64m,
};
unsafe { a_crc64m_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn new_lsb(poly: u64) -> Self {
let mut ctx: Self = Self {
table: [0; 0x100],
eval: a_crc64l,
};
unsafe { a_crc64l_init(ctx.table.as_mut_ptr(), poly) };
ctx
}
#[inline(always)]
pub fn gen_msb(&mut self, poly: u64) -> &mut Self {
unsafe { a_crc64m_init(self.table.as_mut_ptr(), poly) };
self.eval = a_crc64m;
self
}
#[inline(always)]
pub fn gen_lsb(&mut self, poly: u64) -> &mut Self {
unsafe { a_crc64l_init(self.table.as_mut_ptr(), poly) };
self.eval = a_crc64l;
self
}
#[inline(always)]
pub fn eval(self, block: &[u8], value: u64) -> u64 {
unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
}
}
#[test]
fn crc64() {
extern crate std;
{
let ctx = crate::crc64::new_msb(0x000000000000001B);
assert_eq!(ctx.eval(b"0123456789", 0), 0xE4FFBEA588AFC790);
}
{
let ctx = crate::crc64::new_lsb(0x42F0E1EBA9EA3693);
assert_eq!(ctx.eval(b"0123456789", 0), 0xDA60676A5CDE0008);
}
}
#[allow(clippy::excessive_precision)]
const TAU: float = 6.28318530717958647692528676655900577;
#[repr(C)]
pub struct hpf {
pub alpha: float,
pub output: float,
pub input: float,
}
impl hpf {
#[inline(always)]
pub fn new(fc: float, ts: float) -> Self {
Self {
alpha: 1.0 / (TAU * fc * ts + 1.0),
output: 0.0,
input: 0.0,
}
}
#[inline(always)]
pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
self.alpha = 1.0 / (TAU * fc * ts + 1.0);
self
}
#[inline(always)]
pub fn iter(&mut self, x: float) -> float {
self.output = self.alpha * (self.output + x - self.input);
self.input = x;
self.output
}
#[inline(always)]
pub fn zero(&mut self) -> &mut Self {
self.output = 0.0;
self.input = 0.0;
self
}
}
#[test]
fn hpf() {
extern crate std;
let mut a = crate::hpf::new(10.0, 0.01);
a.gen(10.0, 0.01).zero().iter(1.0);
}
#[allow(clippy::excessive_precision)]
const _1_TAU: float = 0.159154943091895335768883763372514362;
#[repr(C)]
pub struct lpf {
pub alpha: float,
pub output: float,
}
impl lpf {
#[inline(always)]
pub fn new(fc: float, ts: float) -> Self {
Self {
alpha: ts / (_1_TAU / fc + ts),
output: 0.0,
}
}
#[inline(always)]
pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
self.alpha = ts / (_1_TAU / fc + ts);
self
}
#[inline(always)]
pub fn iter(&mut self, x: float) -> float {
self.output *= 1.0 - self.alpha;
self.output += x * self.alpha;
self.output
}
#[inline(always)]
pub fn zero(&mut self) -> &mut Self {
self.output = 0.0;
self
}
}
#[test]
fn lpf() {
extern crate std;
let mut a = crate::lpf::new(10.0, 0.01);
a.gen(10.0, 0.01).zero().iter(1.0);
}
pub mod mf {
use crate::int;
pub const NUL: int = 0;
pub const GAUSS: int = 1;
pub const GAUSS2: int = 2;
pub const GBELL: int = 3;
pub const SIG: int = 4;
pub const DSIG: int = 5;
pub const PSIG: int = 6;
pub const TRAP: int = 7;
pub const TRI: int = 8;
pub const LINS: int = 9;
pub const LINZ: int = 10;
pub const S: int = 11;
pub const Z: int = 12;
pub const PI: int = 13;
use crate::float;
extern "C" {
fn a_mf_gauss(x: float, sigma: float, c: float) -> float;
fn a_mf_gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float;
fn a_mf_gbell(x: float, a: float, b: float, c: float) -> float;
fn a_mf_sig(x: float, a: float, c: float) -> float;
fn a_mf_dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
fn a_mf_psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
fn a_mf_trap(x: float, a: float, b: float, c: float, d: float) -> float;
fn a_mf_tri(x: float, a: float, b: float, c: float) -> float;
fn a_mf_lins(x: float, a: float, b: float) -> float;
fn a_mf_linz(x: float, a: float, b: float) -> float;
fn a_mf_s(x: float, a: float, b: float) -> float;
fn a_mf_z(x: float, a: float, b: float) -> float;
fn a_mf_pi(x: float, a: float, b: float, c: float, d: float) -> float;
}
#[inline(always)]
pub fn gauss(x: float, sigma: float, c: float) -> float {
unsafe { a_mf_gauss(x, sigma, c) }
}
#[inline(always)]
pub fn gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float {
unsafe { a_mf_gauss2(x, sigma1, c1, sigma2, c2) }
}
#[inline(always)]
pub fn gbell(x: float, a: float, b: float, c: float) -> float {
unsafe { a_mf_gbell(x, a, b, c) }
}
#[inline(always)]
pub fn sig(x: float, a: float, c: float) -> float {
unsafe { a_mf_sig(x, a, c) }
}
#[inline(always)]
pub fn dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
unsafe { a_mf_dsig(x, a1, c1, a2, c2) }
}
#[inline(always)]
pub fn psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
unsafe { a_mf_psig(x, a1, c1, a2, c2) }
}
#[inline(always)]
pub fn trap(x: float, a: float, b: float, c: float, d: float) -> float {
unsafe { a_mf_trap(x, a, b, c, d) }
}
#[inline(always)]
pub fn tri(x: float, a: float, b: float, c: float) -> float {
unsafe { a_mf_tri(x, a, b, c) }
}
#[inline(always)]
pub fn lins(x: float, a: float, b: float) -> float {
unsafe { a_mf_lins(x, a, b) }
}
#[inline(always)]
pub fn linz(x: float, a: float, b: float) -> float {
unsafe { a_mf_linz(x, a, b) }
}
#[inline(always)]
pub fn s(x: float, a: float, b: float) -> float {
unsafe { a_mf_s(x, a, b) }
}
#[inline(always)]
pub fn z(x: float, a: float, b: float) -> float {
unsafe { a_mf_z(x, a, b) }
}
#[inline(always)]
pub fn pi(x: float, a: float, b: float, c: float, d: float) -> float {
unsafe { a_mf_pi(x, a, b, c, d) }
}
#[cfg(test)]
mod test {
extern crate std;
#[test]
fn gauss2() {
for i in -4..=4 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::gauss2(x, 1.0, -1.0, 1.0, 1.0));
}
}
#[test]
fn gbell() {
for i in -4..=4 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::gbell(x, 2.0, 4.0, 0.0));
}
}
#[test]
fn sig() {
for i in -4..=4 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::sig(x, 2.0, 0.0));
}
}
#[test]
fn dsig() {
for i in -4..=4 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::dsig(x, 5.0, -2.0, 5.0, 2.0));
}
}
#[test]
fn psig() {
for i in -4..=4 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::psig(x, 5.0, -2.0, -5.0, 2.0));
}
}
#[test]
fn trap() {
for i in -3..=3 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::trap(x, -2.0, -1.0, 1.0, 2.0));
}
}
#[test]
fn tri() {
for i in -2..=2 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::tri(x, -1.0, 0.0, 1.0));
}
}
#[test]
fn lins() {
for i in -2..=2 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::lins(x, -1.0, 1.0));
}
}
#[test]
fn linz() {
for i in -2..=2 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::linz(x, -1.0, 1.0));
}
}
#[test]
fn s() {
for i in -2..=2 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::s(x, -1.0, 1.0));
}
}
#[test]
fn z() {
for i in -2..=2 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::z(x, -1.0, 1.0));
}
}
#[test]
fn pi() {
for i in -3..=3 {
let x = i as crate::float;
std::println!("{:+} {}", x, crate::mf::pi(x, -2.0, -1.0, 1.0, 2.0));
}
}
}
}
#[repr(C)]
pub struct pid {
pub kp: float,
pub ki: float,
pub kd: float,
pub summax: float,
pub summin: float,
pub sum: float,
pub outmax: float,
pub outmin: float,
pub out: float,
pub fdb: float,
pub(crate) var: float,
pub err: float,
}
impl Default for pid {
#[inline(always)]
fn default() -> Self {
Self {
kp: 0.0,
ki: 0.0,
kd: 0.0,
summax: float::INFINITY,
summin: -float::INFINITY,
sum: 0.0,
outmax: float::INFINITY,
outmin: -float::INFINITY,
out: 0.0,
fdb: 0.0,
var: 0.0,
err: 0.0,
}
}
}
extern "C" {
fn a_pid_kpid(ctx: *mut pid, kp: float, ki: float, kd: float);
fn a_pid_run(ctx: *mut pid, set: float, fdb: float) -> float;
fn a_pid_pos(ctx: *mut pid, set: float, fdb: float) -> float;
fn a_pid_inc(ctx: *mut pid, set: float, fdb: float) -> float;
fn a_pid_zero(ctx: *mut pid);
}
impl pid {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
#[inline(always)]
pub fn kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
unsafe { a_pid_kpid(self, kp, ki, kd) };
self
}
#[inline(always)]
pub fn run(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_run(self, set, fdb) }
}
#[inline(always)]
pub fn pos(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_pos(self, set, fdb) }
}
#[inline(always)]
pub fn inc(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_inc(self, set, fdb) }
}
#[inline(always)]
pub fn zero(&mut self) -> &mut Self {
unsafe { a_pid_zero(self) };
self
}
}
#[test]
fn pid() {
extern crate std;
let mut a = crate::pid::new();
a.kpid(10.0, 0.1, 1.0);
std::println!("{}", a.zero().pos(1.0, 0.0));
std::println!("{}", a.zero().inc(1.0, 0.0));
}
pub mod fuzzy {
use crate::uint;
pub const CAP: uint = 1;
pub const CAP_ALGEBRA: uint = 2;
pub const CAP_BOUNDED: uint = 3;
pub const CUP: uint = 4;
pub const CUP_ALGEBRA: uint = 5;
pub const CUP_BOUNDED: uint = 6;
pub const EQU: uint = 0;
}
#[macro_export]
macro_rules! PID_FUZZY_JOINT {
($n:expr) => {{
core::mem::size_of::<uint>() * $n * 2 + core::mem::size_of::<float>() * $n * (2 + $n)
}};
}
#[repr(C)]
pub struct pid_fuzzy {
pub pid: pid,
pub(crate) me: *const float,
pub(crate) mec: *const float,
pub(crate) mkp: *const float,
pub(crate) mki: *const float,
pub(crate) mkd: *const float,
pub(crate) idx: *mut uint,
pub(crate) val: *mut float,
pub(crate) op: extern "C" fn(float, float) -> float,
pub kp: float,
pub ki: float,
pub kd: float,
pub(crate) order: uint,
pub(crate) joint: uint,
}
impl Default for pid_fuzzy {
#[inline(always)]
fn default() -> Self {
Self {
pid: pid::default(),
me: core::ptr::null(),
mec: core::ptr::null(),
mkp: core::ptr::null(),
mki: core::ptr::null(),
mkd: core::ptr::null(),
idx: core::ptr::null_mut(),
val: core::ptr::null_mut(),
op: unsafe { a_pid_fuzzy_op(fuzzy::EQU) },
kp: 0.0,
ki: 0.0,
kd: 0.0,
order: 0,
joint: 0,
}
}
}
extern "C" {
fn a_pid_fuzzy_op(op: uint) -> extern "C" fn(float, float) -> float;
fn a_pid_fuzzy_set_op(ctx: *mut pid_fuzzy, op: uint);
fn a_pid_fuzzy_rule(
ctx: *mut pid_fuzzy,
num: uint,
me: *const float,
mec: *const float,
mkp: *const float,
mki: *const float,
mkd: *const float,
);
fn a_pid_fuzzy_joint(ctx: *mut pid_fuzzy) -> *mut u8;
fn a_pid_fuzzy_set_joint(ctx: *mut pid_fuzzy, ptr: *mut u8, num: usize);
fn a_pid_fuzzy_kpid(ctx: *mut pid_fuzzy, kp: float, ki: float, kd: float);
fn a_pid_fuzzy_run(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
fn a_pid_fuzzy_pos(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
fn a_pid_fuzzy_inc(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
fn a_pid_fuzzy_zero(ctx: *mut pid_fuzzy);
}
impl pid_fuzzy {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
#[inline(always)]
pub fn rule(
&mut self,
col: usize,
me: &[float],
mec: &[float],
mkp: &[float],
mki: &[float],
mkd: &[float],
) -> &mut Self {
unsafe {
a_pid_fuzzy_rule(
self,
col as uint,
me.as_ptr(),
mec.as_ptr(),
mkp.as_ptr(),
mki.as_ptr(),
mkd.as_ptr(),
)
};
self
}
#[inline(always)]
pub fn kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
unsafe { a_pid_fuzzy_kpid(self, kp, ki, kd) };
self
}
#[inline(always)]
pub fn set_joint(&mut self, ptr: &mut [u8], num: usize) -> &mut Self {
unsafe { a_pid_fuzzy_set_joint(self, ptr.as_mut_ptr(), num) };
self
}
#[inline(always)]
pub fn joint(&mut self) -> &mut [u8] {
unsafe {
core::slice::from_raw_parts_mut(
a_pid_fuzzy_joint(self),
PID_FUZZY_JOINT!(self.joint as usize),
)
}
}
#[inline(always)]
pub fn op(&mut self, op: uint) -> &mut Self {
unsafe { a_pid_fuzzy_set_op(self, op) };
self
}
#[inline(always)]
pub fn run(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_fuzzy_run(self, set, fdb) }
}
#[inline(always)]
pub fn pos(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_fuzzy_pos(self, set, fdb) }
}
#[inline(always)]
pub fn inc(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_fuzzy_inc(self, set, fdb) }
}
#[inline(always)]
pub fn zero(&mut self) -> &mut Self {
unsafe { a_pid_fuzzy_zero(self) };
self
}
}
#[test]
#[allow(non_snake_case)]
fn pid_fuzzy() {
extern crate std;
let NL: float = -3.0;
let NM: float = -2.0;
let NS: float = -1.0;
let ZO: float = 0.0;
let PS: float = 1.0;
let PM: float = 2.0;
let PL: float = 3.0;
let me = [
[crate::mf::TRI as float, NL, NL, NM],
[crate::mf::TRI as float, NL, NM, NS],
[crate::mf::TRI as float, NM, NS, ZO],
[crate::mf::TRI as float, NS, ZO, PS],
[crate::mf::TRI as float, ZO, PS, PM],
[crate::mf::TRI as float, PS, PM, PL],
[crate::mf::TRI as float, PM, PL, PL],
];
let NL: float = -3.0;
let NM: float = -2.0;
let NS: float = -1.0;
let ZO: float = 0.0;
let PS: float = 1.0;
let PM: float = 2.0;
let PL: float = 3.0;
let mec = [
[crate::mf::TRI as float, NL, NL, NM],
[crate::mf::TRI as float, NL, NM, NS],
[crate::mf::TRI as float, NM, NS, ZO],
[crate::mf::TRI as float, NS, ZO, PS],
[crate::mf::TRI as float, ZO, PS, PM],
[crate::mf::TRI as float, PS, PM, PL],
[crate::mf::TRI as float, PM, PL, PL],
];
let NL: float = -15.0;
let NM: float = -10.0;
let NS: float = -5.0;
let ZO: float = 0.0;
let PS: float = 5.0;
let PM: float = 10.0;
let PL: float = 15.0;
let mkp = [
[NL, NL, NM, NM, NS, ZO, ZO],
[NL, NL, NM, NS, NS, ZO, PS],
[NM, NM, NM, NS, ZO, PS, PS],
[NM, NM, NS, ZO, PS, PM, PM],
[NS, NS, ZO, PS, PS, PM, PM],
[NS, ZO, PS, PM, PM, PM, PL],
[ZO, ZO, PM, PM, PM, PL, PL],
];
let NL: float = -3.0;
let NM: float = -2.0;
let NS: float = -1.0;
let ZO: float = 0.0;
let PS: float = 1.0;
let PM: float = 2.0;
let PL: float = 3.0;
let mki = [
[PL, PL, PM, PM, PS, ZO, ZO],
[PL, PL, PM, PS, PS, ZO, ZO],
[PL, PM, PS, PS, ZO, NS, NS],
[PM, PM, PS, ZO, NS, NM, NM],
[PM, PS, ZO, NS, NS, NM, NL],
[ZO, ZO, NS, NS, NM, NL, NL],
[ZO, ZO, NS, NM, NM, NL, NL],
];
let mkd = [
[NS, PS, PL, PL, PL, PM, NS],
[NS, PS, PL, PM, PM, PS, ZO],
[ZO, PS, PM, PM, PS, PS, ZO],
[ZO, PS, PS, PS, PS, PS, ZO],
[ZO, ZO, ZO, ZO, ZO, ZO, ZO],
[NL, NS, NS, NS, NS, NS, NL],
[NL, NM, NM, NM, NS, NS, NL],
];
let mut joint = [0u8; crate::PID_FUZZY_JOINT!(2)];
let mut a = pid_fuzzy::new();
a.rule(
me.len(),
&me.concat(),
&mec.concat(),
&mkp.concat(),
&mki.concat(),
&mkd.concat(),
)
.kpid(10.0, 0.1, 1.0)
.set_joint(&mut joint, 2);
a.op(crate::fuzzy::EQU).zero();
std::println!("{} {}", a.pos(1.0, 0.0), a.pos(1.0, 0.0));
a.op(crate::fuzzy::EQU).zero();
std::println!("{} {}", a.inc(1.0, 0.0), a.inc(1.0, 0.0));
}
#[repr(C)]
pub struct pid_neuro {
pub pid: pid,
pub k: float,
pub wp: float,
pub wi: float,
pub wd: float,
pub ec: float,
}
impl Default for pid_neuro {
#[inline(always)]
fn default() -> Self {
Self {
pid: pid::default(),
k: 0.0,
wp: 0.0,
wi: 0.0,
wd: 0.0,
ec: 0.0,
}
}
}
extern "C" {
fn a_pid_neuro_kpid(ctx: *mut pid_neuro, k: float, kp: float, ki: float, kd: float);
fn a_pid_neuro_wpid(ctx: *mut pid_neuro, wp: float, wi: float, wd: float);
fn a_pid_neuro_run(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
fn a_pid_neuro_inc(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
fn a_pid_neuro_zero(ctx: *mut pid_neuro);
}
impl pid_neuro {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
#[inline(always)]
pub fn kpid(&mut self, k: float, kp: float, ki: float, kd: float) -> &mut Self {
unsafe { a_pid_neuro_kpid(self, k, kp, ki, kd) };
self
}
#[inline(always)]
pub fn wpid(&mut self, wp: float, wi: float, wd: float) -> &mut Self {
unsafe { a_pid_neuro_wpid(self, wp, wi, wd) };
self
}
#[inline(always)]
pub fn run(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_neuro_run(self, set, fdb) }
}
#[inline(always)]
pub fn inc(&mut self, set: float, fdb: float) -> float {
unsafe { a_pid_neuro_inc(self, set, fdb) }
}
#[inline(always)]
pub fn zero(&mut self) -> &mut Self {
unsafe { a_pid_neuro_zero(self) };
self
}
}
#[test]
fn pid_neuro() {
extern crate std;
let mut a = crate::pid_neuro::new();
a.kpid(10.0, 1.0, 0.1, 1.0).wpid(1.0, 0.0, 0.0);
std::println!("{}", a.inc(1.0, 0.0));
a.zero();
}
#[repr(C)]
pub struct tf {
input: *mut float,
output: *mut float,
num_p: *const float,
den_p: *const float,
num_n: uint,
den_n: uint,
}
extern "C" {
fn a_tf_set_num(ctx: *mut tf, num_n: uint, num_p: *const float, input: *mut float);
fn a_tf_set_den(ctx: *mut tf, den_n: uint, den_p: *const float, output: *mut float);
fn a_tf_init(
ctx: *mut tf,
num_n: uint,
num_p: *const float,
input: *mut float,
den_n: uint,
den_p: *const float,
output: *mut float,
);
fn a_tf_iter(ctx: *const tf, x: float) -> float;
fn a_tf_zero(ctx: *const tf);
}
impl tf {
#[inline(always)]
pub fn new(num: &[float], input: &mut [float], den: &[float], output: &mut [float]) -> Self {
let mut ctx: Self = Self {
input: core::ptr::null_mut(),
output: core::ptr::null_mut(),
num_p: core::ptr::null(),
den_p: core::ptr::null(),
num_n: 0,
den_n: 0,
};
unsafe {
a_tf_init(
&mut ctx,
num.len() as uint,
num.as_ptr(),
input.as_mut_ptr(),
den.len() as uint,
den.as_ptr(),
output.as_mut_ptr(),
)
};
ctx
}
#[inline(always)]
pub fn iter(&mut self, x: float) -> float {
unsafe { a_tf_iter(self, x) }
}
#[inline(always)]
pub fn zero(&mut self) -> &mut Self {
unsafe { a_tf_zero(self) };
self
}
#[inline(always)]
pub fn input(&self) -> &[float] {
unsafe { core::slice::from_raw_parts(self.input, self.num_n as usize) }
}
#[inline(always)]
pub fn num(&self) -> &[float] {
unsafe { core::slice::from_raw_parts(self.num_p, self.num_n as usize) }
}
#[inline(always)]
pub fn set_num(&mut self, num: &[float], input: &mut [float]) -> &mut Self {
unsafe { a_tf_set_num(self, num.len() as uint, num.as_ptr(), input.as_mut_ptr()) };
self
}
#[inline(always)]
pub fn output(&self) -> &[float] {
unsafe { core::slice::from_raw_parts(self.output, self.den_n as usize) }
}
#[inline(always)]
pub fn den(&self) -> &[float] {
unsafe { core::slice::from_raw_parts(self.den_p, self.den_n as usize) }
}
#[inline(always)]
pub fn set_den(&mut self, den: &[float], output: &mut [float]) -> &mut Self {
unsafe { a_tf_set_den(self, den.len() as uint, den.as_ptr(), output.as_mut_ptr()) };
self
}
}
#[test]
fn tf() {
extern crate std;
let num = [6.59492796e-05, 6.54019884e-05];
let den = [-1.97530991, 0.97530991];
let mut input = [0.0; 2];
let mut output = [0.0; 2];
let mut a = crate::tf::new(&num, &mut input, &den, &mut output);
a.set_num(&num, &mut input).set_den(&den, &mut output);
std::println!("{} {}", a.iter(10.0), a.iter(10.0));
std::println!("{:?} {:?}", a.num(), a.input());
std::println!("{:?} {:?}", a.den(), a.output());
a.zero();
}
#[repr(C)]
pub struct trajbell {
pub t: float,
pub tv: float,
pub ta: float,
pub td: float,
pub taj: float,
pub tdj: float,
pub q0: float,
pub q1: float,
pub v0: float,
pub v1: float,
pub vm: float,
pub jm: float,
pub am: float,
pub dm: float,
}
impl Default for trajbell {
#[inline(always)]
fn default() -> Self {
Self {
t: 0.0,
tv: 0.0,
ta: 0.0,
td: 0.0,
taj: 0.0,
tdj: 0.0,
q0: 0.0,
q1: 0.0,
v0: 0.0,
v1: 0.0,
vm: 0.0,
jm: 0.0,
am: 0.0,
dm: 0.0,
}
}
}
extern "C" {
fn a_trajbell_gen(
ctx: *mut trajbell,
jm: float,
am: float,
vm: float,
q0: float,
q1: float,
v0: float,
v1: float,
) -> float;
fn a_trajbell_pos(ctx: *const trajbell, dt: float) -> float;
fn a_trajbell_vel(ctx: *const trajbell, dt: float) -> float;
fn a_trajbell_acc(ctx: *const trajbell, dt: float) -> float;
fn a_trajbell_jer(ctx: *const trajbell, dt: float) -> float;
}
impl trajbell {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
#[allow(clippy::too_many_arguments)]
#[inline(always)]
pub fn gen(
&mut self,
jm: float,
am: float,
vm: float,
q0: float,
q1: float,
v0: float,
v1: float,
) -> float {
unsafe { a_trajbell_gen(self, jm, am, vm, q0, q1, v0, v1) }
}
#[inline(always)]
pub fn pos(&mut self, dt: float) -> float {
unsafe { a_trajbell_pos(self, dt) }
}
#[inline(always)]
pub fn vel(&mut self, dt: float) -> float {
unsafe { a_trajbell_vel(self, dt) }
}
#[inline(always)]
pub fn acc(&mut self, dt: float) -> float {
unsafe { a_trajbell_acc(self, dt) }
}
#[inline(always)]
pub fn jer(&mut self, dt: float) -> float {
unsafe { a_trajbell_jer(self, dt) }
}
}
#[test]
fn trajbell() {
extern crate std;
let dt = 0.5;
{
let mut a = crate::trajbell::new();
std::print!("{} ", a.gen(3.0, 2.0, 3.0, 0.0, 10.0, 0.0, 0.0));
std::println!(
"[{}, {}, {}, {}]",
a.pos(dt),
a.vel(dt),
a.acc(dt),
a.jer(dt)
);
}
}
#[repr(C)]
pub struct trajpoly3 {
pub q: [float; 4],
pub v: [float; 3],
pub a: [float; 2],
}
extern "C" {
fn a_trajpoly3_gen(ctx: *mut trajpoly3, ts: float, q0: float, q1: float, v0: float, v1: float);
fn a_trajpoly3_pos(ctx: *const trajpoly3, dt: float) -> float;
fn a_trajpoly3_vel(ctx: *const trajpoly3, dt: float) -> float;
fn a_trajpoly3_acc(ctx: *const trajpoly3, dt: float) -> float;
}
impl trajpoly3 {
#[inline(always)]
pub fn new(ts: float, q0: float, q1: float, v0: float, v1: float) -> Self {
let mut ctx: Self = Self {
q: [0.0; 4],
v: [0.0; 3],
a: [0.0; 2],
};
unsafe { a_trajpoly3_gen(&mut ctx, ts, q0, q1, v0, v1) };
ctx
}
#[inline(always)]
pub fn gen(&mut self, ts: float, q0: float, q1: float, v0: float, v1: float) -> &mut Self {
unsafe { a_trajpoly3_gen(self, ts, q0, q1, v0, v1) };
self
}
#[inline(always)]
pub fn pos(&mut self, dt: float) -> float {
unsafe { a_trajpoly3_pos(self, dt) }
}
#[inline(always)]
pub fn vel(&mut self, dt: float) -> float {
unsafe { a_trajpoly3_vel(self, dt) }
}
#[inline(always)]
pub fn acc(&mut self, dt: float) -> float {
unsafe { a_trajpoly3_acc(self, dt) }
}
}
#[test]
fn trajpoly3() {
extern crate std;
let dt = 0.5;
{
let mut a = crate::trajpoly3::new(1.0, 0.0, 1.0, 0.0, 1.0);
std::println!("[{}, {}, {}]", a.pos(dt), a.vel(dt), a.acc(dt));
}
}
#[repr(C)]
pub struct trajpoly5 {
pub q: [float; 6],
pub v: [float; 5],
pub a: [float; 4],
}
extern "C" {
fn a_trajpoly5_gen(
ctx: *mut trajpoly5,
ts: float,
q0: float,
q1: float,
v0: float,
v1: float,
a0: float,
a1: float,
);
fn a_trajpoly5_pos(ctx: *const trajpoly5, dt: float) -> float;
fn a_trajpoly5_vel(ctx: *const trajpoly5, dt: float) -> float;
fn a_trajpoly5_acc(ctx: *const trajpoly5, dt: float) -> float;
}
impl trajpoly5 {
#[allow(clippy::too_many_arguments)]
#[inline(always)]
pub fn new(
ts: float,
q0: float,
q1: float,
v0: float,
v1: float,
a0: float,
a1: float,
) -> Self {
let mut ctx: Self = Self {
q: [0.0; 6],
v: [0.0; 5],
a: [0.0; 4],
};
unsafe { a_trajpoly5_gen(&mut ctx, ts, q0, q1, v0, v1, a0, a1) };
ctx
}
#[allow(clippy::too_many_arguments)]
#[inline(always)]
pub fn gen(
&mut self,
ts: float,
q0: float,
q1: float,
v0: float,
v1: float,
a0: float,
a1: float,
) -> &mut Self {
unsafe { a_trajpoly5_gen(self, ts, q0, q1, v0, v1, a0, a1) };
self
}
#[inline(always)]
pub fn pos(&mut self, dt: float) -> float {
unsafe { a_trajpoly5_pos(self, dt) }
}
#[inline(always)]
pub fn vel(&mut self, dt: float) -> float {
unsafe { a_trajpoly5_vel(self, dt) }
}
#[inline(always)]
pub fn acc(&mut self, dt: float) -> float {
unsafe { a_trajpoly5_acc(self, dt) }
}
}
#[test]
fn trajpoly5() {
extern crate std;
let dt = 0.5;
{
let mut a = crate::trajpoly5::new(1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
std::println!("[{}, {}, {}]", a.pos(dt), a.vel(dt), a.acc(dt));
}
}
#[repr(C)]
pub struct trajpoly7 {
pub q: [float; 8],
pub v: [float; 7],
pub a: [float; 6],
pub j: [float; 5],
}
extern "C" {
fn a_trajpoly7_gen(
ctx: *mut trajpoly7,
ts: float,
q0: float,
q1: float,
v0: float,
v1: float,
a0: float,
a1: float,
j0: float,
j1: float,
);
fn a_trajpoly7_pos(ctx: *const trajpoly7, dt: float) -> float;
fn a_trajpoly7_vel(ctx: *const trajpoly7, dt: float) -> float;
fn a_trajpoly7_acc(ctx: *const trajpoly7, dt: float) -> float;
fn a_trajpoly7_jer(ctx: *const trajpoly7, dt: float) -> float;
}
impl trajpoly7 {
#[allow(clippy::too_many_arguments)]
#[inline(always)]
pub fn new(
ts: float,
q0: float,
q1: float,
v0: float,
v1: float,
a0: float,
a1: float,
j0: float,
j1: float,
) -> Self {
let mut ctx: Self = Self {
q: [0.0; 8],
v: [0.0; 7],
a: [0.0; 6],
j: [0.0; 5],
};
unsafe { a_trajpoly7_gen(&mut ctx, ts, q0, q1, v0, v1, a0, a1, j0, j1) };
ctx
}
#[allow(clippy::too_many_arguments)]
#[inline(always)]
pub fn gen(
&mut self,
ts: float,
q0: float,
q1: float,
v0: float,
v1: float,
a0: float,
a1: float,
j0: float,
j1: float,
) -> &mut Self {
unsafe { a_trajpoly7_gen(self, ts, q0, q1, v0, v1, a0, a1, j0, j1) };
self
}
#[inline(always)]
pub fn pos(&mut self, dt: float) -> float {
unsafe { a_trajpoly7_pos(self, dt) }
}
#[inline(always)]
pub fn vel(&mut self, dt: float) -> float {
unsafe { a_trajpoly7_vel(self, dt) }
}
#[inline(always)]
pub fn acc(&mut self, dt: float) -> float {
unsafe { a_trajpoly7_acc(self, dt) }
}
#[inline(always)]
pub fn jer(&mut self, dt: float) -> float {
unsafe { a_trajpoly7_jer(self, dt) }
}
}
#[test]
fn trajpoly7() {
extern crate std;
let dt = 0.5;
{
let mut a = crate::trajpoly7::new(1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
std::println!(
"[{}, {}, {}, {}]",
a.pos(dt),
a.vel(dt),
a.acc(dt),
a.jer(dt)
);
}
}
#[repr(C)]
pub struct trajtrap {
pub t: float,
pub q0: float,
pub q1: float,
pub v0: float,
pub v1: float,
pub vc: float,
pub ta: float,
pub td: float,
pub qa: float,
pub qd: float,
pub ac: float,
pub de: float,
}
impl Default for trajtrap {
#[inline(always)]
fn default() -> Self {
Self {
t: 0.0,
q0: 0.0,
q1: 0.0,
v0: 0.0,
v1: 0.0,
vc: 0.0,
ta: 0.0,
td: 0.0,
qa: 0.0,
qd: 0.0,
ac: 0.0,
de: 0.0,
}
}
}
extern "C" {
fn a_trajtrap_gen(
ctx: *mut trajtrap,
vm: float,
ac: float,
de: float,
q0: float,
q1: float,
v0: float,
v1: float,
) -> float;
fn a_trajtrap_pos(ctx: *const trajtrap, dt: float) -> float;
fn a_trajtrap_vel(ctx: *const trajtrap, dt: float) -> float;
fn a_trajtrap_acc(ctx: *const trajtrap, dt: float) -> float;
}
impl trajtrap {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
#[allow(clippy::too_many_arguments)]
#[inline(always)]
pub fn gen(
&mut self,
vm: float,
ac: float,
de: float,
q0: float,
q1: float,
v0: float,
v1: float,
) -> float {
unsafe { a_trajtrap_gen(self, vm, ac, de, q0, q1, v0, v1) }
}
#[inline(always)]
pub fn pos(&mut self, dt: float) -> float {
unsafe { a_trajtrap_pos(self, dt) }
}
#[inline(always)]
pub fn vel(&mut self, dt: float) -> float {
unsafe { a_trajtrap_vel(self, dt) }
}
#[inline(always)]
pub fn acc(&mut self, dt: float) -> float {
unsafe { a_trajtrap_acc(self, dt) }
}
}
#[test]
fn trajtrap() {
extern crate std;
let dt = 0.5;
{
let mut a = crate::trajtrap::new();
std::print!("{} ", a.gen(2.0, 2.0, -2.0, 0.0, 2.0, 0.0, 0.0));
std::println!("[{}, {}, {}]", a.pos(dt), a.vel(dt), a.acc(dt));
}
}
#[repr(C)]
pub struct version {
pub major: uint,
pub minor: uint,
pub third: uint,
pub extra: uint,
}
extern "C" {
static a_version_major: uint;
static a_version_minor: uint;
static a_version_patch: uint;
static a_version_tweak: u32;
fn a_version_check(major: uint, minor: uint, patch: uint) -> int;
fn a_version_cmp(lhs: *const version, rhs: *const version) -> int;
fn a_version_lt(lhs: *const version, rhs: *const version) -> bool;
fn a_version_gt(lhs: *const version, rhs: *const version) -> bool;
fn a_version_le(lhs: *const version, rhs: *const version) -> bool;
fn a_version_ge(lhs: *const version, rhs: *const version) -> bool;
fn a_version_eq(lhs: *const version, rhs: *const version) -> bool;
}
impl version {
#[inline(always)]
pub fn new(major: uint, minor: uint, third: uint) -> Self {
Self {
major,
minor,
third,
extra: 0,
}
}
#[inline(always)]
pub fn check(major: uint, minor: uint, patch: uint) -> int {
unsafe { a_version_check(major, minor, patch) }
}
#[inline(always)]
pub fn major() -> uint {
unsafe { a_version_major }
}
#[inline(always)]
pub fn minor() -> uint {
unsafe { a_version_minor }
}
#[inline(always)]
pub fn patch() -> uint {
unsafe { a_version_patch }
}
#[inline(always)]
pub fn tweak() -> u32 {
unsafe { a_version_tweak }
}
}
impl PartialOrd for version {
#[inline(always)]
fn partial_cmp(&self, other: &version) -> Option<core::cmp::Ordering> {
let ok: int = unsafe { a_version_cmp(self, other) };
if ok > 0 {
return Some(core::cmp::Ordering::Greater);
}
if ok < 0 {
return Some(core::cmp::Ordering::Less);
}
Some(core::cmp::Ordering::Equal)
}
#[inline(always)]
fn lt(&self, other: &version) -> bool {
unsafe { a_version_lt(self, other) }
}
#[inline(always)]
fn gt(&self, other: &version) -> bool {
unsafe { a_version_gt(self, other) }
}
#[inline(always)]
fn le(&self, other: &version) -> bool {
unsafe { a_version_le(self, other) }
}
#[inline(always)]
fn ge(&self, other: &version) -> bool {
unsafe { a_version_ge(self, other) }
}
}
impl PartialEq for version {
#[inline(always)]
fn eq(&self, other: &version) -> bool {
unsafe { a_version_eq(self, other) }
}
}
#[test]
fn version() {
extern crate std;
impl core::fmt::Debug for version {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("version")
.field("major", &self.major)
.field("minor", &self.minor)
.field("third", &self.third)
.field("extra", &self.extra)
.finish()
}
}
std::println!("{}", crate::version::check(0, 0, 0));
std::println!("major {}", crate::version::major());
std::println!("minor {}", crate::version::minor());
std::println!("patch {}", crate::version::patch());
std::println!("tweak {}", crate::version::tweak());
let v000 = version::new(0, 0, 0);
let v001 = version::new(0, 0, 1);
std::println!("{:?}", v001);
assert!(v001 > v000);
assert!(v000 < v001);
assert!(v000 >= v000);
assert!(v000 <= v000);
assert!(v000 == v000);
assert!(v000 != v001);
}