#![cfg_attr(not(feature = "std"), no_std)]
mod lib {
#[cfg(feature="std")]
pub use std::*;
#[cfg(not(feature="std"))]
pub use core::*;
}
#[macro_use]
extern crate log;
extern crate bit_field;
#[cfg(feature="serialport")]
extern crate serialport;
#[macro_use]
pub mod protocol1;
#[macro_use]
pub mod protocol2;
pub mod pro;
pub mod dynamixel;
#[cfg(feature="serialport")]
mod serial_impl;
pub trait Servo<I: Interface> {
fn set_enable_torque(&mut self, interface: &mut I, enable_torque: bool) -> Result<(), ::Error>;
fn set_position(&mut self, interface: &mut I, value: f32) -> Result<(), ::Error>;
fn get_position(&mut self, interface: &mut I) -> Result<f32, ::Error>;
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CommunicationError {
TimedOut,
UnsupportedBaud(BaudRate),
Other,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Error {
Unfinished,
Communication(CommunicationError),
Format,
Processing,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum BaudRate {
Baud9600,
Baud19200,
Baud57600,
Baud115200,
Baud200000,
Baud250000,
Baud400000,
Baud500000,
Baud1000000,
Baud2000000,
Baud3000000,
Baud4000000,
Baud4500000,
Baud10500000,
}
impl From<BaudRate> for u32 {
fn from(b: BaudRate) -> u32 {
match b {
BaudRate::Baud9600 => 9600,
BaudRate::Baud19200 => 19200,
BaudRate::Baud57600 => 57600,
BaudRate::Baud115200 => 115200,
BaudRate::Baud200000 => 200_000,
BaudRate::Baud250000 => 250_000,
BaudRate::Baud400000 => 400_000,
BaudRate::Baud500000 => 500_000,
BaudRate::Baud1000000 => 1_000_000,
BaudRate::Baud2000000 => 2_000_000,
BaudRate::Baud3000000 => 3_000_000,
BaudRate::Baud4000000 => 4_000_000,
BaudRate::Baud4500000 => 4_500_000,
BaudRate::Baud10500000 => 10_500_000,
}
}
}
impl BaudRate {
fn variants() -> &'static [Self] {
&[BaudRate::Baud9600,
BaudRate::Baud19200,
BaudRate::Baud57600,
BaudRate::Baud115200,
BaudRate::Baud200000,
BaudRate::Baud250000,
BaudRate::Baud400000,
BaudRate::Baud500000,
BaudRate::Baud1000000,
BaudRate::Baud2000000,
BaudRate::Baud3000000,
BaudRate::Baud4000000,
BaudRate::Baud4500000,
BaudRate::Baud10500000,
]
}
}
pub trait Interface {
fn set_baud_rate(&mut self, b: BaudRate) -> Result<(), CommunicationError>;
fn flush(&mut self);
fn read(&mut self, data: &mut [u8]) -> Result<(), CommunicationError>;
fn write(&mut self, data: &[u8]) -> Result<(), CommunicationError>;
}
#[cfg(feature="std")]
impl From<std::io::Error> for CommunicationError {
fn from(e: std::io::Error) -> CommunicationError {
match e.kind() {
std::io::ErrorKind::TimedOut => CommunicationError::TimedOut,
_ => CommunicationError::Other,
}
}
}
#[derive(Debug, Clone)]
pub enum ServoInfo {
Protocol1(protocol1::ServoInfo),
Protocol2(protocol2::ServoInfo),
}
#[cfg(feature="std")]
pub fn enumerate<I: ::Interface>(interface: &mut I) -> Result<Vec<ServoInfo>, CommunicationError> {
let mut servos = Vec::new();
let servos_protocol1 = protocol1::enumerate(interface)?;
let servos_protocol2 = protocol2::enumerate(interface)?;
servos.append(&mut servos_protocol1.into_iter().map(|x| ServoInfo::Protocol1(x)).collect());
servos.append(&mut servos_protocol2.into_iter().map(|x| ServoInfo::Protocol2(x)).collect());
Ok(servos)
}
#[cfg(feature="std")]
pub fn connect<I: Interface + 'static>(interface: &mut I, info: ServoInfo) -> Result<Box<Servo<I>>, CommunicationError> {
match info {
ServoInfo::Protocol1(si) => protocol1::connect(interface, si),
ServoInfo::Protocol2(si) => protocol2::connect(interface, si),
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}