Skip to content

Commit 85627d2

Browse files
authored
Merge pull request #1166 from StanfordVL/r1pro
R1pro
2 parents fc894b1 + db5f679 commit 85627d2

File tree

6 files changed

+170
-9
lines changed

6 files changed

+170
-9
lines changed

omnigibson/action_primitives/starter_semantic_action_primitives.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,19 @@
3232
)
3333
from omnigibson.macros import create_module_macros
3434
from omnigibson.objects.object_base import BaseObject
35-
from omnigibson.robots import R1, BaseRobot, BehaviorRobot, Fetch, Freight, Husky, Locobot, Stretch, Tiago, Turtlebot
35+
from omnigibson.robots import (
36+
R1,
37+
R1Pro,
38+
BaseRobot,
39+
BehaviorRobot,
40+
Fetch,
41+
Freight,
42+
Husky,
43+
Locobot,
44+
Stretch,
45+
Tiago,
46+
Turtlebot,
47+
)
3648
from omnigibson.robots.manipulation_robot import ManipulationRobot
3749
from omnigibson.robots.holonomic_base_robot import HolonomicBaseRobot
3850
from omnigibson.tasks.behavior_task import BehaviorTask
@@ -56,6 +68,7 @@
5668
Locobot: 1.5,
5769
BehaviorRobot: 0.3,
5870
R1: 0.3,
71+
R1Pro: 0.3,
5972
}
6073
m.KP_ANGLE_VEL = {
6174
Tiago: 0.2,
@@ -67,6 +80,7 @@
6780
Locobot: 1.0,
6881
BehaviorRobot: 0.2,
6982
R1: 0.2,
83+
R1Pro: 0.2,
7084
}
7185

7286
m.DEFAULT_COLLISION_ACTIVATION_DISTANCE = 0.02

omnigibson/examples/robots/import_custom_robot.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -728,9 +728,14 @@ def get_joint_upper_limit(root_prim, joint_name):
728728
assert joint_prim is not None, f"Could not find joint prim with name {joint_name}!"
729729
return joint_prim.GetAttribute("physics:upperLimit").Get()
730730

731+
# The original format from Lula is a list of dicts, so we need to convert to a single dict
732+
if isinstance(curobo_cfg.collision_spheres, list):
733+
collision_spheres = {k: v for c in curobo_cfg.collision_spheres for k, v in c.to_dict().items()}
734+
else:
735+
collision_spheres = curobo_cfg.collision_spheres.to_dict()
736+
731737
# Generate list of collision link names -- this is simply the list of all link names from the
732738
# collision spheres specification
733-
collision_spheres = curobo_cfg.collision_spheres.to_dict()
734739
all_collision_link_names = list(collision_spheres.keys())
735740

736741
joint_prims = find_all_joints(robot_prim, only_articulated=True)
@@ -833,7 +838,7 @@ def get_joint_upper_limit(root_prim, joint_name):
833838
"--config",
834839
required=True,
835840
type=click.Path(exists=True, dir_okay=False),
836-
help="Absolute path to robot URDF file to import",
841+
help="Absolute path to robot config yaml file to import",
837842
)
838843
def import_custom_robot(config):
839844
# Load config

omnigibson/robots/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from omnigibson.robots.locomotion_robot import LocomotionRobot
1111
from omnigibson.robots.manipulation_robot import ManipulationRobot
1212
from omnigibson.robots.r1 import R1
13+
from omnigibson.robots.r1pro import R1Pro
1314
from omnigibson.robots.robot_base import REGISTERED_ROBOTS, BaseRobot
1415
from omnigibson.robots.stretch import Stretch
1516
from omnigibson.robots.tiago import Tiago
@@ -31,6 +32,7 @@
3132
"LocomotionRobot",
3233
"ManipulationRobot",
3334
"R1",
35+
"R1Pro",
3436
"REGISTERED_ROBOTS",
3537
"Stretch",
3638
"Tiago",

omnigibson/robots/r1.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ def __init__(
137137
**kwargs,
138138
)
139139

