2026-08-09 #414
markaren
announced in
Announcements
2026-08-09
#414
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
This release includes various fixes and polishing after yesterdays major release.
The robot can see: a colour camera sensor (#409)
A new sensor type beside the depth camera and LIDAR — the one that produces a
picture, which is what a wrist camera publishes and a perception policy
consumes. Author it on a Camera object — the next section is why — and read it
from a Play script:
cam.imageis exactly whatsensor_msgs/Imagewithencoding="rgb8"wants —no flip, no conversion — and
cam.timeis on the same sim clock as every othersensor's measurements. Record writes one PNG per frame plus an index CSV: a
dataset, not a plot. Raster backends; on Vulkan the sensor reports an honest
status instead of a wrong picture.
Aiming a sensor is aiming a camera
The wrist camera exposed the friction the moment it worked: a pinhole sensor
looks down its −Z, and rotating a host object by degrees until an invisible
frustum points the right way is authoring blind. So the two pinhole sensors —
Depth and Camera — now author on a real
PerspectiveCameranode, andeverything a camera already has becomes the sensor's: the gizmo aims it, the
frustum helper shows the cone, and the camera dock previews exactly what it
will record — live, in edit mode, before Play is ever pressed.
One consequence worth knowing: the camera's FOV/near/far are now the frustum's
single source of truth. They are edited in the Camera section, the sensor
section shows them read-only, and Play builds the scan from the camera itself —
a stale copy in a saved document cannot out-vote it.
Old scenes keep playing; the gate is authoring-side only. A vision sensor
found on a plain object gets a one-click Move To Camera Child: the config
crosses whole, the camera is stamped from the authored numbers, the child sits
at the host's origin so the aim survives to the millimetre, and the whole move
is one undo step. The LIDAR stays on a plain node — 360 degrees has no frustum
for a camera to be the truth of.
The chrome moved into the viewport
The toolbar row is gone, and the hierarchy and inspector run the full height
from the menu bar to the status bar. What the bar held became viewport
furniture, drawn with the view gizmo's brush — vector sprites on the
background draw list, no textures, the same picture on either backend, crisp
at any DPI:
toggle and Snap as icon buttons, active tool on the accent, tooltips
carrying the W/E/R/Q keys.
on the buttons — green under Play while the clock runs, amber under Pause
while it holds — so the old PLAY banner is gone; the pill says it.
and orthographic toggle, in the corner that already answers "where am I
standing".
During Play the whole palette sleeps, Snap included — nothing it controls can
act while the gizmo is parked. Shift stays the hold-to-snap override.
The gripper is scriptable: runtime joints (#408)
Build a constraint mid-Play between any two of: a scene object (including any
link of a simulated robot — resolved by the same rule an authored joint node
uses), an
editor.RigidBody, anArticulationLink, or the world. The partstays a real dynamic body throughout — it keeps its mass and its contacts,
where the old workaround (reparenting) teleported it out of the simulation.
The session owns the joint, so Stop tears it down in the right order however
long a script keeps the handle, and
release()wakes both sides so the partactually falls.
Scripts can light a scene (#410)
The editor's embedded module now carries the loaders —
RGBELoader,EXRLoader,TextureLoader,ModelLoaderand friends — so a script canbuild a texture and assign
scene.environmentinstead of that being aUI-only action. Headless runs get the same power as
--environment=PATH.Python can open what the editor saves
ModelLoaderrouted every interchange format and answered "unsupportedextension" to
.json— the one format this project's own File → Save writes.One dispatch branch closes it everywhere at once: wheel, editor scripts,
load_async. The document root is adopted as the group's child, neverunwrapped, so a Scene root keeps its environment, fog and userData.
A URDF that will not load says why
URDFLoader.load/parseraised "failed to parse URDF XML" and threw away themessage that names the file, the line, and the symbol it could not resolve.
Now the exception is the diagnosis — which matters most on
/robot_description, where the XML never touched a disk:loader.last_errorandloader.diagnosticsare readable afterwards, and thewarnings a successful xacro expansion produces (a redefined macro, an ignored
attribute) reach both Python and the editor console instead of only stderr.
load_articulationand the editor's own robot import carry the same account.Files find their classes (#411)
stage_look.pyholdingclass StageLookis the ordinary way to write Python,and the lookup treated it as a non-match. Case and punctuation are now folded
on both sides —
stage_look/stage-look/StageLook/stageLookare onename — with the literal match still first, so nothing that resolved before
resolves differently. Setup scripts that only implement
start()are foundtoo, and the errors name the classes that exist plus a spelling that would
match.
And the rest
parameterised robot simulates as the robot on screen, not as the file's
defaults.
ImageStorage::Referencedocument no longer round-trips every textureupside down.
VK_EXT_headless_surfacewith a hidden-window fallback where the ICD lacksit.
editor.scene()correctly typed asScenein the stubs.Closes #406, #407, #408, #409, #410, #411.
This discussion was created from the release 2026-08-09.
All reactions