Skip to content

Gamepad Teleop: Flying gripper control mode#17

Open
hello-robot-shehab wants to merge 6 commits into
mainfrom
feature/flying-gripper-control-mode
Open

Gamepad Teleop: Flying gripper control mode#17
hello-robot-shehab wants to merge 6 commits into
mainfrom
feature/flying-gripper-control-mode

Conversation

@hello-robot-shehab
Copy link
Copy Markdown
Contributor

@hello-robot-shehab hello-robot-shehab commented May 21, 2026

Brings https://github.com/hello-robot/stretch4_flying_gripper to stretch_gamepad_teleop.

This PR adds https://github.com/hello-robot/stretch4_flying_gripper as a dependency in pyproject.toml.

To Test

Update May 22: it's probably more useful to test flying gripper in #21 or #22 instead of this PR; they contain the commits in this PR.

  1. Clone https://github.com/hello-robot/stretch4_flying_gripper:
cd ~/repos
git clone  https://github.com/hello-robot/stretch4_flying_gripper
pip install -e stretch4_flying_gripper

Note: if you already have it, make sure to checkout the latest main and pip install -e .
2. Run stretch_gamepad_teleop
3. Hold Select to change to the Flying Gripper Mapping and make sure it works in a similar manner to https://github.com/hello-robot/stretch4_flying_gripper/blob/main/stretch4_flying_gripper/stretch_gamepad_teleop_gripper.py, but with all the features in stretch_gamepad_teleop like changing speeds, handedness and self-collision vibration.

@hello-robot-shehab hello-robot-shehab marked this pull request as ready for review May 22, 2026 23:11
@hello-robot-shehab hello-robot-shehab changed the base branch from main to feature/analog-precision-mode May 22, 2026 23:25
@hello-garv
Copy link
Copy Markdown
Contributor

Would it be possible to make a util script with most of the flying gripper kinematics logic? If it can be abstracted into util functions that take position commands as their input, it can be used as a library for both gamepad control and the grasping demos. The gamepad script can handle the button press --> position change logic.

@@ -1,5 +1,6 @@
#!/usr/bin/env python3

from stretch4_flying_gripper.teleop_config import _get_base_planar_ik_urdf_file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be called directly from stretch4_urdf?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a wrapper around existing stretch4_urdf utils. Maybe we need an additional util to return just the desired urdf_path, rather than having to find it from a list?

def _get_base_planar_ik_urdf_file():
    tmp_gamepad_folder = "/tmp/stretch_gamepad_teleop"
    setup_shared_directory(Path(tmp_gamepad_folder))
    robot = generate_robot_from_base_xacro()
    urdf_paths = generate_ik_urdfs(robot, "gamepad_teleop", tmp_gamepad_folder)
    urdf_path = [urdf_path for urdf_path in urdf_paths if "planar_ik" in urdf_path and not "fixed_wrist" in urdf_path][0]
    return urdf_path

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yah makes sense, I'll add it in, thanks Anna!

import threading

from stretch4_body.utils.file_access_utils import acquire_lock_if_available, setup_shared_directory
from stretch4_flying_gripper.kinematic_controller import KinematicController
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like KinematicController already has a method for compute_ik_step, is there a reason why that can't be used in _map_flying_gripper_ik?

v_desired = np.array(cmd['v_desired']) * gamepad_speed_trans * speed_multiplier * dt
rot_change = np.array(cmd['rot_change']) * gamepad_speed_rot * speed_multiplier * dt
                
# v maps to joint displacements [delta_q_base_x, delta_q_base_y, delta_q_base_theta, delta_q_lift, delta_q_arm, delta_q_yaw, delta_q_ pitch, delta_q_roll]
v, _ = ikin.compute_ik_step(v_desired, rot_change, control_mode)
              
# Scale from displacement `v` back to continuous velocity by dividing by `dt`
v_vel = v / dt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is being used here:

v, _ = ikin.compute_ik_step(v_desired_vel, rot_change_vel, control_mode)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see it now. It seemed like a lot of computation inside the mapping function, but maybe that's unavoidable. I see it pretty much mirrors what was done in the gamepad teleop script that was in the flying gripper control package.

Base automatically changed from feature/analog-precision-mode to main May 29, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants