Skip to content

Commit 7b7342f

Browse files
feat: add dualsense option in demos
1 parent 6a0fe7e commit 7b7342f

6 files changed

Lines changed: 233 additions & 39 deletions

File tree

robosuite/demos/demo_device_control.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@
155155
type=int,
156156
help="Sleep when simluation runs faster than specified frame rate; 20 fps is real time.",
157157
)
158+
parser.add_argument(
159+
"--reverse_xy",
160+
type=bool,
161+
default=False,
162+
help="(DualSense Only)Reverse the effect of the x and y axes of the joystick.It is used to handle the case that the left/right and front/back sides of the view are opposite to the LX and LY of the joystick(Push LX up but the robot move left in your view)",
163+
)
158164
args = parser.parse_args()
159165

160166
# Get controller config
@@ -220,14 +226,14 @@
220226
env=env,
221227
pos_sensitivity=args.pos_sensitivity,
222228
rot_sensitivity=args.rot_sensitivity,
223-
reverse_xy=True,
229+
reverse_xy=args.reverse_xy,
224230
)
225231
elif args.device == "mjgui":
226232
from robosuite.devices.mjgui import MJGUI
227233

228234
device = MJGUI(env=env)
229235
else:
230-
raise Exception("Invalid device choice: choose either 'keyboard' or 'spacemouse'.")
236+
raise Exception("Invalid device choice: choose either 'keyboard', 'dualsene' or 'spacemouse'.")
231237

232238
while True:
233239
# Reset the environment

robosuite/demos/demo_sensor_corruption.py

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,65 @@
2525
if __name__ == "__main__":
2626
parser = argparse.ArgumentParser()
2727
parser.add_argument("--environment", type=str, default="Lift")
28-
parser.add_argument("--robots", nargs="+", type=str, default="Panda", help="Which robot(s) to use in the env")
2928
parser.add_argument(
30-
"--config", type=str, default="default", help="Specified environment configuration if necessary"
29+
"--robots",
30+
nargs="+",
31+
type=str,
32+
default="Panda",
33+
help="Which robot(s) to use in the env",
3134
)
32-
parser.add_argument("--arm", type=str, default="right", help="Which arm to control (eg bimanual) 'right' or 'left'")
33-
parser.add_argument("--switch-on-grasp", action="store_true", help="Switch gripper control on gripper action")
3435
parser.add_argument(
35-
"--toggle-corruption-on-grasp", action="store_true", help="Toggle corruption ON / OFF on gripper action"
36+
"--config",
37+
type=str,
38+
default="default",
39+
help="Specified environment configuration if necessary",
40+
)
41+
parser.add_argument(
42+
"--arm",
43+
type=str,
44+
default="right",
45+
help="Which arm to control (eg bimanual) 'right' or 'left'",
46+
)
47+
parser.add_argument(
48+
"--switch-on-grasp",
49+
action="store_true",
50+
help="Switch gripper control on gripper action",
51+
)
52+
parser.add_argument(
53+
"--toggle-corruption-on-grasp",
54+
action="store_true",
55+
help="Toggle corruption ON / OFF on gripper action",
3656
)
3757
parser.add_argument("--device", type=str, default="keyboard")
38-
parser.add_argument("--pos-sensitivity", type=float, default=1.0, help="How much to scale position user inputs")
39-
parser.add_argument("--rot-sensitivity", type=float, default=1.0, help="How much to scale rotation user inputs")
58+
parser.add_argument(
59+
"--pos-sensitivity",
60+
type=float,
61+
default=1.0,
62+
help="How much to scale position user inputs",
63+
)
64+
parser.add_argument(
65+
"--rot-sensitivity",
66+
type=float,
67+
default=1.0,
68+
help="How much to scale rotation user inputs",
69+
)
4070
parser.add_argument("--delay", type=float, default=0.04, help="average delay to use (sec)")
41-
parser.add_argument("--corruption", type=float, default=20.0, help="Scale of corruption to use (std dev)")
71+
parser.add_argument(
72+
"--corruption",
73+
type=float,
74+
default=20.0,
75+
help="Scale of corruption to use (std dev)",
76+
)
4277
parser.add_argument("--camera", type=str, default="agentview", help="Name of camera to render")
4378
parser.add_argument("--width", type=int, default=512)
4479
parser.add_argument("--height", type=int, default=384)
80+
parser.add_argument(
81+
"--reverse_xy",
82+
type=bool,
83+
default=False,
84+
help="(DualSense Only)Reverse the effect of the x and y axes of the joystick.It is used to handle the case that the left/right and front/back sides of the view are opposite to the LX and LY of the joystick(Push LX up but the robot move left in your view)",
85+
)
86+
4587
args = parser.parse_args()
4688

4789
# Create argument configuration
@@ -164,13 +206,30 @@ def calculate_proprio_delay():
164206
if args.device == "keyboard":
165207
from robosuite.devices import Keyboard
166208