140+
def _post_load(self):
141+
super()._post_load()
142+
143+
# R1 and R1Pro's URDFs still use the mesh type for the collision meshes of the wheels (see the source URDFs)
144+
# as opposed to sphere primitives. As a result, even though import robot script changes to sphere approximation,
145+
# GeomPrim will change it back to convex hull approximation during post load. We need to manually set it back to sphere.
146+
# TODO: replace the mesh collision mesh with sphere primitives in the import robot script if use_sphere_wheels=True.
147+
for wheel_name in self.floor_touching_base_link_names:
148+
wheel_link = self.links[wheel_name]
149+
assert set(wheel_link.collision_meshes) == {"collisions"}, "Wheel link should only have 1 collision!"
150+
wheel_link.collision_meshes["collisions"].set_collision_approximation("boundingSphere")
151+
140152
# Name of the actual root link that we are interested in. Note that this is different from self.root_link_name,
141153
# which is "base_footprint_x", corresponding to the first of the 6 1DoF joints to control the base.
142154
@property
@@ -175,7 +187,7 @@ def tucked_default_joint_pos(self):
175187
# Keep the current joint positions for the base joints
176188
pos[self.base_idx] = self.get_joint_positions()[self.base_idx]
177189
for arm in self.arm_names:
178-
pos[self.gripper_control_idx[arm]] = th.tensor([0.03, 0.03]) # open gripper
190+
pos[self.gripper_control_idx[arm]] = th.tensor([0.05, 0.05]) # open gripper
179191
return pos
180192

181193
@property
@@ -184,7 +196,7 @@ def untucked_default_joint_pos(self):
184196
# Keep the current joint positions for the base joints
185197
pos[self.base_idx] = self.get_joint_positions()[self.base_idx]
186198
for arm in self.arm_names:
187-
pos[self.gripper_control_idx[arm]] = th.tensor([0.03, 0.03]) # open gripper
199+
pos[self.gripper_control_idx[arm]] = th.tensor([0.05, 0.05]) # open gripper
188200
pos[self.arm_control_idx[arm]] = th.tensor([0.0, 1.906, -0.991, 1.571, 0.915, -1.571])
189201
return pos
190202

omnigibson/robots/r1pro.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from functools import cached_property
2+
3+
import torch as th
4+
5+
from omnigibson.robots.r1 import R1
6+
7+
8+
class R1Pro(R1):
9+
"""
10+
R1 Pro Robot
11+
"""
12+
13+
@property
14+
def tucked_default_joint_pos(self):
15+
pos = th.zeros(self.n_dof)
16+
# Keep the current joint positions for the base joints
17+
pos[self.base_idx] = self.get_joint_positions()[self.base_idx]
18+
for arm in self.arm_names:
19+
pos[self.gripper_control_idx[arm]] = th.tensor([0.05, 0.05]) # open gripper
20+
return pos
21+
22+
@property
23+
def untucked_default_joint_pos(self):
24+
pos = th.zeros(self.n_dof)
25+
# Keep the current joint positions for the base joints
26+
pos[self.base_idx] = self.get_joint_positions()[self.base_idx]
27+
for arm in self.arm_names:
28+
pos[self.gripper_control_idx[arm]] = th.tensor([0.05, 0.05]) # open gripper
29+
pos[self.arm_control_idx["left"]] = th.tensor([0.0, 1.57, 0.0, -1.57, 1.57, 0.0, 0.0])
30+
pos[self.arm_control_idx["right"]] = th.tensor([0.0, -1.57, 0.0, -1.57, -1.57, 0.0, 0.0])
31+
return pos
32+
33+
@cached_property
34+
def floor_touching_base_link_names(self):
35+
return ["wheel_motor_link1", "wheel_motor_link2", "wheel_motor_link3"]
36+
37+
@cached_property
38+
def arm_link_names(self):
39+
return {arm: [f"{arm}_arm_link{i}" for i in range(1, 8)] for arm in self.arm_names}
40+
41+
@cached_property
42+
def arm_joint_names(self):
43+
return {arm: [f"{arm}_arm_joint{i}" for i in range(1, 8)] for arm in self.arm_names}
44+
45+
@cached_property
46+
def finger_link_names(self):
47+
return {arm: [f"{arm}_gripper_finger_link{i}" for i in range(1, 3)] for arm in self.arm_names}
48+
49+
@cached_property
50+
def finger_joint_names(self):
51+
return {arm: [f"{arm}_gripper_finger_joint{i}" for i in range(1, 3)] for arm in self.arm_names}
52+
53+
@property
54+
def arm_workspace_range(self):
55+
return {arm: th.deg2rad(th.tensor([-45, 45], dtype=th.float32)) for arm in self.arm_names}
56+
57+
@property
58+
def disabled_collision_pairs(self):
59+
# badly modeled gripper collision meshes
60+
return [
61+
["left_arm_link1", "torso_link4"],
62+
["left_arm_link2", "torso_link4"],
63+
["right_arm_link1", "torso_link4"],
64+
["right_arm_link2", "torso_link4"],
65+
["left_arm_link5", "left_arm_link7"],
66+
["right_arm_link5", "right_arm_link7"],
67+
["left_gripper_finger_link1", "left_realsense_link"],
68+
["right_gripper_finger_link1", "right_realsense_link"],
69+
["left_gripper_finger_link1", "left_gripper_finger_link2"],
70+
["right_gripper_finger_link1", "right_gripper_finger_link2"],
71+
["base_link", "wheel_motor_link1"],
72+
["base_link", "wheel_motor_link2"],
73+
["base_link", "wheel_motor_link3"],
74+
["torso_link2", "torso_link4"],
75+
]

