1use super::prelude::{CouldNotGetFrameSensorError, FrameCategory, FrameConstructionError, FrameEx};
8use crate::{
9 check_rs2_error,
10 kind::{Rs2Extension, Rs2FrameMetadata, Rs2StreamKind, Rs2TimestampDomain},
11 sensor::Sensor,
12 stream_profile::StreamProfile,
13};
14use anyhow::Result;
15use num_traits::FromPrimitive;
16use realsense_sys as sys;
17use std::{
18 convert::{TryFrom, TryInto},
19 mem::MaybeUninit,
20 ptr::{self, NonNull},
21};
22
23#[derive(Debug)]
25pub struct PoseFrame {
26 frame_ptr: NonNull<sys::rs2_frame>,
28 timestamp: f64,
30 timestamp_domain: Rs2TimestampDomain,
32 frame_number: u64,
34 frame_stream_profile: StreamProfile,
36 data: sys::rs2_pose,
38 should_drop: bool,
41}
42
43pub enum Confidence {
45 Failed,
47 Low,
49 Medium,
51 High,
53}
54
55impl PoseFrame {
56 pub fn translation(&self) -> [f32; 3] {
58 let sys::rs2_vector { x, y, z } = self.data.translation;
59 [x, y, z]
60 }
61
62 pub fn velocity(&self) -> [f32; 3] {
64 let sys::rs2_vector { x, y, z } = self.data.velocity;
65 [x, y, z]
66 }
67
68 pub fn acceleration(&self) -> [f32; 3] {
70 let sys::rs2_vector { x, y, z } = self.data.acceleration;
71 [x, y, z]
72 }
73
74 pub fn rotation(&self) -> [f32; 4] {
76 let sys::rs2_quaternion { x, y, z, w } = self.data.rotation;
77 [x, y, z, w]
78 }
79
80 pub fn angular_velocity(&self) -> [f32; 3] {
82 let sys::rs2_vector { x, y, z } = self.data.angular_velocity;
83 [x, y, z]
84 }
85
86 pub fn angular_acceleration(&self) -> [f32; 3] {
88 let sys::rs2_vector { x, y, z } = self.data.angular_acceleration;
89 [x, y, z]
90 }
91
92 pub fn tracker_confidence(&self) -> Confidence {
94 match self.data.tracker_confidence {
95 0x0 => Confidence::Failed,
96 0x1 => Confidence::Low,
97 0x2 => Confidence::Medium,
98 0x3 => Confidence::High,
99 _ => panic!("Unknown confidence, please report a bug!"),
100 }
101 }
102
103 pub fn mapper_confidence(&self) -> Confidence {
105 match self.data.tracker_confidence {
106 0x0 => Confidence::Failed,
107 0x1 => Confidence::Low,
108 0x2 => Confidence::Medium,
109 0x3 => Confidence::High,
110 _ => panic!("Unknown confidence, please report a bug!"),
111 }
112 }
113}
114
115impl Drop for PoseFrame {
116 fn drop(&mut self) {
118 unsafe {
119 if self.should_drop {
120 sys::rs2_release_frame(self.frame_ptr.as_ptr());
121 }
122 }
123 }
124}
125
126unsafe impl Send for PoseFrame {}
127
128impl FrameCategory for PoseFrame {
129 fn extension() -> Rs2Extension {
130 Rs2Extension::PoseFrame
131 }
132
133 fn kind() -> Rs2StreamKind {
134 Rs2StreamKind::Pose
135 }
136
137 fn has_correct_kind(&self) -> bool {
138 self.frame_stream_profile.kind() == Self::kind()
139 }
140}
141
142impl TryFrom<NonNull<sys::rs2_frame>> for PoseFrame {
143 type Error = anyhow::Error;
144
145 fn try_from(frame_ptr: NonNull<sys::rs2_frame>) -> Result<Self, Self::Error> {
162 unsafe {
163 let mut err = ptr::null_mut::<sys::rs2_error>();
164
165 let timestamp = sys::rs2_get_frame_timestamp(frame_ptr.as_ptr(), &mut err);
166 check_rs2_error!(err, FrameConstructionError::CouldNotGetTimestamp)?;
167
168 let timestamp_domain =
169 sys::rs2_get_frame_timestamp_domain(frame_ptr.as_ptr(), &mut err);
170 check_rs2_error!(err, FrameConstructionError::CouldNotGetTimestampDomain)?;
171
172 let frame_number = sys::rs2_get_frame_number(frame_ptr.as_ptr(), &mut err);
173 check_rs2_error!(err, FrameConstructionError::CouldNotGetFrameNumber)?;
174
175 let profile_ptr = sys::rs2_get_frame_stream_profile(frame_ptr.as_ptr(), &mut err);
176 check_rs2_error!(err, FrameConstructionError::CouldNotGetFrameStreamProfile)?;
177
178 let nonnull_profile_ptr =
179 NonNull::new(profile_ptr as *mut sys::rs2_stream_profile).unwrap();
180 let profile = StreamProfile::try_from(nonnull_profile_ptr)?;
181
182 let mut pose_data = MaybeUninit::uninit();
183 sys::rs2_pose_frame_get_pose_data(frame_ptr.as_ptr(), pose_data.as_mut_ptr(), &mut err);
184 check_rs2_error!(err, FrameConstructionError::CouldNotGetData)?;
185
186 Ok(PoseFrame {
187 frame_ptr,
188 timestamp,
189 timestamp_domain: Rs2TimestampDomain::from_i32(timestamp_domain as i32).unwrap(),
190 frame_number,
191 frame_stream_profile: profile,
192 data: pose_data.assume_init(),
193 should_drop: true,
194 })
195 }
196 }
197}
198
199impl FrameEx for PoseFrame {
200 fn stream_profile(&self) -> &StreamProfile {
201 &self.frame_stream_profile
202 }
203
204 fn sensor(&self) -> Result<Sensor> {
205 unsafe {
206 let mut err = std::ptr::null_mut::<sys::rs2_error>();
207 let sensor_ptr = sys::rs2_get_frame_sensor(self.frame_ptr.as_ptr(), &mut err);
208 check_rs2_error!(err, CouldNotGetFrameSensorError)?;
209
210 Ok(Sensor::from(NonNull::new(sensor_ptr).unwrap()))
211 }
212 }
213
214 fn timestamp(&self) -> f64 {
215 self.timestamp
216 }
217
218 fn timestamp_domain(&self) -> Rs2TimestampDomain {
219 self.timestamp_domain
220 }
221
222 fn frame_number(&self) -> u64 {
223 self.frame_number
224 }
225
226 fn metadata(&self, metadata_kind: Rs2FrameMetadata) -> Option<std::os::raw::c_longlong> {
227 if !self.supports_metadata(metadata_kind) {
228 return None;
229 }
230
231 unsafe {
232 let mut err = std::ptr::null_mut::<sys::rs2_error>();
233
234 let val = sys::rs2_get_frame_metadata(
235 self.frame_ptr.as_ptr(),
236 #[allow(clippy::useless_conversion)]
237 (metadata_kind as i32).try_into().unwrap(),
238 &mut err,
239 );
240
241 if err.as_ref().is_none() {
242 Some(val)
243 } else {
244 sys::rs2_free_error(err);
245 None
246 }
247 }
248 }
249
250 fn supports_metadata(&self, metadata_kind: Rs2FrameMetadata) -> bool {
251 unsafe {
252 let mut err = std::ptr::null_mut::<sys::rs2_error>();
253
254 let supports_metadata = sys::rs2_supports_frame_metadata(
255 self.frame_ptr.as_ptr(),
256 #[allow(clippy::useless_conversion)]
257 (metadata_kind as i32).try_into().unwrap(),
258 &mut err,
259 );
260
261 if err.as_ref().is_none() {
262 supports_metadata != 0
263 } else {
264 sys::rs2_free_error(err);
265 false
266 }
267 }
268 }
269
270 unsafe fn get_owned_raw(mut self) -> NonNull<sys::rs2_frame> {
271 self.should_drop = false;
272
273 self.frame_ptr
274 }
275}
276
277#[cfg(test)]
278mod tests {
279 use super::*;
280
281 #[test]
282 fn frame_has_correct_kind() {
283 assert_eq!(PoseFrame::kind(), Rs2StreamKind::Pose);
284 }
285}