From 3ecd2645e212a2f413dc946ffd5f0c2f79bc696f Mon Sep 17 00:00:00 2001 From: Aemulation <112875887+Aemulation@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:32:56 +0100 Subject: [PATCH 1/7] Implement zip for leg joints --- nidhogg/src/types/mod.rs | 70 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/nidhogg/src/types/mod.rs b/nidhogg/src/types/mod.rs index c4a5924..da0c2a8 100644 --- a/nidhogg/src/types/mod.rs +++ b/nidhogg/src/types/mod.rs @@ -488,6 +488,31 @@ pub struct LeftLegJoints { pub ankle_roll: T, } +impl LeftLegJoints { + /// Zips two [`LeftLegJoints`] instances element-wise, creating a new [`LeftLegJoints`] + /// containing tuples of corresponding elements from the two arrays. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::JointArray; + /// + /// let zipped = LeftLegJoints::::default().zip(LeftLegJoints::::default()); + /// + /// assert_eq!(zipped.head_yaw, (0_u32, 0_f32)); + /// ``` + pub fn zip(self, other: LeftLegJoints) -> LeftLegJoints<(T, U)> { + LeftLegJoints { + hip_yaw_pitch: (self.hip_yaw_pitch, other.hip_yaw_pitch), + hip_roll: (self.hip_roll, other.hip_roll), + hip_pitch: (self.hip_pitch, other.hip_pitch), + knee_pitch: (self.knee_pitch, other.knee_pitch), + ankle_pitch: (self.ankle_pitch, other.ankle_pitch), + ankle_roll: (self.ankle_roll, other.ankle_roll), + } + } +} + /// Wrapper struct containing right left leg joints of the robot. #[derive(Builder, Clone, Debug, Default, Filler, PartialEq, Eq)] pub struct RightLegJoints { @@ -500,6 +525,30 @@ pub struct RightLegJoints { pub ankle_roll: T, } +impl RightLegJoints { + /// Zips two [`RightLegJoints`] instances element-wise, creating a new [`RightLegJoints`] + /// containing tuples of corresponding elements from the two arrays. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::JointArray; + /// + /// let zipped = RightLegJoints::::default().zip(RightLegJoints::::default()); + /// + /// assert_eq!(zipped.head_yaw, (0_u32, 0_f32)); + /// ``` + pub fn zip(self, other: RightLegJoints) -> RightLegJoints<(T, U)> { + RightLegJoints { + hip_roll: (self.hip_roll, other.hip_roll), + hip_pitch: (self.hip_pitch, other.hip_pitch), + knee_pitch: (self.knee_pitch, other.knee_pitch), + ankle_pitch: (self.ankle_pitch, other.ankle_pitch), + ankle_roll: (self.ankle_roll, other.ankle_roll), + } + } +} + /// Wrapper struct containing joint values for both legs of the robot. #[derive(Builder, Clone, Debug, Default, PartialEq, Eq)] pub struct LegJoints { @@ -507,6 +556,27 @@ pub struct LegJoints { pub right_leg: RightLegJoints, } +impl LegJoints { + /// Zips two [`LegJoints`] instances element-wise, creating a new [`LegJoints`] + /// containing tuples of corresponding elements from the two arrays. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::JointArray; + /// + /// let zipped = LegJoints::::default().zip(LegJoints::::default()); + /// + /// assert_eq!(zipped.head_yaw, (0_u32, 0_f32)); + /// ``` + pub fn zip(self, other: LegJoints) -> LegJoints<(T, U)> { + LegJoints { + left_leg: self.left_leg.zip(other.left_leg), + right_leg: self.right_leg.zip(other.right_leg), + } + } +} + impl FillExt for LegJoints { fn fill(value: T) -> LegJoints { LegJoints { From def5eaa03ea5b3af63b3ec9b38afe6250e3ddb5d Mon Sep 17 00:00:00 2001 From: Aemulation <112875887+Aemulation@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:49:10 +0100 Subject: [PATCH 2/7] Add map functions --- nidhogg/src/types/mod.rs | 79 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/nidhogg/src/types/mod.rs b/nidhogg/src/types/mod.rs index da0c2a8..32dd546 100644 --- a/nidhogg/src/types/mod.rs +++ b/nidhogg/src/types/mod.rs @@ -489,6 +489,34 @@ pub struct LeftLegJoints { } impl LeftLegJoints { + /// Transforms each element in the [`LeftLegJoints`] using the provided closure `f`, + /// producing a new [`LeftLegJoints`] with the transformed values. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::LeftLegJoints; + /// + /// let joints = LeftLegJoints::::default(); + /// + /// let transformed = joints.map(|x| x + 1); + /// + /// assert_eq!(transformed.head_yaw, 1); + /// ``` + pub fn map(self, f: &mut F) -> LeftLegJoints + where + F: FnMut(T) -> U, + { + LeftLegJoints { + hip_yaw_pitch: f(self.hip_yaw_pitch), + hip_roll: f(self.hip_roll), + hip_pitch: f(self.hip_pitch), + knee_pitch: f(self.knee_pitch), + ankle_pitch: f(self.ankle_pitch), + ankle_roll: f(self.ankle_roll), + } + } + /// Zips two [`LeftLegJoints`] instances element-wise, creating a new [`LeftLegJoints`] /// containing tuples of corresponding elements from the two arrays. /// @@ -526,6 +554,33 @@ pub struct RightLegJoints { } impl RightLegJoints { + /// Transforms each element in the [`RightLegJoints`] using the provided closure `f`, + /// producing a new [`RightLegJoints`] with the transformed values. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::RightLegJoints; + /// + /// let joints = RightLegJoints::::default(); + /// + /// let transformed = joints.map(|x| x + 1); + /// + /// assert_eq!(transformed.head_yaw, 1); + /// ``` + pub fn map(self, mut f: F) -> RightLegJoints + where + F: FnMut(T) -> U, + { + RightLegJoints { + hip_roll: f(self.hip_roll), + hip_pitch: f(self.hip_pitch), + knee_pitch: f(self.knee_pitch), + ankle_pitch: f(self.ankle_pitch), + ankle_roll: f(self.ankle_roll), + } + } + /// Zips two [`RightLegJoints`] instances element-wise, creating a new [`RightLegJoints`] /// containing tuples of corresponding elements from the two arrays. /// @@ -557,6 +612,30 @@ pub struct LegJoints { } impl LegJoints { + /// Transforms each element in the [`LegJoints`] using the provided closure `f`, + /// producing a new [`LegJoints`] with the transformed values. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::LegJoints; + /// + /// let joints = LegJoints::::default(); + /// + /// let transformed = joints.map(|x| x + 1); + /// + /// assert_eq!(transformed.head_yaw, 1); + /// ``` + pub fn map(self, f: &mut F) -> LegJoints + where + F: FnMut(T) -> U, + { + LegJoints { + left_leg: self.left_leg.map(f), + right_leg: self.right_leg.map(f), + } + } + /// Zips two [`LegJoints`] instances element-wise, creating a new [`LegJoints`] /// containing tuples of corresponding elements from the two arrays. /// From 5cb1226f72114d8aea243b29ccb16fd03ccab4ed Mon Sep 17 00:00:00 2001 From: Aemulation <112875887+Aemulation@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:51:59 +0100 Subject: [PATCH 3/7] Take f by mut reference --- nidhogg/src/types/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nidhogg/src/types/mod.rs b/nidhogg/src/types/mod.rs index 32dd546..4dbc929 100644 --- a/nidhogg/src/types/mod.rs +++ b/nidhogg/src/types/mod.rs @@ -568,7 +568,7 @@ impl RightLegJoints { /// /// assert_eq!(transformed.head_yaw, 1); /// ``` - pub fn map(self, mut f: F) -> RightLegJoints + pub fn map(self, f: &mut F) -> RightLegJoints where F: FnMut(T) -> U, { @@ -626,13 +626,13 @@ impl LegJoints { /// /// assert_eq!(transformed.head_yaw, 1); /// ``` - pub fn map(self, f: &mut F) -> LegJoints + pub fn map(self, mut f: F) -> LegJoints where F: FnMut(T) -> U, { LegJoints { - left_leg: self.left_leg.map(f), - right_leg: self.right_leg.map(f), + left_leg: self.left_leg.map(&mut f), + right_leg: self.right_leg.map(&mut f), } } From 5a60a434ad6487bade456df24e1dd3b1d9df6779 Mon Sep 17 00:00:00 2001 From: Aemulation <112875887+Aemulation@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:59:15 +0100 Subject: [PATCH 4/7] Implement `zip` and `map` for `SingleArmJoints` --- nidhogg/src/types/mod.rs | 94 ++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/nidhogg/src/types/mod.rs b/nidhogg/src/types/mod.rs index 4dbc929..0c2e1ae 100644 --- a/nidhogg/src/types/mod.rs +++ b/nidhogg/src/types/mod.rs @@ -496,14 +496,15 @@ impl LeftLegJoints { /// /// ``` /// use nidhogg::types::LeftLegJoints; + /// use nidhogg::types::FillExt; /// /// let joints = LeftLegJoints::::default(); /// /// let transformed = joints.map(|x| x + 1); /// - /// assert_eq!(transformed.head_yaw, 1); + /// assert_eq!(transformed, LeftLegJoints::fill(1)); /// ``` - pub fn map(self, f: &mut F) -> LeftLegJoints + pub fn map(self, mut f: F) -> LeftLegJoints where F: FnMut(T) -> U, { @@ -523,11 +524,12 @@ impl LeftLegJoints { /// # Example /// /// ``` - /// use nidhogg::types::JointArray; + /// use nidhogg::types::LeftLegJoints; + /// use nidhogg::types::FillExt; /// - /// let zipped = LeftLegJoints::::default().zip(LeftLegJoints::::default()); + /// let zipped = LeftLegJoints::::default().zip(LeftLegJoints::::default()); /// - /// assert_eq!(zipped.head_yaw, (0_u32, 0_f32)); + /// assert_eq!(zipped, LeftLegJoints::<(u32, u32)>::fill((0_u32, 0_u32))); /// ``` pub fn zip(self, other: LeftLegJoints) -> LeftLegJoints<(T, U)> { LeftLegJoints { @@ -561,14 +563,15 @@ impl RightLegJoints { /// /// ``` /// use nidhogg::types::RightLegJoints; + /// use nidhogg::types::FillExt; /// /// let joints = RightLegJoints::::default(); /// /// let transformed = joints.map(|x| x + 1); /// - /// assert_eq!(transformed.head_yaw, 1); + /// assert_eq!(transformed, RightLegJoints::::fill(1)); /// ``` - pub fn map(self, f: &mut F) -> RightLegJoints + pub fn map(self, mut f: F) -> RightLegJoints where F: FnMut(T) -> U, { @@ -587,11 +590,12 @@ impl RightLegJoints { /// # Example /// /// ``` - /// use nidhogg::types::JointArray; + /// use nidhogg::types::RightLegJoints; + /// use nidhogg::types::FillExt; /// - /// let zipped = RightLegJoints::::default().zip(RightLegJoints::::default()); + /// let zipped = RightLegJoints::::default().zip(RightLegJoints::::default()); /// - /// assert_eq!(zipped.head_yaw, (0_u32, 0_f32)); + /// assert_eq!(zipped, RightLegJoints::<(u32, u32)>::fill((0_u32, 0_u32))); /// ``` pub fn zip(self, other: RightLegJoints) -> RightLegJoints<(T, U)> { RightLegJoints { @@ -619,20 +623,21 @@ impl LegJoints { /// /// ``` /// use nidhogg::types::LegJoints; + /// use nidhogg::types::FillExt; /// /// let joints = LegJoints::::default(); /// /// let transformed = joints.map(|x| x + 1); /// - /// assert_eq!(transformed.head_yaw, 1); + /// assert_eq!(transformed, LegJoints::fill(1)); /// ``` - pub fn map(self, mut f: F) -> LegJoints + pub fn map(self, f: F) -> LegJoints where - F: FnMut(T) -> U, + F: FnMut(T) -> U + Clone, { LegJoints { - left_leg: self.left_leg.map(&mut f), - right_leg: self.right_leg.map(&mut f), + left_leg: self.left_leg.map(f.clone()), + right_leg: self.right_leg.map(f), } } @@ -642,11 +647,12 @@ impl LegJoints { /// # Example /// /// ``` - /// use nidhogg::types::JointArray; + /// use nidhogg::types::LegJoints; + /// use nidhogg::types::FillExt; /// - /// let zipped = LegJoints::::default().zip(LegJoints::::default()); + /// let zipped = LegJoints::::default().zip(LegJoints::::default()); /// - /// assert_eq!(zipped.head_yaw, (0_u32, 0_f32)); + /// assert_eq!(zipped, LegJoints::<(u32, u32)>::fill((0_u32, 0_u32))); /// ``` pub fn zip(self, other: LegJoints) -> LegJoints<(T, U)> { LegJoints { @@ -676,6 +682,58 @@ pub struct SingleArmJoints { pub hand: T, } +impl SingleArmJoints { + /// Transforms each element in the [`SingleArmJoints`] using the provided closure `f`, + /// producing a new [`SingleArmJoints`] with the transformed values. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::SingleArmJoints; + /// + /// let joints = SingleArmJoints::::default(); + /// + /// let transformed = joints.map(&mut |x| x + 1); + /// ``` + pub fn map(self, f: &mut F) -> SingleArmJoints + where + F: FnMut(T) -> U, + { + SingleArmJoints { + shoulder_pitch: f(self.shoulder_pitch), + shoulder_roll: f(self.shoulder_roll), + elbow_yaw: f(self.elbow_yaw), + elbow_roll: f(self.elbow_roll), + wrist_yaw: f(self.wrist_yaw), + hand: f(self.hand), + } + } + + /// Zips two [`SingleArmJoints`] instances element-wise, creating a new [`SingleArmJoints`] + /// containing tuples of corresponding elements from the two arrays. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::SingleArmJoints; + /// use nidhogg::types::FillExt; + /// + /// let zipped = SingleArmJoints::::default().zip(SingleArmJoints::::default()); + /// + /// assert_eq!(zipped, SingleArmJoints::<(u32, u32)>::fill((0_u32, 0_u32))); + /// ``` + pub fn zip(self, other: SingleArmJoints) -> SingleArmJoints<(T, U)> { + SingleArmJoints { + shoulder_pitch: (self.shoulder_pitch, other.shoulder_pitch), + shoulder_roll: (self.shoulder_roll, other.shoulder_roll), + elbow_yaw: (self.elbow_yaw, other.elbow_yaw), + elbow_roll: (self.elbow_roll, other.elbow_roll), + wrist_yaw: (self.wrist_yaw, other.wrist_yaw), + hand: (self.hand, other.hand), + } + } +} + /// Type definition for the left arm joints of the robot. /// Introduced for api consistency with [`LeftLegJoints`]. pub type LeftArmJoints = SingleArmJoints; From e25889d766fac2aafcefb42044022086fc1851b9 Mon Sep 17 00:00:00 2001 From: Aemulation <112875887+Aemulation@users.noreply.github.com> Date: Thu, 6 Feb 2025 17:01:10 +0100 Subject: [PATCH 5/7] Take closure by ownership --- nidhogg/src/types/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nidhogg/src/types/mod.rs b/nidhogg/src/types/mod.rs index 0c2e1ae..ffb31a9 100644 --- a/nidhogg/src/types/mod.rs +++ b/nidhogg/src/types/mod.rs @@ -693,9 +693,9 @@ impl SingleArmJoints { /// /// let joints = SingleArmJoints::::default(); /// - /// let transformed = joints.map(&mut |x| x + 1); + /// let transformed = joints.map(|x| x + 1); /// ``` - pub fn map(self, f: &mut F) -> SingleArmJoints + pub fn map(self, mut f: F) -> SingleArmJoints where F: FnMut(T) -> U, { From 4fcc913f9ea1a394bc1672739db9cab5df4e5c55 Mon Sep 17 00:00:00 2001 From: Aemulation <112875887+Aemulation@users.noreply.github.com> Date: Thu, 6 Feb 2025 17:08:10 +0100 Subject: [PATCH 6/7] Implement `zip` and `map` for `ArmJoints` --- nidhogg/src/types/mod.rs | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/nidhogg/src/types/mod.rs b/nidhogg/src/types/mod.rs index ffb31a9..0064aa1 100644 --- a/nidhogg/src/types/mod.rs +++ b/nidhogg/src/types/mod.rs @@ -749,6 +749,50 @@ pub struct ArmJoints { pub right_arm: SingleArmJoints, } +impl ArmJoints { + /// Transforms each element in the [`ArmJoints`] using the provided closure `f`, + /// producing a new [`ArmJoints`] with the transformed values. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::ArmJoints; + /// + /// let joints = ArmJoints::::default(); + /// + /// let transformed = joints.map(|x| x + 1); + /// ``` + pub fn map(self, f: F) -> ArmJoints + where + F: FnMut(T) -> U + Clone, + { + ArmJoints { + left_arm: self.left_arm.map(f.clone()), + right_arm: self.right_arm.map(f), + } + } + + /// Zips two [`ArmJoints`] instances element-wise, creating a new [`ArmJoints`] + /// containing tuples of corresponding elements from the two arrays. + /// + /// # Example + /// + /// ``` + /// use nidhogg::types::ArmJoints; + /// use nidhogg::types::FillExt; + /// + /// let zipped = ArmJoints::::default().zip(ArmJoints::::default()); + /// + /// assert_eq!(zipped, ArmJoints::<(u32, u32)>::fill((0_u32, 0_u32))); + /// ``` + pub fn zip(self, other: ArmJoints) -> ArmJoints<(T, U)> { + ArmJoints { + left_arm: self.left_arm.zip(other.left_arm), + right_arm: self.right_arm.zip(other.right_arm), + } + } +} + impl FillExt for ArmJoints { fn fill(value: T) -> ArmJoints { ArmJoints { From fa4bcd01b55682dd27867a014f4c37f71f4b3894 Mon Sep 17 00:00:00 2001 From: Mark Honkoop Date: Fri, 7 Feb 2025 14:43:46 +0100 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: Harold <37922636+YukumoHunter@users.noreply.github.com> --- nidhogg/src/types/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nidhogg/src/types/mod.rs b/nidhogg/src/types/mod.rs index 0064aa1..9bb0342 100644 --- a/nidhogg/src/types/mod.rs +++ b/nidhogg/src/types/mod.rs @@ -631,13 +631,13 @@ impl LegJoints { /// /// assert_eq!(transformed, LegJoints::fill(1)); /// ``` - pub fn map(self, f: F) -> LegJoints + pub fn map(self, mut f: F) -> LegJoints where - F: FnMut(T) -> U + Clone, + F: FnMut(T) -> U, { LegJoints { - left_leg: self.left_leg.map(f.clone()), - right_leg: self.right_leg.map(f), + left_leg: self.left_leg.map(&mut f), + right_leg: self.right_leg.map(&mut f), } } @@ -762,13 +762,13 @@ impl ArmJoints { /// /// let transformed = joints.map(|x| x + 1); /// ``` - pub fn map(self, f: F) -> ArmJoints + pub fn map(self, mut f: F) -> ArmJoints where - F: FnMut(T) -> U + Clone, + F: FnMut(T) -> U, { ArmJoints { - left_arm: self.left_arm.map(f.clone()), - right_arm: self.right_arm.map(f), + left_arm: self.left_arm.map(&mut f), + right_arm: self.right_arm.map(&mut f), } }