167-
device = Keyboard(env=env, pos_sensitivity=args.pos_sensitivity, rot_sensitivity=args.rot_sensitivity)
209+
device = Keyboard(
210+
env=env,
211+
pos_sensitivity=args.pos_sensitivity,
212+
rot_sensitivity=args.rot_sensitivity,
213+
)
168214
elif args.device == "spacemouse":
169215
from robosuite.devices import SpaceMouse
170216

171-
device = SpaceMouse(env=env, pos_sensitivity=args.pos_sensitivity, rot_sensitivity=args.rot_sensitivity)
217+
device = SpaceMouse(
218+
env=env,
219+
pos_sensitivity=args.pos_sensitivity,
220+
rot_sensitivity=args.rot_sensitivity,
221+
)
222+
elif args.device == "dualsense":
223+
from robosuite.devices import DualSense
224+
225+
device = DualSense(
226+
env=env,
227+
pos_sensitivity=args.pos_sensitivity,
228+
rot_sensitivity=args.rot_sensitivity,
229+
reverse_xy=args.reverse_xy,
230+
)
172231
else:
173-
raise Exception("Invalid device choice: choose either 'keyboard' or 'spacemouse'.")
232+
raise Exception("Invalid device choice: choose either 'keyboard' or 'spacemouse' or 'dualsense'.")
174233

175234
while True:
176235
# Reset the environment

robosuite/demos/demo_usd_export.py

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
""" Exports a USD file corresponding to the collected trajectory.
1+
"""Exports a USD file corresponding to the collected trajectory.
22
33
The USD (Universal Scene Description) file format allows users to save
44
trajectories such that they can be rendered in external renderers such
@@ -8,8 +8,9 @@
88
99
***IMPORTANT***: If you are using mujoco version 3.1.1, please make sure
1010
that you also have numpy < 2 installed in your environment. Failure to do
11-
so may result in incorrect renderings.
11+
so may result in incorrect renderings.
1212
"""
13+
1314
import argparse
1415

1516
import mujoco
@@ -26,21 +27,68 @@
2627
ROBOSUITE_DEFAULT_LOGGER.warning("If using mujoco==3.1.1, please use numpy < 2 for rendering with USD.")
2728

2829
if __name__ == "__main__":
29-
3030
parser = argparse.ArgumentParser()
3131
parser.add_argument("--environment", type=str, default="Lift")
32-
parser.add_argument("--robots", nargs="+", type=str, default="Panda", help="Which robot(s) to use in the env")
3332
parser.add_argument(
34-
"--config", type=str, default="default", help="Specified environment configuration if necessary"
33+
"--robots",
34+
nargs="+",
35+
type=str,
36+
default="Panda",
37+
help="Which robot(s) to use in the env",
38+
)
39+
parser.add_argument(
40+
"--config",
41+
type=str,
42+
default="default",
43+
help="Specified environment configuration if necessary",
44+
)
45+
parser.add_argument(
46+
"--arm",
47+
type=str,
48+
default="right",
49+
help="Which arm to control (eg bimanual) 'right' or 'left'",
50+
)
51+
parser.add_argument(
52+
"--camera",
53+
type=str,
54+
default="agentview",
55+
help="Which camera to use for collecting demos",
56+
)
57+
parser.add_argument(
58+
"--switch-on-grasp",
59+
action="store_true",
60+
help="Switch gripper control on gripper action",
61+
)
62+
parser.add_argument(
63+
"--toggle-camera-on-grasp",
64+
action="store_true",
65+
help="Switch camera angle on gripper action",
66+
)
67+
parser.add_argument(
68+
"--controller",
69+
type=str,
70+
default="BASIC",
71+
help="Choice of controller. Can be 'ik' or 'osc'",
3572
)
36-
parser.add_argument("--arm", type=str, default="right", help="Which arm to control (eg bimanual) 'right' or 'left'")
37-
parser.add_argument("--camera", type=str, default="agentview", help="Which camera to use for collecting demos")
38-
parser.add_argument("--switch-on-grasp", action="store_true", help="Switch gripper control on gripper action")
39-
parser.add_argument("--toggle-camera-on-grasp", action="store_true", help="Switch camera angle on gripper action")
40-
parser.add_argument("--controller", type=str, default="BASIC", help="Choice of controller. Can be 'ik' or 'osc'")
4173
parser.add_argument("--device", type=str, default="keyboard")
42-
parser.add_argument("--pos-sensitivity", type=float, default=1.0, help="How much to scale position user inputs")
43-
parser.add_argument("--rot-sensitivity", type=float, default=1.0, help="How much to scale rotation user inputs")
74+
parser.add_argument(
75+
"--pos-sensitivity",
76+
type=float,
77+
default=1.0,
78+
help="How much to scale position user inputs",
79+
)
80+
parser.add_argument(
81+
"--rot-sensitivity",
82+
type=float,
83+
default=1.0,
84+
help="How much to scale rotation user inputs",
85+
)
86+
parser.add_argument(
87+
"--reverse_xy",
88+
type=bool,
89+
default=False,
90+
help="(DualSense Only)Reverse the effect of the x and y axes of the joystick.It is used to handle the case that the left/right and front/back sides of the view are opposite to the LX and LY of the joystick(Push LX up but the robot move left in your view)",
91+
)
4492
args = parser.parse_args()
4593

4694
# Get controller config
@@ -87,14 +135,31 @@
87135
if args.device == "keyboard":
88136
from robosuite.devices import Keyboard
89137

90-
device = Keyboard(env=env, pos_sensitivity=args.pos_sensitivity, rot_sensitivity=args.rot_sensitivity)
138+
device = Keyboard(
139+
env=env,
140+
pos_sensitivity=args.pos_sensitivity,
141+
rot_sensitivity=args.rot_sensitivity,
142+
)
91143
env.viewer.add_keypress_callback(device.on_press)
92144
elif args.device == "spacemouse":
93145
from robosuite.devices import SpaceMouse
94146

95-
device = SpaceMouse(env=env, pos_sensitivity=args.pos_sensitivity, rot_sensitivity=args.rot_sensitivity)
147+
device = SpaceMouse(
148+
env=env,
149+
pos_sensitivity=args.pos_sensitivity,
150+
rot_sensitivity=args.rot_sensitivity,
151+
)
152+
elif args.device == "dualsense":
153+
from robosuite.devices import DualSense
154+
155+
device = DualSense(
156+
env=env,
157+
pos_sensitivity=args.pos_sensitivity,
158+
rot_sensitivity=args.rot_sensitivity,
159+
reverse_xy=args.reverse_xy,
160+
)
96161
else:
97-
raise Exception("Invalid device choice: choose either 'keyboard' or 'spacemouse'.")
162+
raise Exception("Invalid device choice: choose either 'keyboard' or 'spacemouse' or 'dualsense'.")
98163

99164
env.reset()
100165
cam_id = 0

robosuite/devices/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
except ImportError as e:
88
print("Exception!", e)
99
print(
10-
"""Unable to load module hid, required to interface with SpaceMouse.\n
10+
"""Unable to load module hid, required to interface with SpaceMouse or DualSense.\n
1111
Only macOS is officially supported. Install the additional\n
1212
requirements with `pip install -r requirements-extra.txt`"""
1313
)

