All notable changes to GeneLab are recorded here.
- Root-velocity writes were silent no-ops on rigid articulations (#242): Genesis's
RigidEntityhasget_vel/get_angbut noset_vel/set_ang(those setters exist only on FEM / tool entities), sopush_by_setting_velocity, the velocity half ofreset_root_state_uniform, andArticulation.write_root_statewrote nothing — push-based domain randomization never reached the simulator. Root velocity now routes through the newgenelab.entity.write_root_velocity, which drivesset_dofs_velocityon the base free joint's 6 DoFs (0–2 world-frame linear, 3–5 angular) and falls back to direct setters for entity types that have them. The wuji reorient cube kick / reset and the Franka cube reset inexamples/had the same dead idiom and now use the shared helper. Policies previously trained with push events effectively had those disturbances disabled; retraining may be needed where push robustness matters. - Teleop HUD text never displayed under Genesis 1.2 (same bug class as #242, found by
auditing every
getattr-guarded Genesis call): the outerViewerforwardsregister_keybindsbut notset_message_text, so the keyboard bridge's HUD write silently no-opped. The bridge now falls back to the inner pyrender viewer. A newtests/test_genesis_api_contract.pypins everygetattr-guarded Genesis method name against the installed Genesis so future upstream renames fail tests instead of silently disabling physics or UI.
- Genesis 1.2: the simulator floor moves to
genesis-world>=1.2.0,<1.3.0(from the 1.0.x pin). GeneLab-side adaptations:SimulationCfg.render_fpsnow maps toViewerOptions.refresh_rate(Genesis split the oldmax_FPSintorefresh_ratefor repaints andrealtime_factorfor sim pacing;render_fps=Nonedisables the pacer to keep the documented "uncapped" contract), and the ImGui panel host is discovered through the publicviewer.pluginsproperty (the private_viewer_pluginsattribute was renamed upstream; kept as a fallback). Note for pre-trained checkpoints: Genesis 1.2 parses kinematic trees depth-first, so joint/link enumeration order changes on branched robots — GeneLab resolves joints by name and stays self-consistent, but policies trained on 1.0.x whose observation/action layouts baked the old order must be re-mapped or re-trained.
Git history was rewritten in this release to purge ~24 MB of accidentally-committed vendored robot meshes (Unitree G1 + WUJI hand
.STL); commit hashes changed and thev0.2.0tag moved. Existing clones must re-clone. Robot assets are fetched on demand at runtime, so nothing breaks.
- G1 velocity tracking on rough terrain: added
Genelab-Velocity-Rough-Unitree-G1-v0, a 10-level mixed-terrain curriculum (stairs / boxes / random rough / slopes, mirroring Isaac Lab'sROUGH_TERRAINS_CFG) driven byterrain_levels_velwith capability-relative demotion, aheight_scanactor observation, and a 6k-iter PPO budget. Reference: 4-seed sweep, deterministic evalreturn_mean84–87 on rough terrain (docs/best-practices/reference-runs). - In-viewport ImGui panels:
SimulationCfg.panelstakes a list ofcallback(imgui)functions that GeneLab forwards to Genesis's ImGui overlay after build (a non-empty list auto-enables the overlay). Adding a viewer GUI element is now one function — noBridgesubclass required. New public helpersregister_viewer_panels/find_imgui_panel_hostexported fromgenelab.scene; newimguiextra (imgui-bundle). See theGeneLab-GUI-Panels-Demo-v0cookbook inexamples/genelab_examples. - ImGui twist bridge seeding:
ImGuiTwistBridgeCfggaineddefault_vx/vy/wz, seeded into the slider state and command buffer at attach (parity with the removed DearPyGui bridge). - Single-G1 teleop play + free-fly camera:
genelab playfor the G1 velocity tasks now builds a single robot, frames the camera on it, wires the ImGui twist sliders, and disables episode auto-reset (ManagerBasedRlEnvCfg.auto_reset) — an interactive single-robot session. A core Blender-style free-fly camera (SimulationCfg.fly_camera, on by default) lets you hold the right mouse button to look and fly withWASD/Space/Shift(and disables Genesis' conflicting default W/A/S/D keybinds); newSimulationCfg.camera_pos/camera_lookatframe the viewer so the mouse-wheel zooms in on the subject. - Direct yaw-rate G1 command: the velocity twist command's third component is now a
directly-commanded yaw rate
(vx, vy, vw)(heading_command=False) instead of heading-driven, so a teleopwzslider drives yaw directly. (Retrain required for the velocity policies.)
-
G1 rough-terrain PPO de-learning: the rough velocity policy would reach a good walk and then unlearn it — reward decaying back toward noise as training continued and the action std inflating, even on a fixed terrain distribution. Root cause: the PPO entropy bonus. Near convergence the advantages vanish, so the surrogate gradient dies and the entropy bonus — however small — dominates and inflates the action std until the policy diffuses back to noise (and the adaptive LR, floored by the resulting KL spikes, can't recover). Fixed by setting
entropy_coef = 0and replacing the exploration it supplied with a per-state (heteroscedastic) action std carrying an exploration floor (std_range = (0.3, 2.0)): the policy keeps a minimum action noise without an unbounded bonus pushing it up, and now trains stably to convergence while the terrain curriculum climbs. Two supporting fixes were also required:feet_swing_heightmeasured peak foot height in absolute world z with an unbounded squared error (spiking the cost and diverging the value function on rough/elevated terrain and curriculum reseats) — it now measures height relative to the terrain surface under each foot and clamps the error; and the rough task lightens the heavyfoot_clearance/foot_swing_heightshaping penalties (-2.0 → -0.5,-1.0 → -0.25) so they don't overwhelm velocity tracking as the ground roughens (the flat task keeps the heavier weights).terrain_levels_velalso gains Isaac-Lab-aligned capability-relative demotion. -
Terrain level curriculum collapsing to a single difficulty:
TerrainGeneratorpassedsubterrain_parametersto Genesis keyed by terrain type, so a layout that reused onegenesis_typeat different parameters (e.g. a RandomRoughrough_l0..l4level curriculum) silently built every cell at the last level's difficulty — the intended easy→hard gradient did not exist.TerrainGenerator.build_height_fieldnow generates each cell from its own parameters and the importer feeds it to Genesis viaheight_field, so per-cell difficulty is honoured. Affects every same-type multi-difficulty layout, includingGenelab-Velocity-Rough-Unitree-G1-v0and the curriculum showcase. -
ImGui overlay close crash: closing a viewer built with
viewer_imgui/panelsno longer exits withGenesisException: Unexpected viewer error.—InteractiveScenenow wraps Genesis'sImGuiOverlayPlugin.on_close(a Genesis/imgui_bundleteardown bug that assertsNo current contexton window close), mirroring the existing pyrender save-filename patch. -
Feet sinking / overlapping terrain on rough ground: the ray-cast height sensor and
TerrainImporter.surface_height_atnow interpolate over the Genesis collision triangle (instead of bilinear), so foot-clearance and spawn seating match the surface the feet actually contact; and terrain scenes build withenv_spacing=(0, 0)so the single shared height-field is no longer replicated/offset per env (which had rendered overlapping terrain with buried robots).
- DearPyGui twist bridge and
teleopextra:genelab.bridges.dearpyguiand theteleop(DearPyGui) extra are removed — the in-viewportImGuiTwistBridgecovers the same(vx, vy, ωz)teleop with no separate window, thread, or third GUI toolkit. Migrate--extra teleop→--extra imguiandDearPyGuiTwistBridgeCfg→ImGuiTwistBridgeCfg(plussimulation.viewer_imgui=True).
- ImGui migration: the Unitree G1 play teleop and the
actuatorsshowcase sliders now render in the viewport ImGui overlay instead of a separate DearPyGui / PyQt window (the actuator tracking curves stay in their pyqtgraph window).
Patch release. Adds a Genesis-backed mesh ray-caster to the sensor zoo and a
live-image recording sink, and converts every bundled genelab_showcase
example to real-time on-screen display instead of writing files to disk.
- Mesh ray-cast sensor: added
MeshRayCastSensor(withMeshRayCastSensorCfgandMeshRayCastData) over Genesis's native BVHRaycaster, plus theMeshGridPattern/MeshSphericalPatternray patterns — exported fromgenelab.sensorandgenelab.lab. It complements the existing analyticRayCastSensor(terrain height-field scan) by ray-casting real mesh geometry.RigidObjectCfg.use_visual_raycastingopts an object's visual mesh into the BVH. - Live-image recording sink: added
MPLImagePlotCfgtogenelab.recording, a Matplotlib image output for camera-style(H, W, C)recording sources.
- Recorder warning noise: the recording bridge now filters Genesis's repeated
start_thread(): Processor thread already existswarning aroundsave_on_resetflushes (Genesis restarts the still-running recorder thread each episode; the restart is a harmless no-op). Benefits any env with threadedsave_on_resetrecorders, not only the showcases.
- Real-time showcases: converted all eight bundled
genelab_showcaseexamples (sensors, ray-cast, contact, terrain, curriculum, actuator, MLP-residual actuator, recording) from silent disk-dumping to live Qt / pyqtgraph display. Added a sharedLazyQtWindowshelper and a virtual-spring base class for the showcase runners; file dumps, where still available, are opt-in and documented.
Third development release. The headline is the Genesis 1.0 migration:
the simulator floor moves to genesis-world>=1.0.0,<2.0.0 and the v1.0 API
surface is the baseline for sensors, actuators, scene helpers, and robot
loading. Alongside the migration this release lands a CLI command group
for managing the asset zoo and finishes the per-CLI download-progress-bar
coverage.
- Architecture contracts: added
genelab.contractsas the public home forEnvContext,SceneContext, andNoiseCfg, so domain terms can type-hint the env/scene surfaces they need without importing concrete runtime implementations. - Typed backend dispatch: added the
BackendConfigmarker base ingenelab.rl.config. RL backends now register againsttype[BackendConfig], andselect_backend(agent_cfg)dispatches through the typed registry. - Public API guardrails: made
genelab.laba lazy facade and added snapshot coverage for the blessedlab.__all__andextensions.__all__public surfaces. - MDP package structure: split rewards into the
mdp/rewardspackage while preserving the existinggenelab.mdpimport surface. - Sensor zoo: added wrappers over three Genesis 1.0 sensor primitives —
ProximitySensor(overgs.sensors.SurfaceDistanceProbe),KinematicContactSensor(overgs.sensors.ContactProbe), andTemperatureGridSensor(overgs.sensors.TemperatureGrid). Each exposeshistory_length: int = 0on its Cfg, forwarded verbatim to the Genesis sensor constructor so a single integer flips the ring-buffer on at the Genesis layer rather than in user code. Bilingual reference pages underdocs/reference/sensors/. - Tactile family: added two more wrappers in the same shape —
ElastomerTactileSensor(overgs.sensors.ElastomerTaxel, deformable elastomer model with Lamélambda_d/lambda_s) andPointCloudTactileSensor(overgs.sensors.ProximityTaxel, lighter stiffness-and-shear model). Both sample a point cloud from the parent link's mesh. Addedgenelab.mdp.rewards.tactilewith two reward primitives generic oversensor.data.raw:contact_intensity_l2(Σ raw²) andcontact_count(count above threshold). Bilingual reference pages. - Tactile slip reward + integration coverage: added
genelab.mdp.rewards.slip_penalty(env, sensor_name)— squared sum of the lateral (xy) components ofdata.raw, valid for both elastomer displacement and point-cloud force outputs (both expose(B, [H,] P, 3)with the third channel as the probe normal). Added a real-Genesis integration test that exercises all four new sensor wrappers viags.Scene + add_sensor + build + step, validating the wrappers'pre_build_genesis/_compute_dataround-trip end-to-end. - Energy rewards: added
genelab.mdp.rewards.{kinetic_energy_l2, potential_energy, energy_budget}wrapping Genesis 1.0'sgs_handle.{get_kinetic_energy, get_potential_energy, get_total_energy}.kinetic_energy_l2andenergy_budgetare non-negative (squared);potential_energyis signed. - MJCF-style actuator cfg: added
MujocoStyleActuatorCfg, a thin cfg overIdealPDActuatorthat accepts Mujoco's(gear, bias_prm, dyntype="none", gaintype="fixed", biastype="affine")shape and translates it into(stiffness, damping, effort_limit). Mirrors what Genesis's own MJCF parser does for<actuator>elements at load time, so robots whose actuator parameters live in Python config — rather than in an MJCF file — can use the same named knobs without hand-translating to PD gains. - Camera debug helpers: added
InteractiveScene.draw_camera_frustums(camera_names=None, color=...)andInteractiveScene.draw_camera_trajectory(positions, radius, color)wrapping Genesis 1.0'sscene.draw_debug_frustum/scene.draw_debug_trajectory. The frustum helper resolves names against the scene'sCameraSensorset; the trajectory helper passes positions through verbatim. Added a publicgs_cameraproperty onCameraSensorso the scene helper can reach the Genesis handle without poking private state. - URDF / xacro support on
ArticulationCfg: addedurdf_pathandxacro_argsfields.Articulation.spawndispatches on which path is set —mjcf_path→gs.morphs.MJCF,urdf_path→gs.morphs.URDF(which auto-preprocesses.xacro/.urdf.xacrovia thexacropackage at load time). Exactly one of the two paths must be set;xacro_argsis rejected whenmjcf_pathis used. - ImGui twist bridge: new
src/genelab/bridges/imgui.pywithImGuiTwistBridgeandImGuiTwistBridgeCfg. Same(vx, vy, ωz)output shape as the keyboard / DearPyGui bridges, but renders three nativeimgui.slider_floatwidgets in Genesis's built-inImGuiOverlayPlugin(enabled viaSimulationCfg.viewer_imgui=Truefrom S1) so no extra GUI dependency is required. Falls back to a warned no-op when the plugin isn't attached (headless /viewer_imguioff). - Bundled
sample-armxacro showcase: added a minimal 2-DoF arm undergenelab.asset_zoo(SampleArmCfg(link_length=…)), shipping the xacro file inside the wheel atgenelab/asset_zoo/data/sample_arm.urdf.xacro. DemonstratesArticulationCfg.urdf_path+xacro_argsend-to-end: a singlelink_lengthargument flows throughxacro:arg, the preprocessor substitutes${L}and derived${L * 0.6}sizes, and Genesis'sgs.morphs.URDFconsumes the result. Unlike the other asset-zoo entries the file ships in the wheel rather than via theKraHsu/genelab-assetsmirror. Avatarkinematic entity: addedsrc/genelab/entity/avatar.pywithAvatar+AvatarCfg, a sibling toRigidObjectthat wraps Genesis 1.0'sKinematicEntity(the v0.4.1 "avatar" concept rebadged in v1.0). Avatars participate in the visual / sensor pipeline but are ignored by the rigid solver — no contacts, no constraints — making them the right shape for scripted scene actors (motion-clip ghosts, target reference markers, follow-the-leader demonstrators). Per-step pose updates flow throughavatar.set_pose(pos, quat).InteractiveSceneCfg.use_rasterizertoggle: added a new bool field (defaultFalse) that's forwarded togs.renderers.BatchRenderer(use_rasterizer=…)whenbatch_render=True.Falsekeeps the raytracer (default, higher fidelity),Trueswitches to the rasterizer (faster batched rendering when photorealism isn't required). Ignored whenbatch_render=False.genelab assetCLI command group: addedasset {list,info,download,purge}for managing the bundled asset-zoo cache.asset listenumerates everyAssetSpecdeclared undergenelab.asset_zoowith downloaded / not-downloaded status + on-disk size;asset info NAMEshows URL / md5 / cache path;asset download NAME(or--all,--force) explicitly downloads through the existingfetch_asset/ md5-verify path;asset purge NAME(or--all,--yes) removes a cached asset. Discovery walks the zoo's submodules, so adding a new robot automatically shows up underasset listwithout any registration call.
- Bumped genesis-world to v1.0.0 (
>=1.0.0,<2.0.0). Picks up non-convex multi-contact collision detection, contact pruning, several upstream bug fixes (static-contact drift, spurious yaw on flat terrain), and the rigid-solver speedup on contact-rich scenes. Exposes the new ImGui debug overlay viaSimulationCfg.viewer_imgui(forwarded togs.options.ViewerOptions(enable_gui=...); off by default). - Removed three pre-0.4.7 compatibility shims (
envs_idx=try/except in_articulation_writer,PyQtPlot/MPLPlotrecorder-name fallback inrecording.register, and thegs.devicegetattr softprobe inInteractiveScene.build) now that the v1.0 API surface is the floor. KinematicContactSensor.data: dropped the mis-nameddepthfield (GenesisContactProbe.read()returns a bool, not a depth) and the redundant threshold operation.data.in_contactis now the(num_envs, [history,] num_probes)booltensor Genesis returns, already thresholded atcfg.contact_threshold.PointCloudTactileSensor.data: replaced the singlerawfield withforceandtorquetensors extracted from Genesis's structuredProximityTaxelData.rawis kept as a property alias forforceso the shape-agnostic reward primitives still see the right tensor.- Asset-download progress bar reaches every CLI surface.
genelab exportnow wraps its task-construction step in the samefetch_progress()Rich callback every other CLI surface uses (play,train,eval,info, the newasset *subcommands), so a first-touch asset download from any command renders a progress bar instead of staying silent. The download infrastructure itself was already callback-driven; only_exportwas missing thewith fetch_progress():block. - Breaking: removed
lab.GenesisBackendCfg. - Breaking: renamed the environment registration protocol from
lab.ManagerBasedEnvtolab.ManagerBasedEnvProtocol. - Moved backend-specific config modules from
genelab.rl.{skrl_config,skrl_models,sb3_config}togenelab.rl.backends.{skrl,sb3}.{config,models}. Thegenelab.rl.*Cfgfacades remain available for user code. - Moved
NoiseCfg's canonical home togenelab.contracts; it remains re-exported from the MDP noise module and the public facades.
Second development release.
- Reproducibility: added deterministic evaluation with
genelab eval, model export withgenelab export, multi-seed training withgenelab train --seeds a,b,c [--parallel N], periodic in-training evaluation with--eval-every K, best-model saving, RGB-D camera sensing, and five bundled asset-zoo robots. - Sim2real hardening: added actuator and joint domain randomization, interval-mode
domain randomization, out-of-limit terminations, reward hard-constraints, the
MlpResidualActuator, and observation-noise models includingScaledNoise,CorrelatedNoise, andBiasDrift. - Platform breadth: added new sub-terrain types, difficulty-ordered terrain curriculum,
camera segmentation,
ForceTorqueSensor, additional Genesis rigid-body simulation options, a benchmark command with regression gating, and three new robots: Unitree H1, UR10e, and Allegro Hand. - Multi-robot API: added
env.articulations[name]and per-entity routing viaSceneEntityCfg.name,ActionTermCfg.asset_name, andSensorCfg.entity_name. - Public extension API: added
genelab.extensionsandgenelab.registry.Runnableas the stable extension surface for third-party robots, environments, tasks, and backends. - Architecture tooling: added a required import-linting CI gate and additional guards for optional dependencies, CLI help output, and articulation size.
- Breaking: removed the singular
env.robot,env.robot_state, andenv.articulationaccessors, along with name-table convenience accessors such asjoint_namesanddefault_joint_pos. Entities should now be accessed by name, for example:env.articulations["robot"].{gs_handle, data, joint_names, …}. - Broke the cycle between the RL runner and RL backends.
- Added a shared base manager for term-keyed managers.
- Consolidated small duplicated implementations.
- Decomposed the CLI dispatcher.
- Moved configuration parsing ownership into the domain layer.
- Split task-specific rewards.
- Renamed and colocated vector-environment adapters under the canonical RL vector-env layout.
- Promoted layering checks from advisory linting to a blocking import-linting gate.
- Removed deprecated RL wrapper and vector-environment re-export shims. Import vector environments from their canonical locations instead.
- Removed unused
RslRlBaseRunnerCfgfields:resume,load_run, andload_checkpoint.
- Added
InteractiveSceneand extractedArticulation/RigidObjectentities fromManagerBasedRlEnv. - Split simulation and scene configuration.
- Added the
Sensor[T]abstraction with contact, body velocity, ray-cast, and terrain height sensors. - Added a mouse-interaction viewer plugin.
- Added rsl_rl-based PPO training and replay for the inverted-pendulum and Unitree G1 examples.