Skip to content

Commit

Permalink
Merge pull request #18 from robohouse-delft/bike-shedding
Browse files Browse the repository at this point in the history
Naming and design tweaks
  • Loading branch information
de-vri-es authored Oct 23, 2024
2 parents 0a272c5 + 566e78a commit 160a0f5
Show file tree
Hide file tree
Showing 26 changed files with 223 additions and 286 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ log = "0.4.8"
[features]
default = ["std", "serial2"]
alloc = []
std = []
std = ["alloc"]
rs4xx = ["serial2/rs4xx"]

[workspace]
Expand Down
4 changes: 2 additions & 2 deletions dynamixel2-cli/src/bin/dynamixel2/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::Path;
use std::time::{Duration, Instant};
use dynamixel2::transport::serial2::Serial2Port;
use dynamixel2::serial2::SerialPort;

mod logging;
mod options;
Expand Down Expand Up @@ -152,7 +152,7 @@ fn do_main(options: Options) -> Result<(), ()> {
Ok(())
}

fn open_bus(options: &Options) -> Result<dynamixel2::Bus<Vec<u8>, Vec<u8>, Serial2Port>, ()> {
fn open_bus(options: &Options) -> Result<dynamixel2::Bus<Vec<u8>, Vec<u8>, SerialPort>, ()> {
let bus = dynamixel2::Bus::open(&options.serial_port, options.baud_rate)
.map_err(|e| log::error!("Failed to open serial port: {}: {}", options.serial_port.display(), e))?;
log::debug!(
Expand Down
30 changes: 15 additions & 15 deletions src/bus.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::time::Duration;
use crate::endian::{read_u16_le, read_u32_le, read_u8_le};
use crate::transport::Transport;
use crate::serial_port::SerialPort;
use crate::{ReadError, TransferError, WriteError};

#[cfg(feature = "serial2")]
Expand All @@ -13,24 +13,24 @@ use crate::messaging::Messenger;
use crate::packet::{Packet, STATUS_HEADER_SIZE};

/// Dynamixel Protocol 2 communication bus.
pub struct Bus<ReadBuffer, WriteBuffer, T: Transport> {
pub struct Bus<ReadBuffer, WriteBuffer, T: SerialPort> {
messenger: Messenger<ReadBuffer, WriteBuffer, T>,
}
//
impl<ReadBuffer, WriteBuffer, T> core::fmt::Debug for Bus<ReadBuffer, WriteBuffer, T>
where
T: Transport + core::fmt::Debug,
T: SerialPort + core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Bus")
.field("transport", &self.messenger.transport)
.field("serial_port", &self.messenger.serial_port)
.field("baud_rate", &self.messenger.baud_rate)
.finish_non_exhaustive()
}
}

#[cfg(feature = "serial2")]
impl Bus<Vec<u8>, Vec<u8>, crate::transport::serial2::Serial2Port> {
impl Bus<Vec<u8>, Vec<u8>, serial2::SerialPort> {
/// Open a serial port with the given baud rate.
///
/// This will allocate a new read and write buffer of 128 bytes each.
Expand All @@ -48,14 +48,14 @@ impl Bus<Vec<u8>, Vec<u8>, crate::transport::serial2::Serial2Port> {
///
/// This will allocate a new read and write buffer of 128 bytes each.
/// Use [`Self::with_buffers()`] if you want to use a custom buffers.
pub fn new(serial_port: serial2::SerialPort) -> Result<Self, crate::InitializeError<std::io::Error>> {
pub fn new(serial_port: serial2::SerialPort) -> std::io::Result<Self> {
let messenger = Messenger::with_buffers(serial_port, vec![0; 128], vec![0; 128])?;
Ok(Self { messenger })
}
}

#[cfg(feature = "serial2")]
impl<ReadBuffer, WriteBuffer> Bus<ReadBuffer, WriteBuffer, crate::transport::serial2::Serial2Port>
impl<ReadBuffer, WriteBuffer> Bus<ReadBuffer, WriteBuffer, serial2::SerialPort>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
Expand All @@ -79,18 +79,18 @@ impl<ReadBuffer, WriteBuffer, T> Bus<ReadBuffer, WriteBuffer, T>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
/// Create a new bus using pre-allocated buffers.
///
/// The serial port must already be configured in raw mode with the correct baud rate,
/// character size (8), parity (disabled) and stop bits (1).
pub fn with_buffers(
transport: T,
serial_port: T,
read_buffer: ReadBuffer,
write_buffer: WriteBuffer,
) -> Result<Self, crate::InitializeError<T::Error>> {
let messenger = Messenger::with_buffers(transport, read_buffer, write_buffer)?;
) -> Result<Self, T::Error> {
let messenger = Messenger::with_buffers(serial_port, read_buffer, write_buffer)?;
Ok(Self { messenger })
}

Expand All @@ -100,16 +100,16 @@ where
/// and may disrupt the communication with the motors.
/// In general, it should be safe to read and write to the bus manually in between instructions,
/// if the response from the motors has already been received.
pub fn transport(&self) -> &T {
&self.messenger.transport
pub fn serial_port(&self) -> &T {
&self.messenger.serial_port
}

/// Consume this bus object to get ownership of the serial port.
///
/// This discards any data in internal the read buffer of the bus object.
/// This is normally not a problem, since all data in the read buffer is also discarded when transmitting a new command.
pub fn into_transport(self) -> T {
self.messenger.transport
pub fn into_serial_port(self) -> T {
self.messenger.serial_port
}

/// Get the baud rate of the bus.
Expand Down
30 changes: 15 additions & 15 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
use crate::endian::read_u16_le;
use crate::instructions::instruction_id;
use crate::messaging::Messenger;
use crate::{InvalidParameterCount, Packet, ReadError, Transport, WriteError};
use crate::{InvalidParameterCount, Packet, ReadError, SerialPort, WriteError};
use core::time::Duration;

#[cfg(feature = "alloc")]
use alloc::{borrow::ToOwned, vec::Vec};

/// Dynamixel [`Device`] for communicating with a [`Bus`].
pub struct Device<ReadBuffer, WriteBuffer, T: Transport> {
pub struct Device<ReadBuffer, WriteBuffer, T: SerialPort> {
messenger: Messenger<ReadBuffer, WriteBuffer, T>,
}

impl<ReadBuffer, WriteBuffer, T> core::fmt::Debug for Device<ReadBuffer, WriteBuffer, T>
where
T: Transport + core::fmt::Debug,
T: SerialPort + core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Device")
.field("transport", &self.messenger.transport)
.field("serial_port", &self.messenger.serial_port)
.field("baud_rate", &self.messenger.baud_rate)
.finish_non_exhaustive()
}
}

#[cfg(feature = "serial2")]
impl Device<Vec<u8>, Vec<u8>, crate::transport::serial2::Serial2Port> {
impl Device<Vec<u8>, Vec<u8>, serial2::SerialPort> {
/// Open a serial port with the given baud rate.
///
/// This will allocate a new read and write buffer of 128 bytes each.
Expand All @@ -43,14 +43,14 @@ impl Device<Vec<u8>, Vec<u8>, crate::transport::serial2::Serial2Port> {
///
/// This will allocate a new read and write buffer of 128 bytes each.
/// Use [`Self::with_buffers()`] if you want to use a custom buffers.
pub fn new(serial_port: serial2::SerialPort) -> Result<Self, crate::InitializeError<std::io::Error>> {
pub fn new(serial_port: serial2::SerialPort) -> std::io::Result<Self> {
let messenger = Messenger::with_buffers(serial_port, vec![0; 128], vec![0; 128])?;
Ok(Self { messenger })
}
}

#[cfg(feature = "serial2")]
impl<ReadBuffer, WriteBuffer> Device<ReadBuffer, WriteBuffer, crate::transport::serial2::Serial2Port>
impl<ReadBuffer, WriteBuffer> Device<ReadBuffer, WriteBuffer, serial2::SerialPort>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
Expand All @@ -73,15 +73,15 @@ impl<ReadBuffer, WriteBuffer, T> Device<ReadBuffer, WriteBuffer, T>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
/// Create a new device using pre-allocated buffers.
pub fn with_buffers(
transport: impl Into<T>,
serial_port: T,
read_buffer: ReadBuffer,
write_buffer: WriteBuffer,
) -> Result<Self, crate::InitializeError<T::Error>> {
let messenger = Messenger::with_buffers(transport, read_buffer, write_buffer)?;
) -> Result<Self, T::Error> {
let messenger = Messenger::with_buffers(serial_port, read_buffer, write_buffer)?;
Ok(Device { messenger })
}

Expand All @@ -91,16 +91,16 @@ where
/// and may disrupt the communication with the motors.
/// In general, it should be safe to read and write to the device manually in between instructions,
/// if the response from the motors has already been received.
pub fn transport(&self) -> &T {
&self.messenger.transport
pub fn serial_port(&self) -> &T {
&self.messenger.serial_port
}

/// Consume this device object to get ownership of the serial port.
///
/// This discards any data in internal the read buffer of the device object.
/// This is normally not a problem, since all data in the read buffer is also discarded when transmitting a new command.
pub fn into_transport(self) -> T {
self.messenger.transport
pub fn into_serial_port(self) -> T {
self.messenger.serial_port
}

/// Get the baud rate of the device.
Expand Down
28 changes: 0 additions & 28 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
use crate::instructions::packet_id::BROADCAST;
use core::fmt::{Debug, Display, Formatter, Result as FmtResult};

/// An error that can occur while initializing a bus.
#[derive(Debug)]
pub enum InitializeError<E> {
/// Failed to get the configuration of the serial port.
GetConfiguration(E),

/// Failed to get the baud rate from the configuration of the serial port.
GetBaudRate(E),
}

/// An error that can occur during a read/write transfer.
#[derive(Debug)]
pub enum TransferError<E> {
Expand Down Expand Up @@ -56,9 +46,6 @@ pub enum ReadError<E> {
/// Failed to read from the serial port.
Io(E),

/// A timeout occurred while waiting for a response.
Timeout,

/// The received message is invalid.
InvalidMessage(InvalidMessage),

Expand Down Expand Up @@ -301,8 +288,6 @@ impl InvalidParameterCount {
}
}

#[cfg(feature = "std")]
impl<E: Debug + Display> std::error::Error for InitializeError<E> {}
#[cfg(feature = "std")]
impl<E: Debug + Display> std::error::Error for TransferError<E> {}
#[cfg(feature = "std")]
Expand Down Expand Up @@ -458,18 +443,6 @@ impl From<InvalidParameterCount> for InvalidMessage {
}
}

impl<E> Display for InitializeError<E>
where
E: Display,
{
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::GetConfiguration(e) => write!(f, "failed to get configuration of serial port: {e}"),
Self::GetBaudRate(e) => write!(f, "failed to get baud rate of serial port: {e}"),
}
}
}

impl<E> Display for TransferError<E>
where
E: Display,
Expand Down Expand Up @@ -521,7 +494,6 @@ where
e.required_size, e.total_size
),
Self::Io(e) => write!(f, "failed to read from serial port: {}", e),
Self::Timeout => write!(f, "timeout while waiting for response"),
Self::InvalidMessage(e) => write!(f, "{}", e),
Self::MotorError(e) => write!(f, "{}", e),
}
Expand Down
4 changes: 2 additions & 2 deletions src/instructions/action.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use super::{instruction_id, packet_id};
use crate::transport::Transport;
use crate::serial_port::SerialPort;
use crate::{Bus, Response, TransferError, WriteError};

impl<ReadBuffer, WriteBuffer, T> Bus<ReadBuffer, WriteBuffer, T>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
/// Send an action command to trigger a previously registered instruction.
///
Expand Down
4 changes: 2 additions & 2 deletions src/instructions/bulk_read.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{instruction_id, packet_id, BulkReadData};
use crate::endian::{write_u16_le, write_u8_le};
use crate::transport::Transport;
use crate::serial_port::SerialPort;
use crate::{Bus, ReadError, Response, WriteError};

#[cfg(feature = "alloc")]
Expand All @@ -11,7 +11,7 @@ impl<ReadBuffer, WriteBuffer, T> Bus<ReadBuffer, WriteBuffer, T>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
/// Synchronously read arbitrary data ranges from multiple motors in one command.
///
Expand Down
6 changes: 3 additions & 3 deletions src/instructions/bulk_write.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use super::{instruction_id, packet_id, BulkWriteData};
use crate::endian::{write_u16_le, write_u8_le};
use crate::transport::Transport;
use crate::serial_port::SerialPort;
use crate::{Bus, WriteError};

impl<ReadBuffer, WriteBuffer, T> Bus<ReadBuffer, WriteBuffer, T>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
/// Synchronously write arbitrary data ranges to multiple motors.
///
Expand Down Expand Up @@ -93,7 +93,7 @@ where
mod tests {
use super::*;

type Bus = crate::Bus<Vec<u8>, Vec<u8>, crate::transport::serial2::Serial2Port>;
type Bus = crate::Bus<Vec<u8>, Vec<u8>, serial2::SerialPort>;

/// Ensure that `bulk_write` accepts a slice of `BulkWriteData`.
///
Expand Down
4 changes: 2 additions & 2 deletions src/instructions/clear.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{instruction_id, packet_id};
use crate::transport::Transport;
use crate::serial_port::SerialPort;
use crate::{Bus, Response, TransferError, WriteError};

/// The parameters for the CLEAR command to clear the revolution counter.
Expand All @@ -9,7 +9,7 @@ impl<ReadBuffer, WriteBuffer, T> Bus<ReadBuffer, WriteBuffer, T>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
/// Clear the multi-revolution counter of a motor.
///
Expand Down
4 changes: 2 additions & 2 deletions src/instructions/factory_reset.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{instruction_id, packet_id};
use crate::transport::Transport;
use crate::serial_port::SerialPort;
use crate::{Bus, Response, TransferError, WriteError};

/// The kind of factory reset to perform.
Expand All @@ -20,7 +20,7 @@ impl<ReadBuffer, WriteBuffer, T> Bus<ReadBuffer, WriteBuffer, T>
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
/// Reset the settings of a motor to the factory defaults.
///
Expand Down
4 changes: 2 additions & 2 deletions src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ mod sync_read;
mod sync_write;
mod write;

use crate::Transport;
use crate::SerialPort;
pub use factory_reset::FactoryResetKind;
pub use ping::Ping;

Expand Down Expand Up @@ -113,7 +113,7 @@ fn read_response_if_not_broadcast<ReadBuffer, WriteBuffer, T>(
where
ReadBuffer: AsRef<[u8]> + AsMut<[u8]>,
WriteBuffer: AsRef<[u8]> + AsMut<[u8]>,
T: Transport,
T: SerialPort,
{
if motor_id == packet_id::BROADCAST {
Ok(crate::Response {
Expand Down
Loading

0 comments on commit 160a0f5

Please sign in to comment.