Skip to content

About

Template-based ROS project generator with Docker, VSCode integration, and multi-platform build support.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

ros-project-generator

ros-project-generator logo

ros-project-generator creates a ROS 2 workspace skeleton and can optionally add a VS Code Dev Container configuration. It does not generate Docker images by itself.

Docker files are generated by robotics_dockers. It is declared as a Python dependency and installed automatically with this project.

Responsibility Boundary

ros-project-generator owns project structure:

  • workspace files such as README.md, pyproject.toml, .gitignore, and optional pre-commit config
  • deps.repos
  • src/0_deps
  • starter ROS 2 packages such as bringup and simulation
  • optional VS Code files under .devcontainer/, .vscode/, and ws.code-workspace

robotics_dockers owns Docker image generation:

  • docker/Dockerfile
  • docker/build.py
  • docker/.resources/
  • ROS installation scripts
  • entrypoints
  • image user setup
  • image-level extra package mechanisms

ros-project-generator owns the two project runtime definitions:

  • docker/compose_files/docker-compose.yaml
  • .devcontainer/docker-compose.yaml

This boundary is intentional. If a generated file controls how the Docker image is built, it belongs in robotics_dockers. If a generated file controls the ROS workspace or the editor experience, it belongs in ros-project-generator.

Installation

Keep Python environments outside the source tree. This makes the separation between cloned source code and the installed Python runtime explicit.

robotics_dockers is obtained from the release tag declared in pyproject.toml, so every installation receives the same tested Docker-context contract.

User installation

Use this installation when you want to create ROS projects without modifying the generator:

git clone https://github.com/jfrascon/ros_project_generator.git
cd ros_project_generator

python3 -m venv "${HOME}/.python_venvs/ros-project-generator"
. "${HOME}/.python_venvs/ros-project-generator/bin/activate"

python -m pip install --upgrade pip
python -m pip install .

Installing this project downloads and installs the declared robotics_dockers Git dependency in the same virtual environment. No second clone or submodule command is required.

Activate the same environment in each new terminal before using the command:

. "${HOME}/.python_venvs/ros-project-generator/bin/activate"
ros-project --help

Developer installation

Use two editable installations when developing and testing ros_project_generator together with robotics_dockers. The repositories do not need to be adjacent; the paths below are examples and may be replaced with any two source directories:

git clone \
    https://github.com/jfrascon/robotics_dockers.git \
    /ruta/a/robotics_dockers

git clone \
    https://github.com/jfrascon/ros_project_generator.git \
    /ruta/segunda/a/ros_project_generator

cd /ruta/segunda/a/ros_project_generator

python3 -m venv "${HOME}/.python_venvs/ros-project-generator-dev"
. "${HOME}/.python_venvs/ros-project-generator-dev/bin/activate"

python -m pip install --upgrade pip
python -m pip install -e '.[dev]'
python -m pip install --no-deps -e /ruta/a/robotics_dockers

The first editable installation connects ros_project_generator to its source checkout and installs its development dependencies. It also installs the robotics_dockers release tag declared in pyproject.toml, because that is the normal project dependency. The final command replaces only that installed dependency with the local editable checkout.

Afterwards, verify that both packages report an editable project location:

python -m pip show ros-project-generator robotics-dockers

Changes in either source tree are now used immediately without reinstalling the package. Running python -m pip install -e '.[dev]' again may restore the declared robotics_dockers release tag. When that command is run again, repeat the final python -m pip install --no-deps -e /ruta/a/robotics_dockers command afterwards.

When changing only ros_project_generator, the final editable robotics_dockers command may be omitted. In that case, the generator continues to use the release tag declared in pyproject.toml.

Commands

Create a ROS 2 project:

ros-project new PROJECT_ID PROJECT_DIR ROS_DISTRO [options]

Example:

ros-project new my_robot ~/workspaces/my_robot jazzy \
  --img-id my_robot:jazzy

PROJECT_ID also becomes the default Docker Compose project name. It must start with a lowercase letter or digit and may contain only lowercase letters, digits, - and _. This is checked before any project files are created.

Create the same project without VS Code files:

ros-project new my_robot ~/workspaces/my_robot jazzy \
  --img-id my_robot:jazzy \
  --no-vscode

The project generator does not ask for an account. The generated Docker context is safe to commit because it contains no developer-specific UID or GID. Select the account later, when building the image:

cd ~/workspaces/my_robot/docker
python3 build.py developer "$(id --user)" "$(id --group)"

The primary group name defaults to the build command's user name; pass --group GROUP_NAME to build.py when they must differ. The base image defaults to the Ubuntu release associated with ROS_DISTRO; use --base-img IMAGE on ros-project new only when the project needs another compatible base.

