1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
use snafu::Snafu;
#[cfg(target_os = "linux")]
/// Implementations of [`HasViconHardware`]
/// for use with a real Vicon system.
pub mod sys;
/// A thing that can read from a Vicon data stream.
pub trait HasViconHardware {
/// Returns a list of all identified [`ViconSubject`]s
/// in the next available frame from the system.
fn read_frame_subjects(&mut self) -> Result<Vec<ViconSubject>, ViconError>;
}
/// A single subject identified in a frame
/// read by a thing that [`HasViconHardware`].
#[derive(Debug)]
pub struct ViconSubject {
/// The subject's name.
pub name: String,
/// The subject's in cartesian space.
pub origin: Vector3D,
/// TODO: Should the subject instead
/// have its quaternion instead
/// of these values?
///
/// The subject's yaw, pitch, and roll
/// in space, derived from its rotational
/// quaternion.
///
/// The axes correspond to the subject's
/// yaw ([`Vector3D::x`]), pitch ([`Vector3D::y`]),
/// and roll ([`Vector3D::z`]),
pub rotation: Vector3D,
}
/// A three-dimensional vector of data.
#[derive(Debug)]
pub struct Vector3D {
/// The X-axis (1st dimension).
pub x: f64,
/// The Y-axis (2nd dimension).
pub y: f64,
/// The Z-axis (3rd dimension).
pub z: f64,
}
/// Enumeration of errors returned by a
/// thing that [HasViconHardware].
#[derive(Debug, Snafu)]
pub enum ViconError {
/// An error from the Vicon SDK.
SdkError { source: ViconSdkStatus },
}
/// Implementation of [`TryFrom`] which
/// returns `Ok` for _successful_
/// [`ViconSdkStatus`] codes, and `Err`
/// for all other status codes.
impl TryFrom<i32> for ViconError {
type Error = ViconError;
fn try_from(value: i32) -> Result<Self, Self::Error> {
let status = ViconSdkStatus::from(value);
if status.is_success() {
Ok(ViconError::SdkError { source: status })
} else {
Err(ViconError::SdkError { source: status })
}
}
}
/// Enumeration of status codes returned
/// by Vicon data stream SDK.
///
/// These status codes are derived from
/// the codes listed in the Vicon SDK's
/// `CTypeDefs.h` file.
#[derive(Debug, Snafu)]
pub enum ViconSdkStatus {
Unknown { code: i32 },
Unimplemented,
Success,
InvalidHostname,
InvalidMulticastIp,
ClientAlreadyConnected,
ClientConnectionFailed,
ServerAlreadyTransmittingMulticast,
ServerNotTransmittingMulticast,
NotConnected,
NoDataFrame,
InvalidIndex,
InvalidCameraName,
InvalidSubjectName,
InvalidSegmentName,
InvalidMarkerName,
InvalidDeviceName,
InvalidDeviceOutputName,
InvalidLatencySampleRate,
InvalidCoLinearAxes,
LeftHandedAxes,
HapticAlreadySet,
EarlyDataRequested,
LateDataRequested,
InvalidOperation,
Unsupported,
ConfigurationFailed,
NotPresent,
}
impl ViconSdkStatus {
/// Returns `true` iff this status
/// represents a success.
pub fn is_success(&self) -> bool {
matches!(self, ViconSdkStatus::Success)
}
}
impl From<i32> for ViconSdkStatus {
fn from(value: i32) -> Self {
match value {
0 => Self::Unknown { code: 0 },
1 => Self::Unimplemented,
2 => Self::Success,
3 => Self::InvalidHostname,
4 => Self::InvalidMulticastIp,
5 => Self::ClientAlreadyConnected,
6 => Self::ClientConnectionFailed,
7 => Self::ServerAlreadyTransmittingMulticast,
8 => Self::ServerNotTransmittingMulticast,
9 => Self::NotConnected,
10 => Self::NoDataFrame,
11 => Self::InvalidIndex,
12 => Self::InvalidCameraName,
13 => Self::InvalidSubjectName,
14 => Self::InvalidSegmentName,
15 => Self::InvalidMarkerName,
16 => Self::InvalidDeviceName,
17 => Self::InvalidDeviceOutputName,
18 => Self::InvalidLatencySampleRate,
19 => Self::InvalidCoLinearAxes,
20 => Self::LeftHandedAxes,
21 => Self::HapticAlreadySet,
22 => Self::EarlyDataRequested,
23 => Self::LateDataRequested,
24 => Self::InvalidOperation,
25 => Self::Unsupported,
26 => Self::ConfigurationFailed,
27 => Self::NotPresent,
_ => Self::Unknown { code: value },
}
}
}