use autocxx::WithinUniquePtr;
use uom::si::angle::{degree, revolution};
use uom::si::electric_potential::volt;
use uom::si::f64::{
Acceleration, Angle, AngularAcceleration, AngularVelocity, ElectricPotential,
ThermodynamicTemperature,
};
use crate::ffi;
use crate::prelude::*;
use prelude::*;
pub mod configuration;
pub mod enums;
pub mod prelude;
pub type KrakenX60 = TalonFX;
pub type KrakenX44 = TalonFX;
pub type Falcon500 = TalonFX;
use std::ffi::CStr;
pub struct StatusCode {
status: cxx::UniquePtr<ffi::StatusCode>,
}
impl StatusCode {
pub(crate) fn new(status: cxx::UniquePtr<ffi::StatusCode>) -> Self {
Self { status }
}
pub fn is_error(&mut self) -> bool {
self.status.pin_mut().IsError()
}
pub fn is_warning(&mut self) -> bool {
self.status.pin_mut().IsWarning()
}
pub fn is_ok(&mut self) -> bool {
self.status.pin_mut().IsOK()
}
pub fn get_name(&mut self) -> &'static str {
let name = self.status.pin_mut().GetName();
let name = unsafe { CStr::from_ptr(name) };
name.to_str().unwrap()
}
pub fn get_description(&mut self) -> &'static str {
let name = self.status.pin_mut().GetDescription();
let name = unsafe { CStr::from_ptr(name) };
name.to_str().unwrap()
}
pub fn result(mut self) -> Result<(), StatusCode> {
if self.is_error() { Err(self) } else { Ok(()) }
}
pub fn result_with<T>(mut self, with: T) -> Result<T, StatusCode> {
if self.is_error() { Err(self) } else { Ok(with) }
}
}
pub struct TalonFX {
motor: cxx::UniquePtr<ffi::talon::TalonFX>,
}
impl TalonFX {
pub fn new(can: i32, bus: &str) -> Self {
let motor = ffi::talon::TalonFX::new3(autocxx::c_int(can), bus).within_unique_ptr();
Self { motor }
}
pub fn configurator(&'_ mut self) -> TalonFXConfigurator<'_> {
TalonFXConfigurator::new(ffi::talon::get_configurator(self.motor.pin_mut()))
}
pub fn set(&mut self, speed: f64) {
ffi::talon::set(self.motor.pin_mut(), speed);
}
pub fn set_voltage(&mut self, voltage: ElectricPotential) {
ffi::talon::set_voltage(self.motor.pin_mut(), voltage.get::<volt>());
}
pub fn set_position(&mut self, position: Angle) -> StatusCode {
StatusCode::new(
ffi::talon::set_position(self.motor.pin_mut(), position.get::<revolution>())
.within_unique_ptr(),
)
}
pub fn get_duty_cycle(&mut self) -> f64 {
ffi::talon::get_duty_cycle(self.motor.pin_mut())
}
pub fn get_position(&mut self) -> Angle {
ffi::talon::get_position(self.motor.pin_mut()).rotations()
}
pub fn get_velocity(&mut self) -> AngularVelocity {
ffi::talon::get_velocity(self.motor.pin_mut()).rotations_per_second()
}
pub fn get_acceleration(&mut self) -> AngularAcceleration {
ffi::talon::get_acceleration(self.motor.pin_mut()).rotations_per_second_squared()
}
pub fn coast(&mut self) {
ffi::talon::coast(self.motor.pin_mut())
}
pub fn neutral(&mut self) {
ffi::talon::neutral(self.motor.pin_mut())
}
}
pub struct CANCoder {
coder: cxx::UniquePtr<ffi::cancoder::CANcoder>,
}
impl CANCoder {
pub fn new(id: i32, bus: &str) -> Self {
Self {
coder: ffi::cancoder::CANcoder::new3(autocxx::c_int(id), bus).within_unique_ptr(),
}
}
pub fn configurator(&'_ mut self) -> CANCoderConfigurator<'_> {
CANCoderConfigurator::new(ffi::cancoder::get_configurator(self.coder.pin_mut()))
}
pub fn get_position(&mut self, refresh: bool) -> Angle {
ffi::cancoder::get_position(self.coder.pin_mut(), refresh).rotations()
}
pub fn get_absolute_position(&mut self, refresh: bool) -> Angle {
ffi::cancoder::get_absolute_position(self.coder.pin_mut(), refresh).rotations()
}
pub fn get_position_since_boot(&mut self, refresh: bool) -> Angle {
ffi::cancoder::get_position_since_boot(self.coder.pin_mut(), refresh).rotations()
}
pub fn get_velocity(&mut self, refresh: bool) -> AngularVelocity {
ffi::cancoder::get_velocity(self.coder.pin_mut(), refresh).rotations_per_second()
}
pub fn get_unfiltered_velocity(&mut self, refresh: bool) -> AngularVelocity {
ffi::cancoder::get_unfiltered_velocity(self.coder.pin_mut(), refresh).rotations_per_second()
}
pub fn get_supply_voltage(&mut self, refresh: bool) -> ElectricPotential {
ffi::cancoder::get_velocity(self.coder.pin_mut(), refresh).volts()
}
pub fn set_position(&mut self, angle: Angle) -> StatusCode {
StatusCode::new(
ffi::cancoder::set_position(self.coder.pin_mut(), angle.get::<revolution>())
.within_unique_ptr(),
)
}
}
pub struct Pigeon2 {
gyro: cxx::UniquePtr<ffi::pigeon2::Pigeon2>,
}
impl Pigeon2 {
pub fn new(id: i32, bus: &str) -> Self {
Self {
gyro: ffi::pigeon2::Pigeon2::new3(autocxx::c_int(id), bus).within_unique_ptr(),
}
}
pub fn configurator(&'_ mut self) -> Pigeon2Configurator<'_> {
Pigeon2Configurator::new(ffi::pigeon2::get_configurator(self.gyro.pin_mut()))
}
pub fn get_yaw(&mut self) -> Angle {
ffi::pigeon2::get_yaw(self.gyro.pin_mut()).degrees()
}
pub fn get_pitch(&mut self) -> Angle {
ffi::pigeon2::get_pitch(self.gyro.pin_mut()).degrees()
}
pub fn get_roll(&mut self) -> Angle {
ffi::pigeon2::get_roll(self.gyro.pin_mut()).degrees()
}
pub fn get_temperature(&mut self) -> ThermodynamicTemperature {
ffi::pigeon2::get_temperature(self.gyro.pin_mut()).celsius()
}
pub fn get_acceleration_x(&mut self) -> Acceleration {
ffi::pigeon2::get_acceleration_x(self.gyro.pin_mut()).meters_per_second_squared()
}
pub fn get_acceleration_y(&mut self) -> Acceleration {
ffi::pigeon2::get_acceleration_y(self.gyro.pin_mut()).meters_per_second_squared()
}
pub fn get_acceleration_z(&mut self) -> Acceleration {
ffi::pigeon2::get_acceleration_z(self.gyro.pin_mut()).meters_per_second_squared()
}
pub fn get_supply_voltage(&mut self) -> ElectricPotential {
ffi::pigeon2::get_supply_voltage(self.gyro.pin_mut()).volts()
}
pub fn set_yaw(&mut self, yaw: Angle) -> StatusCode {
StatusCode::new(
ffi::pigeon2::set_yaw(self.gyro.pin_mut(), yaw.get::<degree>()).within_unique_ptr(),
)
}
}