Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/_static/css/environment-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
["Isaac-Lift-Cable-Franka-Camera", "rsl_rl", "newton_mjwarp_vbd_proxy", "isaacsim_rtx,newton_renderer,ovrtx", "ik,joint", "tasks/manipulation/franka_lift_cable.jpg", false, {"*": ["joint"]}],
["Isaac-Lift-Cloth-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "", "ik,joint", "tasks/manipulation/franka_lift_cloth.jpg", false, {"*": ["joint"]}],
["Isaac-Lift-Cloth-Franka-Camera", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "isaacsim_rtx,newton_renderer,ovrtx", "ik,joint", "tasks/manipulation/franka_lift_cloth.jpg", false, {"*": ["joint"]}],
["Isaac-Lift-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "cube,shapes", "", false, {"*": ["shapes"]}],
["Isaac-Lift-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "arm_collisions,cube,shapes", "", false, {"*": ["shapes"]}],
["Isaac-Lift-KukaAllegro", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "cube,shapes", "tasks/manipulation/kuka_allegro_lift.jpg", false, {"*": ["shapes"]}],
["Isaac-Lift-KukaAllegro-Camera", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "isaacsim_rtx,newton_renderer,ovrtx", "albedo128,albedo256,albedo64,cube,depth128,depth256,depth64,duo_camera,raycaster_depth128,raycaster_depth256,raycaster_depth64,rgb128,rgb256,rgb64,semantic_segmentation128,semantic_segmentation256,semantic_segmentation64,shapes,simple_shading_constant_diffuse128,simple_shading_constant_diffuse256,simple_shading_constant_diffuse64,simple_shading_diffuse_mdl128,simple_shading_diffuse_mdl256,simple_shading_diffuse_mdl64,simple_shading_full_mdl128,simple_shading_full_mdl256,simple_shading_full_mdl64,single_camera", "tasks/manipulation/kuka_allegro_lift.jpg", false, {"*": ["rgb64", "shapes", "single_camera"]}],
["Isaac-Lift-Soft-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "", "ik,joint", "newton/franka-mjwarp-vbd-coupling.png", false, {"*": ["joint"]}, {}, "tetrahedralization"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Changed
^^^^^^^

* Migrated Franka rigid and deformable Lift tasks to the shared flat asset, with backend-specific physics
and gripper-only collisions by default. Select ``arm_collisions`` to enable primitive arm contacts.

Fixed
^^^^^

* Corrected rigid Lift reset sampling and success-driven motion regularization without changing
Kuka-Allegro rewards. Requalify existing Franka Lift checkpoints because the reset distribution changed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,24 @@

from isaaclab.actuators import ImplicitActuatorCfg
from isaaclab.assets import ArticulationCfg
from isaaclab.managers import CurriculumTermCfg as CurrTerm
from isaaclab.managers import EventTermCfg as EventTerm
from isaaclab.managers import ObservationTermCfg as ObsTerm
from isaaclab.managers import RewardTermCfg as RewTerm
from isaaclab.managers import SceneEntityCfg
from isaaclab.sensors import ContactSensorCfg
from isaaclab.sim import MeshCapsuleCfg, MeshCuboidCfg, MeshSphereCfg
from isaaclab.utils import clone, configclass, replace
from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR

from isaaclab_assets.robots import FRANKA_PANDA_CFG
from isaaclab_tasks.utils import preset

from isaaclab_assets.robots import FRANKA_PANDA_FLAT_CFG

from ... import lift_env_cfg as lift
from ... import mdp

##
# Scene assets
##

# The lift tasks run the menagerie-converted asset (identified inertials, authored finger coupling) with
# actuators calibrated for it, while the other Franka tasks keep the stock asset.
FRANKA_PANDA_LIFT_CFG = clone(FRANKA_PANDA_CFG)
FRANKA_PANDA_LIFT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda"
# Reset clearance was calibrated for these arm meshes; the asset's primitive colliders intersect the ground.
FRANKA_PANDA_LIFT_CFG.spawn.variants = {"Colliders": "convex_hulls"}
# Lift uses task-specific actuators calibrated for contact-rich manipulation.
FRANKA_PANDA_LIFT_CFG = clone(FRANKA_PANDA_FLAT_CFG)
FRANKA_PANDA_LIFT_CFG.actuators = {
# inspired by libfranka's joint_impedance_control.cpp; ``actuator_velocity_limit`` is the soft task
# limit and ``joint_velocity_limit`` the separate solver request
Expand All @@ -51,6 +45,7 @@
"panda_joint6": 25.0,
"panda_joint7": 15.0,
},
viscous_friction=0.0,
armature={
"panda_joint[1-2]": 0.6057,
"panda_joint[3-4]": 0.4625,
Expand All @@ -64,6 +59,7 @@
joint_velocity_limit=2.0,
stiffness=350.0,
damping=175.0,
viscous_friction=0.0,
armature=0.1,
),
"panda_finger2_passive": ImplicitActuatorCfg(
Expand All @@ -73,6 +69,7 @@
joint_velocity_limit=2.0,
stiffness=0.0,
damping=0.0,
viscous_friction=0.0,
armature=0.1,
),
}
Expand Down Expand Up @@ -102,6 +99,12 @@ class FrankaSceneCfg(lift.SceneCfg):

def __post_init__(self):
super().__post_init__()
# Lift only requires hand-object and fingertip-object contacts; the asset's
# complete primitive colliders remain available for general robot use.
self.robot.spawn.variants = {
"Physics": preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx"),
"Colliders": preset(default="gripper_only", arm_collisions="primitives"),
}
self.robot.spawn.activate_contact_sensors = True
# the base is rotated by 180 degrees about z so the workspace lies at positive x
self.robot.init_state.rot = (0.0, 0.0, 1.0, 0.0)
Expand Down Expand Up @@ -157,9 +160,12 @@ class FrankaRelJointPosActionCfg:


@configclass
class FrankaReorientRewardCfg(lift.RewardsCfg):
class FrankaLiftRewardCfg(lift.RewardsCfg):
"""Reward terms for the MDP, with the Franka finger contact sensors filled in."""

action_rate = RewTerm(func=mdp.action_rate_l2, weight=-1e-4)
joint_vel = RewTerm(func=mdp.joint_vel_l2, weight=-1e-4, params={"asset_cfg": SceneEntityCfg("robot")})

good_finger_contact = RewTerm(
func=mdp.contacts,
weight=0.75,
Expand All @@ -186,6 +192,28 @@ def __post_init__(self):
self.success.params["finger_names"] = FINGER_SENSORS


@configclass
class FrankaLiftCurriculumCfg(lift.CurriculumCfg):
"""Franka-specific motion regularization as grasp difficulty increases."""

action_rate = CurrTerm(
func=mdp.modify_term_cfg,
params={
"address": "rewards.action_rate.weight",
"modify_fn": mdp.difficulty_interpolate_float,
"modify_params": {"initial_value": -1e-4, "final_value": -1e-1, "difficulty_term_str": "adr"},
},
)
joint_vel = CurrTerm(
func=mdp.modify_term_cfg,
params={
"address": "rewards.joint_vel.weight",
"modify_fn": mdp.difficulty_interpolate_float,
"modify_params": {"initial_value": -1e-4, "final_value": -1e-1, "difficulty_term_str": "adr"},
},
)


@configclass
class FrankaEventCfg(lift.EventCfg):
"""Franka-specific event configuration."""
Expand Down Expand Up @@ -243,10 +271,10 @@ def __post_init__(self):

@configclass
class FrankaMixinCfg:
"""Franka-specific scene, observation, action, reward and event terms, mixed into the task configurations."""
"""Franka scene, observation, action, reward and event terms for the lift task."""

scene: FrankaSceneCfg = FrankaSceneCfg(num_envs=4096, env_spacing=3, replicate_physics=True)
rewards: FrankaReorientRewardCfg = FrankaReorientRewardCfg()
rewards: FrankaLiftRewardCfg = FrankaLiftRewardCfg()
observations: StateObservationCfg = StateObservationCfg()
actions: FrankaRelJointPosActionCfg = FrankaRelJointPosActionCfg()
events: FrankaEventCfg = FrankaEventCfg()
Expand All @@ -256,13 +284,37 @@ def __post_init__(self):
self.commands.object_pose.body_name = "panda_hand"
# Franka base is rotated 180 deg about z, so the workspace mirrors to positive x.
self.commands.object_pose.ranges.pos_x = (0.3, 0.7)
# The actuator limits are nominal policy limits, not evidence of unstable physics.
# Reserve the abnormal-state termination for velocities beyond the solver contract.
self.terminations.abnormal_robot.func = mdp.abnormal_robot_state
self.terminations.abnormal_robot.params["asset_cfg"] = SceneEntityCfg("robot", joint_names="panda_joint.*")


@configclass
class FrankaLiftEnvCfg(FrankaMixinCfg, lift.LiftEnvCfg):
"""Franka object lifting environment."""

curriculum: FrankaLiftCurriculumCfg | None = FrankaLiftCurriculumCfg()

def __post_init__(self):
super().__post_init__()
reset = self.events.conditional_reset.params
terms = reset["terms"]
# The aligned opening must be written after the generic gripper-width reset.
pregrasp = terms.pop("reset_object_to_target")
terms["reset_object_to_target"] = pregrasp
pregrasp.func = mdp.reset_to_grasp
pregrasp.params.update(
probability=0.75,
gripper_cfg=SceneEntityCfg("robot", joint_names="panda_finger_joint.*"),
pose_range={"x": (-0.002, 0.002), "y": (-0.002, 0.002), "z": (0.1, 0.1)},
gripper_joint_positions=[0.026, 0.026, 0.0135, 0.026, 0.021, 0.026, 0.026, 0.011],
asset_orientations=[(0.0, 0.0, 0.0, 1.0)] * 5 + [(0.0, 2.0**-0.5, 0.0, 2.0**-0.5)] * 3,
)
pregrasp.params.pop("velocity_range")
# Farthest-point thinning discards valid near-grasp starts.
reset["diversity_feature"] = None

def play_mode(self):
super().play_mode()
# evaluate at the datasheet gripper speed: without the closing-speed randomization the hand
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@
from isaaclab_tasks.utils import PresetCfg, preset
from isaaclab_tasks.utils.presets import MultiBackendRendererCfg

from isaaclab_assets.robots.franka import FRANKA_PANDA_MENAGERIE_CFG
from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG

from ... import mdp

##
# Scene assets
##

# shared volume material parameters; the Newton configuration uses the equivalent Lame parameters
# Shared volume material parameters. The Newton config below uses the equivalent Lame parameters.
YOUNGS_MODULUS = 2e5
POISSONS_RATIO = 0.3

Expand Down Expand Up @@ -190,12 +190,12 @@ class PhysicsCfg(PresetCfg):
class FrankaSoftBaseSceneCfg(InteractiveSceneCfg):
"""Scene for the Franka deformable environment, also the base of the cloth and cable scenes."""

robot: ArticulationCfg = replace(FRANKA_PANDA_MENAGERIE_CFG, prim_path="{ENV_REGEX_NS}/Robot")
robot.spawn.variants = preset(
default={"Physics": "mujoco"},
isaacsim_physx={"Physics": "physx"},
physx={"Physics": "physx"},
)
robot: ArticulationCfg = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot")
# Deformable contact is restricted to the hand and fingertips for throughput.
robot.spawn.variants = {
"Physics": preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx"),
"Colliders": "gripper_only",
}

# end-effector frame for reward shaping
ee_frame: FrameTransformerCfg = FrameTransformerCfg(
Expand Down Expand Up @@ -257,6 +257,7 @@ def __post_init__(self):
"panda_joint6": 25.0,
"panda_joint7": 15.0,
},
viscous_friction=0.0,
armature={
"panda_joint[1-2]": 0.6057,
"panda_joint[3-4]": 0.4625,
Expand All @@ -270,6 +271,7 @@ def __post_init__(self):
joint_velocity_limit=2.0,
stiffness=350.0,
damping=175.0,
viscous_friction=0.0,
armature=0.1,
),
"panda_finger2_passive": ImplicitActuatorCfg(
Expand All @@ -279,6 +281,7 @@ def __post_init__(self):
joint_velocity_limit=2.0,
stiffness=0.0,
damping=0.0,
viscous_friction=0.0,
armature=0.1,
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ __all__ = [
"deformable_ee_distance",
"deformable_lifting",
"deformable_outside_bounds",
"difficulty_interpolate_float",
"ee_below_minimum",
"fingers_contact_force_b",
"get_reset_state",
Expand All @@ -51,6 +52,7 @@ __all__ = [
"reset_cable_state_uniform",
"reset_deformable_over_support",
"reset_joints_shared_offset",
"reset_to_grasp",
"reset_to_target",
"set_reset_state",
"slab_clearance",
Expand All @@ -61,14 +63,15 @@ __all__ = [
from isaaclab_tasks.utils.success_monitor import SuccessMonitor, SuccessMonitorCfg

from .commands import CableUniformPoseCommandCfg, DeformableUniformPoseCommandCfg, ObjectUniformPoseCommandCfg
from .curriculums import gravity_range_linear
from .curriculums import difficulty_interpolate_float, gravity_range_linear
from .events import (
conditional_reset,
grasp_travel_distance,
mesh_clearance,
reset_cable_state_uniform,
reset_deformable_over_support,
reset_joints_shared_offset,
reset_to_grasp,
reset_to_target,
slab_clearance,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@
from isaaclab.envs import ManagerBasedRLEnv


def difficulty_interpolate_float(
env: ManagerBasedRLEnv,
_env_ids: Sequence[int],
_data: float,
initial_value: float,
final_value: float,
difficulty_term_str: str,
) -> float:
"""Interpolate a scalar continuously with an ADR term's success-driven difficulty."""
difficulty_term = getattr(env.curriculum_manager.cfg, difficulty_term_str).func
fraction = min(max(difficulty_term.difficulty_frac, 0.0), 1.0)
return initial_value + fraction * (final_value - initial_value)


def gravity_range_linear(
env: ManagerBasedRLEnv,
_env_ids: Sequence[int],
Expand Down
Loading
Loading