tests/test_curobo.py

+57-4
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,57 @@ def test_curobo():
193193
},
194194
},
195195
},
196+
{
197+
"type": "R1Pro",
198+
"obs_modalities": "rgb",
199+
"position": [0.7, -0.75, 0.056],
200+
"orientation": [0, 0, 0.707, 0.707],
201+
"self_collisions": True,
202+
"action_normalize": False,
203+
"controller_config": {
204+
"base": {
205+
"name": "HolonomicBaseJointController",
206+
"motor_type": "position",
207+
"command_input_limits": None,
208+
"use_impedances": False,
209+
},
210+
"trunk": {
211+
"name": "JointController",
212+
"motor_type": "position",
213+
"command_input_limits": None,
214+
"use_delta_commands": False,
215+
"use_impedances": False,
216+
},
217+
"arm_left": {
218+
"name": "JointController",
219+
"motor_type": "position",
220+
"command_input_limits": None,
221+
"use_delta_commands": False,
222+
"use_impedances": False,
223+
},
224+
"arm_right": {
225+
"name": "JointController",
226+
"motor_type": "position",
227+
"command_input_limits": None,
228+
"use_delta_commands": False,
229+
"use_impedances": False,
230+
},
231+
"gripper_left": {
232+
"name": "JointController",
233+
"motor_type": "position",
234+
"command_input_limits": None,
235+
"use_delta_commands": False,
236+
"use_impedances": False,
237+
},
238+
"gripper_right": {
239+
"name": "JointController",
240+
"motor_type": "position",
241+
"command_input_limits": None,
242+
"use_delta_commands": False,
243+
"use_impedances": False,
244+
},
245+
},
246+
},
196247
]
197248
for robot_cfg in robot_cfgs:
198249
cfg["robots"] = [robot_cfg]
@@ -226,6 +277,8 @@ def test_curobo():
226277
# Create CuRobo instance
227278
batch_size = 2
228279
n_samples = 20
280+
max_false_positive_rate = 0.05
281+
max_false_negative_rate = 0.0
229282

230283
cmg = CuRoboMotionGenerator(
231284
robot=robot,
@@ -326,11 +379,11 @@ def test_curobo():
326379
f"Collision checking false positive: {false_positive / n_samples}, false negative: {false_negative / n_samples}."
327380
)
328381
assert (
329-
false_positive / n_samples == 0.0
330-
), f"Collision checking false positive rate: {false_positive / n_samples}, should be == 0.0."
382+
false_positive / n_samples <= max_false_positive_rate
383+
), f"Collision checking false positive rate: {false_positive / n_samples} > {max_false_positive_rate}"
331384
assert (
332-
false_negative / n_samples == 0.0
333-
), f"Collision checking false negative rate: {false_negative / n_samples}, should be == 0.0."
385+
false_negative / n_samples <= max_false_negative_rate
386+
), f"Collision checking false negative rate: {false_negative / n_samples} > {max_false_negative_rate}"
334387

335388
env.scene.reset()
336389

0 commit comments

Comments
 (0)