Skip to content

Commit 1436f73

Browse files
authored
Merge pull request #1075 from StanfordVL/feat/robot-fixes
Feat/robot fixes
2 parents 6203d71 + 2d8c585 commit 1436f73

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1044
-472
lines changed

docs/tutorials/custom_robot_import.md

-22
Original file line numberDiff line numberDiff line change
@@ -494,28 +494,6 @@ Now that we have the USD file for the robot, let's write our own robot class. Fo
494494
def wheel_axle_length(self):
495495
return 0.330
496496

497-
@property
498-
def finger_lengths(self):
499-
return {self.default_arm: 0.04}
500-
501-
@property
502-
def assisted_grasp_start_points(self):
503-
return {
504-
self.default_arm: [
505-
GraspingPoint(link_name="link_gripper_finger_right", position=th.tensor([0.013, 0.0, 0.01])),
506-
GraspingPoint(link_name="link_gripper_finger_right", position=th.tensor([-0.01, 0.0, 0.009])),
507-
]
508-
}
509-
510-
@property
511-
def assisted_grasp_end_points(self):
512-
return {
513-
self.default_arm: [
514-
GraspingPoint(link_name="link_gripper_finger_left", position=th.tensor([0.013, 0.0, 0.01])),
515-
GraspingPoint(link_name="link_gripper_finger_left", position=th.tensor([-0.01, 0.0, 0.009])),
516-
]
517-
}
518-
519497
@property
520498
def disabled_collision_pairs(self):
521499
return [

docs/tutorials/demo_collection.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ playback_env = DataPlaybackWrapper.create_from_hdf5(
101101
)
102102

103103
# Playback the entire dataset and record observations
104-
playback_env.playback_dataset(record=True)
104+
playback_env.playback_dataset(record_data=True)
105105

106106
# Save the recorded playback data
107107
playback_env.save_data()

omnigibson/action_primitives/starter_semantic_action_primitives.py

+29-14
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
m.LOW_PRECISION_DIST_THRESHOLD = 0.1
103103
m.LOW_PRECISION_ANGLE_THRESHOLD = 0.2
104104

105-
m.JOINT_POS_DIFF_THRESHOLD = 0.01
105+
m.JOINT_POS_DIFF_THRESHOLD = 0.005
106106
m.LOW_PRECISION_JOINT_POS_DIFF_THRESHOLD = 0.05
107107
m.JOINT_CONTROL_MIN_ACTION = 0.0
108108
m.MAX_ALLOWED_JOINT_ERROR_FOR_LINEAR_MOTION = math.radians(45)
@@ -506,7 +506,10 @@ def _sample_grasp_pose(self, obj):
506506
# Identity quaternion for top-down grasping (x-forward, y-right, z-down)
507507
approach_dir = T.quat2mat(grasp_quat) @ th.tensor([0.0, 0.0, -1.0])
508508

509-
pregrasp_offset = self.robot.finger_lengths[self.arm] / 2.0 + m.GRASP_APPROACH_DISTANCE
509+
avg_finger_offset = th.mean(
510+
th.tensor([length for length in self.robot.eef_to_fingertip_lengths[self.arm].values()])
511+
)
512+
pregrasp_offset = avg_finger_offset + m.GRASP_APPROACH_DISTANCE
510513

511514
pregrasp_pos = grasp_pos - approach_dir * pregrasp_offset
512515

@@ -581,7 +584,7 @@ def _grasp(self, obj):
581584
# By default, it's NOT the z-axis of the world frame unless `project_pose_to_goal_frame=False` is set in curobo.
582585
# For sticky grasping, we also need to ignore the object during motion planning because the fingers are already closed.
583586
yield from self._move_hand(
584-
grasp_pose, motion_constraint=[1, 1, 1, 1, 1, 0], stop_on_contact=True, ignore_objects=[obj]
587+
grasp_pose, motion_constraint=[1, 1, 1, 1, 1, 0], stop_on_ag=True, ignore_objects=[obj]
585588
)
586589
elif self.robot.grasping_mode == "assisted":
587590
indented_print("Assisted grasping: approach")
@@ -853,6 +856,7 @@ def _move_hand(
853856
self,
854857
target_pose,
855858
stop_on_contact=False,
859+
stop_on_ag=False,
856860
motion_constraint=None,
857861
low_precision=False,
858862
lock_auxiliary_arm=False,
@@ -864,6 +868,7 @@ def _move_hand(
864868
Args:
865869
target_pose (Tuple[th.tensor, th.tensor]): target pose to reach for the default end-effector in the world frame
866870
stop_on_contact (bool): Whether to stop executing motion plan if contact is detected
871+
stop_on_ag (bool): Whether to stop executing motion plan if assisted grasping is activated
867872
motion_constraint (MotionConstraint): Motion constraint for the motion
868873
low_precision (bool): Whether to use low precision for the motion
869874
lock_auxiliary_arm (bool): Whether to lock the other arm in place
@@ -906,7 +911,9 @@ def _move_hand(
906911
)
907912

908913
indented_print(f"Plan has {len(q_traj)} steps")
909-
yield from self._execute_motion_plan(q_traj, stop_on_contact=stop_on_contact, low_precision=low_precision)
914+
yield from self._execute_motion_plan(
915+
q_traj, stop_on_contact=stop_on_contact, stop_on_ag=stop_on_ag, low_precision=low_precision
916+
)
910917

911918
def _plan_joint_motion(
912919
self,
@@ -972,7 +979,13 @@ def _plan_joint_motion(
972979
return q_traj
973980

974981
def _execute_motion_plan(
975-
self, q_traj, stop_on_contact=False, ignore_failure=False, low_precision=False, ignore_physics=False
982+
self,
983+
q_traj,
984+
stop_on_contact=False,
985+
stop_on_ag=False,
986+
ignore_failure=False,
987+
low_precision=False,
988+
ignore_physics=False,
976989
):
977990
for i, joint_pos in enumerate(q_traj):
978991
# indented_print(f"Executing motion plan step {i + 1}/{len(q_traj)}")
@@ -992,6 +1005,12 @@ def _execute_motion_plan(
9921005
articulation_control_idx = th.cat(articulation_control_idx)
9931006
for j in range(m.MAX_STEPS_FOR_JOINT_MOTION):
9941007
# indented_print(f"Step {j + 1}/{m.MAX_STEPS_FOR_JOINT_MOTION}")
1008+
1009+
# We need to call @q_to_action for every step because as the robot base moves, the same base joint_pos will be
1010+
# converted to different actions, since HolonomicBaseJointController accepts an action in the robot local frame.
1011+
action = self.robot.q_to_action(joint_pos)
1012+
yield self._postprocess_action(action)
1013+
9951014
current_joint_pos = self.robot.get_joint_positions()
9961015
joint_pos_diff = joint_pos - current_joint_pos
9971016
base_joint_diff = joint_pos_diff[self.robot.base_control_idx]
@@ -1014,14 +1033,10 @@ def _execute_motion_plan(
10141033

10151034
collision_detected = detect_robot_collision_in_sim(self.robot)
10161035
if stop_on_contact and collision_detected:
1017-
indented_print(f"Collision detected at step {i + 1}/{len(q_traj)}")
10181036
return
10191037

1020-
# We need to call @q_to_action for every step because as the robot base moves, the same base joint_pos will be
1021-
# converted to different actions, since HolonomicBaseJointController accepts an action in the robot local frame.
1022-
action = self.robot.q_to_action(joint_pos)
1023-
1024-
yield self._postprocess_action(action)
1038+
if stop_on_ag and self._get_obj_in_hand() is not None:
1039+
return
10251040

10261041
if not ignore_failure:
10271042
if not base_target_reached:
@@ -1334,13 +1349,13 @@ def _move_fingers_to_limit(self, limit_type):
13341349
target_joint_positions = self._get_joint_position_with_fingers_at_limit(limit_type)
13351350
action = self.robot.q_to_action(target_joint_positions)
13361351
for _ in range(m.MAX_STEPS_FOR_GRASP_OR_RELEASE):
1337-
current_joint_positinos = self.robot.get_joint_positions()
1338-
if th.allclose(current_joint_positinos, target_joint_positions, atol=0.005):
1352+
yield self._postprocess_action(action)
1353+
current_joint_positions = self.robot.get_joint_positions()
1354+
if th.allclose(current_joint_positions, target_joint_positions, atol=m.JOINT_POS_DIFF_THRESHOLD):
13391355
break
13401356
elif limit_type == "lower" and self._get_obj_in_hand() is not None:
13411357
# If we are grasping an object, we should stop when object is detected in hand
13421358
break
1343-
yield self._postprocess_action(action)
13441359

13451360
def _execute_grasp(self):
13461361
"""

omnigibson/configs/fetch_behavior.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ scene:
4040
robots:
4141
- type: Fetch
4242
obs_modalities: [scan, rgb, depth]
43+
include_sensor_names: null
44+
exclude_sensor_names: null
4345
scale: 1.0
4446
self_collision: false
4547
action_normalize: true

omnigibson/configs/r1_primitives.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ scene:
3232
robots:
3333
- type: R1
3434
obs_modalities: [rgb]
35+
include_sensor_names: null
36+
exclude_sensor_names: null
3537
scale: 1.0
3638
self_collisions: true
3739
action_normalize: false

omnigibson/configs/robots/fetch.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ robot:
1717
self_collision: true
1818
grasping_mode: physical
1919
default_arm_pose: vertical
20+
include_sensor_names: null
21+
exclude_sensor_names: null
2022
sensor_config:
2123
VisionSensor:
2224
sensor_kwargs:

omnigibson/configs/robots/freight.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ robot:
1010
base_name: null
1111
scale: 1.0
1212
self_collision: false
13+
include_sensor_names: null
14+
exclude_sensor_names: null
1315
sensor_config:
1416
VisionSensor:
1517
sensor_kwargs:

omnigibson/configs/robots/husky.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ robot:
1010
base_name: null
1111
scale: 1.0
1212
self_collision: false
13+
include_sensor_names: null
14+
exclude_sensor_names: null
1315
sensor_config:
1416
VisionSensor:
1517
sensor_kwargs:

omnigibson/configs/robots/locobot.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ robot:
1010
base_name: null
1111
scale: 1.0
1212
self_collision: false
13+
include_sensor_names: null
14+
exclude_sensor_names: null
1315
sensor_config:
1416
VisionSensor:
1517
sensor_kwargs:

omnigibson/configs/robots/turtlebot.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ robot:
1010
base_name: null
1111
scale: 1.0
1212
self_collision: false
13+
include_sensor_names: null
14+
exclude_sensor_names: null
1315
sensor_config:
1416
VisionSensor:
1517
sensor_kwargs:

omnigibson/configs/tiago_primitives.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ scene:
3333
robots:
3434
- type: Tiago
3535
obs_modalities: [rgb]
36+
include_sensor_names: null
37+
exclude_sensor_names: null
3638
scale: 1.0
3739
self_collisions: true
3840
action_normalize: false

omnigibson/configs/turtlebot_nav.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ scene:
3030
robots:
3131
- type: Turtlebot
3232
obs_modalities: [scan, rgb, depth]
33+
include_sensor_names: null
34+
exclude_sensor_names: null
3335
scale: 1.0
3436
self_collision: false
3537
action_normalize: true

omnigibson/controllers/controller_base.py

+61
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@
44

55
import torch as th
66

7+
from omnigibson.macros import create_module_macros
78
from omnigibson.utils.backend_utils import _compute_backend as cb
89
from omnigibson.utils.python_utils import Recreatable, Registerable, Serializable, assert_valid_key, classproperty
910

11+
# Create settings for this module
12+
m = create_module_macros(module_path=__file__)
13+
14+
# Set default isaac kp / kd for controllers
15+
m.DEFAULT_ISAAC_KP = 1e7
16+
m.DEFAULT_ISAAC_KD = 1e5
17+
1018
# Global dicts that will contain mappings
1119
REGISTERED_CONTROLLERS = dict()
1220
REGISTERED_LOCOMOTION_CONTROLLERS = dict()
@@ -76,6 +84,8 @@ def __init__(
7684
dof_idx,
7785
command_input_limits="default",
7886
command_output_limits="default",
87+
isaac_kp=None,
88+
isaac_kd=None,
7989
):
8090
"""
8191
Args:
@@ -99,6 +109,12 @@ def __init__(
99109
then all inputted command values will be scaled from the input range to the output range.
100110
If either is None, no scaling will be used. If "default", then this range will automatically be set
101111
to the @control_limits entry corresponding to self.control_type
112+
isaac_kp (None or float or Array[float]): If specified, stiffness gains to apply to the underlying
113+
isaac DOFs. Can either be a single number or a per-DOF set of numbers.
114+
Should only be nonzero if self.control_type is position
115+
isaac_kd (None or float or Array[float]): If specified, damping gains to apply to the underlying
116+
isaac DOFs. Can either be a single number or a per-DOF set of numbers
117+
Should only be nonzero if self.control_type is position or velocity
102118
"""
103119
# Store arguments
104120
self._control_freq = control_freq
@@ -154,6 +170,33 @@ def __init__(
154170
)
155171
)
156172

173+
# Set gains
174+
if self.control_type == ControlType.POSITION:
175+
# Set default kp / kd values if not specified
176+
isaac_kp = m.DEFAULT_ISAAC_KP if isaac_kp is None else isaac_kp
177+
isaac_kd = m.DEFAULT_ISAAC_KD if isaac_kd is None else isaac_kd
178+
elif self.control_type == ControlType.VELOCITY:
179+
# No kp should be specified, but kd should be
180+
assert (
181+
isaac_kp is None
182+
), f"Control type for controller {self.__class__.__name__} is VELOCITY, so no isaac_kp should be set!"
183+
isaac_kd = m.DEFAULT_ISAAC_KP if isaac_kd is None else isaac_kd
184+
elif self.control_type == ControlType.EFFORT:
185+
# Neither kp nor kd should be specified
186+
assert (
187+
isaac_kp is None
188+
), f"Control type for controller {self.__class__.__name__} is EFFORT, so no isaac_kp should be set!"
189+
assert (
190+
isaac_kd is None
191+
), f"Control type for controller {self.__class__.__name__} is EFFORT, so no isaac_kd should be set!"
192+
else:
193+
raise ValueError(
194+
f"Expected control type to be one of: [POSITION, VELOCITY, EFFORT], but got: {self.control_type}"
195+
)
196+
197+
self._isaac_kp = None if isaac_kp is None else self.nums2array(isaac_kp, self.control_dim)
198+
self._isaac_kd = None if isaac_kd is None else self.nums2array(isaac_kd, self.control_dim)
199+
157200
def _generate_default_command_input_limits(self):
158201
"""
159202
Generates default command input limits based on the control limits
@@ -510,6 +553,24 @@ def control_type(self):
510553
"""
511554
raise NotImplementedError
512555

556+
@property
557+
def isaac_kp(self):
558+
"""
559+
Returns:
560+
None or Array[float]: Stiffness gains that should be applied to the underlying Isaac joint motors.
561+
None if not specified.
562+
"""
563+
return self._isaac_kp
564+
565+
@property
566+
def isaac_kd(self):
567+
"""
568+
Returns:
569+
None or Array[float]: Stiffness gains that should be applied to the underlying Isaac joint motors.
570+
None if not specified.
571+
"""
572+
return self._isaac_kd
573+
513574
@property
514575
def command_input_limits(self):
515576
"""

omnigibson/controllers/dd_controller.py

+10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ def __init__(
2121
dof_idx,
2222
command_input_limits="default",
2323
command_output_limits="default",
24+
isaac_kp=None,
25+
isaac_kd=None,
2426
):
2527
"""
2628
Args:
@@ -47,6 +49,12 @@ def __init__(
4749
If either is None, no scaling will be used. If "default", then this range will automatically be set
4850
to the maximum linear and angular velocities calculated from @wheel_radius, @wheel_axle_length, and
4951
@control_limits velocity limits entry
52+
isaac_kp (None or float or Array[float]): If specified, stiffness gains to apply to the underlying
53+
isaac DOFs. Can either be a single number or a per-DOF set of numbers.
54+
Should only be nonzero if self.control_type is position
55+
isaac_kd (None or float or Array[float]): If specified, damping gains to apply to the underlying
56+
isaac DOFs. Can either be a single number or a per-DOF set of numbers
57+
Should only be nonzero if self.control_type is position or velocity
5058
"""
5159
# Store internal variables
5260
self._wheel_radius = wheel_radius
@@ -76,6 +84,8 @@ def __init__(
7684
dof_idx=dof_idx,
7785
command_input_limits=command_input_limits,
7886
command_output_limits=command_output_limits,
87+
isaac_kp=isaac_kp,
88+
isaac_kd=isaac_kd,
7989
)
8090

8191
def _update_goal(self, command, control_dict):

omnigibson/controllers/holonomic_base_joint_controller.py

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ def __init__(
2525
dof_idx,
2626
command_input_limits=None,
2727
command_output_limits=None,
28+
isaac_kp=None,
29+
isaac_kd=None,
2830
pos_kp=None,
2931
pos_damping_ratio=None,
3032
vel_kp=None,
@@ -55,6 +57,12 @@ def __init__(
5557
then all inputted command values will be scaled from the input range to the output range.
5658
If either is None, no scaling will be used. If "default", then this range will automatically be set
5759
to the @control_limits entry corresponding to self.control_type
60+
isaac_kp (None or float or Array[float]): If specified, stiffness gains to apply to the underlying
61+
isaac DOFs. Can either be a single number or a per-DOF set of numbers.
62+
Should only be nonzero if self.control_type is position
63+
isaac_kd (None or float or Array[float]): If specified, damping gains to apply to the underlying
64+
isaac DOFs. Can either be a single number or a per-DOF set of numbers
65+
Should only be nonzero if self.control_type is position or velocity
5866
pos_kp (None or float): If @motor_type is "position" and @use_impedances=True, this is the
5967
proportional gain applied to the joint controller. If None, a default value will be used.
6068
pos_damping_ratio (None or float): If @motor_type is "position" and @use_impedances=True, this is the
@@ -78,6 +86,8 @@ def __init__(
7886
dof_idx=dof_idx,
7987
command_input_limits=command_input_limits,
8088
command_output_limits=command_output_limits,
89+
isaac_kp=isaac_kp,
90+
isaac_kd=isaac_kd,
8191
pos_kp=pos_kp,
8292
pos_damping_ratio=pos_damping_ratio,
8393
vel_kp=vel_kp,

0 commit comments

Comments
 (0)