From 6600df96f6f676de297ade6e670edee6ac07132b Mon Sep 17 00:00:00 2001 From: cremebrule <84cremebrule@gmail.com> Date: Tue, 5 Sep 2023 14:25:24 -0700 Subject: [PATCH 01/13] add ability to specify sensor config for robots --- omnigibson/robots/fetch.py | 6 ++ omnigibson/robots/manipulation_robot.py | 6 ++ omnigibson/robots/robot_base.py | 137 +++++++++++++++++++++--- omnigibson/robots/tiago.py | 6 ++ omnigibson/sensors/__init__.py | 11 +- 5 files changed, 150 insertions(+), 16 deletions(-) diff --git a/omnigibson/robots/fetch.py b/omnigibson/robots/fetch.py index d956cf2a8..ebbc189d8 100644 --- a/omnigibson/robots/fetch.py +++ b/omnigibson/robots/fetch.py @@ -56,6 +56,7 @@ def __init__( # Unique to BaseRobot obs_modalities="all", proprio_obs="default", + sensor_config=None, # Unique to ManipulationRobot grasping_mode="physical", @@ -99,10 +100,14 @@ def __init__( obs_modalities (str or list of str): Observation modalities to use for this robot. Default is "all", which corresponds to all modalities being used. Otherwise, valid options should be part of omnigibson.sensors.ALL_SENSOR_MODALITIES. + Note: If @sensor_config explicitly specifies `modalities` for a given sensor class, it will + override any values specified from @obs_modalities! proprio_obs (str or list of str): proprioception observation key(s) to use for generating proprioceptive observations. If str, should be exactly "default" -- this results in the default proprioception observations being used, as defined by self.default_proprio_obs. See self._get_proprioception_dict for valid key choices + sensor_config (None or dict): nested dictionary mapping sensor class name(s) to specific sensor + configurations for this object. This will override any default values specified by this class. grasping_mode (str): One of {"physical", "assisted", "sticky"}. If "physical", no assistive grasping will be applied (relies on contact friction + finger force). If "assisted", will magnetize any object touching and within the gripper's fingers. @@ -149,6 +154,7 @@ def __init__( reset_joint_pos=reset_joint_pos, obs_modalities=obs_modalities, proprio_obs=proprio_obs, + sensor_config=sensor_config, grasping_mode=grasping_mode, **kwargs, ) diff --git a/omnigibson/robots/manipulation_robot.py b/omnigibson/robots/manipulation_robot.py index bdc899f68..6927e7e31 100644 --- a/omnigibson/robots/manipulation_robot.py +++ b/omnigibson/robots/manipulation_robot.py @@ -102,6 +102,7 @@ def __init__( # Unique to BaseRobot obs_modalities="all", proprio_obs="default", + sensor_config=None, # Unique to ManipulationRobot grasping_mode="physical", @@ -141,10 +142,14 @@ def __init__( obs_modalities (str or list of str): Observation modalities to use for this robot. Default is "all", which corresponds to all modalities being used. Otherwise, valid options should be part of omnigibson.sensors.ALL_SENSOR_MODALITIES. + Note: If @sensor_config explicitly specifies `modalities` for a given sensor class, it will + override any values specified from @obs_modalities! proprio_obs (str or list of str): proprioception observation key(s) to use for generating proprioceptive observations. If str, should be exactly "default" -- this results in the default proprioception observations being used, as defined by self.default_proprio_obs. See self._get_proprioception_dict for valid key choices + sensor_config (None or dict): nested dictionary mapping sensor class name(s) to specific sensor + configurations for this object. This will override any default values specified by this class. grasping_mode (str): One of {"physical", "assisted", "sticky"}. If "physical", no assistive grasping will be applied (relies on contact friction + finger force). If "assisted", will magnetize any object touching and within the gripper's fingers. @@ -189,6 +194,7 @@ def __init__( reset_joint_pos=reset_joint_pos, obs_modalities=obs_modalities, proprio_obs=proprio_obs, + sensor_config=sensor_config, **kwargs, ) diff --git a/omnigibson/robots/robot_base.py b/omnigibson/robots/robot_base.py index 21c8a61d4..266cf9a59 100644 --- a/omnigibson/robots/robot_base.py +++ b/omnigibson/robots/robot_base.py @@ -7,7 +7,7 @@ from omnigibson.objects.usd_object import USDObject from omnigibson.objects.controllable_object import ControllableObject from omnigibson.utils.gym_utils import GymObservable -from omnigibson.utils.python_utils import classproperty +from omnigibson.utils.python_utils import classproperty, merge_nested_dicts from omnigibson.utils.vision_utils import segmentation_to_rgb from omnigibson.utils.constants import PrimType from pxr import PhysxSchema @@ -59,6 +59,7 @@ def __init__( # Unique to this class obs_modalities="all", proprio_obs="default", + sensor_config=None, **kwargs, ): @@ -95,10 +96,14 @@ def __init__( obs_modalities (str or list of str): Observation modalities to use for this robot. Default is "all", which corresponds to all modalities being used. Otherwise, valid options should be part of omnigibson.sensors.ALL_SENSOR_MODALITIES. + Note: If @sensor_config explicitly specifies `modalities` for a given sensor class, it will + override any values specified from @obs_modalities! proprio_obs (str or list of str): proprioception observation key(s) to use for generating proprioceptive observations. If str, should be exactly "default" -- this results in the default proprioception observations being used, as defined by self.default_proprio_obs. See self._get_proprioception_dict for valid key choices + sensor_config (None or dict): nested dictionary mapping sensor class name(s) to specific sensor + configurations for this object. This will override any default values specified by this class. kwargs (dict): Additional keyword arguments that are used for other super() calls from subclasses, allowing for flexible compositions of various object subclasses (e.g.: Robot is USDObject + ControllableObject). """ @@ -106,6 +111,7 @@ def __init__( self._obs_modalities = obs_modalities if obs_modalities == "all" else \ {obs_modalities} if isinstance(obs_modalities, str) else set(obs_modalities) # this will get updated later when we fill in our sensors self._proprio_obs = self.default_proprio_obs if proprio_obs == "default" else list(proprio_obs) + self._sensor_config = sensor_config # Process abilities robot_abilities = {"robot": {}} @@ -148,6 +154,32 @@ def _post_load(self): # Run super post load first super()._post_load() + # Load the sensors + self._load_sensors() + + def _initialize(self): + # Run super first + super()._initialize() + + # Initialize all sensors + for sensor in self._sensors.values(): + sensor.initialize() + + # Load the observation space for this robot + self.load_observation_space() + + # Validate this robot configuration + self._validate_configuration() + + def _load_sensors(self): + """ + Loads sensor(s) to retrieve observations from this object. + Stores created sensors as dictionary mapping sensor names to specific sensor + instances used by this object. + """ + # Populate sensor config + self._sensor_config = self._generate_sensor_config(custom_config=self._sensor_config) + # Search for any sensors this robot might have attached to any of its links self._sensors = dict() obs_modalities = set() @@ -158,15 +190,17 @@ def _post_load(self): if prim_type in SENSOR_PRIMS_TO_SENSOR_CLS: # Infer what obs modalities to use for this sensor sensor_cls = SENSOR_PRIMS_TO_SENSOR_CLS[prim_type] - modalities = sensor_cls.all_modalities if self._obs_modalities == "all" else \ - sensor_cls.all_modalities.intersection(self._obs_modalities) - obs_modalities = obs_modalities.union(modalities) + sensor_kwargs = self._sensor_config[sensor_cls.__name__] + if "modalities" not in sensor_kwargs: + sensor_kwargs["modalities"] = sensor_cls.all_modalities if self._obs_modalities == "all" else \ + sensor_cls.all_modalities.intersection(self._obs_modalities) + obs_modalities = obs_modalities.union(sensor_kwargs["modalities"]) # Create the sensor and store it internally sensor = create_sensor( sensor_type=prim_type, prim_path=str(prim.GetPrimPath()), name=f"{self.name}:{link_name}_{prim_type}_sensor", - modalities=modalities, + **sensor_kwargs, ) self._sensors[sensor.name] = sensor @@ -177,19 +211,28 @@ def _post_load(self): # Update our overall obs modalities self._obs_modalities = obs_modalities - def _initialize(self): - # Run super first - super()._initialize() + def _generate_sensor_config(self, custom_config=None): + """ + Generates a fully-populated sensor config, overriding any default values with the corresponding values + specified in @custom_config - # Initialize all sensors - for sensor in self._sensors.values(): - sensor.initialize() + Args: + custom_config (None or Dict[str, ...]): nested dictionary mapping sensor class name(s) to specific custom + sensor configurations for this object. This will override any default values specified by this class - # Load the observation space for this robot - self.load_observation_space() + Returns: + dict: Fully-populated nested dictionary mapping sensor class name(s) to specific sensor configurations + for this object + """ + sensor_config = {} if custom_config is None else deepcopy(custom_config) - # Validate this robot configuration - self._validate_configuration() + # Merge the sensor dictionaries + sensor_config = merge_nested_dicts( + base_dict=self._default_sensor_config, + extra_dict=sensor_config, + ) + + return sensor_config def _validate_configuration(self): """ @@ -392,6 +435,70 @@ def proprioception_dim(self): """ return len(self.get_proprioception()) + @property + def _default_sensor_config(self): + """ + Returns: + dict: default nested dictionary mapping sensor class name(s) to specific sensor + configurations for this object. See kwargs from omnigibson/sensors/__init__/create_sensor for more + details + + Expected structure is as follows: + SensorClassName1: + modalities: ... + enabled: ... + noise_type: ... + noise_kwargs: + ... + sensor_kwargs: + ... + SensorClassName2: + modalities: ... + enabled: ... + noise_type: ... + noise_kwargs: + ... + sensor_kwargs: + ... + ... + """ + return { + "VisionSensor": { + "enabled": True, + "noise_type": None, + "noise_kwargs": None, + "sensor_kwargs": { + "image_height": 128, + "image_width": 128, + }, + }, + "ScanSensor": { + "enabled": True, + "noise_type": None, + "noise_kwargs": None, + "sensor_kwargs": { + + # Basic LIDAR kwargs + "min_range": 0.05, + "max_range": 10.0, + "horizontal_fov": 360.0, + "vertical_fov": 1.0, + "yaw_offset": 0.0, + "horizontal_resolution": 1.0, + "vertical_resolution": 1.0, + "rotation_rate": 0.0, + "draw_points": False, + "draw_lines": False, + + # Occupancy Grid kwargs + "occupancy_grid_resolution": 128, + "occupancy_grid_range": 5.0, + "occupancy_grid_inner_radius": 0.5, + "occupancy_grid_local_link": None, + }, + }, + } + @property def default_proprio_obs(self): """ diff --git a/omnigibson/robots/tiago.py b/omnigibson/robots/tiago.py index 1387778a5..104fbd994 100644 --- a/omnigibson/robots/tiago.py +++ b/omnigibson/robots/tiago.py @@ -71,6 +71,7 @@ def __init__( # Unique to BaseRobot obs_modalities="all", proprio_obs="default", + sensor_config=None, # Unique to ManipulationRobot grasping_mode="physical", @@ -116,10 +117,14 @@ def __init__( obs_modalities (str or list of str): Observation modalities to use for this robot. Default is "all", which corresponds to all modalities being used. Otherwise, valid options should be part of omnigibson.sensors.ALL_SENSOR_MODALITIES. + Note: If @sensor_config explicitly specifies `modalities` for a given sensor class, it will + override any values specified from @obs_modalities! proprio_obs (str or list of str): proprioception observation key(s) to use for generating proprioceptive observations. If str, should be exactly "default" -- this results in the default proprioception observations being used, as defined by self.default_proprio_obs. See self._get_proprioception_dict for valid key choices + sensor_config (None or dict): nested dictionary mapping sensor class name(s) to specific sensor + configurations for this object. This will override any default values specified by this class. grasping_mode (str): One of {"physical", "assisted", "sticky"}. If "physical", no assistive grasping will be applied (relies on contact friction + finger force). If "assisted", will magnetize any object touching and within the gripper's fingers. @@ -169,6 +174,7 @@ def __init__( reset_joint_pos=reset_joint_pos, obs_modalities=obs_modalities, proprio_obs=proprio_obs, + sensor_config=sensor_config, grasping_mode=grasping_mode, **kwargs, ) diff --git a/omnigibson/sensors/__init__.py b/omnigibson/sensors/__init__.py index 11ba84d2c..215aa0924 100644 --- a/omnigibson/sensors/__init__.py +++ b/omnigibson/sensors/__init__.py @@ -19,6 +19,7 @@ def create_sensor( prim_path, name, modalities="all", + enabled=True, sensor_kwargs=None, noise_type=None, noise_kwargs=None @@ -35,6 +36,7 @@ def create_sensor( name (str): Name for the sensor. Names need to be unique per scene. modalities (str or list of str): Modality(s) supported by this sensor. Valid options are part of sensor.all_modalities. Default is "all", which corresponds to all modalities being used + enabled (bool): Whether this sensor should be enabled or not sensor_kwargs (dict): Any keyword kwargs to pass to the constructor noise_type (str): Type of sensor to create. Should be one of REGISTERED_SENSOR_NOISES (i.e.: the string name of the desired class to create) @@ -64,6 +66,13 @@ def create_sensor( # Create the sensor sensor_kwargs = dict() if sensor_kwargs is None else sensor_kwargs - sensor = sensor_cls(prim_path=prim_path, name=name, modalities=modalities, noise=noise, **sensor_kwargs) + sensor = sensor_cls( + prim_path=prim_path, + name=name, + modalities=modalities, + enabled=enabled, + noise=noise, + **sensor_kwargs, + ) return sensor From e555affbc0d8c2f7d9a55a959a15b169a88803e1 Mon Sep 17 00:00:00 2001 From: cremebrule <84cremebrule@gmail.com> Date: Tue, 5 Sep 2023 14:28:03 -0700 Subject: [PATCH 02/13] update configs with sensor_config --- omnigibson/configs/fetch_behavior.yaml | 9 +++++++ omnigibson/configs/robots/fetch.yaml | 9 +++++++ omnigibson/configs/robots/freight.yaml | 9 +++++++ omnigibson/configs/robots/husky.yaml | 9 +++++++ omnigibson/configs/robots/locobot.yaml | 9 +++++++ omnigibson/configs/robots/turtlebot.yaml | 9 +++++++ omnigibson/configs/sensors/scan.yaml | 30 ++++++++++++++++++++++++ omnigibson/configs/sensors/vision.yaml | 14 +++++++++++ omnigibson/configs/turtlebot_nav.yaml | 9 +++++++ 9 files changed, 107 insertions(+) create mode 100644 omnigibson/configs/sensors/scan.yaml create mode 100644 omnigibson/configs/sensors/vision.yaml diff --git a/omnigibson/configs/fetch_behavior.yaml b/omnigibson/configs/fetch_behavior.yaml index 84da35e39..a2e57cad0 100644 --- a/omnigibson/configs/fetch_behavior.yaml +++ b/omnigibson/configs/fetch_behavior.yaml @@ -33,6 +33,15 @@ robots: default_trunk_offset: 0.365 default_arm_pose: diagonal30 reset_joint_pos: tuck + sensor_config: + VisionSensor: + sensor_kwargs: + image_height: 128 + image_width: 128 + ScanSensor: + sensor_kwargs: + min_range: 0.05 + max_range: 10.0 controller_config: base: name: DifferentialDriveController diff --git a/omnigibson/configs/robots/fetch.yaml b/omnigibson/configs/robots/fetch.yaml index 42bdeb8ac..9d8054e17 100644 --- a/omnigibson/configs/robots/fetch.yaml +++ b/omnigibson/configs/robots/fetch.yaml @@ -19,6 +19,15 @@ robot: rigid_trunk: false default_trunk_offset: 0.365 default_arm_pose: vertical + sensor_config: + VisionSensor: + sensor_kwargs: + image_height: 128 + image_width: 128 + ScanSensor: + sensor_kwargs: + min_range: 0.05 + max_range: 10.0 controller_config: base: name: DifferentialDriveController diff --git a/omnigibson/configs/robots/freight.yaml b/omnigibson/configs/robots/freight.yaml index e3de96e4f..7431b464d 100644 --- a/omnigibson/configs/robots/freight.yaml +++ b/omnigibson/configs/robots/freight.yaml @@ -10,6 +10,15 @@ robot: base_name: null scale: 1.0 self_collision: false + sensor_config: + VisionSensor: + sensor_kwargs: + image_height: 128 + image_width: 128 + ScanSensor: + sensor_kwargs: + min_range: 0.05 + max_range: 10.0 controller_config: base: name: DifferentialDriveController \ No newline at end of file diff --git a/omnigibson/configs/robots/husky.yaml b/omnigibson/configs/robots/husky.yaml index 9f63cd58b..d35680b5b 100644 --- a/omnigibson/configs/robots/husky.yaml +++ b/omnigibson/configs/robots/husky.yaml @@ -10,6 +10,15 @@ robot: base_name: null scale: 1.0 self_collision: false + sensor_config: + VisionSensor: + sensor_kwargs: + image_height: 128 + image_width: 128 + ScanSensor: + sensor_kwargs: + min_range: 0.05 + max_range: 10.0 controller_config: base: name: JointController \ No newline at end of file diff --git a/omnigibson/configs/robots/locobot.yaml b/omnigibson/configs/robots/locobot.yaml index f5565fb75..c36e144f3 100644 --- a/omnigibson/configs/robots/locobot.yaml +++ b/omnigibson/configs/robots/locobot.yaml @@ -10,6 +10,15 @@ robot: base_name: null scale: 1.0 self_collision: false + sensor_config: + VisionSensor: + sensor_kwargs: + image_height: 128 + image_width: 128 + ScanSensor: + sensor_kwargs: + min_range: 0.05 + max_range: 10.0 controller_config: base: name: DifferentialDriveController \ No newline at end of file diff --git a/omnigibson/configs/robots/turtlebot.yaml b/omnigibson/configs/robots/turtlebot.yaml index 28fdc8613..0431a430f 100644 --- a/omnigibson/configs/robots/turtlebot.yaml +++ b/omnigibson/configs/robots/turtlebot.yaml @@ -10,6 +10,15 @@ robot: base_name: null scale: 1.0 self_collision: false + sensor_config: + VisionSensor: + sensor_kwargs: + image_height: 128 + image_width: 128 + ScanSensor: + sensor_kwargs: + min_range: 0.05 + max_range: 10.0 controller_config: base: name: DifferentialDriveController \ No newline at end of file diff --git a/omnigibson/configs/sensors/scan.yaml b/omnigibson/configs/sensors/scan.yaml new file mode 100644 index 000000000..632bbb793 --- /dev/null +++ b/omnigibson/configs/sensors/scan.yaml @@ -0,0 +1,30 @@ +# Example ScanSensor sensor config +# See omnigibson/sensors/__init__/create_sensor and omnigibson/sensors/scan_sensor for docstring of arguments +# Arguments below are the arguments that should be specified by external user (other kwargs +# used in constructor are generated automatically at runtime) +robot: + sensor_config: + VisionSensor: + modalities: [scan, occupancy_grid] # if specified, this will override the values in robots_config["obs_modalities"] + enabled: true + noise_type: null + noise_kwargs: null + sensor_kwargs: + + # Basic LIDAR kwargs + min_range: 0.05 + max_range: 10.0 + horizontal_fov: 360.0 + vertical_fov: 1.0 + yaw_offset: 0.0 + horizontal_resolution: 1.0 + vertical_resolution: 1.0 + rotation_rate: 0.0 + draw_points: false + draw_lines: false + + # Occupancy Grid kwargs + occupancy_grid_resolution: 128 + occupancy_grid_range: 5.0 + occupancy_grid_inner_radius: 0.5 + occupancy_grid_local_link: null \ No newline at end of file diff --git a/omnigibson/configs/sensors/vision.yaml b/omnigibson/configs/sensors/vision.yaml new file mode 100644 index 000000000..44fdfc6c6 --- /dev/null +++ b/omnigibson/configs/sensors/vision.yaml @@ -0,0 +1,14 @@ +# Example VisionSensor sensor config +# See omnigibson/sensors/__init__/create_sensor and omnigibson/sensors/vision_sensor for docstring of arguments +# Arguments below are the arguments that should be specified by external user (other kwargs +# used in constructor are generated automatically at runtime) +robot: + sensor_config: + VisionSensor: + modalities: [rgb, depth] # if specified, this will override the values in robots_config["obs_modalities"] + enabled: true + noise_type: null + noise_kwargs: null + sensor_kwargs: + image_height: 128 + image_width: 128 \ No newline at end of file diff --git a/omnigibson/configs/turtlebot_nav.yaml b/omnigibson/configs/turtlebot_nav.yaml index 864af5d12..36abc695f 100644 --- a/omnigibson/configs/turtlebot_nav.yaml +++ b/omnigibson/configs/turtlebot_nav.yaml @@ -29,6 +29,15 @@ robots: self_collision: false action_normalize: true action_type: continuous + sensor_config: + VisionSensor: + sensor_kwargs: + image_height: 128 + image_width: 128 + ScanSensor: + sensor_kwargs: + min_range: 0.05 + max_range: 10.0 controller_config: base: name: DifferentialDriveController From 20040b8cf9a938edb0f90fae3d736922e16871cd Mon Sep 17 00:00:00 2001 From: cremebrule <84cremebrule@gmail.com> Date: Tue, 5 Sep 2023 15:58:01 -0700 Subject: [PATCH 03/13] fix typo --- omnigibson/configs/sensors/scan.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omnigibson/configs/sensors/scan.yaml b/omnigibson/configs/sensors/scan.yaml index 632bbb793..318b761de 100644 --- a/omnigibson/configs/sensors/scan.yaml +++ b/omnigibson/configs/sensors/scan.yaml @@ -4,7 +4,7 @@ # used in constructor are generated automatically at runtime) robot: sensor_config: - VisionSensor: + ScanSensor: modalities: [scan, occupancy_grid] # if specified, this will override the values in robots_config["obs_modalities"] enabled: true noise_type: null From d83b66e2b71c8f796aaa8d5b9a47c8175a2a7dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cem=20G=C3=B6kmen?= <1408354+cgokmen@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:43:07 -0700 Subject: [PATCH 04/13] Fix Python version reader on Linux --- scripts/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup.sh b/scripts/setup.sh index 76e0af306..238369233 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -27,7 +27,7 @@ conda_name=${conda_name:-omnigibson} echo -e "\nUsing $conda_name as the conda environment name\n" # Get Python version from Isaac Sim -ISAAC_PYTHON_VERSION=$(${ISAAC_SIM_PATH}/python -c "import platform; print(platform.python_version())") +ISAAC_PYTHON_VERSION=$(${ISAAC_SIM_PATH}/python.sh -c "import platform; print(platform.python_version())") echo Using Python version $ISAAC_PYTHON_VERSION[0m matching your current Isaac Sim version # Create a conda environment with the appropriate python version From 97e1711750e047a4a7a7cdc5d440a1a14575b8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cem=20G=C3=B6kmen?= Date: Tue, 3 Oct 2023 02:25:06 -0700 Subject: [PATCH 05/13] No more docs build on the OG repo. --- .github/workflows/docs.yml | 77 -------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index ad99e03df..000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Build & deploy docs - -on: - workflow_dispatch: - pull_request: - branches: - - og-develop - -concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} - cancel-in-progress: true - -jobs: - docs: - runs-on: [linux] - container: - image: stanfordvl/omnigibson-dev:latest - options: --gpus=all --privileged --user=root - env: - DISPLAY: "" - OMNIGIBSON_HEADLESS: 1 - volumes: - - /scr/omni-data/datasets:/data - - /usr/share/vulkan/icd.d/nvidia_icd.json:/etc/vulkan/icd.d/nvidia_icd.json - - /usr/share/vulkan/icd.d/nvidia_layers.json:/etc/vulkan/implicit_layer.d/nvidia_layers.json - - /usr/share/glvnd/egl_vendor.d/10_nvidia.json:/usr/share/glvnd/egl_vendor.d/10_nvidia.json - - /scr/omni-data/isaac-sim/cache/ov:/root/.cache/ov:rw - - /scr/omni-data/isaac-sim/cache/pip:/root/.cache/pip:rw - - /scr/omni-data/isaac-sim/cache/glcache:/root/.cache/nvidia/GLCache:rw - - /scr/omni-data/isaac-sim/cache/computecache:/root/.nv/ComputeCache:rw - - /scr/omni-data/isaac-sim/logs:/root/.nvidia-omniverse/logs:rw - - /scr/omni-data/isaac-sim/config:/root/.nvidia-omniverse/config:rw - - /scr/omni-data/isaac-sim/data:/root/.local/share/ov/data:rw - - /scr/omni-data/isaac-sim/documents:/root/Documents:rw - - defaults: - run: - shell: micromamba run -n omnigibson /bin/bash -leo pipefail {0} - - steps: - - name: Fix home - run: echo "HOME=/root" >> $GITHUB_ENV - - - name: Checkout source - uses: actions/checkout@v3 - with: - submodules: true - path: omnigibson-src - - - name: Install - working-directory: omnigibson-src - run: pip install -e . - - - name: Install dev requirements - working-directory: omnigibson-src - run: pip install -r requirements-dev.txt - - - name: Build docs - working-directory: omnigibson-src - run: source scripts/build_docs.sh - - - name: Copy benchmark index page - working-directory: omnigibson-src - run: mkdir site/benchmark && cp scripts/benchmark* site/benchmark/ && cd site/benchmark && mv benchmark.html index.html - - - name: Fetch benchmark file from gh-pages branch - working-directory: omnigibson-src - run: | - git fetch origin gh-pages:gh-pages --force - git show gh-pages:benchmark/data.js > ./site/benchmark/data.js - git diff - - - name: Deploy to gh-pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./omnigibson-src/site From fcc463e15c7d7d1908474425ca7bbab06f1bbd89 Mon Sep 17 00:00:00 2001 From: Wensi Ai Date: Thu, 12 Oct 2023 14:08:16 -0700 Subject: [PATCH 06/13] Add franka allegro robot --- omnigibson/robots/franka_allegro.py | 330 ++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 omnigibson/robots/franka_allegro.py diff --git a/omnigibson/robots/franka_allegro.py b/omnigibson/robots/franka_allegro.py new file mode 100644 index 000000000..66a440690 --- /dev/null +++ b/omnigibson/robots/franka_allegro.py @@ -0,0 +1,330 @@ +import os +import numpy as np + +from omnigibson.macros import gm +from omnigibson.robots.manipulation_robot import ManipulationRobot +from omnigibson.robots.active_camera_robot import ActiveCameraRobot + +from omni.isaac.core.utils.prims import get_prim_at_path + +RESET_JOINT_OPTIONS = { + "tuck", + "untuck", +} + + +class FrankaAllegro(ManipulationRobot): + """ + Franka Robot with Allegro hand + """ + + def __init__( + self, + # Shared kwargs in hierarchy + name, + prim_path=None, + class_id=None, + uuid=None, + scale=None, + visible=True, + visual_only=False, + self_collisions=True, + load_config=None, + fixed_base=True, + + # Unique to USDObject hierarchy + abilities=None, + + # Unique to ControllableObject hierarchy + control_freq=None, + controller_config=None, + action_type="continuous", + action_normalize=True, + reset_joint_pos=None, + + # Unique to BaseRobot + obs_modalities="all", + proprio_obs="default", + sensor_config=None, + + # Unique to ManipulationRobot + grasping_mode="physical", + + **kwargs, + ): + """ + Args: + name (str): Name for the object. Names need to be unique per scene + prim_path (None or str): global path in the stage to this object. If not specified, will automatically be + created at /World/ + class_id (None or int): What class ID the object should be assigned in semantic segmentation rendering mode. + If None, the ID will be inferred from this object's category. + uuid (None or int): Unique unsigned-integer identifier to assign to this object (max 8-numbers). + If None is specified, then it will be auto-generated + scale (None or float or 3-array): if specified, sets either the uniform (float) or x,y,z (3-array) scale + for this object. A single number corresponds to uniform scaling along the x,y,z axes, whereas a + 3-array specifies per-axis scaling. + visible (bool): whether to render this object or not in the stage + visual_only (bool): Whether this object should be visual only (and not collide with any other objects) + self_collisions (bool): Whether to enable self collisions for this object + load_config (None or dict): If specified, should contain keyword-mapped values that are relevant for + loading this prim at runtime. + abilities (None or dict): If specified, manually adds specific object states to this object. It should be + a dict in the form of {ability: {param: value}} containing object abilities and parameters to pass to + the object state instance constructor. + control_freq (float): control frequency (in Hz) at which to control the object. If set to be None, + simulator.import_object will automatically set the control frequency to be 1 / render_timestep by default. + controller_config (None or dict): nested dictionary mapping controller name(s) to specific controller + configurations for this object. This will override any default values specified by this class. + action_type (str): one of {discrete, continuous} - what type of action space to use + action_normalize (bool): whether to normalize inputted actions. This will override any default values + specified by this class. + reset_joint_pos (None or n-array): if specified, should be the joint positions that the object should + be set to during a reset. If None (default), self.default_joint_pos will be used instead. + obs_modalities (str or list of str): Observation modalities to use for this robot. Default is "all", which + corresponds to all modalities being used. + Otherwise, valid options should be part of omnigibson.sensors.ALL_SENSOR_MODALITIES. + Note: If @sensor_config explicitly specifies `modalities` for a given sensor class, it will + override any values specified from @obs_modalities! + proprio_obs (str or list of str): proprioception observation key(s) to use for generating proprioceptive + observations. If str, should be exactly "default" -- this results in the default proprioception + observations being used, as defined by self.default_proprio_obs. See self._get_proprioception_dict + for valid key choices + sensor_config (None or dict): nested dictionary mapping sensor class name(s) to specific sensor + configurations for this object. This will override any default values specified by this class. + grasping_mode (str): One of {"physical", "assisted", "sticky"}. + If "physical", no assistive grasping will be applied (relies on contact friction + finger force). + If "assisted", will magnetize any object touching and within the gripper's fingers. + If "sticky", will magnetize any object touching the gripper's fingers. + kwargs (dict): Additional keyword arguments that are used for other super() calls from subclasses, allowing + for flexible compositions of various object subclasses (e.g.: Robot is USDObject + ControllableObject). + """ + # Parse reset joint pos if specifying special string + if isinstance(reset_joint_pos, str): + assert ( + reset_joint_pos in RESET_JOINT_OPTIONS + ), "reset_joint_pos should be one of {} if using a string!".format(RESET_JOINT_OPTIONS) + reset_joint_pos = ( + self.tucked_default_joint_pos if reset_joint_pos == "tuck" else self.untucked_default_joint_pos + ) + + # Run super init + super().__init__( + prim_path=prim_path, + name=name, + class_id=class_id, + uuid=uuid, + scale=scale, + visible=visible, + fixed_base=fixed_base, + visual_only=visual_only, + self_collisions=self_collisions, + load_config=load_config, + abilities=abilities, + control_freq=control_freq, + controller_config=controller_config, + action_type=action_type, + action_normalize=action_normalize, + reset_joint_pos=reset_joint_pos, + obs_modalities=obs_modalities, + proprio_obs=proprio_obs, + sensor_config=sensor_config, + grasping_mode=grasping_mode, + **kwargs, + ) + + def _post_load(self): + super()._post_load() + self._world_base_fixed_joint_prim = get_prim_at_path(f"{self._prim_path}/root_joint") + + @property + def model_name(self): + return "FrankaAllegro" + + @property + def tucked_default_joint_pos(self): + return np.zeros(23) + + @property + def untucked_default_joint_pos(self): + # return np.r_[[0.012, -0.57, 0, -2.81, 0, 3.037, 0.741], np.zeros(16)] + return np.r_[[0.86, -0.27, -0.68, -1.52, -0.18, 1.29, 1.72], np.zeros(16)] + + @property + def discrete_action_list(self): + # Not supported for this robot + raise NotImplementedError() + + def _create_discrete_action_space(self): + # Fetch does not support discrete actions + raise ValueError("Fetch does not support discrete actions!") + + def tuck(self): + """ + Immediately set this robot's configuration to be in tucked mode + """ + self.set_joint_positions(self.tucked_default_joint_pos) + + def untuck(self): + """ + Immediately set this robot's configuration to be in untucked mode + """ + self.set_joint_positions(self.untucked_default_joint_pos) + + def update_controller_mode(self): + super().update_controller_mode() + # overwrite joint params here + # self.joints[f"panda_joint1"].damping = 10472 + # self.joints[f"panda_joint1"].stiffness = 104720 + # self.joints[f"panda_joint2"].damping = 1047.2 + # self.joints[f"panda_joint2"].stiffness = 10472 + # self.joints[f"panda_joint3"].damping = 5236 + # self.joints[f"panda_joint3"].stiffness = 104720 + # self.joints[f"panda_joint4"].damping = 523.6 + # self.joints[f"panda_joint4"].stiffness = 10472 + # self.joints[f"panda_joint5"].damping = 52.36 + # self.joints[f"panda_joint5"].stiffness = 436.3 + # self.joints[f"panda_joint6"].damping = 52.36 + # self.joints[f"panda_joint6"].stiffness = 261.8 + # self.joints[f"panda_joint7"].damping = 52.36 + # self.joints[f"panda_joint7"].stiffness = 872.66 + for i in range(7): + self.joints[f"panda_joint{i+1}"].damping = 1000 + self.joints[f"panda_joint{i+1}"].stiffness = 1000 + for i in range(16): + self.joints[f"joint_{i}_0"].damping = 100 + self.joints[f"joint_{i}_0"].stiffness = 300 + self.joints[f"joint_{i}_0"].max_effort = 15 + + @property + def controller_order(self): + # Ordered by general robot kinematics chain + return ["arm_{}".format(self.default_arm), "gripper_{}".format(self.default_arm)] + + @property + def _default_controllers(self): + # Always call super first + controllers = super()._default_controllers + controllers["arm_{}".format(self.default_arm)] = "InverseKinematicsController" + controllers["gripper_{}".format(self.default_arm)] = "JointController" + + return controllers + + @property + def default_joint_pos(self): + return self.untucked_default_joint_pos + + @property + def finger_lengths(self): + return {self.default_arm: 0.1} + + @property + def arm_control_idx(self): + return {self.default_arm: np.arange(7)} + + @property + def gripper_control_idx(self): + return {self.default_arm: np.arange(7, 23)} + + @property + def arm_link_names(self): + return {self.default_arm: [ + "panda_link0", + "panda_link1", + "panda_link2", + "panda_link3", + "panda_link4", + "panda_link5", + "panda_link6", + "panda_link7", + ]} + + @property + def arm_joint_names(self): + return {self.default_arm: [ + "panda_joint_1", + "panda_joint_2", + "panda_joint_3", + "panda_joint_4", + "panda_joint_5", + "panda_joint_6", + "panda_joint_7", + ]} + + @property + def eef_link_names(self): + return {self.default_arm: "base_link"} + + @property + def finger_link_names(self): + return {self.default_arm: [ + "link_0_0", + "link_1_0", + "link_2_0", + "link_3_0", + "link_4_0", + "link_5_0", + "link_6_0", + "link_7_0", + "link_8_0", + "link_9_0", + "link_10_0", + "link_11_0", + "link_12_0", + "link_13_0", + "link_14_0", + "link_15_0", + ]} + + @property + def finger_joint_names(self): + return {self.default_arm: [ + "joint_0_0", + "joint_1_0", + "joint_2_0", + "joint_3_0", + "joint_4_0", + "joint_5_0", + "joint_6_0", + "joint_7_0", + "joint_8_0", + "joint_9_0", + "joint_10_0", + "joint_11_0", + "joint_12_0", + "joint_13_0", + "joint_14_0", + "joint_15_0", + ]} + + @property + def usd_path(self): + return os.path.join(gm.ASSET_PATH, "models/franka_allegro/franka_allegro.usd") + + @property + def robot_arm_descriptor_yamls(self): + return {self.default_arm: os.path.join(gm.ASSET_PATH, "models/franka_allegro/franka_allegro_description.yaml")} + + @property + def robot_gripper_descriptor_yamls(self): + return { + finger: os.path.join(gm.ASSET_PATH, f"models/franka_allegro/allegro_{finger}_description.yaml") + for finger in ["thumb", "index", "middle", "ring"] + } + + @property + def urdf_path(self): + return os.path.join(gm.ASSET_PATH, "models/franka_allegro/franka_allegro.urdf") + + @property + def gripper_urdf_path(self): + return os.path.join(gm.ASSET_PATH, "models/franka_allegro/allegro_hand.urdf") + + @property + def disabled_collision_pairs(self): + return [ + ["link_12_0", "part_studio_link"], + ] + + def set_position(self, position): + self._world_base_fixed_joint_prim.GetAttribute("physics:localPos0").Set(tuple(position)) From d99eb8586eef155fabd276fc5ef4103282668dd5 Mon Sep 17 00:00:00 2001 From: Wensi Ai Date: Thu, 12 Oct 2023 14:08:51 -0700 Subject: [PATCH 07/13] Change init file --- omnigibson/robots/__init__.py | 1 + omnigibson/simulator.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/omnigibson/robots/__init__.py b/omnigibson/robots/__init__.py index 3c3088cdb..d44f06d23 100644 --- a/omnigibson/robots/__init__.py +++ b/omnigibson/robots/__init__.py @@ -9,3 +9,4 @@ from omnigibson.robots.fetch import Fetch from omnigibson.robots.tiago import Tiago from omnigibson.robots.two_wheel_robot import TwoWheelRobot +from omnigibson.robots.franka_allegro import FrankaAllegro diff --git a/omnigibson/simulator.py b/omnigibson/simulator.py index 9d6f9e39f..45e930b8a 100644 --- a/omnigibson/simulator.py +++ b/omnigibson/simulator.py @@ -70,7 +70,7 @@ class Simulator(SimulationContext, Serializable): def __init__( self, gravity=9.81, - physics_dt=1.0 / 60.0, + physics_dt=1.0 / 240.0, rendering_dt=1.0 / 60.0, stage_units_in_meters=1.0, viewer_width=gm.DEFAULT_VIEWER_WIDTH, From 6614ab6b155f31a00f181be025f7c40ac0f8e582 Mon Sep 17 00:00:00 2001 From: Wensi Ai Date: Thu, 12 Oct 2023 20:19:48 -0700 Subject: [PATCH 08/13] Revert simulator change --- omnigibson/simulator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omnigibson/simulator.py b/omnigibson/simulator.py index 45e930b8a..9d6f9e39f 100644 --- a/omnigibson/simulator.py +++ b/omnigibson/simulator.py @@ -70,7 +70,7 @@ class Simulator(SimulationContext, Serializable): def __init__( self, gravity=9.81, - physics_dt=1.0 / 240.0, + physics_dt=1.0 / 60.0, rendering_dt=1.0 / 60.0, stage_units_in_meters=1.0, viewer_width=gm.DEFAULT_VIEWER_WIDTH, From 7cfb3eab026a55572895da7e759752e8051c9f18 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Mon, 16 Oct 2023 19:30:51 +0900 Subject: [PATCH 09/13] Fix typo in scene_base.py arbitary -> arbitrary --- omnigibson/scenes/scene_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omnigibson/scenes/scene_base.py b/omnigibson/scenes/scene_base.py index 296814f6f..e166f9402 100644 --- a/omnigibson/scenes/scene_base.py +++ b/omnigibson/scenes/scene_base.py @@ -31,7 +31,7 @@ class Scene(Serializable, Registerable, Recreatable, ABC): """ Base class for all Scene objects. - Contains the base functionalities for an arbitary scene with an arbitrary set of added objects + Contains the base functionalities for an arbitrary scene with an arbitrary set of added objects """ def __init__( self, From 8c0e8ae8d7f09e146dca0e983d0e3654ce80113d Mon Sep 17 00:00:00 2001 From: Wensi Ai Date: Mon, 16 Oct 2023 10:21:05 -0700 Subject: [PATCH 10/13] Clean up franka allegro class --- omnigibson/robots/franka_allegro.py | 87 ++--------------------------- 1 file changed, 5 insertions(+), 82 deletions(-) diff --git a/omnigibson/robots/franka_allegro.py b/omnigibson/robots/franka_allegro.py index 66a440690..70daf4112 100644 --- a/omnigibson/robots/franka_allegro.py +++ b/omnigibson/robots/franka_allegro.py @@ -3,7 +3,6 @@ from omnigibson.macros import gm from omnigibson.robots.manipulation_robot import ManipulationRobot -from omnigibson.robots.active_camera_robot import ActiveCameraRobot from omni.isaac.core.utils.prims import get_prim_at_path @@ -133,10 +132,6 @@ def __init__( **kwargs, ) - def _post_load(self): - super()._post_load() - self._world_base_fixed_joint_prim = get_prim_at_path(f"{self._prim_path}/root_joint") - @property def model_name(self): return "FrankaAllegro" @@ -147,7 +142,7 @@ def tucked_default_joint_pos(self): @property def untucked_default_joint_pos(self): - # return np.r_[[0.012, -0.57, 0, -2.81, 0, 3.037, 0.741], np.zeros(16)] + # position where the hand is parallel to the ground return np.r_[[0.86, -0.27, -0.68, -1.52, -0.18, 1.29, 1.72], np.zeros(16)] @property @@ -174,20 +169,6 @@ def untuck(self): def update_controller_mode(self): super().update_controller_mode() # overwrite joint params here - # self.joints[f"panda_joint1"].damping = 10472 - # self.joints[f"panda_joint1"].stiffness = 104720 - # self.joints[f"panda_joint2"].damping = 1047.2 - # self.joints[f"panda_joint2"].stiffness = 10472 - # self.joints[f"panda_joint3"].damping = 5236 - # self.joints[f"panda_joint3"].stiffness = 104720 - # self.joints[f"panda_joint4"].damping = 523.6 - # self.joints[f"panda_joint4"].stiffness = 10472 - # self.joints[f"panda_joint5"].damping = 52.36 - # self.joints[f"panda_joint5"].stiffness = 436.3 - # self.joints[f"panda_joint6"].damping = 52.36 - # self.joints[f"panda_joint6"].stiffness = 261.8 - # self.joints[f"panda_joint7"].damping = 52.36 - # self.joints[f"panda_joint7"].stiffness = 872.66 for i in range(7): self.joints[f"panda_joint{i+1}"].damping = 1000 self.joints[f"panda_joint{i+1}"].stiffness = 1000 @@ -198,16 +179,12 @@ def update_controller_mode(self): @property def controller_order(self): - # Ordered by general robot kinematics chain return ["arm_{}".format(self.default_arm), "gripper_{}".format(self.default_arm)] @property def _default_controllers(self): - # Always call super first controllers = super()._default_controllers controllers["arm_{}".format(self.default_arm)] = "InverseKinematicsController" - controllers["gripper_{}".format(self.default_arm)] = "JointController" - return controllers @property @@ -228,28 +205,11 @@ def gripper_control_idx(self): @property def arm_link_names(self): - return {self.default_arm: [ - "panda_link0", - "panda_link1", - "panda_link2", - "panda_link3", - "panda_link4", - "panda_link5", - "panda_link6", - "panda_link7", - ]} + return {self.default_arm: [f"panda_link{i}" for i in range(8)]} @property def arm_joint_names(self): - return {self.default_arm: [ - "panda_joint_1", - "panda_joint_2", - "panda_joint_3", - "panda_joint_4", - "panda_joint_5", - "panda_joint_6", - "panda_joint_7", - ]} + return {self.default_arm: [f"panda_joint_{i+1}" for i in range(7)]} @property def eef_link_names(self): @@ -257,45 +217,11 @@ def eef_link_names(self): @property def finger_link_names(self): - return {self.default_arm: [ - "link_0_0", - "link_1_0", - "link_2_0", - "link_3_0", - "link_4_0", - "link_5_0", - "link_6_0", - "link_7_0", - "link_8_0", - "link_9_0", - "link_10_0", - "link_11_0", - "link_12_0", - "link_13_0", - "link_14_0", - "link_15_0", - ]} + return {self.default_arm: [f"link_{i}_0" for i in range(16)]} @property def finger_joint_names(self): - return {self.default_arm: [ - "joint_0_0", - "joint_1_0", - "joint_2_0", - "joint_3_0", - "joint_4_0", - "joint_5_0", - "joint_6_0", - "joint_7_0", - "joint_8_0", - "joint_9_0", - "joint_10_0", - "joint_11_0", - "joint_12_0", - "joint_13_0", - "joint_14_0", - "joint_15_0", - ]} + return {self.default_arm: [f"joint_{i}_0" for i in range(16)]} @property def usd_path(self): @@ -325,6 +251,3 @@ def disabled_collision_pairs(self): return [ ["link_12_0", "part_studio_link"], ] - - def set_position(self, position): - self._world_base_fixed_joint_prim.GetAttribute("physics:localPos0").Set(tuple(position)) From f00ad62c61b365f9de067fbf02feb762e113a19a Mon Sep 17 00:00:00 2001 From: Wensi Ai Date: Mon, 16 Oct 2023 14:51:06 -0700 Subject: [PATCH 11/13] Add franka panda robot --- omnigibson/robots/__init__.py | 1 + omnigibson/robots/franka.py | 229 ++++++++++++++++++++++++++++ omnigibson/robots/franka_allegro.py | 14 +- 3 files changed, 236 insertions(+), 8 deletions(-) create mode 100644 omnigibson/robots/franka.py diff --git a/omnigibson/robots/__init__.py b/omnigibson/robots/__init__.py index d44f06d23..17b4af9a0 100644 --- a/omnigibson/robots/__init__.py +++ b/omnigibson/robots/__init__.py @@ -9,4 +9,5 @@ from omnigibson.robots.fetch import Fetch from omnigibson.robots.tiago import Tiago from omnigibson.robots.two_wheel_robot import TwoWheelRobot +from omnigibson.robots.franka import FrankaPanda from omnigibson.robots.franka_allegro import FrankaAllegro diff --git a/omnigibson/robots/franka.py b/omnigibson/robots/franka.py new file mode 100644 index 000000000..0b1761838 --- /dev/null +++ b/omnigibson/robots/franka.py @@ -0,0 +1,229 @@ +import os +import numpy as np + +from omnigibson.macros import gm +from omnigibson.robots.manipulation_robot import ManipulationRobot + + +RESET_JOINT_OPTIONS = { + "tuck", + "untuck", +} + + +class FrankaPanda(ManipulationRobot): + """ + The Franka Emika Panda robot + """ + + def __init__( + self, + # Shared kwargs in hierarchy + name, + prim_path=None, + class_id=None, + uuid=None, + scale=None, + visible=True, + visual_only=False, + self_collisions=True, + load_config=None, + fixed_base=True, + + # Unique to USDObject hierarchy + abilities=None, + + # Unique to ControllableObject hierarchy + control_freq=None, + controller_config=None, + action_type="continuous", + action_normalize=True, + reset_joint_pos=None, + + # Unique to BaseRobot + obs_modalities="all", + proprio_obs="default", + sensor_config=None, + + # Unique to ManipulationRobot + grasping_mode="physical", + + **kwargs, + ): + """ + Args: + name (str): Name for the object. Names need to be unique per scene + prim_path (None or str): global path in the stage to this object. If not specified, will automatically be + created at /World/ + class_id (None or int): What class ID the object should be assigned in semantic segmentation rendering mode. + If None, the ID will be inferred from this object's category. + uuid (None or int): Unique unsigned-integer identifier to assign to this object (max 8-numbers). + If None is specified, then it will be auto-generated + scale (None or float or 3-array): if specified, sets either the uniform (float) or x,y,z (3-array) scale + for this object. A single number corresponds to uniform scaling along the x,y,z axes, whereas a + 3-array specifies per-axis scaling. + visible (bool): whether to render this object or not in the stage + visual_only (bool): Whether this object should be visual only (and not collide with any other objects) + self_collisions (bool): Whether to enable self collisions for this object + load_config (None or dict): If specified, should contain keyword-mapped values that are relevant for + loading this prim at runtime. + abilities (None or dict): If specified, manually adds specific object states to this object. It should be + a dict in the form of {ability: {param: value}} containing object abilities and parameters to pass to + the object state instance constructor. + control_freq (float): control frequency (in Hz) at which to control the object. If set to be None, + simulator.import_object will automatically set the control frequency to be 1 / render_timestep by default. + controller_config (None or dict): nested dictionary mapping controller name(s) to specific controller + configurations for this object. This will override any default values specified by this class. + action_type (str): one of {discrete, continuous} - what type of action space to use + action_normalize (bool): whether to normalize inputted actions. This will override any default values + specified by this class. + reset_joint_pos (None or n-array): if specified, should be the joint positions that the object should + be set to during a reset. If None (default), self.default_joint_pos will be used instead. + obs_modalities (str or list of str): Observation modalities to use for this robot. Default is "all", which + corresponds to all modalities being used. + Otherwise, valid options should be part of omnigibson.sensors.ALL_SENSOR_MODALITIES. + Note: If @sensor_config explicitly specifies `modalities` for a given sensor class, it will + override any values specified from @obs_modalities! + proprio_obs (str or list of str): proprioception observation key(s) to use for generating proprioceptive + observations. If str, should be exactly "default" -- this results in the default proprioception + observations being used, as defined by self.default_proprio_obs. See self._get_proprioception_dict + for valid key choices + sensor_config (None or dict): nested dictionary mapping sensor class name(s) to specific sensor + configurations for this object. This will override any default values specified by this class. + grasping_mode (str): One of {"physical", "assisted", "sticky"}. + If "physical", no assistive grasping will be applied (relies on contact friction + finger force). + If "assisted", will magnetize any object touching and within the gripper's fingers. + If "sticky", will magnetize any object touching the gripper's fingers. + kwargs (dict): Additional keyword arguments that are used for other super() calls from subclasses, allowing + for flexible compositions of various object subclasses (e.g.: Robot is USDObject + ControllableObject). + """ + # Parse reset joint pos if specifying special string + if isinstance(reset_joint_pos, str): + assert ( + reset_joint_pos in RESET_JOINT_OPTIONS + ), "reset_joint_pos should be one of {} if using a string!".format(RESET_JOINT_OPTIONS) + reset_joint_pos = ( + self.tucked_default_joint_pos if reset_joint_pos == "tuck" else self.untucked_default_joint_pos + ) + + # Run super init + super().__init__( + prim_path=prim_path, + name=name, + class_id=class_id, + uuid=uuid, + scale=scale, + visible=visible, + fixed_base=fixed_base, + visual_only=visual_only, + self_collisions=self_collisions, + load_config=load_config, + abilities=abilities, + control_freq=control_freq, + controller_config=controller_config, + action_type=action_type, + action_normalize=action_normalize, + reset_joint_pos=reset_joint_pos, + obs_modalities=obs_modalities, + proprio_obs=proprio_obs, + sensor_config=sensor_config, + grasping_mode=grasping_mode, + **kwargs, + ) + + @property + def model_name(self): + return "FrankaPanda" + + @property + def tucked_default_joint_pos(self): + return np.zeros(9) + + @property + def untucked_default_joint_pos(self): + return np.array([0.00, -1.3, 0.00, -2.87, 0.00, 2.00, 0.75, 0.00, 0.00]) + + @property + def discrete_action_list(self): + # Not supported for this robot + raise NotImplementedError() + + def _create_discrete_action_space(self): + # Fetch does not support discrete actions + raise ValueError("Franka does not support discrete actions!") + + def tuck(self): + """ + Immediately set this robot's configuration to be in tucked mode + """ + self.set_joint_positions(self.tucked_default_joint_pos) + + def untuck(self): + """ + Immediately set this robot's configuration to be in untucked mode + """ + self.set_joint_positions(self.untucked_default_joint_pos) + + def update_controller_mode(self): + super().update_controller_mode() + # overwrite joint params (e.g. damping, stiffess, max_effort) here + + @property + def controller_order(self): + return ["arm_{}".format(self.default_arm), "gripper_{}".format(self.default_arm)] + + @property + def _default_controllers(self): + controllers = super()._default_controllers + controllers["arm_{}".format(self.default_arm)] = "InverseKinematicsController" + controllers["gripper_{}".format(self.default_arm)] = "MultiFingerGripperController" + return controllers + + @property + def default_joint_pos(self): + return self.untucked_default_joint_pos + + @property + def finger_lengths(self): + return {self.default_arm: 0.1} + + @property + def arm_control_idx(self): + return {self.default_arm: np.arange(7)} + + @property + def gripper_control_idx(self): + return {self.default_arm: np.arange(7, 9)} + + @property + def arm_link_names(self): + return {self.default_arm: [f"panda_link{i}" for i in range(8)]} + + @property + def arm_joint_names(self): + return {self.default_arm: [f"panda_joint_{i+1}" for i in range(7)]} + + @property + def eef_link_names(self): + return {self.default_arm: "panda_hand"} + + @property + def finger_link_names(self): + return {self.default_arm: ["panda_leftfinger", "panda_rightfinger"]} + + @property + def finger_joint_names(self): + return {self.default_arm: ["panda_finger_joint1", "panda_finger_joint2"]} + + @property + def usd_path(self): + return os.path.join(gm.ASSET_PATH, "models/franka/franka_panda.usd") + + @property + def robot_arm_descriptor_yamls(self): + return {self.default_arm: os.path.join(gm.ASSET_PATH, "models/franka/franka_panda_description.yaml")} + + @property + def urdf_path(self): + return os.path.join(gm.ASSET_PATH, "models/franka/franka_panda.urdf") + \ No newline at end of file diff --git a/omnigibson/robots/franka_allegro.py b/omnigibson/robots/franka_allegro.py index 70daf4112..40bf953fb 100644 --- a/omnigibson/robots/franka_allegro.py +++ b/omnigibson/robots/franka_allegro.py @@ -4,8 +4,6 @@ from omnigibson.macros import gm from omnigibson.robots.manipulation_robot import ManipulationRobot -from omni.isaac.core.utils.prims import get_prim_at_path - RESET_JOINT_OPTIONS = { "tuck", "untuck", @@ -152,7 +150,7 @@ def discrete_action_list(self): def _create_discrete_action_space(self): # Fetch does not support discrete actions - raise ValueError("Fetch does not support discrete actions!") + raise ValueError("Franka does not support discrete actions!") def tuck(self): """ @@ -225,26 +223,26 @@ def finger_joint_names(self): @property def usd_path(self): - return os.path.join(gm.ASSET_PATH, "models/franka_allegro/franka_allegro.usd") + return os.path.join(gm.ASSET_PATH, "models/franka/franka_allegro.usd") @property def robot_arm_descriptor_yamls(self): - return {self.default_arm: os.path.join(gm.ASSET_PATH, "models/franka_allegro/franka_allegro_description.yaml")} + return {self.default_arm: os.path.join(gm.ASSET_PATH, "models/franka/franka_allegro_description.yaml")} @property def robot_gripper_descriptor_yamls(self): return { - finger: os.path.join(gm.ASSET_PATH, f"models/franka_allegro/allegro_{finger}_description.yaml") + finger: os.path.join(gm.ASSET_PATH, f"models/franka/allegro_{finger}_description.yaml") for finger in ["thumb", "index", "middle", "ring"] } @property def urdf_path(self): - return os.path.join(gm.ASSET_PATH, "models/franka_allegro/franka_allegro.urdf") + return os.path.join(gm.ASSET_PATH, "models/franka/franka_allegro.urdf") @property def gripper_urdf_path(self): - return os.path.join(gm.ASSET_PATH, "models/franka_allegro/allegro_hand.urdf") + return os.path.join(gm.ASSET_PATH, "models/franka/allegro_hand.urdf") @property def disabled_collision_pairs(self): From e5ba3dba73cb1a5bd8e55fcb1e7906efe0b87821 Mon Sep 17 00:00:00 2001 From: Wensi Ai Date: Mon, 16 Oct 2023 15:04:59 -0700 Subject: [PATCH 12/13] Remove tuck/untuck for Franka --- omnigibson/robots/franka.py | 25 +------------------------ omnigibson/robots/franka_allegro.py | 25 ++----------------------- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/omnigibson/robots/franka.py b/omnigibson/robots/franka.py index 0b1761838..c4e2f9a90 100644 --- a/omnigibson/robots/franka.py +++ b/omnigibson/robots/franka.py @@ -5,12 +5,6 @@ from omnigibson.robots.manipulation_robot import ManipulationRobot -RESET_JOINT_OPTIONS = { - "tuck", - "untuck", -} - - class FrankaPanda(ManipulationRobot): """ The Franka Emika Panda robot @@ -97,15 +91,6 @@ def __init__( kwargs (dict): Additional keyword arguments that are used for other super() calls from subclasses, allowing for flexible compositions of various object subclasses (e.g.: Robot is USDObject + ControllableObject). """ - # Parse reset joint pos if specifying special string - if isinstance(reset_joint_pos, str): - assert ( - reset_joint_pos in RESET_JOINT_OPTIONS - ), "reset_joint_pos should be one of {} if using a string!".format(RESET_JOINT_OPTIONS) - reset_joint_pos = ( - self.tucked_default_joint_pos if reset_joint_pos == "tuck" else self.untucked_default_joint_pos - ) - # Run super init super().__init__( prim_path=prim_path, @@ -135,14 +120,6 @@ def __init__( def model_name(self): return "FrankaPanda" - @property - def tucked_default_joint_pos(self): - return np.zeros(9) - - @property - def untucked_default_joint_pos(self): - return np.array([0.00, -1.3, 0.00, -2.87, 0.00, 2.00, 0.75, 0.00, 0.00]) - @property def discrete_action_list(self): # Not supported for this robot @@ -181,7 +158,7 @@ def _default_controllers(self): @property def default_joint_pos(self): - return self.untucked_default_joint_pos + return np.array([0.00, -1.3, 0.00, -2.87, 0.00, 2.00, 0.75, 0.00, 0.00]) @property def finger_lengths(self): diff --git a/omnigibson/robots/franka_allegro.py b/omnigibson/robots/franka_allegro.py index 40bf953fb..9303d313c 100644 --- a/omnigibson/robots/franka_allegro.py +++ b/omnigibson/robots/franka_allegro.py @@ -4,11 +4,6 @@ from omnigibson.macros import gm from omnigibson.robots.manipulation_robot import ManipulationRobot -RESET_JOINT_OPTIONS = { - "tuck", - "untuck", -} - class FrankaAllegro(ManipulationRobot): """ @@ -96,14 +91,6 @@ def __init__( kwargs (dict): Additional keyword arguments that are used for other super() calls from subclasses, allowing for flexible compositions of various object subclasses (e.g.: Robot is USDObject + ControllableObject). """ - # Parse reset joint pos if specifying special string - if isinstance(reset_joint_pos, str): - assert ( - reset_joint_pos in RESET_JOINT_OPTIONS - ), "reset_joint_pos should be one of {} if using a string!".format(RESET_JOINT_OPTIONS) - reset_joint_pos = ( - self.tucked_default_joint_pos if reset_joint_pos == "tuck" else self.untucked_default_joint_pos - ) # Run super init super().__init__( @@ -134,15 +121,6 @@ def __init__( def model_name(self): return "FrankaAllegro" - @property - def tucked_default_joint_pos(self): - return np.zeros(23) - - @property - def untucked_default_joint_pos(self): - # position where the hand is parallel to the ground - return np.r_[[0.86, -0.27, -0.68, -1.52, -0.18, 1.29, 1.72], np.zeros(16)] - @property def discrete_action_list(self): # Not supported for this robot @@ -187,7 +165,8 @@ def _default_controllers(self): @property def default_joint_pos(self): - return self.untucked_default_joint_pos + # position where the hand is parallel to the ground + return np.r_[[0.86, -0.27, -0.68, -1.52, -0.18, 1.29, 1.72], np.zeros(16)] @property def finger_lengths(self): From e5b619f7e0158ce1cfc9d05c2caad7662d9c84ca Mon Sep 17 00:00:00 2001 From: vince-ai Date: Mon, 16 Oct 2023 22:26:19 -0700 Subject: [PATCH 13/13] linux setup fix --- scripts/setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/setup.sh b/scripts/setup.sh index 238369233..0c6474f2b 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -28,7 +28,8 @@ echo -e "\nUsing $conda_name as the conda environment name\n" # Get Python version from Isaac Sim ISAAC_PYTHON_VERSION=$(${ISAAC_SIM_PATH}/python.sh -c "import platform; print(platform.python_version())") -echo Using Python version $ISAAC_PYTHON_VERSION[0m matching your current Isaac Sim version +ISAAC_PYTHON_VERSION="${ISAAC_PYTHON_VERSION##*$'\n'}" # get rid of conda activation warnings +echo Using Python version $ISAAC_PYTHON_VERSION matching your current Isaac Sim version # Create a conda environment with the appropriate python version source $(conda info --base)/etc/profile.d/conda.sh