Skip to content

Commit

Permalink
RSDK-3865 - implement get_components for orientation vector in spatia…
Browse files Browse the repository at this point in the history
…lmath FFI (#58)
  • Loading branch information
gvaradarajan authored Jul 3, 2023
1 parent 4446c05 commit e605e7b
Showing 1 changed file with 42 additions and 17 deletions.
59 changes: 42 additions & 17 deletions src/ffi/spatialmath/orientation_vector.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use ffi_helpers::null_pointer_check;
use libc::c_double;
use nalgebra::Quaternion;

use crate::spatialmath::utils::OrientationVector;

/// The FFI Interface for initialization of Viam's Orientation Vector format.
/// Like an axis angle, the format involves a vector axis and a rotation
/// theta (in radians). However, unlike an axis-angle, an orientation vector alters
/// the axes of the given frame of reference by rotating the z-axis to the
/// vector axis provided. The new x-axis is the vector that is both orthogonal to
/// theta (in radians). However, unlike an axis-angle, an orientation vector alters
/// the axes of the given frame of reference by rotating the z-axis to the
/// vector axis provided. The new x-axis is the vector that is both orthogonal to
/// the vector axis provided and co-planar with both the old
/// z-axis and the vector axis (this leaves two choices for the y-axis,
/// but the canonical "right-hand rule" is used to select one consistently). Then,
/// z-axis and the vector axis (this leaves two choices for the y-axis,
/// but the canonical "right-hand rule" is used to select one consistently). Then,
/// a clockwise-rotation of theta is applied about the new-z axis
///
///
/// It is highly recommended not to attempt any mathematics with the orientation
/// vector directly and to convert to quaternions via the FFI interface instead

Expand All @@ -23,9 +24,9 @@ fn to_raw_pointer(o_vec: &OrientationVector) -> *mut OrientationVector {
}

/// Free memory at the address of the orientation vector pointer. Outer processes
/// that work with OrientationVectors via the FFI interface MUST remember
/// that work with OrientationVectors via the FFI interface MUST remember
/// to call this function when finished with a OrientationVector instance
///
///
/// # Safety
#[no_mangle]
pub unsafe extern "C" fn free_orientation_vector_memory(ptr: *mut OrientationVector) {
Expand All @@ -35,34 +36,58 @@ pub unsafe extern "C" fn free_orientation_vector_memory(ptr: *mut OrientationVec
let _ = Box::from_raw(ptr);
}


/// Initialize an orientation vector from raw components and retrieve the C pointer
/// to its address.
///
///
/// # Safety
///
///
/// When finished with the underlying orientation vector initialized by this function
/// the caller must remember to free the orientation vector memory using the
/// the caller must remember to free the orientation vector memory using the
/// free_orientation_vector_memory FFI function
#[no_mangle]
pub unsafe extern "C" fn new_orientation_vector(
o_x: f64, o_y: f64, o_z: f64, theta: f64
o_x: f64,
o_y: f64,
o_z: f64,
theta: f64,
) -> *mut OrientationVector {
let o_vec = OrientationVector::new(o_x, o_y, o_z, theta);
to_raw_pointer(&o_vec)
}

/// Get the components of an orientation vector as a list of C doubles, the order of the
/// components will be (o_x, o_y, o_z, theta).
///
/// # Safety
///
/// When finished with the underlying orientation_vector passed to this function
/// the caller must remember to free the orientation_vector memory using the
/// free_orientation_vector_memory FFI function
#[no_mangle]
pub unsafe extern "C" fn orientation_vector_get_components(
ov_ptr: *const OrientationVector,
) -> *const c_double {
null_pointer_check!(ov_ptr);
let components: [c_double; 4] = [
(*ov_ptr).o_vector.x,
(*ov_ptr).o_vector.y,
(*ov_ptr).o_vector.z,
(*ov_ptr).theta,
];
Box::into_raw(Box::new(components)) as *const _
}

/// Converts a quaternion into an orientation vector.
///
///
/// # Safety
///
///
/// When finished with the underlying quaternion passed to this function
/// the caller must remember to free the quaternion memory using the
/// the caller must remember to free the quaternion memory using the
/// free_quaternion_memory FFI function and the orientation-vector memory using
/// the free_orientation_vector_memory function
#[no_mangle]
pub unsafe extern "C" fn orientation_vector_from_quaternion(
quat_ptr: *const Quaternion<f64>
quat_ptr: *const Quaternion<f64>,
) -> *mut OrientationVector {
null_pointer_check!(quat_ptr);
let o_vec: OrientationVector = (*quat_ptr).into();
Expand Down

0 comments on commit e605e7b

Please sign in to comment.