fn euler_angle_order_to_string(order: attitude::EulerAngleOrder) -> String {
match order {
attitude::EulerAngleOrder::XYX => String::from("XYX"),
attitude::EulerAngleOrder::XYZ => String::from("XYZ"),
attitude::EulerAngleOrder::XZX => String::from("XZX"),
attitude::EulerAngleOrder::XZY => String::from("XZY"),
attitude::EulerAngleOrder::YXY => String::from("YXY"),
attitude::EulerAngleOrder::YXZ => String::from("YXZ"),
attitude::EulerAngleOrder::YZX => String::from("YZX"),
attitude::EulerAngleOrder::YZY => String::from("YZY"),
attitude::EulerAngleOrder::ZXY => String::from("ZXY"),
attitude::EulerAngleOrder::ZXZ => String::from("ZXZ"),
attitude::EulerAngleOrder::ZYX => String::from("ZYX"),
attitude::EulerAngleOrder::ZYZ => String::from("ZYZ"),
}
}
#[pyclass(module = "brahe._brahe", from_py_object)]
#[pyo3(name = "EulerAngleOrder")]
#[derive(Clone)]
pub struct PyEulerAngleOrder {
pub(crate) value: attitude::EulerAngleOrder,
}
#[pymethods]
impl PyEulerAngleOrder {
#[classattr]
#[allow(non_snake_case)]
fn XYX() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::XYX }
}
#[classattr]
#[allow(non_snake_case)]
fn XYZ() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::XYZ }
}
#[classattr]
#[allow(non_snake_case)]
fn XZX() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::XZX }
}
#[classattr]
#[allow(non_snake_case)]
fn XZY() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::XZY }
}
#[classattr]
#[allow(non_snake_case)]
fn YXY() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::YXY }
}
#[classattr]
#[allow(non_snake_case)]
fn YXZ() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::YXZ }
}
#[classattr]
#[allow(non_snake_case)]
fn YZX() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::YZX }
}
#[classattr]
#[allow(non_snake_case)]
fn YZY() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::YZY }
}
#[classattr]
#[allow(non_snake_case)]
fn ZXY() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::ZXY }
}
#[classattr]
#[allow(non_snake_case)]
fn ZXZ() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::ZXZ }
}
#[classattr]
#[allow(non_snake_case)]
fn ZYX() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::ZYX }
}
#[classattr]
#[allow(non_snake_case)]
fn ZYZ() -> Self {
PyEulerAngleOrder { value: attitude::EulerAngleOrder::ZYZ }
}
fn __str__(&self) -> String {
euler_angle_order_to_string(self.value)
}
fn __repr__(&self) -> String {
format!("EulerAngleOrder.{}", euler_angle_order_to_string(self.value))
}
fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult<bool> {
match op {
CompareOp::Eq => Ok(self.value == other.value),
CompareOp::Ne => Ok(self.value != other.value),
_ => Err(exceptions::PyNotImplementedError::new_err(
"Comparison not supported",
)),
}
}
}
#[pyclass(module = "brahe._brahe", from_py_object)]
#[pyo3(name = "Quaternion")]
#[derive(Clone)]
pub struct PyQuaternion {
obj: attitude::Quaternion,
}
#[pymethods]
impl PyQuaternion {
#[new]
#[pyo3(text_signature = "(w, x, y, z)")]
pub fn new(w: f64, x: f64, y: f64, z: f64) -> PyQuaternion {
PyQuaternion {
obj: attitude::Quaternion::new(w, x, y, z),
}
}
#[classmethod]
#[pyo3(text_signature = "(v, scalar_first)")]
pub fn from_vector(
_cls: &Bound<'_, PyType>,
v: &Bound<'_, PyAny>,
scalar_first: bool,
) -> PyResult<PyQuaternion> {
let vec = pyany_to_f64_array1(v, Some(4))?;
Ok(PyQuaternion {
obj: attitude::Quaternion::from_vector(na::SVector::<f64, 4>::from_vec(vec), scalar_first),
})
}
#[pyo3(text_signature = "($self, scalar_first)")]
pub unsafe fn to_vector<'py>(&self, py: Python<'py>, scalar_first: bool) -> Bound<'py, PyArray<f64, Ix1>> {
vector_to_numpy!(py, self.obj.to_vector(scalar_first), 4, f64)
}
#[pyo3(text_signature = "($self)")]
pub fn normalize(&mut self) {
self.obj.normalize();
}
#[pyo3(text_signature = "($self)")]
pub fn norm(&self) -> f64 {
self.obj.norm()
}
#[pyo3(text_signature = "($self)")]
pub fn conjugate(&self) -> PyQuaternion {
PyQuaternion {
obj: self.obj.conjugate()
}
}
#[pyo3(text_signature = "($self)")]
pub fn inverse(&self) -> PyQuaternion {
PyQuaternion {
obj: self.obj.inverse()
}
}
#[pyo3(text_signature = "($self, other, t)")]
pub fn slerp(&self, other: PyQuaternion, t: f64) -> PyQuaternion {
PyQuaternion {
obj: self.obj.slerp(other.obj, t)
}
}
pub fn __repr__(&self) -> String {
format!("{:?}", self.obj)
}
pub fn __str__(&self) -> String {
self.obj.to_string()
}
pub fn __add__(&self, other: PyQuaternion) -> PyResult<PyQuaternion> {
Ok(PyQuaternion {
obj: self.obj + other.obj,
})
}
pub fn __iadd__(&mut self, other: PyQuaternion) {
self.obj += other.obj;
}
pub fn __sub__(&self, other: &PyQuaternion) -> PyResult<PyQuaternion> {
Ok(PyQuaternion {
obj: self.obj - other.obj
})
}
pub fn __mul__(&self, other: &PyQuaternion) -> PyResult<PyQuaternion> {
Ok(PyQuaternion {
obj: self.obj * other.obj
})
}
pub fn __imul__(&mut self, other: PyQuaternion) {
self.obj *= other.obj;
}
pub fn __isub__(&mut self, other: PyQuaternion) {
self.obj -= other.obj;
}
pub fn __eq__(&self, other: &PyQuaternion) -> bool {
self.obj == other.obj
}
pub fn __ne__(&self, other: &PyQuaternion) -> bool {
self.obj != other.obj
}
pub fn __getitem__(&self, index: usize) -> f64 {
self.obj[index]
}
#[getter]
pub unsafe fn data<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray<f64, Ix1>> {
vector_to_numpy!(py, self.obj.data, 4, f64)
}
#[getter]
pub fn w(&self) -> f64 {
self.obj[0]
}
#[getter]
pub fn x(&self) -> f64 {
self.obj[1]
}
#[getter]
pub fn y(&self) -> f64 {
self.obj[2]
}
#[getter]
pub fn z(&self) -> f64 {
self.obj[3]
}
#[classmethod]
#[pyo3(text_signature = "(q)")]
pub fn from_quaternion(_cls: &Bound<'_, PyType>, q: &PyQuaternion) -> PyQuaternion {
PyQuaternion {
obj: Quaternion::from_quaternion(q.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(e)")]
pub fn from_euler_axis(_cls: &Bound<'_, PyType>, e: &PyEulerAxis) -> PyQuaternion {
PyQuaternion {
obj: Quaternion::from_euler_axis(e.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(e)")]
pub fn from_euler_angle(_cls: &Bound<'_, PyType>, e: &PyEulerAngle) -> PyQuaternion {
PyQuaternion {
obj: Quaternion::from_euler_angle(e.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(r)")]
pub fn from_rotation_matrix(_cls: &Bound<'_, PyType>, r: &PyRotationMatrix) -> PyQuaternion {
PyQuaternion {
obj: Quaternion::from_rotation_matrix(r.obj)
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_quaternion(&self) -> PyQuaternion {
PyQuaternion {
obj: self.obj.to_quaternion()
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_euler_axis(&self) -> PyEulerAxis {
PyEulerAxis {
obj: self.obj.to_euler_axis()
}
}
#[pyo3(text_signature = "($self, order)")]
pub fn to_euler_angle(&self, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: self.obj.to_euler_angle(order.value)
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_rotation_matrix(&self) -> PyRotationMatrix {
PyRotationMatrix {
obj: self.obj.to_rotation_matrix()
}
}
}
#[pyclass(module = "brahe._brahe", from_py_object)]
#[pyo3(name = "EulerAngle")]
#[derive(Clone)]
pub struct PyEulerAngle {
obj: attitude::EulerAngle,
}
#[pymethods]
impl PyEulerAngle {
pub fn __repr__(&self) -> String {
format!("{:?}", self.obj)
}
pub fn __str__(&self) -> String {
self.obj.to_string()
}
pub fn __eq__(&self, other: &PyEulerAngle) -> bool {
self.obj == other.obj
}
pub fn __ne__(&self, other: &PyEulerAngle) -> bool {
self.obj != other.obj
}
#[getter]
pub fn phi(&self) -> f64 {
self.obj.phi
}
#[getter]
pub fn theta(&self) -> f64 {
self.obj.theta
}
#[getter]
pub fn psi(&self) -> f64 {
self.obj.psi
}
#[getter]
pub fn order(&self) -> PyEulerAngleOrder {
PyEulerAngleOrder {
value: self.obj.order
}
}
#[new]
#[pyo3(text_signature = "(order, phi, theta, psi, angle_format)")]
pub fn new(order: &PyEulerAngleOrder, phi: f64, theta: f64, psi: f64, angle_format: &PyAngleFormat) -> PyEulerAngle {
PyEulerAngle {
obj: attitude::EulerAngle::new(order.value, phi, theta, psi, angle_format.value),
}
}
#[classmethod]
#[pyo3(text_signature = "(v, order, angle_format)")]
pub fn from_vector(_cls: &Bound<'_, PyType>, v: &Bound<'_, PyAny>, order: &PyEulerAngleOrder, angle_format: &PyAngleFormat) -> PyResult<PyEulerAngle> {
let vec = pyany_to_f64_array1(v, Some(3))?;
Ok(PyEulerAngle {
obj: attitude::EulerAngle::from_vector(na::SVector::<f64, 3>::from_vec(vec), order.value, angle_format.value),
})
}
#[classmethod]
#[pyo3(text_signature = "(q, order)")]
pub fn from_quaternion(_cls: &Bound<'_, PyType>, q: &PyQuaternion, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: attitude::EulerAngle::from_quaternion(q.obj, order.value),
}
}
#[classmethod]
#[pyo3(text_signature = "(e, order)")]
pub fn from_euler_axis(_cls: &Bound<'_, PyType>, e: &PyEulerAxis, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: attitude::EulerAngle::from_euler_axis(e.obj, order.value),
}
}
#[classmethod]
#[pyo3(text_signature = "(e, order)")]
pub fn from_euler_angle(_cls: &Bound<'_, PyType>, e: &PyEulerAngle, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: attitude::EulerAngle::from_euler_angle(e.obj, order.value),
}
}
#[classmethod]
#[pyo3(text_signature = "(r, order)")]
pub fn from_rotation_matrix(_cls: &Bound<'_, PyType>, r: &PyRotationMatrix, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: attitude::EulerAngle::from_rotation_matrix(r.obj, order.value),
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_quaternion(&self) -> PyQuaternion {
PyQuaternion {
obj: self.obj.to_quaternion()
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_euler_axis(&self) -> PyEulerAxis {
PyEulerAxis {
obj: self.obj.to_euler_axis()
}
}
#[pyo3(text_signature = "($self, order)")]
pub fn to_euler_angle(&self, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: self.obj.to_euler_angle(order.value)
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_rotation_matrix(&self) -> PyRotationMatrix {
PyRotationMatrix {
obj: self.obj.to_rotation_matrix()
}
}
}
#[pyclass(module = "brahe._brahe", from_py_object)]
#[pyo3(name = "EulerAxis")]
#[derive(Clone)]
pub struct PyEulerAxis {
obj: attitude::EulerAxis,
}
#[pymethods]
impl PyEulerAxis {
pub fn __repr__(&self) -> String {
format!("{:?}", self.obj)
}
pub fn __str__(&self) -> String {
self.obj.to_string()
}
pub fn __eq__(&self, other: &PyEulerAxis) -> bool {
self.obj == other.obj
}
pub fn __ne__(&self, other: &PyEulerAxis) -> bool {
self.obj != other.obj
}
pub fn __getitem__(&self, index: usize) -> f64 {
self.obj[index]
}
#[getter]
pub fn angle(&self) -> f64 {
self.obj.angle
}
#[getter]
pub unsafe fn axis<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray<f64, Ix1>> {
vector_to_numpy!(py, self.obj.axis, 3, f64)
}
#[new]
#[pyo3(text_signature = "(axis, angle, angle_format)")]
pub fn new(axis: &Bound<'_, PyAny>, angle: f64, angle_format: &PyAngleFormat) -> PyResult<PyEulerAxis> {
let axis_vec = pyany_to_f64_array1(axis, Some(3))?;
Ok(PyEulerAxis {
obj: attitude::EulerAxis::new(na::SVector::<f64, 3>::from_vec(axis_vec), angle, angle_format.value),
})
}
#[classmethod]
#[pyo3(text_signature = "(x, y, z, angle, angle_format)")]
pub fn from_values(_cls: &Bound<'_, PyType>, x: f64, y: f64, z: f64, angle: f64, angle_format: &PyAngleFormat) -> PyEulerAxis {
PyEulerAxis {
obj: attitude::EulerAxis::from_values(x, y, z, angle, angle_format.value),
}
}
#[classmethod]
#[pyo3(text_signature = "(v, angle_format, vector_first)")]
pub fn from_vector(_cls: &Bound<'_, PyType>, v: &Bound<'_, PyAny>, angle_format: &PyAngleFormat, vector_first: bool) -> PyResult<PyEulerAxis> {
let vec = pyany_to_f64_array1(v, Some(4))?;
Ok(PyEulerAxis {
obj: attitude::EulerAxis::from_vector(na::SVector::<f64, 4>::from_vec(vec), angle_format.value, vector_first),
})
}
#[pyo3(text_signature = "($self, angle_format, vector_first)")]
pub unsafe fn to_vector<'py>(&self, py: Python<'py>, angle_format: &PyAngleFormat, vector_first: bool) -> Bound<'py, PyArray<f64, Ix1>> {
vector_to_numpy!(py, self.obj.to_vector(angle_format.value, vector_first), 4, f64)
}
#[classmethod]
#[pyo3(text_signature = "(q)")]
pub fn from_quaternion(_cls: &Bound<'_, PyType>, q: &PyQuaternion) -> PyEulerAxis {
PyEulerAxis {
obj: attitude::EulerAxis::from_quaternion(q.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(e)")]
pub fn from_euler_axis(_cls: &Bound<'_, PyType>, e: &PyEulerAxis) -> PyEulerAxis {
PyEulerAxis {
obj: attitude::EulerAxis::from_euler_axis(e.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(e)")]
pub fn from_euler_angle(_cls: &Bound<'_, PyType>, e: &PyEulerAngle) -> PyEulerAxis {
PyEulerAxis {
obj: attitude::EulerAxis::from_euler_angle(e.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(r)")]
pub fn from_rotation_matrix(_cls: &Bound<'_, PyType>, r: &PyRotationMatrix) -> PyEulerAxis {
PyEulerAxis {
obj: attitude::EulerAxis::from_rotation_matrix(r.obj)
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_quaternion(&self) -> PyQuaternion {
PyQuaternion {
obj: self.obj.to_quaternion()
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_euler_axis(&self) -> PyEulerAxis {
PyEulerAxis {
obj: self.obj.to_euler_axis()
}
}
#[pyo3(text_signature = "($self, order)")]
pub fn to_euler_angle(&self, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: self.obj.to_euler_angle(order.value)
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_rotation_matrix(&self) -> PyRotationMatrix {
PyRotationMatrix {
obj: self.obj.to_rotation_matrix()
}
}
}
#[pyclass(module = "brahe._brahe", from_py_object)]
#[pyo3(name = "RotationMatrix")]
#[derive(Clone)]
pub struct PyRotationMatrix {
obj: attitude::RotationMatrix,
}
#[pymethods]
impl PyRotationMatrix {
pub fn __repr__(&self) -> String {
format!("{:?}", self.obj)
}
pub fn __str__(&self) -> String {
self.obj.to_string()
}
pub fn __eq__(&self, other: &PyRotationMatrix) -> bool {
self.obj == other.obj
}
pub fn __ne__(&self, other: &PyRotationMatrix) -> bool {
self.obj != other.obj
}
pub fn __getitem__(&self, index: (usize, usize)) -> f64 {
self.obj[index]
}
pub fn __mul__(&self, other: &PyRotationMatrix) -> PyRotationMatrix {
PyRotationMatrix {
obj: self.obj * other.obj
}
}
pub fn __imul__(&mut self, other: PyRotationMatrix) {
self.obj *= other.obj;
}
#[new]
#[pyo3(text_signature = "(r11, r12, r13, r21, r22, r23, r31, r32, r33)")]
#[allow(clippy::too_many_arguments)]
pub fn new(r11: f64, r12: f64, r13: f64, r21: f64, r22: f64, r23: f64, r31: f64, r32: f64, r33: f64) -> Result<PyRotationMatrix, RustBraheError> {
Ok(PyRotationMatrix {
obj: attitude::RotationMatrix::new(r11, r12, r13, r21, r22, r23, r31, r32, r33)?,
})
}
#[classmethod]
#[pyo3(text_signature = "(m)")]
pub fn from_matrix(_cls: &Bound<'_, PyType>, m: &Bound<'_, PyAny>) -> Result<PyRotationMatrix, RustBraheError> {
let mat_vec = pyany_to_f64_array2(m, Some((3, 3)))
.map_err(|e| RustBraheError::ParseError(format!("Invalid matrix input: {}", e)))?;
let flat: Vec<f64> = (0..3)
.flat_map(|col| mat_vec.iter().map(move |row| row[col]))
.collect();
Ok(PyRotationMatrix {
obj: attitude::RotationMatrix::from_matrix(na::SMatrix::<f64, 3, 3>::from_vec(flat))?,
})
}
#[pyo3(text_signature = "($self)")]
pub unsafe fn to_matrix<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray<f64, Ix2>> {
matrix_to_numpy!(py, self.obj.to_matrix(), 3, 3, f64)
}
#[getter]
pub fn r11(&self) -> f64 {
self.obj[(0, 0)]
}
#[getter]
pub fn r12(&self) -> f64 {
self.obj[(0, 1)]
}
#[getter]
pub fn r13(&self) -> f64 {
self.obj[(0, 2)]
}
#[getter]
pub fn r21(&self) -> f64 {
self.obj[(1, 0)]
}
#[getter]
pub fn r22(&self) -> f64 {
self.obj[(1, 1)]
}
#[getter]
pub fn r23(&self) -> f64 {
self.obj[(1, 2)]
}
#[getter]
pub fn r31(&self) -> f64 {
self.obj[(2, 0)]
}
#[getter]
pub fn r32(&self) -> f64 {
self.obj[(2, 1)]
}
#[getter]
pub fn r33(&self) -> f64 {
self.obj[(2, 2)]
}
#[classmethod]
#[allow(non_snake_case)]
#[pyo3(text_signature = "(angle, angle_format)")]
pub fn Rx(_cls: &Bound<'_, PyType>, angle: f64, angle_format: &PyAngleFormat) -> PyRotationMatrix {
PyRotationMatrix {
obj: attitude::RotationMatrix::Rx(angle, angle_format.value)
}
}
#[classmethod]
#[allow(non_snake_case)]
#[pyo3(text_signature = "(angle, angle_format)")]
pub fn Ry(_cls: &Bound<'_, PyType>, angle: f64, angle_format: &PyAngleFormat) -> PyRotationMatrix {
PyRotationMatrix {
obj: attitude::RotationMatrix::Ry(angle, angle_format.value)
}
}
#[classmethod]
#[allow(non_snake_case)]
#[pyo3(text_signature = "(angle, angle_format)")]
pub fn Rz(_cls: &Bound<'_, PyType>, angle: f64, angle_format: &PyAngleFormat) -> PyRotationMatrix {
PyRotationMatrix {
obj: attitude::RotationMatrix::Rz(angle, angle_format.value)
}
}
#[classmethod]
#[pyo3(text_signature = "(q)")]
pub fn from_quaternion(_cls: &Bound<'_, PyType>, q: &PyQuaternion) -> PyRotationMatrix {
PyRotationMatrix {
obj: attitude::RotationMatrix::from_quaternion(q.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(e)")]
pub fn from_euler_axis(_cls: &Bound<'_, PyType>, e: &PyEulerAxis) -> PyRotationMatrix {
PyRotationMatrix {
obj: attitude::RotationMatrix::from_euler_axis(e.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(e)")]
pub fn from_euler_angle(_cls: &Bound<'_, PyType>, e: &PyEulerAngle) -> PyRotationMatrix {
PyRotationMatrix {
obj: attitude::RotationMatrix::from_euler_angle(e.obj)
}
}
#[classmethod]
#[pyo3(text_signature = "(r)")]
pub fn from_rotation_matrix(_cls: &Bound<'_, PyType>, r: &PyRotationMatrix) -> PyRotationMatrix {
PyRotationMatrix {
obj: attitude::RotationMatrix::from_rotation_matrix(r.obj)
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_quaternion(&self) -> PyQuaternion {
PyQuaternion {
obj: self.obj.to_quaternion()
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_euler_axis(&self) -> PyEulerAxis {
PyEulerAxis {
obj: self.obj.to_euler_axis()
}
}
#[pyo3(text_signature = "($self, order)")]
pub fn to_euler_angle(&self, order: &PyEulerAngleOrder) -> PyEulerAngle {
PyEulerAngle {
obj: self.obj.to_euler_angle(order.value)
}
}
#[pyo3(text_signature = "($self)")]
pub fn to_rotation_matrix(&self) -> PyRotationMatrix {
PyRotationMatrix {
obj: self.obj.to_rotation_matrix()
}
}
}