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

v29 #178

Merged
merged 4 commits into from
Dec 21, 2024
Merged

v29 #178

Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions autd3-driver/src/datagram/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ mod with_segment;
mod with_timeout;

pub use super::firmware::operation::SwapSegment;
#[doc(inline)]
pub use super::firmware::operation::{ControlPoint, ControlPoints};
pub use clear::Clear;
pub use cpu_gpio_out::{CpuGPIO, CpuGPIOPort};
pub use debug::DebugSettings;
Expand Down
6 changes: 4 additions & 2 deletions autd3-driver/src/datagram/stm/foci/implement.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::sync::Arc;

use crate::{defined::ControlPoints, error::AUTDDriverError, geometry::Device};
use crate::{error::AUTDDriverError, geometry::Device};

use super::{FociSTMContext, FociSTMContextGenerator, FociSTMGenerator, IntoFociSTMGenerator};
use super::{
ControlPoints, FociSTMContext, FociSTMContextGenerator, FociSTMGenerator, IntoFociSTMGenerator,
};

pub struct VecFociSTMContext<const N: usize> {
foci: Arc<Vec<ControlPoints<N>>>,
Expand Down
4 changes: 1 addition & 3 deletions autd3-driver/src/defined/freq/float.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use super::{kHz, Freq, Frequency, Hz};

impl Frequency for Freq<f32> {}
use super::{kHz, Freq, Hz};

impl std::ops::Mul<Hz> for f32 {
type Output = Freq<f32>;
Expand Down
4 changes: 1 addition & 3 deletions autd3-driver/src/defined/freq/int.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use super::{kHz, Freq, Frequency, Hz};

impl Frequency for Freq<u32> {}
use super::{kHz, Freq, Hz};

impl std::ops::Mul<Hz> for u32 {
type Output = Freq<u32>;
Expand Down
2 changes: 0 additions & 2 deletions autd3-driver/src/defined/freq/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ pub struct Hz;
#[allow(non_camel_case_types)]
pub struct kHz;

pub trait Frequency: Clone + Copy + Sync + std::fmt::Debug + PartialEq + PartialOrd {}

use derive_more::{Add, Debug, Div, Mul, Sub};

#[derive(Clone, Copy, PartialEq, PartialOrd, Add, Div, Mul, Sub, Debug)]
Expand Down
2 changes: 0 additions & 2 deletions autd3-driver/src/defined/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod angle;
mod control_point;
mod freq;

pub use std::f32::consts::PI;
Expand All @@ -16,7 +15,6 @@ mod unit {
pub use unit::*;

pub use angle::*;
pub use control_point::*;
pub use freq::*;

pub const MILLIMETER: f32 = METER / 1000.0;
Expand Down
14 changes: 7 additions & 7 deletions autd3-driver/src/firmware/operation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ mod pulse_width_encoder;
mod reads_fpga_state;
mod segment;
mod silencer;
mod stm_foci;
mod stm_gain;
mod stm;
mod sync;

pub(crate) use clear::*;
Expand All @@ -33,10 +32,8 @@ pub(crate) use reads_fpga_state::*;
pub use segment::SwapSegment;
pub(crate) use segment::*;
pub(crate) use silencer::*;
pub use stm_foci::FociSTMContext;
pub(crate) use stm_foci::*;
pub use stm_gain::GainSTMContext;
pub(crate) use stm_gain::*;
pub(crate) use stm::*;
pub use stm::{ControlPoint, ControlPoints, FociSTMContext, GainSTMContext};
pub(crate) use sync::*;
use zerocopy::{Immutable, IntoBytes};

Expand Down Expand Up @@ -73,12 +70,14 @@ pub(crate) enum TypeTag {
CpuGPIOOut = 0xF2,
}

#[doc(hidden)]
pub trait Operation: Send + Sync {
fn required_size(&self, device: &Device) -> usize;
fn pack(&mut self, device: &Device, tx: &mut [u8]) -> Result<usize, AUTDDriverError>;
fn is_done(&self) -> bool;
}

#[doc(hidden)]
pub trait OperationGenerator {
type O1: Operation;
type O2: Operation;
Expand All @@ -105,6 +104,7 @@ impl Default for Box<dyn Operation> {
}
}

#[doc(hidden)]
pub struct OperationHandler {}

impl OperationHandler {
Expand Down Expand Up @@ -185,7 +185,7 @@ pub(crate) fn write_to_tx<T: IntoBytes + Immutable>(tx: &mut [u8], data: T) {
}

#[cfg(test)]
pub mod tests {
pub(crate) mod tests {

use std::mem::size_of;

Expand Down
14 changes: 4 additions & 10 deletions autd3-driver/src/firmware/operation/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,7 @@ impl Operation for SwapSegmentOp {

#[cfg(test)]
mod tests {
use crate::{
ethercat::{DcSysTime, ECAT_DC_SYS_TIME_BASE},
geometry::tests::create_device,
};
use crate::{ethercat::DcSysTime, geometry::tests::create_device};

use super::*;

Expand Down Expand Up @@ -154,8 +151,7 @@ mod tests {
let device = create_device(0, NUM_TRANS_IN_UNIT);
let mut tx = vec![0x00u8; FRAME_SIZE];

let sys_time = DcSysTime::from_utc(ECAT_DC_SYS_TIME_BASE).unwrap()
+ std::time::Duration::from_nanos(0x0123456789ABCDEF);
let sys_time = DcSysTime::ZERO + std::time::Duration::from_nanos(0x0123456789ABCDEF);
let transition_mode = TransitionMode::SysTime(sys_time);
let mut op = SwapSegmentOp::new(SwapSegment::Modulation(Segment::S0, transition_mode));

Expand Down Expand Up @@ -183,8 +179,7 @@ mod tests {
let device = create_device(0, NUM_TRANS_IN_UNIT);
let mut tx = vec![0x00u8; FRAME_SIZE];

let sys_time = DcSysTime::from_utc(ECAT_DC_SYS_TIME_BASE).unwrap()
+ std::time::Duration::from_nanos(0x0123456789ABCDEF);
let sys_time = DcSysTime::ZERO + std::time::Duration::from_nanos(0x0123456789ABCDEF);
let transition_mode = TransitionMode::SysTime(sys_time);
let mut op = SwapSegmentOp::new(SwapSegment::FociSTM(Segment::S0, transition_mode));

Expand Down Expand Up @@ -212,8 +207,7 @@ mod tests {
let device = create_device(0, NUM_TRANS_IN_UNIT);
let mut tx = vec![0x00u8; FRAME_SIZE];

let sys_time = DcSysTime::from_utc(ECAT_DC_SYS_TIME_BASE).unwrap()
+ std::time::Duration::from_nanos(0x0123456789ABCDEF);
let sys_time = DcSysTime::ZERO + std::time::Duration::from_nanos(0x0123456789ABCDEF);
let transition_mode = TransitionMode::SysTime(sys_time);
let mut op = SwapSegmentOp::new(SwapSegment::GainSTM(Segment::S0, transition_mode));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
use std::mem::size_of;

use crate::{
defined::{ControlPoints, METER},
defined::METER,
error::AUTDDriverError,
firmware::{
fpga::{
LoopBehavior, STMFocus, SamplingConfig, Segment, TransitionMode, FOCI_STM_BUF_SIZE_MAX,
FOCI_STM_FOCI_NUM_MAX, STM_BUF_SIZE_MIN, TRANSITION_MODE_NONE,
},
operation::{Operation, TypeTag},
operation::{write_to_tx, Operation, TypeTag},
},
geometry::Device,
};

use derive_new::new;
use zerocopy::{Immutable, IntoBytes};

use super::ControlPoints;

#[derive(Clone, Copy, PartialEq, Debug, IntoBytes, Immutable)]
#[repr(C)]
pub struct FociSTMControlFlags(u8);
Expand Down Expand Up @@ -97,13 +99,13 @@ impl<const N: usize, Context: FociSTMContext<N>> Operation for FociSTMOp<N, Cont
(0..send_num).try_for_each(|_| {
let p = self.context.next();
let p = p.transform(device.inv());
super::write_to_tx(
write_to_tx(
&mut tx[idx..],
STMFocus::create(p[0].point(), p.intensity().value())?,
);
idx += size_of::<STMFocus>();
(1..N).try_for_each(|i| {
super::write_to_tx(
write_to_tx(
&mut tx[idx..],
STMFocus::create(
p[i].point(),
Expand Down Expand Up @@ -131,7 +133,7 @@ impl<const N: usize, Context: FociSTMContext<N>> Operation for FociSTMOp<N, Cont
FociSTMControlFlags::NONE
};
if is_first {
super::write_to_tx(
write_to_tx(
tx,
FociSTMHead {
tag: TypeTag::FociSTM,
Expand All @@ -152,7 +154,7 @@ impl<const N: usize, Context: FociSTMContext<N>> Operation for FociSTMOp<N, Cont
);
Ok(size_of::<FociSTMHead>() + size_of::<STMFocus>() * send_num * N)
} else {
super::write_to_tx(
write_to_tx(
tx,
FociSTMSubseq {
tag: TypeTag::FociSTM,
Expand Down Expand Up @@ -189,9 +191,12 @@ mod tests {

use super::*;
use crate::{
defined::{mm, ControlPoint},
defined::mm,
ethercat::DcSysTime,
firmware::fpga::{FOCI_STM_FIXED_NUM_UNIT, FOCI_STM_FIXED_NUM_UPPER_X},
firmware::{
fpga::{FOCI_STM_FIXED_NUM_UNIT, FOCI_STM_FIXED_NUM_UPPER_X},
operation::ControlPoint,
},
geometry::{tests::create_device, Point3},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ use crate::{
Drive, LoopBehavior, SamplingConfig, Segment, TransitionMode, GAIN_STM_BUF_SIZE_MAX,
STM_BUF_SIZE_MIN, TRANSITION_MODE_NONE,
},
operation::{Operation, TypeTag},
operation::{write_to_tx, GainContext, Operation, TypeTag},
},
geometry::Device,
};

use super::GainContext;

use derive_new::new;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};

Expand Down Expand Up @@ -125,7 +123,7 @@ impl<G: GainContext, Context: GainSTMContext<Context = G>> Operation for GainSTM
.chunks_mut(size_of::<Drive>())
.zip(device.iter())
.for_each(|(dst, tr)| {
super::write_to_tx(dst, g.calc(tr));
write_to_tx(dst, g.calc(tr));
});
send += 1;
}
Expand Down Expand Up @@ -182,7 +180,7 @@ impl<G: GainContext, Context: GainSTMContext<Context = G>> Operation for GainSTM
);

if is_first {
super::write_to_tx(
write_to_tx(
tx,
GainSTMHead {
tag: TypeTag::GainSTM,
Expand All @@ -198,7 +196,7 @@ impl<G: GainContext, Context: GainSTMContext<Context = G>> Operation for GainSTM
},
);
} else {
super::write_to_tx(
write_to_tx(
tx,
GainSTMSubseq {
tag: TypeTag::GainSTM,
Expand Down
7 changes: 7 additions & 0 deletions autd3-driver/src/firmware/operation/stm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod control_point;
mod foci;
mod gain;

pub use control_point::*;
pub use foci::*;
pub use gain::*;
78 changes: 72 additions & 6 deletions autd3-driver/src/geometry/rotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@ use super::{UnitQuaternion, Vector3};

use paste::paste;

macro_rules! make_euler_angle {
macro_rules! make_euler_angle_intrinsic {
($({$first:ident, $second:ident, $third:ident}),*) => {
paste! {
pub enum EulerAngle {
/// Euler angle (intrinsic)
pub enum EulerAngleIntrinsic {
$(
#[doc = stringify!($first-$second-$third)]
#[doc = "euler angle."]
[<$first:upper $second:upper $third:upper>](Angle, Angle, Angle),
)*
}

impl From<EulerAngle> for UnitQuaternion {
fn from(angle: EulerAngle) -> Self {
impl From<EulerAngleIntrinsic> for UnitQuaternion {
fn from(angle: EulerAngleIntrinsic) -> Self {
match angle {
$(
EulerAngle::[<$first:upper $second:upper $third:upper>](first, second, third) => {
EulerAngleIntrinsic::[<$first:upper $second:upper $third:upper>](first, second, third) => {
UnitQuaternion::from_axis_angle(&Vector3::[<$first _axis>](), first.radian())
* UnitQuaternion::from_axis_angle(&Vector3::[<$second _axis>](), second.radian())
* UnitQuaternion::from_axis_angle(&Vector3::[<$third _axis>](), third.radian())
Expand All @@ -30,7 +33,40 @@ macro_rules! make_euler_angle {
}
}

make_euler_angle!({x, y, z}, {x, z, y}, {y, x, z}, {y, z, x}, {z, x, y}, {z, y, x}, {x, y, x}, {x, z, x}, {y, x, y}, {y, z, y}, {z, x, z}, {z, y, z});
macro_rules! make_euler_angle_extrinsic {
($({$first:ident, $second:ident, $third:ident}),*) => {
paste! {
/// Euler angle (extrinsic)
pub enum EulerAngleExtrinsic {
$(
#[doc = stringify!($first-$second-$third)]
#[doc = "euler angle."]
[<$first:upper $second:upper $third:upper>](Angle, Angle, Angle),
)*
}

impl From<EulerAngleExtrinsic> for UnitQuaternion {
fn from(angle: EulerAngleExtrinsic) -> Self {
match angle {
$(
EulerAngleExtrinsic::[<$first:upper $second:upper $third:upper>](first, second, third) => {
UnitQuaternion::from_axis_angle(&Vector3::[<$third _axis>](), third.radian())
* UnitQuaternion::from_axis_angle(&Vector3::[<$second _axis>](), second.radian())
* UnitQuaternion::from_axis_angle(&Vector3::[<$first _axis>](), first.radian())
}
)*
}
}
}
}
}
}

make_euler_angle_intrinsic!({x, y, z}, {x, z, y}, {y, x, z}, {y, z, x}, {z, x, y}, {z, y, x}, {x, y, x}, {x, z, x}, {y, x, y}, {y, z, y}, {z, x, z}, {z, y, z});
make_euler_angle_extrinsic!({x, y, z}, {x, z, y}, {y, x, z}, {y, z, x}, {z, x, y}, {z, y, x}, {x, y, x}, {x, z, x}, {y, x, y}, {y, z, y}, {z, x, z}, {z, y, z});

/// Euler angle (intrinsic)
pub type EulerAngle = EulerAngleIntrinsic;

#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -79,4 +115,34 @@ mod tests {
let angle: UnitQuaternion = angle.into();
assert_approx_eq_quat!(expected, angle);
}

#[rstest::rstest]
#[test]
#[case(UnitQuaternion::from_axis_angle(&Vector3::x_axis(), PI / 2.), EulerAngleExtrinsic::XYZ(90. * deg, 0. * deg, 0. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::y_axis(), PI / 2.), EulerAngleExtrinsic::XYZ(0. * deg, 90. * deg, 0. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::z_axis(), PI / 2.), EulerAngleExtrinsic::XYZ(0. * deg, 0. * deg, 90. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::z_axis(), PI / 2.) * UnitQuaternion::from_axis_angle(&Vector3::y_axis(), PI / 2.), EulerAngleExtrinsic::XYZ(0. * deg, 90. * deg, 90. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::y_axis(), PI / 2.) * UnitQuaternion::from_axis_angle(&Vector3::x_axis(), PI / 2.), EulerAngleExtrinsic::XYZ(90. * deg, 90. * deg, 0. * deg))]
fn test_rotation_xyz_extrinsic(
#[case] expected: UnitQuaternion,
#[case] angle: EulerAngleExtrinsic,
) {
let angle: UnitQuaternion = angle.into();
assert_approx_eq_quat!(expected, angle);
}

#[rstest::rstest]
#[test]
#[case(UnitQuaternion::from_axis_angle(&Vector3::z_axis(), PI / 2.), EulerAngleExtrinsic::ZYZ(90. * deg, 0. * deg, 0. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::y_axis(), PI / 2.), EulerAngleExtrinsic::ZYZ(0. * deg, 90. * deg, 0. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::z_axis(), PI / 2.), EulerAngleExtrinsic::ZYZ(0. * deg, 0. * deg, 90. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::z_axis(), PI / 2.) * UnitQuaternion::from_axis_angle(&Vector3::y_axis(), PI / 2.), EulerAngleExtrinsic::ZYZ(0. * deg, 90. * deg, 90. * deg))]
#[case(UnitQuaternion::from_axis_angle(&Vector3::y_axis(), PI / 2.) * UnitQuaternion::from_axis_angle(&Vector3::z_axis(), PI / 2.), EulerAngleExtrinsic::ZYZ(90. * deg, 90. * deg, 0. * deg))]
fn test_rotation_zyz_extrinsic(
#[case] expected: UnitQuaternion,
#[case] angle: EulerAngleExtrinsic,
) {
let angle: UnitQuaternion = angle.into();
assert_approx_eq_quat!(expected, angle);
}
}
Loading
Loading