PyQt5 desktop controller for the Mobipick Labs Docker simulation
Project description
Mobipick Labs Docker GUI
The Mobipick Labs Docker GUI is a PyQt5 desktop application that controls the Docker-based Mobipick Labs ROS 1 simulation. It wraps Docker Compose commands, sets the environment required by the selected Docker image and ROS workspace, streams process output into GUI tabs, and performs cleanup when the application closes.
Related project and distribution links:
- Mobipick Labs repository: https://github.com/DFKI-NI/mobipick_labs
- PyPI package: https://pypi.org/project/mobipick-labs-docker-gui/
This README is developer documentation for maintaining and extending the
application. User-facing button and menu documentation lives in the
gui_user_documentation.md
resource and is rendered in the application from Help > Documentation.
Repository layout
.
|-- gui.py # Legacy shim that forwards to mobipick_gui.cli
|-- mobipick_gui/
| |-- cli.py # QApplication setup and CLI parsing
| |-- main_window.py # Main PyQt window and Docker/ROS orchestration
| |-- process_tab.py # QProcess plus log widget wrapper
| |-- log_widget.py # Buffered QTextEdit for high-volume logs
| |-- documentation_dialog.py # Rendered user documentation and search
| |-- bug_report.py # Diagnostic report builder
| |-- setup_wizard.py # Image setup and custom image choices
| |-- workspace_dialog.py # Workspace manager dialog
| |-- workspaces.py # Workspace registry and runtime env model
| |-- settings_transfer.py # Portable import/export of GUI settings
| |-- window_layout.py # wmctrl/xprop capture and replay helper
| |-- config.py # Bundled/user config loading and defaults
| `-- resources/
| |-- docker-compose.yml
| |-- custom_entrypoint.sh
| |-- clean.bash
| |-- gui_user_documentation.md
| |-- config/
| | |-- gui_settings.yaml
| | |-- button_commands_labs.yaml
| | |-- worlds.yaml
| | `-- docker_cp_image_tag.yaml
| `-- scripts/
| |-- enter_host_shell.py
| |-- terminal.bashrc
| `-- ros_workspace_setup.bash
|-- tests/mobipick_gui/ # pytest regression tests
|-- pyproject.toml # Packaging metadata and package data
|-- MANIFEST.in # Source distribution manifest
`-- doc/ # Project imagery
Private experiments and templates under mobipick_gui/resources/private/ are
excluded from package data and source distribution output.
Runtime architecture
mobipick_gui.cli.main() creates a QApplication, instantiates
MainWindow, and forwards unknown arguments to Qt. MainWindow owns the GUI
state, menu actions, process tabs, workspace/image selection, recording state,
and shutdown sequence.
Runtime commands are executed in two ways:
- Long-running tasks use
QProcessthroughProcessTab. Output is merged, sanitized for terminal escape sequences, converted from ANSI color to HTML when needed, and flushed intoLogTextEdit. - Short helper commands use
subprocess.run()throughMainWindow._sp_run(), which injects the same runtime environment and logs the command to the GUI.
Docker Compose is always invoked by the GUI with the bundled compose file and a fixed project name. The compose file is not intended to be run directly during normal GUI use, because the GUI also tracks process state, xhost access, tabs, recording, and cleanup.
Prerequisites
The application targets Linux desktops with X11.
- Python 3.8 or newer.
- PyQt5 5.15 or newer.
- Docker Engine and the Docker Compose plugin available to the current user.
- An X11 desktop session for Gazebo, RViz, RQt, and recording.
- Optional but recommended: NVIDIA Container Toolkit for GPU-accelerated simulation.
- Optional tools for specific features:
wmctrlandxpropfor window layout capture/replay.graphvizfor workspace graph rendering.ffmpegfor Auto Launch screen recording.
Common Ubuntu setup:
sudo apt update
sudo apt install docker.io docker-compose-plugin wmctrl x11-utils graphviz ffmpeg
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker "$USER"
Log out and back in after changing Docker group membership, or start a shell
with newgrp docker.
Pull at least one Mobipick image before launching the GUI, or use the setup wizard on first launch:
docker pull ozkrelo/x_mobipick_labs:noetic-v1.1
docker pull ozkrelo/x_mobipick_labs:noetic-v1.2
Installation
Install the released package from PyPI:
python -m pip install mobipick-labs-docker-gui
If you installed an older released version, upgrade it in the same Python environment:
python -m pip install --upgrade mobipick-labs-docker-gui
python -m pip show mobipick-labs-docker-gui
If the command was installed with --user and your shell cannot find
mobipick-labs-docker-gui, make sure Python's user script directory is on
PATH, for example ~/.local/bin on many Linux systems.
Development setup
Create an editable install from the checkout:
python -m pip install -e .
Install test-only tools when working on regression tests:
python -m pip install pytest pytest-qt
Launch the GUI from the checkout:
mobipick-labs-docker-gui --verbose 2
Equivalent debug entry points:
python -m mobipick_gui --verbose 2
python gui.py --verbose 2
The verbosity option accepts levels 1 through 3. Unknown CLI arguments are
passed to Qt, for example -platform offscreen in headless checks.
Tests
Run the full test suite:
pytest
Most GUI tests set QT_QPA_PLATFORM=offscreen and stub Docker discovery or
process methods. Keep new tests Docker-independent unless the test explicitly
targets Docker command construction.
Current coverage includes:
- configuration loading and writable user config paths;
- workspace registry, switching, import/export, and image/workspace matching;
- setup wizard and custom image profile persistence;
- remote ROS master behavior;
- Auto Launch and recording state transitions;
- menu-only status/image controls and menu tooltips;
- bug report formatting;
- documentation dialog rendering and keyword search.
Packaging
The package version is declared in pyproject.toml. The fallback version used
when running directly from an unpackaged source tree lives in
mobipick_gui/version.py; keep both values in sync for releases.
Build source and wheel artifacts with:
python -m pip install --upgrade build
python -m build
Optionally validate the artifacts before uploading:
python -m pip install --upgrade twine
python -m twine check dist/*
Package data is declared in both pyproject.toml and MANIFEST.in. When adding
new runtime assets under mobipick_gui/resources/, update both files so editable
installs, wheels, and source distributions all behave the same.
The console script installed by the package is:
mobipick-labs-docker-gui = mobipick_gui.cli:main
PyPI release flow
Publishing is handled by .github/workflows/python-publish.yml. The workflow
builds the distributions and uploads them to PyPI when a GitHub Release is
published. Merging to main alone does not publish a new PyPI version.
Recommended release steps:
- Update the version in
pyproject.tomlandmobipick_gui/version.py. - Run the tests and build locally.
- Merge the release branch to
main. - Create and publish a GitHub Release from
main, using a tag such asv0.1.1. - Confirm the workflow succeeds, then verify the new release on https://pypi.org/project/mobipick-labs-docker-gui/.
Configuration model
Bundled defaults live under mobipick_gui/resources/config/.
mobipick_gui.config.CONFIG_DEFAULTS supplies hard defaults, then
config/gui_settings.yaml is merged over them, then the per-user
gui_settings.yaml is merged last.
Important environment overrides:
MOBIPICK_GUI_DATA_ROOTpoints the package at an alternate resources root.MOBIPICK_GUI_CONFIGpoints to an alternate per-user GUI settings file.MOBIPICK_WORKSPACE_CONFIGpoints to an alternate workspace registry.XDG_CONFIG_HOMEandXDG_DATA_HOMEcontrol the default per-user roots.
Default per-user state locations:
~/.config/mobipick-labs-docker-gui/gui_settings.yaml
~/.config/mobipick-labs-docker-gui/workspaces.yaml
~/.config/mobipick-labs-docker-gui/window_layouts/{workspace}.yaml
~/.config/mobipick-labs-docker-gui/docker_cp_image_tag.yaml
~/.config/mobipick-labs-docker-gui/docker_cp_profiles/{workspace}_docker_cp_image_tag.yaml
~/.config/mobipick-labs-docker-gui/launch_sequences/
~/.config/mobipick-labs-docker-gui/profiles/
~/.local/share/mobipick-labs-docker-gui/recordings/
~/.local/share/mobipick-labs-docker-gui/image_builds/
Keep bundled resource files immutable at runtime. User edits should be written to per-user config/data paths.
The top-level Settings menu exposes migration and troubleshooting actions: Export All Settings... writes the workspace registry, per-user GUI settings, and workspace profiles to one portable YAML file; Import All Settings... restores that file under a chosen workspace master folder; Show Configuration Paths displays the writable config/data paths that the GUI manages.
Docker and ROS services
The bundled compose file defines three services:
mobipickruns the simulator.mobipick_cmdruns local ROS tools, scripts, terminals, and custom commands.mobipick_remote_cmdruns tools with host networking for external ROS master mode.
The GUI injects these important values into Docker commands:
MOBIPICK_IMAGEselected from the image combo box.MOBIPICK_WORLDselected fromworlds.yaml.MOBIPICK_CONTAINER_USER,MOBIPICK_CONTAINER_ENTRYPOINT, andMOBIPICK_CONTAINER_WORKDIRderived from image profiles.MOBIPICK_UID,MOBIPICK_GID,MOBIPICK_HOST_USER,MOBIPICK_HOST_GROUP, andMOBIPICK_HOST_HOMEderived from the host user.- Workspace mount and ROS environment values from
WorkspaceRegistry. ROS_MASTER_URIfrom local Roscore or remote ROS master mode.
The GUI creates or reuses the external Docker network named mobipick and
labels one-off containers with mobipick.exec and mobipick.tab so they can be
found and stopped reliably.
Workspace model
WorkspaceRegistry stores host catkin workspaces, their inheritance, optional
workspace-specific Docker images, button profiles, auto-launch profiles, and
simulator command overrides.
For host workspace mode, the registry mounts the common workspace root once
inside Docker at the canonical container root ~/ros_ws. It maps selected
workspaces and underlays into that root, exports MOBIPICK_WORKSPACE_*
variables, and provides fallback source paths when a workspace is not built.
WorkspaceManagerDialog is the UI for:
- choosing or creating a master folder;
- discovering child workspaces with
src/; - adding or creating standalone workspaces;
- editing inheritance and image/button/launch profiles;
- building the active workspace inside Docker;
- exporting/importing portable GUI settings;
- rendering the workspace graph.
Builds use catkin build inside the selected development image. Public root
images are configured as image-default only and do not mount host workspaces.
Image profiles and setup wizard
Image behavior is controlled by images in gui_settings.yaml.
defaultis the preferred Docker image.discovery_filterscontrols which local images appear in the combo box. The Configure Image Filters dialog shows these filters next to the blacklist and previews which local Docker images will be used, ignored, or hidden.blacklistcontains image refs or glob patterns ignored after discovery filtering.profilesmaps image refs or glob patterns to container user behavior, workspace support, compatible workspaces, working directory, entrypoint, and tooltip description.
The setup wizard can pull public images, choose a default image, build a
host-user development image, and clone/build DFKI-NI/mobipick_labs from
source in a host-mounted workspace. Each optional wizard page has a skip button.
The custom image builder writes a Docker build context under the per-user data
directory, copies custom_entrypoint.sh, adds a host-matching user, installs
passwordless sudo, and tags the result according to the wizard fields.
The source install step creates
<master folder>/clean_mobipick_labs_ws/src/mobipick_labs by default, runs the
work inside Docker with the workspace mounted to the host, sources
/opt/ros/noetic/setup.bash, then executes ./install-deps.sh and ./build.sh.
Output streams into an Install Source tab. Existing git checkouts are
updated; existing non-git paths stop the step with an explicit error.
Button profiles
Default toolbar buttons are loaded from
resources/config/button_commands_labs.yaml. load_button_layout() supports
workspace-specific replacements through the workspace registry.
Use Tools > Configure Toolbar Buttons to edit the active profile from the
GUI. Workspace edits are saved as writable per-user copies named for the active
workspace, and that workspace is updated to point at its copy. Packaged global
profiles are also copied before saving. The dialog shows the editable button
key, label, command, compose service, and tooltip; other execution fields are
preserved when saving.
Use Load Profile and Export Profile in that dialog to move complete button configurations as one YAML file. The automatic save location is the per-user XDG config directory so an installed package is never modified at runtime; exporting is the way to place a profile in a private repository or share it with another setup.
Button entries can be:
kind: builtinwith actions such assim,tables_demo,rviz, andrqt_tables;kind: commandwith an arbitrary command executed either in Docker or on the host.
Every editable top-row button has a command. Default commands for the bundled
sim, tables, rviz, and rqt buttons live in the button profile and are
used by their builtin start/stop wrappers. Legacy workspace sim_command
values remain supported and are written into the button profile when saved from
the GUI editor.
Command entries can declare:
requires_roscore;reuse_tab;world_config_requiredandworld_arg_name;setuporpre_command;host;stop_command;log_command;pass_ros_master_uri;service, for choosing the compose service used by Docker command buttons. Leave it empty for the normal tool service, or usemobipickfor launch files that start Gazebo themselves and need the simulator service identity.
The GUI normalizes all entries and creates matching process tabs and start/stop visual state.
roscore and terminal are fixed top-row buttons and are not stored in button
profiles. sim and rviz are required profile buttons: they cannot be
removed, but their command fields can override the default simulation and
RViz launch commands. Other profile buttons can be added, removed, reordered,
or changed.
Auto Launch
load_launch_sequence_plan() resolves Auto Launch YAML from a workspace
profile, per-user launch sequence directory, or fallback filenames derived from
the active button profile.
The saved format stores:
timeline: button key plusat_seconds;shutdown.order: reverse or custom stop order;- optional
shutdown.skip; - optional button text/tooltip metadata;
recording.start_delay_seconds.
AutoLaunchWizard edits the timeline and saves it to a writable per-user path
when the source is a packaged resource. Auto Launch can also coordinate window
layout replay and delayed recording startup.
Recording and window layout
Recording captures X11 screen video with ffmpeg -f x11grab. It is armed by the
GUI checkbox and starts only after Auto Launch begins and the timeline/layout
delay has elapsed. Recording sessions create timestamped folders containing the
MP4, ffmpeg.log, and saved HTML logs when requested.
Window layout capture uses WindowLayoutManager plus wmctrl and xprop.
The manager records the baseline windows present when the GUI starts, excludes
the GUI/helper windows during capture, stores a separate layout for each active
workspace, and applies saved positions to matching new windows after the
configured delay. The window_layout.state_file setting may include
{workspace} or {workspace_slug}; paths without a placeholder are treated as
a base location and expanded into one YAML file per workspace.
Remote ROS master mode
Remote mode is controlled by the hidden Remote ROS Master view controls. When enabled:
- local Roscore and simulation actions are disabled;
- tools, scripts, terminals, configured commands, and custom commands use
mobipick_remote_cmd; ROS_MASTER_URIis normalized and passed into containers;- host networking is used so ROS 1 callbacks can reach the nodes.
Changing remote mode or the URI is blocked while workspace processes are running.
Docker cp profiles
docker_cp_image_tag.yaml defines optional copy rules keyed by default or
by ROS workspace name.
host_to_containerentries run automatically after eligible containers appear.container_to_hostentries run from Tools > Docker > Execute Docker cp for the current running tab.
When the Docker image default workspace is active, user edits are saved to
~/.config/mobipick-labs-docker-gui/docker_cp_image_tag.yaml. When a ROS
workspace is active, edits are saved to
~/.config/mobipick-labs-docker-gui/docker_cp_profiles/{workspace}_docker_cp_image_tag.yaml.
The editor shows workspaces rather than Docker image tags. Add Row opens a
path setup dialog; the host side uses a local file picker, and the container
side can use a selected running setup container or manual path entry. Empty
profiles in the active writable file override bundled entries.
Logging and reports
Every process tab uses LogTextEdit, which buffers updates to keep high-volume
process output responsive. The log widget keeps only the configured maximum
block count.
GUI-originated messages and executed commands are written to the Log tab. Users can save the current tab, save all tabs, or load a saved HTML log into a closable tab. The bottom search row searches only the current log tab.
The bug report dialog collects selected diagnostic sections, including GUI version, selected workspace, selected image/workspace match, optional command outputs, workspace graph, log tab text, and user notes. Keep new diagnostics optional so report generation remains useful on machines without every tool installed.
User documentation dialog
The Help documentation window renders
resources/gui_user_documentation.md with QTextBrowser. It supports keyword
search from a line edit plus Find and Previous buttons. Matching keywords are
highlighted and the current match is selected and scrolled into view.
When editing user documentation, keep the text task-oriented and avoid developer internals. Developer details belong in this README or code comments.
Shutdown behavior
Closing the GUI starts a controlled shutdown:
- cancel Auto Launch timers and pending recording start;
- stop screen recording if active;
- stop the external terminal container;
- kill GUI-owned background
QProcessinstances; - stop simulator and related Mobipick containers;
- run
clean.bashwhen available; - revoke temporary X11 access;
- quit the Qt application.
Avoid adding early returns in shutdown paths unless they still leave the GUI in a recoverable state.
Development guidelines
- Keep user-visible defaults in
resources/config/and hard fallbacks inconfig.py. - Keep per-user writes out of packaged resources.
- Prefer extending existing helper methods in
MainWindowbefore adding a new orchestration path. - Add tests under
tests/mobipick_gui/for new behavior. - Stub Docker and external tools in tests unless the test only validates command construction.
- For new package resources, update
pyproject.tomlandMANIFEST.in. - For new user-visible controls, update
resources/gui_user_documentation.md. - For new developer-facing configuration, update this README.
Troubleshooting for developers
- If no images appear, open Configure Image Filters to inspect
images.discovery_filters,images.blacklist, and the preview of local images fromdocker images. - If GUI tests create real dialogs unexpectedly, set
QT_QPA_PLATFORM=offscreenand monkeypatch Docker discovery. - If a workspace does not mount, check the selected image profile for
supports_host_workspaces. - If RViz or Gazebo windows do not open, verify X11,
DISPLAY, Docker permissions, and temporaryxhostaccess. - If recordings produce no MP4, inspect the session
ffmpeg.logand the configured display/resolution. - If window layout replay does nothing, install
wmctrlandxpropand save a layout after simulator windows are visible.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mobipick_labs_docker_gui-0.1.1.tar.gz.
File metadata
- Download URL: mobipick_labs_docker_gui-0.1.1.tar.gz
- Upload date:
- Size: 149.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cd370ee3cf511098c65522a81a4f4064185b6ab4bb93eef16932aa84306a3f0
|
|
| MD5 |
6ec20ee58669a9f5b8907e4c17cb8eeb
|
|
| BLAKE2b-256 |
54f7b4328862662a6ba331a07f9ef33810bbcfe1f4c50e037be58bee184c0728
|
Provenance
The following attestation bundles were made for mobipick_labs_docker_gui-0.1.1.tar.gz:
Publisher:
python-publish.yml on oscar-lima/mobipick_labs_docker_gui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mobipick_labs_docker_gui-0.1.1.tar.gz -
Subject digest:
2cd370ee3cf511098c65522a81a4f4064185b6ab4bb93eef16932aa84306a3f0 - Sigstore transparency entry: 1912378874
- Sigstore integration time:
-
Permalink:
oscar-lima/mobipick_labs_docker_gui@c1cb03c9226001da44bf3c11e63dcaeb9303e90d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/oscar-lima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@c1cb03c9226001da44bf3c11e63dcaeb9303e90d -
Trigger Event:
release
-
Statement type:
File details
Details for the file mobipick_labs_docker_gui-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mobipick_labs_docker_gui-0.1.1-py3-none-any.whl
- Upload date:
- Size: 151.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee7ae964bc53345d507fae824f62ae0e132827576e0d7e7fea1f78c9bfa47c24
|
|
| MD5 |
9693fb7f4e92da8d349968c0b8838879
|
|
| BLAKE2b-256 |
eefb71d5f7a48fc003ab933ff5398cb518976f42346605f485974779860eff6d
|
Provenance
The following attestation bundles were made for mobipick_labs_docker_gui-0.1.1-py3-none-any.whl:
Publisher:
python-publish.yml on oscar-lima/mobipick_labs_docker_gui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mobipick_labs_docker_gui-0.1.1-py3-none-any.whl -
Subject digest:
ee7ae964bc53345d507fae824f62ae0e132827576e0d7e7fea1f78c9bfa47c24 - Sigstore transparency entry: 1912379092
- Sigstore integration time:
-
Permalink:
oscar-lima/mobipick_labs_docker_gui@c1cb03c9226001da44bf3c11e63dcaeb9303e90d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/oscar-lima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@c1cb03c9226001da44bf3c11e63dcaeb9303e90d -
Trigger Event:
release
-
Statement type: