diff --git a/docs/source/_static/css/environment-browser.css b/docs/source/_static/css/environment-browser.css index 0136fd3501ff..47e73ba9f107 100644 --- a/docs/source/_static/css/environment-browser.css +++ b/docs/source/_static/css/environment-browser.css @@ -53,7 +53,8 @@ html[data-theme="dark"] .environment-browser { white-space: nowrap; } -.environment-mode-switch { +.environment-mode-switch, +.environment-scope-switch { display: inline-flex; flex: 0 0 auto; overflow: hidden; @@ -61,7 +62,8 @@ html[data-theme="dark"] .environment-browser { border-radius: 6px; } -.environment-mode-switch button { +.environment-mode-switch button, +.environment-scope-switch button { min-height: 2.35rem; padding: 0.35rem 0.7rem; border: 0; @@ -72,15 +74,24 @@ html[data-theme="dark"] .environment-browser { font-weight: 600; } -.environment-mode-switch button:last-child { +.environment-mode-switch button:last-child, +.environment-scope-switch button:last-child { border-right: 0; } -.environment-mode-switch button.is-active { +.environment-mode-switch button.is-active, +.environment-scope-switch button.is-active { color: #1f3300; background: #76b900; } +.environment-mode-switch button:disabled, +.environment-scope-switch button:disabled { + color: var(--environment-muted); + cursor: not-allowed; + opacity: 0.65; +} + .environment-inline-field, .environment-selector, .environment-checkpoint-toggle { @@ -102,6 +113,14 @@ html[data-theme="dark"] .environment-browser { flex: 1 1 20rem; } +.environment-task-field > span { + min-width: 4.75rem; +} + +.environment-scope-switch { + margin-left: auto; +} + .environment-inline-field select, .environment-selector select, .environment-task-filter select, @@ -167,8 +186,7 @@ html[data-theme="dark"] .environment-browser { .environment-checkpoint-toggle { justify-content: center; - justify-self: start; - width: calc(100% - 0.35rem); + width: 100%; min-height: 2.4rem; padding: 0.35rem 0.6rem; border: 1px solid var(--environment-border); @@ -187,6 +205,32 @@ html[data-theme="dark"] .environment-browser { accent-color: var(--pst-color-primary); } +.environment-checkpoint-toggle:has(input:disabled) { + color: var(--environment-muted); + background: color-mix(in srgb, var(--pst-color-background) 55%, transparent); + cursor: not-allowed; + opacity: 0.65; +} + +.environment-non-rl-note { + display: flex; + align-items: baseline; + gap: 0.5rem; + margin: 1rem 0 0; + padding: 0.65rem 0.8rem; + border-left: 3px solid var(--pst-color-info); + color: var(--pst-color-text-base); + background: color-mix(in srgb, var(--pst-color-info) 8%, transparent); +} + +.environment-non-rl-note[hidden] { + display: none; +} + +.environment-non-rl-note i { + color: var(--pst-color-info); +} + .environment-command-output { display: grid; grid-template-columns: minmax(0, 1fr) auto; diff --git a/docs/source/_static/css/environment-browser.js b/docs/source/_static/css/environment-browser.js index fd6b9329fe12..4c1c1ec20657 100644 --- a/docs/source/_static/css/environment-browser.js +++ b/docs/source/_static/css/environment-browser.js @@ -9,18 +9,18 @@ "use strict"; const initializeEnvironmentBrowser = () => { - // Generated from the core and contributed rows in source/overview/environments.rst. + // Generated from the task rows in source/overview/environments.rst. // START-AUTO-GENERATED: environment-browser-task-rows const taskRows = [ - ["Isaac-Ant-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/ant.jpg"], - ["Isaac-Ant", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/ant.jpg"], - ["Isaac-Cartpole-Direct", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/cartpole.jpg"], - ["Isaac-Cartpole", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/cartpole.jpg"], + ["Isaac-Ant-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/ant.jpg", true], + ["Isaac-Ant", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/ant.jpg", true], + ["Isaac-Cartpole-Direct", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/cartpole.jpg", true], + ["Isaac-Cartpole", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/cartpole.jpg", true], ["Isaac-Cartpole-Camera-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "isaacsim_rtx,newton_renderer,ovrtx", "albedo,depth,rgb,semantic_segmentation,simple_shading_constant_diffuse,simple_shading_diffuse_mdl,simple_shading_full_mdl", {}, "tasks/classic/cartpole.jpg"], ["Isaac-Cartpole-Camera", "rl_games,rsl_rl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "isaacsim_rtx,newton_renderer,ovrtx", "albedo,depth,resnet18,rgb,semantic_segmentation,simple_shading_constant_diffuse,simple_shading_diffuse_mdl,simple_shading_full_mdl,theia_tiny", {"rl_games_cfg_entry_point": ["albedo", "depth", "rgb", "semantic_segmentation", "simple_shading_constant_diffuse", "simple_shading_diffuse_mdl", "simple_shading_full_mdl"], "rl_games_feature_cfg_entry_point": ["resnet18", "theia_tiny"], "rsl_rl_cfg_entry_point": ["albedo", "depth", "rgb", "semantic_segmentation", "simple_shading_constant_diffuse", "simple_shading_diffuse_mdl", "simple_shading_full_mdl"], "rsl_rl_feature_cfg_entry_point": ["resnet18", "theia_tiny"]}, "tasks/classic/cartpole.jpg"], ["Isaac-Fourbar-Pole-Swingup", "rsl_rl", "newton_kamino", "", "", {}, "tasks/classic/fourbar_pole.jpg"], - ["Isaac-Humanoid-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/humanoid.jpg"], - ["Isaac-Humanoid", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/humanoid.jpg"], + ["Isaac-Humanoid-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/humanoid.jpg", true], + ["Isaac-Humanoid", "rl_games,rsl_rl,skrl,sb3", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/classic/humanoid.jpg", true], ["Isaac-Lift-Cable-Franka", "rsl_rl", "newton_mjwarp_vbd_proxy", "", "ik,joint", {}, "tasks/manipulation/franka_lift_cable.jpg"], ["Isaac-Lift-Cable-Franka-Camera", "rsl_rl", "newton_mjwarp_vbd_proxy", "isaacsim_rtx,newton_renderer,ovrtx", "ik,joint", {}, "tasks/manipulation/franka_lift_cable.jpg"], ["Isaac-Lift-Cloth-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "", "ik,joint", {}, "tasks/manipulation/franka_lift_cloth.jpg"], @@ -33,10 +33,10 @@ ["Isaac-Open-Drawer-Franka-Direct", "rl_games,rsl_rl,skrl", "", "", "", {}, "tasks/manipulation/franka_open_drawer.jpg"], ["Isaac-Open-Drawer-Franka", "rl_games,rsl_rl,skrl", "", "", "", {}, "tasks/manipulation/franka_open_drawer.jpg"], ["Isaac-Pendulum-MARL-Direct", "rl_games,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", ""], - ["Isaac-Reach-Franka", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "diffik,diffik_abs,joint_pos,newton_ik", {}, "tasks/manipulation/franka_reach.jpg"], + ["Isaac-Reach-Franka", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "diffik,diffik_abs,joint_pos,newton_ik", {}, "tasks/manipulation/franka_reach.jpg", true], ["Isaac-Reach-Franka-OSC", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "diffik_abs", {}, "tasks/manipulation/franka_reach.jpg"], - ["Isaac-Reach-UR10", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/manipulation/ur10_reach.jpg"], - ["Isaac-Reorient-Cube-Allegro-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/manipulation/allegro_cube.jpg"], + ["Isaac-Reach-UR10", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/manipulation/ur10_reach.jpg", true], + ["Isaac-Reorient-Cube-Allegro-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/manipulation/allegro_cube.jpg", true], ["Isaac-Reorient-Cube-Allegro", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "randomized,reset_only", {}, "tasks/manipulation/allegro_cube.jpg"], ["Isaac-Reorient-Cube-Shadow-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/manipulation/shadow_cube.jpg"], ["Isaac-Reorient-Cube-Shadow", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "asymmetric,randomized"], @@ -47,11 +47,11 @@ ["Isaac-Reorient-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_reorient.jpg"], ["Isaac-Shadow-Handover-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/manipulation/shadow_hand_over.jpg"], ["Isaac-Shadow-Handover", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "randomized"], - ["Isaac-Velocity-Flat-AnymalD", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_d_flat.jpg"], - ["Isaac-Velocity-Flat-Cassie", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", ""], - ["Isaac-Velocity-Flat-G1", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/g1_flat.jpg"], - ["Isaac-Velocity-Flat-H1", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/h1_flat.jpg"], - ["Isaac-Velocity-Flat-UnitreeGo2", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/go2_flat.jpg"], + ["Isaac-Velocity-Flat-AnymalD", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_d_flat.jpg", true], + ["Isaac-Velocity-Flat-Cassie", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "", true], + ["Isaac-Velocity-Flat-G1", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/g1_flat.jpg", true], + ["Isaac-Velocity-Flat-H1", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/h1_flat.jpg", true], + ["Isaac-Velocity-Flat-UnitreeGo2", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/go2_flat.jpg", true], ["Isaac-Velocity-Rough-AnymalD", "rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_d_rough.jpg"], ["Isaac-Velocity-Rough-Cassie", "rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_d_rough.jpg"], ["Isaac-Velocity-Rough-G1", "rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/g1_rough.jpg"], @@ -135,13 +135,13 @@ ["IsaacContrib-TrackPositionNoObstacles-ARL-Robot-1", "rl_games,rsl_rl,skrl", "", "", "", {}, "tasks/drone_arl/arl_robot_1_track_position_state_based.jpg"], ["IsaacContrib-Tracking-LocoManip-Digit", "rsl_rl", "isaacsim_physx", "", "", {}, "tasks/locomotion/agility_digit_loco_manip.jpg"], ["IsaacContrib-UR10-Particle-Push", "rsl_rl", "", "", "", {}, "tasks/manipulation/ur10_particle_push.jpg"], - ["IsaacContrib-Velocity-Flat-AnymalB", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_b_flat.jpg"], + ["IsaacContrib-Velocity-Flat-AnymalB", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_b_flat.jpg", true], ["IsaacContrib-Velocity-Flat-AnymalC-Direct", "rl_games,rsl_rl,skrl", "", "", "", {}, "tasks/locomotion/anymal_c_flat.jpg"], - ["IsaacContrib-Velocity-Flat-AnymalC", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_c_flat.jpg"], + ["IsaacContrib-Velocity-Flat-AnymalC", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_c_flat.jpg", true], ["IsaacContrib-Velocity-Flat-Digit", "rsl_rl", "isaacsim_physx", "", "", {}, "tasks/locomotion/agility_digit_flat.jpg"], ["IsaacContrib-Velocity-Flat-Spot", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp", "", "", {}, "tasks/locomotion/spot_flat.jpg"], - ["IsaacContrib-Velocity-Flat-UnitreeA1", "rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/a1_flat.jpg"], - ["IsaacContrib-Velocity-Flat-UnitreeGo1", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/go1_flat.jpg"], + ["IsaacContrib-Velocity-Flat-UnitreeA1", "rsl_rl,skrl,sb3", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/a1_flat.jpg", true], + ["IsaacContrib-Velocity-Flat-UnitreeGo1", "rsl_rl,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/go1_flat.jpg", true], ["IsaacContrib-Velocity-Rough-AnymalB", "rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_b_rough.jpg"], ["IsaacContrib-Velocity-Rough-AnymalC-Direct", "rl_games,rsl_rl,skrl", "", "", "", {}, "tasks/locomotion/anymal_c_rough.jpg"], ["IsaacContrib-Velocity-Rough-AnymalC", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", {}, "tasks/locomotion/anymal_c_rough.jpg"], @@ -152,7 +152,9 @@ // END-AUTO-GENERATED: environment-browser-task-rows const splitValues = (value) => value ? value.split(",") : []; - const tasks = taskRows.map(([task, rl, physics, renderer, presets, agentPresetCompatibility = {}, previewImage = ""]) => ({ + const tasks = taskRows.map(([ + task, rl, physics, renderer, presets, agentPresetCompatibility = {}, previewImage = "", supportsWarpFrontend = false, + ]) => ({ task, scope: task.startsWith("IsaacContrib-") ? "contrib" : "core", rl: splitValues(rl), @@ -161,6 +163,7 @@ presets: splitValues(presets), agentPresetCompatibility, previewImage, + supportsWarpFrontend, })); const builder = document.querySelector("[data-environment-browser]"); @@ -175,9 +178,11 @@ [...builder.querySelectorAll("[data-environment-field]")].map((field) => [field.dataset.environmentField, field]) ); const commandOutput = builder.querySelector("[data-command-output]"); + const nonRlNote = builder.querySelector("[data-non-rl-note]"); const copyButton = builder.querySelector("[data-copy-command]"); const copyStatus = builder.querySelector("[data-copy-status]"); const modeButtons = [...builder.querySelectorAll("[data-command-mode]")]; + const scopeButtons = [...builder.querySelectorAll("[data-task-scope]")]; const taskList = taskBrowser.querySelector("[data-task-list]"); const taskSearch = taskBrowser.querySelector("[data-task-search]"); const taskCategory = taskBrowser.querySelector("[data-task-category]"); @@ -185,6 +190,7 @@ const taskEmpty = taskBrowser.querySelector("[data-task-empty]"); const state = { mode: "train", + scope: "core", task: "Isaac-Cartpole", benchmarkWorkload: "runtime", }; @@ -211,6 +217,10 @@ const selectedTask = () => tasks.find((task) => task.task === state.task) || tasks[0]; + const tasksForScope = (scope = state.scope) => tasks.filter((task) => ( + scope === "warp" ? task.supportsWarpFrontend : task.scope === scope + )); + const previewImageFor = (task) => { if (task.previewImage) { return task.previewImage; @@ -263,14 +273,23 @@ const updateTaskControls = () => { const task = selectedTask(); populateSelect(fields.rl, task.rl, [fields.rl.value, "rsl_rl", "rl_games", "skrl", "sb3"]); - populateSelect(fields.physics, task.physics, [fields.physics.value, "newton_mjwarp", "isaacsim_physx", "ovphysx", "newton_kamino"]); + const physics = state.scope === "warp" ? ["newton_mjwarp"] : task.physics; + populateSelect(fields.physics, physics, [fields.physics.value, "newton_mjwarp", "isaacsim_physx", "ovphysx", "newton_kamino"]); const preferredRenderer = fields.physics.value.startsWith("newton") ? "newton_renderer" : "isaacsim_rtx"; populateSelect(fields.renderer, task.renderer, [fields.renderer.value, preferredRenderer, "ovrtx"]); populateSelect(fields.presets, task.presets, [fields.presets.value, "joint", "ik", "rgb", "cube", "single_camera"]); }; const updateModeControls = () => { - const supportsPretrainedCheckpoint = state.mode === "play"; + const supportsRl = selectedTask().rl.length > 0; + for (const modeButton of modeButtons) { + modeButton.disabled = !supportsRl; + const isActive = supportsRl && modeButton.dataset.commandMode === state.mode; + modeButton.classList.toggle("is-active", isActive); + modeButton.setAttribute("aria-pressed", String(isActive)); + } + nonRlNote.hidden = supportsRl; + const supportsPretrainedCheckpoint = supportsRl && state.scope === "core"; fields.checkpoint.disabled = !supportsPretrainedCheckpoint; if (!supportsPretrainedCheckpoint) { fields.checkpoint.checked = false; @@ -297,19 +316,20 @@ for (const extra of extras) { parts.push("--extra", extra); } - parts.push("isaaclab", state.mode); - if (fields.rl.value) { + const task = selectedTask(); + const supportsRl = task.rl.length > 0; + parts.push("isaaclab", supportsRl ? state.mode : "zero_agent"); + if (supportsRl && fields.rl.value) { parts.push("--rl_library", fields.rl.value); } parts.push("--task", state.task); - const task = selectedTask(); const selectedAgent = Object.entries(task.agentPresetCompatibility).find(([agent, presets]) => ( agent.startsWith(`${fields.rl.value}_`) && presets.includes(fields.presets.value) ))?.[0]; if (selectedAgent && selectedAgent !== `${fields.rl.value}_cfg_entry_point`) { parts.push("--agent", selectedAgent); } - if (state.task.includes("-Warp")) { + if (state.scope === "warp") { parts.push("--frontend", "warp"); } for (const selector of ["physics", "renderer", "presets"]) { @@ -317,7 +337,7 @@ parts.push(`${selector}=${fields[selector].value}`); } } - if (fields.checkpoint.checked) { + if (supportsRl && fields.checkpoint.checked) { parts.push("--checkpoint", "pretrained"); } return parts.join(" "); @@ -347,8 +367,11 @@ previewImage.hidden = false; } preview.querySelector("[data-preview-task]").textContent = state.task; - preview.querySelector("[data-preview-mode]").textContent = state.mode === "train" ? "Train" : "Play"; - preview.querySelector("[data-preview-rl]").textContent = fields.rl.value || "Default"; + const supportsRl = selectedTask().rl.length > 0; + preview.querySelector("[data-preview-mode]").textContent = supportsRl + ? (state.mode === "train" ? "Train" : "Play") + : "Zero agent"; + preview.querySelector("[data-preview-rl]").textContent = supportsRl ? fields.rl.value : "Not supported"; preview.querySelector("[data-preview-physics]").textContent = fields.physics.value || "Default"; preview.querySelector("[data-preview-renderer]").textContent = fields.renderer.value || "Default"; preview.querySelector("[data-preview-presets]").textContent = fields.presets.value || "Default"; @@ -369,6 +392,7 @@ const updateSelection = () => { fields.task.value = state.task; updateTaskControls(); + updateModeControls(); commandOutput.textContent = currentCommand(); updatePreview(); for (const row of taskList.querySelectorAll("[data-task-name]")) { @@ -381,10 +405,10 @@ const renderTasks = () => { const query = taskSearch.value.trim().toLowerCase(); const category = taskCategory.value; - const visibleTasks = tasks.filter((task) => { + const visibleTasks = tasksForScope().filter((task) => { const matchesQuery = task.task.toLowerCase().includes(query); const matchesCategory = category === "all" - || (category === "contrib" ? task.scope === "contrib" : task.scope === "core" && categoryFor(task.task) === category); + || categoryFor(task.task) === category; return matchesQuery && matchesCategory; }); taskList.replaceChildren(...visibleTasks.map((task) => { @@ -399,7 +423,10 @@ button.querySelector(".environment-task-name").textContent = task.task; const meta = button.querySelector(".environment-task-meta"); const workflow = task.task.includes("Direct") ? "Direct" : "Manager based"; - meta.replaceChildren(...[workflow, `${task.rl.length} RL ${task.rl.length === 1 ? "library" : "libraries"}`].map((label) => { + const rlSupport = task.rl.length + ? `${task.rl.length} RL ${task.rl.length === 1 ? "library" : "libraries"}` + : "RL not supported"; + meta.replaceChildren(...[workflow, rlSupport].map((label) => { const badge = document.createElement("span"); badge.textContent = label; return badge; @@ -416,7 +443,7 @@ }; const initializeTasks = () => { - fields.task.replaceChildren(...tasks.map((task) => new Option(task.task, task.task))); + fields.task.replaceChildren(...tasksForScope().map((task) => new Option(task.task, task.task))); fields.task.value = state.task; renderTasks(); updateSelection(); @@ -645,6 +672,9 @@ for (const button of modeButtons) { button.addEventListener("click", () => { state.mode = button.dataset.commandMode; + if (state.mode === "train") { + fields.checkpoint.checked = false; + } for (const modeButton of modeButtons) { const isActive = modeButton === button; modeButton.classList.toggle("is-active", isActive); @@ -655,6 +685,42 @@ updatePreview(); }); } + for (const button of scopeButtons) { + button.disabled = tasksForScope(button.dataset.taskScope).length === 0; + button.addEventListener("click", () => { + const scope = button.dataset.taskScope; + const scopedTasks = tasksForScope(scope); + if (scopedTasks.length === 0) { + return; + } + state.scope = scope; + for (const scopeButton of scopeButtons) { + const isActive = scopeButton === button; + scopeButton.classList.toggle("is-active", isActive); + scopeButton.setAttribute("aria-pressed", String(isActive)); + } + if (!scopedTasks.some((task) => task.task === state.task)) { + state.task = scopedTasks[0].task; + } + fields.task.replaceChildren(...scopedTasks.map((task) => new Option(task.task, task.task))); + updateModeControls(); + renderTasks(); + updateSelection(); + }); + } + fields.checkpoint.addEventListener("change", () => { + if (!fields.checkpoint.checked || state.mode === "play") { + return; + } + state.mode = "play"; + for (const modeButton of modeButtons) { + const isActive = modeButton.dataset.commandMode === "play"; + modeButton.classList.toggle("is-active", isActive); + modeButton.setAttribute("aria-pressed", String(isActive)); + } + commandOutput.textContent = currentCommand(); + updatePreview(); + }); for (const button of benchmarks?.querySelectorAll("[data-benchmark-workload]") || []) { button.addEventListener("click", () => { state.benchmarkWorkload = button.dataset.benchmarkWorkload; diff --git a/docs/source/setup/environments.rst b/docs/source/setup/environments.rst index 8dab8c2b331e..1ca42117394c 100644 --- a/docs/source/setup/environments.rst +++ b/docs/source/setup/environments.rst @@ -31,6 +31,11 @@ Command Builder --task +
+ + This environment does not support RL training or playback. The command runs it with the + zero-action agent instead. +