Robot and trajectory viewer
Display the robot, task previews, and configured obstacles in an embedded 3D viewer.
mtc_gui.visualization_panel · Source
Operator GUI · Guide · Symbol index
How it is used
MTCMainWindow creates VisualizationPanel and connects joint, gripper, and trajectory signals. The panel starts a loopback HTTP server for viewer assets and robot meshes, then waits for the embedded WebEngine page before loading the model. Its controls and previews affect the display only.
Use preview_pose() and end_preview() around a task editor’s goal preview; play_trajectory() animates an orchestrator preview. Pose lists use degrees, while trajectory waypoint positions use radians. Python uses the configured arm-joint order, but the JavaScript viewer still expects six fixed UR joint names. closeEvent() stops the panel’s timer and mesh server.
Start here
Callable |
Purpose |
|---|---|
Locate robot assets, create the viewer controls, and start local asset serving. |
|
Display a six-angle goal preview and temporarily suppress live pose updates. |
|
Release a goal-pose preview and restore the most recently cached live pose. |
|
Convert trajectory waypoints into arm poses and animate them in the viewer. |
|
Stop trajectory playback and clear its active interpolation track. |
VisualizationPanel
Own the WebEngine view, robot model selection, preview state, and visual scene. Updates arrive on the GUI thread; the panel does not command the robot.
Inherits from: QWidget.
VisualizationPanel.__init__()
Locate robot assets, create the viewer controls, and start local asset serving.
Lifecycle · Source
__init__(self, ros2_bridge=None, parent=None)
Parameter |
Meaning |
|---|---|
|
Optional bridge reference retained as ros2; this constructor does not connect its signals. |
|
Optional parent widget. |
Errors: Description-package lookup falls back to cms_robot_description; other package/UI/server failures propagate.
Side effects: Creates an inactive 33 ms preview timer, resolves paths/packages, creates WebEngine or fallback UI, and starts mesh server/page loading when WebEngine is available. Initial gripper name is epick.
VisualizationPanel.preview_pose()
Display a six-angle goal preview and temporarily suppress live pose updates.
Method · Source
preview_pose(self, pose_deg)
Parameter |
Meaning |
|---|---|
|
List or tuple of exactly six values in degrees; contents are not checked for numeric validity. |
Returns: None.
Errors: Returns for unreadied page or wrong container/length; Qt errors propagate.
Side effects: Sets _preview_hold=True and calls window.updateJoints with a list. This is display-only.
VisualizationPanel.end_preview()
Release a goal-pose preview and restore the most recently cached live pose.
Method · Source
end_preview(self)
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Clears _preview_hold and, when ready with a truthy cached pose, sends it to window.updateJoints.
VisualizationPanel.play_trajectory()
Convert trajectory waypoints into arm poses and animate them in the viewer.
Callback · Source
play_trajectory(self, _unused_names, waypoints)
Parameter |
Meaning |
|---|---|
|
Ignored compatibility signal argument; names come from each waypoint. |
|
Sequence of (joint_names, positions_in_radians, cumulative_seconds). Named positions may include arm or gripper joints; complete arm samples are converted to degrees rounded to three decimals. |
Returns: None.
Errors: Returns before readiness or for no points; malformed names/positions/times raise. Does not validate chronological order or that all points have six arm joints.
Side effects: Seeds from the first complete arm sample or six zeros, holds the last arm state across partial/gripper-only points, stores the full track, duration from its last point, and monotonic start; shows preview controls and starts the timer. It does not set _preview_hold, so live updates can interleave with playback.
VisualizationPanel.stop_preview()
Stop trajectory playback and clear its active interpolation track.
Callback · Source
stop_preview(self)
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Stops timer, clears label, hides Stop Preview, and clears _preview_arm_track. It does not restore live pose, clear saved waypoints, or change goal-preview hold.
Referenced in source (1)
VisualizationPanel._setup_ui— mtc_gui.visualization_panel
VisualizationPanel.closeEvent()
Stop preview timing and the mesh server before delegating widget closure.
Lifecycle · Source
closeEvent(self, event)
Parameter |
Meaning |
|---|---|
|
QCloseEvent passed unchanged to the base widget handler. |
Returns: None.
Errors: Server shutdown/Qt errors propagate; readiness polling is not explicitly stopped here.
Side effects: Stops preview timer, shuts down loopback server when present, then invokes QWidget.closeEvent.
Internal callbacks and helpers
VisualizationPanel._setup_ui()
Create the 3D viewport and display-only controls, or a fallback message if WebEngine is unavailable.
Internal helper · Source
_setup_ui(self)
Returns: None.
Errors: Without WebEngine creates an installation hint and returns; other Qt failures propagate.
Side effects: Creates toolbar/status widgets and web_view when available; no ROS goal is sent by these controls.
Referenced in source (1)
VisualizationPanel.__init__— mtc_gui.visualization_panel
VisualizationPanel._referenced_packages()
Collect package references from each distinct URDF named by configured grippers.
Internal helper · Source
_referenced_packages(self) -> set[str]
Returns: Union of package references, or the full known-package set when configuration loading fails, no URDF names are declared, or _urdf_dir is None.
Errors: Malformed gripper mappings and non-OSError file failures may propagate. Individual unreadable files produce empty sets through _packages_referenced_by_urdf, not the broad fallback claimed by the docstring.
Side effects: Loads beamline configuration and reads declared URDF files.
Referenced in source (1)
VisualizationPanel.__init__— mtc_gui.visualization_panel
VisualizationPanel._start_server()
Serve the viewer locally and begin loading viewer.html into WebEngine.
Internal helper · Source
_start_server(self)
Returns: None.
Errors: No-op without WebEngine. Socket/server/Qt errors propagate.
Side effects: Creates/starts _MeshServer, updates status with the port, connects loadFinished, and loads the loopback static URL.
Referenced in source (1)
VisualizationPanel.__init__— mtc_gui.visualization_panel
VisualizationPanel._on_page_loaded()
Start readiness polling after a successful browser page load.
Callback · Source
_on_page_loaded(self, ok)
Parameter |
Meaning |
|---|---|
|
QWebEngine loadFinished Boolean; False shows failure and returns. |
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Shows Waiting for JS, creates _ready_poll, connects readiness checks, and starts it every 100 ms after success.
Referenced in source (1)
VisualizationPanel._start_server— mtc_gui.visualization_panel
VisualizationPanel._check_ready()
Ask JavaScript whether the viewer has set window._vizReady to true.
Callback · Source
_check_ready(self)
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Runs a WebEngine script and routes its asynchronous result to _on_ready_result.
Referenced in source (1)
VisualizationPanel._on_page_loaded— mtc_gui.visualization_panel
VisualizationPanel._on_ready_result()
Finish readiness polling and load the current robot model and scene when JavaScript is ready.
Callback · Source
_on_ready_result(self, ready)
Parameter |
Meaning |
|---|---|
|
Result of the window._vizReady equality check; false values leave polling active. |
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Stops readiness timer, sets _page_ready=True, updates status, calls _load_urdf and _reload_scene.
Referenced in source (1)
VisualizationPanel._check_ready— mtc_gui.visualization_panel
VisualizationPanel._load_urdf()
Load the configured gripper’s robot URDF through the local mesh server.
Internal helper · Source
_load_urdf(self, gripper)
Parameter |
Meaning |
|---|---|
|
Gripper name passed to gripper_urdf_file, with ur_standalone.urdf as the fallback filename. |
Returns: None.
Errors: No-op before page readiness. Configuration import/lookup, missing server, or Qt failures propagate.
Side effects: Builds a loopback URDF URL and runs window.loadRobot(url, port); does not await or report JavaScript load success.
Referenced in source (2)
VisualizationPanel._on_ready_result— mtc_gui.visualization_panelVisualizationPanel.set_gripper— mtc_gui.visualization_panel
VisualizationPanel.set_gripper()
Normalize the selected gripper to lowercase and request its visual robot model.
Callback · Source
set_gripper(self, gripper_name)
Parameter |
Meaning |
|---|---|
|
String gripper selection. |
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Sets _current_gripper and calls _load_urdf, which waits for page readiness by returning early when necessary.
VisualizationPanel._on_joint_state()
Cache live joint angles and update the viewer unless a goal preview is held.
Callback · Source
_on_joint_state(self, pose_deg)
Parameter |
Meaning |
|---|---|
|
Joint-angle list in configured arm order, conventionally six numeric degrees values; this handler does not validate shape or types. The JavaScript consumer maps array positions to its hardcoded UR joint-name order. |
Returns: None.
Errors: No-op before readiness; malformed/Qt errors otherwise propagate.
Side effects: Caches the latest pose only after readiness, suppresses updates during _preview_hold, throttles by monotonic 0.033 s, and runs window.updateJoints.
VisualizationPanel._reset_view()
Reset the JavaScript camera view when the page is ready.
Callback · Source
_reset_view(self)
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Runs window.resetView(); no-op before readiness.
Referenced in source (1)
VisualizationPanel._setup_ui— mtc_gui.visualization_panel
VisualizationPanel._home_pose()
Show the viewer’s home pose when the page is ready.
Callback · Source
_home_pose(self)
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Runs window.setHomePose(); changes only visualization, not robot joint state.
Referenced in source (1)
VisualizationPanel._setup_ui— mtc_gui.visualization_panel
VisualizationPanel._toggle_demo()
Enable or disable the viewer’s demonstration animation.
Callback · Source
_toggle_demo(self, checked)
Parameter |
Meaning |
|---|---|
|
Boolean toggle state serialized as JavaScript true/false. |
Returns: None.
Errors: Qt/widget errors propagate; no local exception handler.
Side effects: Runs window.demoMode when ready; controls only the local viewer.
Referenced in source (1)
VisualizationPanel._setup_ui— mtc_gui.visualization_panel
VisualizationPanel._tick_preview()
Advance visual trajectory playback by interpolating between timed arm poses.
Callback · Source
_tick_preview(self)
Returns: None.
Errors: Empty track stops timer. Invalid track data/Qt errors propagate; times before the first point or outside a matching segment cause no update.
Side effects: Uses monotonic elapsed time and a linear scan, sends three-decimal interpolated joints, or snaps to final pose and stops at completion. Shows PREVIEW done and schedules label clearing after two seconds; completed track remains stored.
Referenced in source (1)
VisualizationPanel.__init__— mtc_gui.visualization_panel
VisualizationPanel._reload_scene()
Load supported obstacle shapes from the configured scene into the viewer.
Callback · Source
_reload_scene(self)
Returns: None.
Errors: Missing path and YAML read/parse exceptions update status and return. Per-obstacle KeyError/TypeError/ValueError entries are skipped; unsupported types are skipped. A nonmapping YAML root, malformed obstacle object raising AttributeError, short box size raising IndexError, or JavaScript-call error can still propagate despite the docstring’s broader promise.
Side effects: Reads YAML and emits window.setSceneObstacles([{name,type,pos:[x,y,z],rot:[roll,pitch,yaw],dims:{size|height,radius}}]); positions and dimensions are interpreted as metres and rotations as radians by viewer.html, with no per-obstacle frame transform in this Python path. JavaScript replaces the existing displayed obstacle list. Updates obstacle/skipped count status; makes no planning-scene service call.
Referenced in source (2)
VisualizationPanel._on_ready_result— mtc_gui.visualization_panelVisualizationPanel._setup_ui— mtc_gui.visualization_panel
Functions
Internal callbacks and helpers
_load_arm_joints()
Read configured arm-joint order, falling back to the six standard UR joint names.
Internal helper · Source
_load_arm_joints() -> list[str]
Returns: List of joint-name strings; the module stores the result once in _ARM_JOINTS. The bundled JavaScript still has its own hardcoded six-name UR order; this helper does not configure it.
Errors: Catches all Exception failures from the config-loader import/call.
Side effects: Loads beamline joint configuration when available.
_base_packages()
Resolve required arm and beamline description package names.
Internal helper · Source
_base_packages() -> list[str]
Returns: [“ur_description”, configured_description_package], or [“ur_description”, “cms_robot_description”] on failure.
Errors: Catches all Exception failures.
Side effects: Consults config_loader; module caches the result in _BASE_PACKAGES.
_packages_referenced_by_urdf()
Extract unique package names from package:// references in URDF text.
Internal helper · Source
_packages_referenced_by_urdf(urdf_path: Path) -> set[str]
Parameter |
Meaning |
|---|---|
|
Path object supporting read_text; content is scanned with a regular expression rather than parsed as XML. |
Returns: Set of referenced package names, or an empty set after an OSError.
Errors: Catches only OSError; decoding/type errors propagate.
Side effects: Reads the URDF file.
Referenced in source (1)
VisualizationPanel._referenced_packages— mtc_gui.visualization_panel
_find_workspace_roots()
Locate a source/install workspace from this module’s ancestry, optionally including an ancestor main workspace.
Internal helper · Source
_find_workspace_roots()
Returns: List of Path roots. Fallback is Path(file).resolve().parents[3] when no matching ancestor is found.
Errors: Filesystem/path errors are not caught.
Side effects: Checks ancestor src/install directories; does not change the workspace.
Referenced in source (2)
VisualizationPanel.__init__— mtc_gui.visualization_panel_resolve_packages— mtc_gui.visualization_panel
_resolve_packages()
Map required description packages to installed or workspace source directories.
Internal helper · Source
_resolve_packages(required: set[str] | None=None)
Parameter |
Meaning |
|---|---|
|
Optional package-name set; None starts with all known descriptions. Base packages are always included, even for an empty set. |
Returns: Dict of package name to directory string; packages that cannot be located are omitted.
Errors: Missing ament import and per-package ament lookup failures are tolerated; other filesystem/type errors propagate.
Side effects: Checks ament and fixed /opt/ros/jazzy/workspace install/source candidates; reads no meshes and writes no files.
Referenced in source (1)
VisualizationPanel.__init__— mtc_gui.visualization_panel
_resolve_scene_yaml()
Resolve the active beamline’s scene_file to an existing file.
Internal helper · Source
_resolve_scene_yaml()
Returns: Path to the scene YAML, or None for missing configuration, absent scene_file, nonexistent file, or any caught failure.
Errors: Catches all Exception failures from config/path resolution.
Side effects: Loads beamline configuration and checks the candidate file.
Referenced in source (1)
VisualizationPanel._reload_scene— mtc_gui.visualization_panel
_MeshRequestHandler
Map viewer URLs to static, URDF, and package files. Filesystem containment checks keep requests within the configured roots.
Inherits from: SimpleHTTPRequestHandler.
_MeshRequestHandler.__init__()
Attach viewer route roots before the standard HTTP request handler processes a request.
Lifecycle · Source
__init__(self, *args, package_map, resources_dir, urdf_dir, **kwargs)
Parameter |
Meaning |
|---|---|
|
Positional SimpleHTTPRequestHandler arguments, normally request socket, client address, and server. |
|
Mapping of ROS package names to share/source directories. |
|
Root for viewer HTML/JavaScript/static files. |
|
Root for configured robot URDF files. |
|
Keyword arguments forwarded to SimpleHTTPRequestHandler. |
Errors: Standard HTTP-handler and filesystem errors follow base-class behavior.
Side effects: Stores routing roots and delegates request handling to SimpleHTTPRequestHandler.
Internal callbacks and helpers
_MeshRequestHandler.translate_path()
Decode the URL path and route static, URDF, or package requests through containment-checked filesystem resolution.
Callback · Source
translate_path(self, path)
Parameter |
Meaning |
|---|---|
|
HTTP request URL/path; query and fragment are removed via urlsplit and percent escapes decoded once. |
Returns: Filesystem path string. /static/ uses resources_dir, /urdf/ uses urdf_dir, known /package/… uses package_map; all other paths fall back under resources_dir.
Errors: URL/path errors propagate; traversal is redirected by _resolve_under rather than explicitly raising an HTTP error.
Side effects: Resolves filesystem paths; does not itself open the response file.
_MeshRequestHandler._resolve_under()
Resolve a relative path and prevent it from escaping its resolved root, including through symlinks.
Internal helper · Source
@staticmethod
_resolve_under(root, relative)
Parameter |
Meaning |
|---|---|
|
Allowed filesystem directory. |
|
Path component interpreted beneath root; may contain traversal components that are checked after resolution. |
Returns: Resolved candidate path string when contained, otherwise root/.beambot-path-denied.
Errors: Path-resolution errors propagate; denial uses a sentinel filename and does not itself guarantee that filename is absent.
Side effects: Performs path resolution only.
Referenced in source (1)
_MeshRequestHandler.translate_path— mtc_gui.visualization_panel
_MeshRequestHandler.end_headers()
Attach a one-hour public cache directive to every HTTP response before finishing headers.
Callback · Source
end_headers(self)
Returns: None.
Errors: HTTP header/output failures from send_header or the base end_headers propagate; no local exception handler.
Side effects: Sends Cache-Control: public, max-age=3600 and delegates to the base end_headers.
_MeshRequestHandler.log_message()
Suppress the standard HTTP request-log output.
Callback · Source
log_message(self, format, *args)
Parameter |
Meaning |
|---|---|
|
Ignored logging format string supplied by the HTTP handler. |
|
Ignored formatting arguments. |
Returns: None.
Errors: No validation or error handling.
Side effects: None; deliberately emits no request logs.
_MeshServer
Serve local viewer files and robot meshes on an ephemeral loopback port. VisualizationPanel starts and stops its daemon thread.
_MeshServer.__init__()
Bind the viewer’s HTTP server to an ephemeral loopback port.
Lifecycle · Source
__init__(self, package_map, resources_dir, urdf_dir)
Parameter |
Meaning |
|---|---|
|
Package route mapping passed to each request handler. |
|
Viewer static-resource root. |
|
Robot URDF root. |
Errors: Bind/server construction failures propagate.
Side effects: Opens an HTTP listening socket at 127.0.0.1:0, records the assigned port, and creates but does not start the serving thread.
Referenced in source (1)
VisualizationPanel._start_server— mtc_gui.visualization_panel
_MeshServer.start()
Start the prepared daemon HTTP-serving thread.
Lifecycle · Source
start(self)
Returns: None.
Errors: Thread errors propagate; repeated starts are not guarded.
Side effects: Begins serving viewer/URDF/mesh resources over loopback.
_MeshServer.stop()
Shut down serving, close the listening socket, and join the worker for up to one second.
Lifecycle · Source
stop(self)
Returns: None.
Errors: Server/thread errors propagate; this assumes serve_forever was started.
Side effects: Stops HTTP service and closes its socket.