Skip to main content

UdpChannel

Struct UdpChannel 

Source
pub struct UdpChannel { /* private fields */ }
Expand description

The client’s UDP socket for robot states and robot commands.

Neither UdpChannel::try_receive nor UdpChannel::send allocates, so both are safe to call from a 1 kHz control loop.

Implementations§

Source§

impl UdpChannel

Source

pub fn bind(timeout: Duration) -> FrankaResult<UdpChannel>

Binds 0.0.0.0:0 and sets the receive timeout, as franka::Network’s constructor does.

Source

pub fn port(&self) -> u16

The local port, which is announced to the server in the Connect request.

Source

pub fn peer(&self) -> Option<SocketAddr>

Source address of the last received datagram, if any.

Source

pub fn try_receive(&self, buf: &mut [u8]) -> FrankaResult<Option<usize>>

Reads one datagram if one is already queued, without blocking and without allocating.

Uses recvfrom(2) with MSG_DONTWAIT rather than toggling O_NONBLOCK around every call, so a 1 kHz control loop performs exactly one syscall per poll. Returns Ok(None) when no datagram is waiting (libfranka’s udpReceive returning false).

§Note

This raw byte API does not check the datagram length. libfranka’s udpBlockingReceiveUnsafe rejects bytes_received != sizeof(T) with ProtocolException("libfranka: incorrect object size") (network.h:140-142); here that is the caller’s job. Parsing a short datagram against a full-size buffer would silently read stale bytes, so prefer UdpChannel::try_receive_struct, which performs the check.

Source

pub fn blocking_receive(&self, buf: &mut [u8]) -> FrankaResult<usize>

Blocks until a datagram arrives or the receive timeout expires.

A timeout is reported as Network("libfranka: UDP receive: Timeout"), which is the text libfranka produces from "libfranka: UDP receive: "s + Poco::TimeoutException::what().

§Note

Like UdpChannel::try_receive, this raw byte API does not check the datagram length; use UdpChannel::blocking_receive_struct to get libfranka’s "libfranka: incorrect object size" check.

Source

pub fn try_receive_struct<T>(&self) -> FrankaResult<Option<T>>
where T: FromBytes + IntoBytes + Immutable + KnownLayout,

Reads one datagram as a T if one is already queued, without blocking.

Typed counterpart of UdpChannel::try_receive and the port of Network::udpReceive<T> (network.h:117-125): the datagram is read into a T-sized stack buffer (no allocation, so this is control-loop safe) and its length must be exactly size_of::<T>(), otherwise Protocol("libfranka: incorrect object size") is returned (network.h:140-142).

A datagram longer than size_of::<T>() is truncated by recvfrom and therefore looks like an exact-size read — the same blind spot libfranka has.

Source

pub fn blocking_receive_struct<T>(&self) -> FrankaResult<T>
where T: FromBytes + IntoBytes + Immutable + KnownLayout,

Blocks until a datagram arrives and returns it as a T.

Typed counterpart of UdpChannel::blocking_receive and the port of Network::udpBlockingReceive<T> (network.h:128-132), including the Protocol("libfranka: incorrect object size") check on the datagram length.

Source

pub fn send(&self, addr: SocketAddr, data: &[u8]) -> FrankaResult<()>

Sends data to addr, which is normally UdpChannel::peer.

A short write is reported as Network("libfranka: could not send UDP data"), matching udpSend.

Trait Implementations§

Source§

impl Debug for UdpChannel

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.