vicon_sys/
lib.rs

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