Supported ROS distributions are listed by:

ros-project new -h

At the time this README was written, the project supports ROS 2 distributions only.

Generated Project

A normal generated project contains:

PROJECT_DIR/
  docker/
    Dockerfile             # image context generated through robotics_dockers
    build.py
    compose_files/
      docker-compose.yaml  # project runtime owned by ros-project-generator
    robotics_dockers_user_env.py
    env_files/
      .gitkeep
  deps.repos
  pyproject.toml
  README.md
  src/
    0_deps/
    bringup/
    simulation/

If VS Code support is enabled, the project also contains:

PROJECT_DIR/
  .devcontainer/
    code-devcont
    devcont
    devcontainer.json
    docker-compose.yaml
  .vscode/
    c_cpp_properties.json
    tasks.json
  ws.code-workspace

The two generated Compose files have identical initial content but different purposes:

  • docker/compose_files/docker-compose.yaml is the normal production/deployment Compose file owned by the generated ROS project. Additional production or machine-specific Compose definitions can be stored beside it.
  • .devcontainer/docker-compose.yaml is an independent copy for VS Code. A developer may customize this copy without changing the normal project runtime.

The complete .devcontainer/ directory, .vscode/ directory and workspace file are ignored by the generated Git repository. They are developer-local starting points and may diverge completely between developers during the life of the project.

There is currently one project Compose template in ros-project-generator. It is rendered once for production and then copied into .devcontainer, so the two files start with identical mounts, devices, NVIDIA settings and capabilities. The generated files are physically independent and may diverge after project creation. If their intended runtime behavior diverges in the generator itself, the single source template can then be split deliberately.

Both files default their Compose project name to the generated ROS project ID. Set COMPOSE_PROJECT_NAME when two deployments or checkouts on the same host must use different names; the standard docker compose --project-name option can also override it.

The template also documents optional rtprio and memlock limits beside the SYS_NICE and IPC_LOCK capabilities they complement. These limits remain disabled until a project needs them. A 30-second stop grace period is active so ROS nodes, rosbag recorders and simulators can close before Docker sends SIGKILL.

The production and development environments are deliberately independent. docker/build.py builds and validates the image, but it does not create a Compose environment file. For each deployment machine, create a deliberately named file below docker/env_files/, such as production.env or robot-a.env. These files can be versioned when they contain shared machine configuration and no secrets.

After building or pulling the selected image, copy its five identity values into that file and then add the paths, display and device values belonging to the deployment machine:

cd docker
python3 robotics_dockers_user_env.py PROJECT_IMAGE \
    --output env_files/production.env
docker compose \
    --env-file env_files/production.env \
    --file compose_files/docker-compose.yaml \
    up

The helper preserves other variables and comments already present in the file. It does not create host-specific values.

The .devcontainer/code-devcont script inspects the configured Docker image, exports the generic IMAGE_USER_ID, IMAGE_USER_PRIMARY_GROUP_ID and COMPOSE_PROJECT_NAME Compose variables, adds HOST_WORKSPACE, DISPLAY, HOST_XAUTHORITY_FILE and RENDER_GID, and opens ws.code-workspace. It does not write an environment file; the Dev Containers extension inherits the exported values from the VS Code process.

The .devcontainer/devcont script starts or stops the independent Dev Container Compose project; running it without arguments is the same as devcont --up. devcont --up inspects the image and writes all development-machine values, including the effective COMPOSE_PROJECT_NAME, to .devcontainer/.env. devcont --down reuses that file, so it stops the same project even when the original shell override is no longer present. Neither command reads files below docker/env_files/.

devcontainer.json leaves remoteUser and containerUser unset, uses /workspace, and sets updateRemoteUserUID: false. Docker therefore uses the account stored in the selected image, whatever its name. VS Code must not apply a second UID conversion after robotics_dockers fixed the identity during the image build.

Tests

Run the test suite from this repository root:

pytest -q

The tests mock Docker generation only when checking argument delegation. Integration tests render the real robotics_dockers image context and the project-owned Compose template without building an image. They verify the generic identity contract, /workspace, XDG, optional NVIDIA configuration, the exact initial Compose copy and the later independence of the two Compose files.

Development Notes

  • Do not add Dockerfile, Docker build, ROS installation, entrypoint, or image-extra resources to this repository.
  • Add those resources to robotics_dockers instead, after explicitly deciding to change that project.
  • Keep deps.repos and src/0_deps; they describe the source workspace, not the Docker image.
  • Keep ROS package templates here when they generate project packages such as bringup or simulation.

About

Template-based ROS project generator with Docker, VSCode integration, and multi-platform build support.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Used by

Contributors

Languages