robosuite/devices/dualsense.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,14 @@ class DualSense(Device):
182182
You can look up its vendor/product id from this method.
183183
184184
You can test your DualSense in https://hardwaretester.com/gamepad and https://nondebug.github.io/dualsense/dualsense-explorer.html
185+
DualSense HID protocol refer to https://github.com/nondebug/dualsense
185186
186187
Args:
187188
env (RobotEnv): The environment which contains the robot(s) to control
188189
using this device.
189190
pos_sensitivity (float): Magnitude of input position command scaling
190191
rot_sensitivity (float): Magnitude of scale input rotation commands scaling
192+
reverse_xy (bool): Whether to reverse the effect of the x and y axes of the joystick. It is used to handle the case that the left/right and front/back sides of the view are opposite to the LX and LY of the joystick(Push LX up but the robot move left in your view)
191193
"""
192194

193195
def __init__(
@@ -232,7 +234,7 @@ def __init__(
232234
print("DualSense Connection type: %s" % ConnectionType.to_string(self.connection_type))
233235
print("")
234236
print(
235-
"PS: You can set `reverse_xy` to True if the left and right sides of the view are opposite to the LX and LY of the joystick."
237+
"PS: You can modify `reverse_xy` if the left/right and front/back sides of the view are opposite to the LX and LY of the joystick(Push LX up but the robot move left in your view)."
236238
)
237239

238240
self.reverse_xy = reverse_xy
@@ -310,6 +312,17 @@ def start_control(self):
310312
self._enabled = True
311313

312314
def _check_connection_type(self):
315+
"""
316+
Get the connection type of the DualSense controller.
317+
ConnectionType:
318+
- USB: DualSense connected via USB
319+
- BT01: DualSense connected via Bluetooth, sends input report id 0x01
320+
- BT31: DualSense connected via Bluetooth, sends input report id 0x31
321+
- UNKNOWN: Unknown connection type
322+
323+
Returns:
324+
ConnectionType: connection type(USB, BT01, BT31, UNKNOWN)
325+
"""
313326
dummy_report = self.device.read(100)
314327
dummy_report_length = len(dummy_report)
315328
if dummy_report_length == USB_REPORT_LENGTH:

0 commit comments

Comments
 (0)