diff --git a/Cargo.lock b/Cargo.lock index 1ab1c2d..47d2150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,7 +46,7 @@ checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "booster_sdk" -version = "0.1.0-alpha.11" +version = "0.1.0-alpha.12" dependencies = [ "futures", "rustdds", @@ -62,7 +62,7 @@ dependencies = [ [[package]] name = "booster_sdk_py" -version = "0.1.0-alpha.11" +version = "0.1.0-alpha.12" dependencies = [ "booster_sdk", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 376dc54..d5c2a8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["booster_sdk", "booster_sdk_py", "examples/rust/*"] resolver = "2" [workspace.package] -version = "0.1.0-alpha.11" +version = "0.1.0-alpha.12" edition = "2024" authors = ["Team whIRLwind"] license = "MIT OR Apache-2.0" diff --git a/booster_sdk/src/client/loco.rs b/booster_sdk/src/client/loco.rs index 7a85ae2..8340afa 100644 --- a/booster_sdk/src/client/loco.rs +++ b/booster_sdk/src/client/loco.rs @@ -372,6 +372,30 @@ impl BoosterClient { self.rpc.call_void(LocoApiId::ExitWbcGait, "").await } + /// Move both hand end-effectors to target postures simultaneously. + pub async fn move_dual_hand_end_effector( + &self, + left_target_posture: &crate::types::Posture, + right_target_posture: &crate::types::Posture, + time_millis: i32, + ) -> Result<()> { + let param = json!({ + "left_target_posture": left_target_posture, + "right_target_posture": right_target_posture, + "time_millis": time_millis, + }) + .to_string(); + self.rpc + .call_void(LocoApiId::MoveDualHandEndEffector, param) + .await + } + + /// Start or stop a visual kick (side-foot kick). + pub async fn visual_kick(&self, start: bool) -> Result<()> { + let param = json!({ "start": start }).to_string(); + self.rpc.call_void(LocoApiId::VisualKick, param).await + } + /// Publish a raw gripper control topic message. pub fn publish_gripper(&self, control: GripperControl) -> Result<()> { self.gripper_publisher.write(control) diff --git a/booster_sdk/src/types/b1.rs b/booster_sdk/src/types/b1.rs index b8bdeac..76122ae 100644 --- a/booster_sdk/src/types/b1.rs +++ b/booster_sdk/src/types/b1.rs @@ -41,6 +41,8 @@ crate::api_id_enum! { UnloadCustomTrainedTraj = 2034, EnterWbcGait = 2035, ExitWbcGait = 2036, + MoveDualHandEndEffector = 2037, + VisualKick = 2038, } } diff --git a/booster_sdk_py/booster_sdk_bindings/booster_sdk_bindings.pyi b/booster_sdk_py/booster_sdk_bindings/booster_sdk_bindings.pyi index 984a8b1..59b9467 100644 --- a/booster_sdk_py/booster_sdk_bindings/booster_sdk_bindings.pyi +++ b/booster_sdk_py/booster_sdk_bindings/booster_sdk_bindings.pyi @@ -1047,6 +1047,19 @@ class BoosterClient: """Exit WBC gait mode.""" ... + def move_dual_hand_end_effector( + self, + left_target_posture: Posture, + right_target_posture: Posture, + time_millis: int, + ) -> None: + """Move both hand end-effectors to target postures simultaneously.""" + ... + + def visual_kick(self, start: bool) -> None: + """Start or stop a visual kick (side-foot kick).""" + ... + def publish_gripper_command(self, command: GripperCommand) -> None: """Publish low-level gripper command message.""" ... diff --git a/booster_sdk_py/src/client/booster.rs b/booster_sdk_py/src/client/booster.rs index 27487b2..b52a0fd 100644 --- a/booster_sdk_py/src/client/booster.rs +++ b/booster_sdk_py/src/client/booster.rs @@ -1626,6 +1626,33 @@ impl PyBoosterClient { wait_for_future(py, async move { client.exit_wbc_gait().await }).map_err(to_py_err) } + fn move_dual_hand_end_effector( + &self, + py: Python<'_>, + left_target_posture: PyPosture, + right_target_posture: PyPosture, + time_millis: i32, + ) -> PyResult<()> { + let client = Arc::clone(&self.client); + let left_target_posture: Posture = left_target_posture.into(); + let right_target_posture: Posture = right_target_posture.into(); + wait_for_future(py, async move { + client + .move_dual_hand_end_effector( + &left_target_posture, + &right_target_posture, + time_millis, + ) + .await + }) + .map_err(to_py_err) + } + + fn visual_kick(&self, py: Python<'_>, start: bool) -> PyResult<()> { + let client = Arc::clone(&self.client); + wait_for_future(py, async move { client.visual_kick(start).await }).map_err(to_py_err) + } + fn publish_gripper_command(&self, command: PyGripperCommand) -> PyResult<()> { let command: GripperCommand = command.into(); self.client diff --git a/pixi.toml b/pixi.toml index d9a28cb..fac071d 100644 --- a/pixi.toml +++ b/pixi.toml @@ -3,7 +3,7 @@ authors = ["Team whIRLwind"] channels = ["conda-forge"] name = "booster-sdk" platforms = ["osx-arm64", "linux-64", "linux-aarch64"] -version = "0.1.0-alpha.11" +version = "0.1.0-alpha.12" [environments] py = ["wheel-build", "python-tasks"]