Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSDK-3865 - implement get_components in spatialmath FFI #58

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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