Skip to content
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
e8785e9
Create ros2 package boilerplate for image segmentation nodes
MadsJJ Oct 22, 2025
8492b91
Add UNet and YOLO segmentation nodes with entry points in setup.py
MadsJJ Oct 22, 2025
74f1e85
create simple launch file
MadsJJ Oct 22, 2025
0884e29
add parameter files for unet, yolo and common
MadsJJ Oct 22, 2025
56a894e
remove duplicates from requirements.txt
MadsJJ Oct 22, 2025
dae704f
add blending of image and mask to the base node. Also update the imag…
MadsJJ Oct 22, 2025
8e12da2
create Dockerfile, and build and run script. Add install, build and l…
MadsJJ Oct 22, 2025
712692d
add training script for yolo model training with roboflow. add packag…
MadsJJ Oct 22, 2025
0575b16
make training script usable without cuda
MadsJJ Oct 22, 2025
8ad50bc
add separate requirements file for training script
MadsJJ Oct 22, 2025
c731202
remove requirements only needed for training
MadsJJ Oct 22, 2025
74fb5bf
upgrde packages in requirements in yolo training
MadsJJ Oct 22, 2025
3319e8c
looks like training on instance segmentation might be working
MadsJJ Oct 22, 2025
fee9c53
gitignore OS generated files
MadsJJ Oct 23, 2025
21e82d5
change model type to segmentation model
MadsJJ Oct 23, 2025
13ac688
add worker amount to be half of cpu count
MadsJJ Oct 23, 2025
13e5bd5
change project_name to project_id to clear up confusion for projects …
MadsJJ Oct 23, 2025
c49673c
change from os paths to Pathlib. Also create parent folder for datase…
MadsJJ Oct 23, 2025
be47cc6
format
MadsJJ Oct 23, 2025
14a3951
add patience parameter to model
MadsJJ Oct 23, 2025
b7fe81c
gitignore .vscode folder
MadsJJ Oct 26, 2025
8f178c9
add devcontainer file
MadsJJ Oct 26, 2025
7443658
remove annoying pylint
MadsJJ Oct 26, 2025
e4d9c5e
add dockerignore
MadsJJ Oct 26, 2025
7b248d8
gitignore bags
MadsJJ Oct 26, 2025
f0e2392
improve python dependency caching in dockerfile
MadsJJ Oct 26, 2025
8232a57
forgotten in previous commit
MadsJJ Oct 26, 2025
4e5e0fb
move bashrc sourcing to a script (wont need to rebuild image to modif…
MadsJJ Oct 26, 2025
633549d
add two launch files (yolo and unet)
MadsJJ Oct 26, 2025
0922ca2
change image_callback to abstract method in base node, because of dif…
MadsJJ Nov 2, 2025
ac2809e
update ultralytics version in requirements for segmentation model inf…
MadsJJ Nov 2, 2025
283007b
remove unet node
MadsJJ Nov 5, 2025
dc19869
simplify base node and use yolo.plot function for visualization
MadsJJ Nov 5, 2025
139f26a
add parameters confidence_threshold, imgsz, max_detections. Move yolo…
MadsJJ Nov 9, 2025
750c6fa
add: todo tree extension in devcontainer
MadsJJ Nov 14, 2025
d0c0c5f
Reword: package description and maintainer
MadsJJ Nov 14, 2025
c7e70f2
Start: remove base node inheritance and split yolo node and yolo impl…
MadsJJ Nov 14, 2025
2bd56f2
Remove: common params
MadsJJ Nov 14, 2025
e30f1a6
Rename "config" dir to "params" dir
MadsJJ Nov 14, 2025
2b15d52
add device, imgsz, compile and debug params
MadsJJ Nov 14, 2025
d4aa066
Delete: base and unet node
MadsJJ Nov 14, 2025
63a64ce
split yolo node into ros node and implementation
MadsJJ Nov 14, 2025
3235cbc
Reformat: yolo
MadsJJ Nov 14, 2025
0050f29
create Dockerfile, and build and run script. Add install, build and l…
MadsJJ Oct 22, 2025
c477d59
add devcontainer file
MadsJJ Oct 26, 2025
f793a52
remove annoying pylint
MadsJJ Oct 26, 2025
2e34410
add dockerignore
MadsJJ Oct 26, 2025
4af58ba
improve python dependency caching in dockerfile
MadsJJ Oct 26, 2025
a5e218d
forgotten in previous commit
MadsJJ Oct 26, 2025
83e4951
move bashrc sourcing to a script (wont need to rebuild image to modif…
MadsJJ Oct 26, 2025
474992e
add: todo tree extension in devcontainer
MadsJJ Nov 14, 2025
a8eef5d
fix: update devcontainer terminal profile setting and clean up runArgs
MadsJJ Nov 28, 2025
66f63a3
fix: copilot pr comment
MadsJJ Nov 28, 2025
e79a74a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 28, 2025
fcaf0fa
add: network=host to docker build script
MadsJJ Jan 5, 2026
33926e2
rename: docker image name to the same as repo name
MadsJJ Jan 5, 2026
118558b
Merge branch 'main' into feat/docker
kluge7 Jan 5, 2026
bcc7ec6
Merge remote-tracking branch 'origin/feat/docker' into 24-yolo-node-f…
MadsJJ Jan 6, 2026
ad75676
fix: image name used by devcontainer
MadsJJ Jan 6, 2026
7a6a964
add: package description and maintainer
MadsJJ Jan 6, 2026
b63d01d
fix: use get_package_share_directory for non docker users
MadsJJ Jan 6, 2026
6353e43
add: type hints
MadsJJ Jan 6, 2026
4fcede2
update: remove unnecessary requirements
MadsJJ Jan 6, 2026
ae382a3
fix: install params file to shared folder. this fixes the broken comm…
MadsJJ Jan 6, 2026
28d2591
update: move hardcoded params to params file.
MadsJJ Jan 6, 2026
7f4b544
Merge commit '8ca393d01e24fafc94309880380edf2940746565' into 24-yolo-…
MadsJJ Jan 6, 2026
878abfc
remove: tests
MadsJJ Jan 7, 2026
77e7523
update: confitionally initialize debug_pub based on debug flag
MadsJJ Jan 8, 2026
65935e1
add: parameterization for publishing mask and bbox. this way, the nod…
MadsJJ Jan 9, 2026
8618fa5
add: retina_masks parameter and only publish one merged mask image
MadsJJ Jan 9, 2026
b66b300
fix: adress jorgen PR review comments
MadsJJ Jan 14, 2026
573e93b
rename: more descriptive topics
MadsJJ Jan 14, 2026
908f532
refactor: add leading underscores to internal variables per PEP 8
MadsJJ Jan 15, 2026
59e6f5b
add: README
MadsJJ Jan 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "vortex-image-segmentation-devcontainer",
"image": "vortex-image-segmentation:latest",
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"extensions": [
"ms-azuretools.vscode-docker",
"ms-vscode.cpptools",
"ranch-hand-robotics.rde-pack",
"ms-python.vscode-pylance",
"twxs.cmake",
"ms-vsliveshare.vsliveshare",
"eamodio.gitlens",
"njpwerner.autodocstring",
"cschlosser.doxdocgen",
"xaver.clang-format",
"visualstudioexptteam.vscodeintellicode",
"ms-vscode-remote.remote-ssh",
"gxl.git-graph-3",
"ms-vscode-remote.remote-containers",
"gruntfuggly.todo-tree"
]
}
},
"remoteUser": "devuser",
"workspaceFolder": "/ros2_ws",
"workspaceMount": "source=${localWorkspaceFolder},target=/ros2_ws,type=bind,consistency=cached",
"runArgs": [
"--privileged",
"--network=host",
"--ipc=host",
"--user=1000:1000"
]
}
30 changes: 30 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Ignore build artifacts and large/runtime folders
build/
install/
log/
*.log

# Docker and local config
docker/
.dockerignore

# VCS
.git
.gitignore

# VS Code
.vscode/

# Python
__pycache__/
*.pyc
*.pyo
*.pyd
venv/
.env

# Misc
*.swp
*.swo
node_modules/
bags/
27 changes: 26 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ share/python-wheels/
*.egg
MANIFEST

#VSCode
.vscode/

# OS Generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
Expand Down Expand Up @@ -128,6 +140,10 @@ ENV/
env.bak/
venv.bak/

# Pipenv files
Pipfile
Pipfile.lock

# Spyder project settings
.spyderproject
.spyproject
Expand Down Expand Up @@ -163,5 +179,14 @@ runs/
*.pt
*jpg

# ROS 2 build artifacts
install/
build/
log/

# data
data/
bags/

# Training outputs and Roboflow datasets
results/
roboflow_data/
77 changes: 77 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# ----------------------------------------------------------------------------
# Base Image
# ----------------------------------------------------------------------------
ARG BASE_IMAGE=ros:humble
FROM ${BASE_IMAGE}

# ----------------------------------------------------------------------------
# Install System & ROS Dependencies
# ----------------------------------------------------------------------------
USER root
SHELL ["/bin/bash", "-c"]
ARG DEBIAN_FRONTEND=noninteractive

ENV WORKSPACE=/ros2_ws
WORKDIR ${WORKSPACE}
ARG ROS_DISTRO=humble

RUN apt-get update && apt-get install -y \
git \
python3-rosdep \
python3-vcstool \
python3-pip \
ros-${ROS_DISTRO}-ros-core \
ros-${ROS_DISTRO}-cv-bridge \
ros-${ROS_DISTRO}-vision-msgs \
ros-${ROS_DISTRO}-pcl-conversions \
libopencv-dev \
libpcl-dev \
python3-colcon-common-extensions \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

# ----------------------------------------------------------------------------
# Ensure Cython is installed (for building packages like lapx)
# ----------------------------------------------------------------------------
RUN pip3 install cython


# ----------------------------------------------------------------------------
# Copy requirements.txt and install Python dependencies first for better caching
# ----------------------------------------------------------------------------
COPY requirements.txt ${WORKSPACE}/requirements.txt
RUN pip3 install -r ${WORKSPACE}/requirements.txt

# ----------------------------------------------------------------------------
# Copy Workspace Files
# ----------------------------------------------------------------------------
COPY . ${WORKSPACE}

# ----------------------------------------------------------------------------
# Install ROS dependencies
# ----------------------------------------------------------------------------
RUN rosdep update && rosdep install --from-paths . --ignore-src -r -y

# ----------------------------------------------------------------------------
# Create non-root user
# ----------------------------------------------------------------------------
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=devuser
RUN groupadd --gid ${GROUP_ID} ${USERNAME} || true && \
useradd --uid ${USER_ID} --gid ${GROUP_ID} -m -s /bin/bash ${USERNAME} || true && \
apt-get update && apt-get install -y sudo && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \
apt-get clean && rm -rf /var/lib/apt/lists/*

USER ${USERNAME}
WORKDIR /home/${USERNAME}

# ----------------------------------------------------------------------------
# Source user bashrc_extra.sh in bashrc
# ----------------------------------------------------------------------------
RUN echo "if [ -f /ros2_ws/scripts/bashrc_extra.sh ]; then source /ros2_ws/scripts/bashrc_extra.sh; fi" >> ~/.bashrc

# ----------------------------------------------------------------------------
# Default command
# ----------------------------------------------------------------------------
CMD ["bash"]
57 changes: 57 additions & 0 deletions docker/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
set -euo pipefail

# ------------------------------------------------------------------------------
# Environment Variables
# ------------------------------------------------------------------------------
IMAGE="vortex-image-segmentation:latest" # Docker image name/tag
BASE_IMAGE="ros:humble" # Base image for Docker builds

# ------------------------------------------------------------------------------
# Platform Detection
# ------------------------------------------------------------------------------
ARCHITECTURE="$(uname -m)"
if [[ "$ARCHITECTURE" == "arm64" || "$ARCHITECTURE" == "aarch64" ]]; then
PLATFORM="linux/arm64"
elif [[ "$ARCHITECTURE" == "x86_64" ]]; then
PLATFORM="linux/amd64"
else
echo "Unsupported architecture: $ARCHITECTURE" >&2
exit 1
fi

# ------------------------------------------------------------------------------
# Locate Script and Workspace Root
# ------------------------------------------------------------------------------
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
WORKSPACE="$(realpath "$SCRIPT_DIR/..")"

# ------------------------------------------------------------------------------
# Build Start Info
# ------------------------------------------------------------------------------
echo "======================================================================"
echo " Building Docker Image"
echo " • PLATFORM: $PLATFORM"
echo " • BASE_IMAGE: $BASE_IMAGE"
echo " • IMAGE: $IMAGE"
echo " • BUILD CONTEXT: $WORKSPACE"
echo "======================================================================"
echo ""

# ------------------------------------------------------------------------------
# Build Docker Image with Buildx
# ------------------------------------------------------------------------------
docker buildx build \
--platform "$PLATFORM" \
--build-arg BASE_IMAGE="$BASE_IMAGE" \
--build-arg USER_ID="$(id -u)" \
--build-arg GROUP_ID="$(id -g)" \
--tag "$IMAGE" \
--file "$SCRIPT_DIR/Dockerfile" \
--load \
"$WORKSPACE"

echo ""
echo "======================================================================"
echo " Successfully built image '$IMAGE' for platform '$PLATFORM'"
echo "======================================================================"
33 changes: 33 additions & 0 deletions docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail

# ------------------------------------------------------------------------------
# Image Configuration
# ------------------------------------------------------------------------------
IMAGE="vortex-image-segmentation:latest" # Default Docker image name/tag

# ------------------------------------------------------------------------------
# Locate Script Directory and Workspace Root
# ------------------------------------------------------------------------------
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
WORKSPACE="$(realpath "$SCRIPT_DIR/..")"

echo "======================================================================"
echo " Running Container"
echo " • IMAGE: $IMAGE"
echo " • Volume mount: $WORKSPACE -> /ros2_ws"
echo "======================================================================"
echo ""

# ------------------------------------------------------------------------------
# Run Docker Container
# ------------------------------------------------------------------------------
docker run -it --rm \
--user "$(id -u):$(id -g)" \
--privileged \
--network host \
--ipc=host \
-v "$WORKSPACE":/ros2_ws \
-w /ros2_ws \
"$IMAGE" \
/bin/bash
Binary file modified requirements.txt
Binary file not shown.
19 changes: 19 additions & 0 deletions scripts/bashrc_extra.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
# /ros2_ws/scripts/bashrc_extra.sh for ROS 2 container

# Print actions for clarity
if [ -f /opt/ros/humble/setup.bash ]; then
echo "[bashrc_extra] Sourcing ROS 2 underlay: /opt/ros/humble/setup.bash"
source /opt/ros/humble/setup.bash
else
echo "[bashrc_extra] ROS 2 underlay not found: /opt/ros/humble/setup.bash"
fi

if [ -f /ros2_ws/install/setup.bash ]; then
echo "[bashrc_extra] Sourcing workspace overlay: /ros2_ws/install/setup.bash"
source /ros2_ws/install/setup.bash
else
echo "[bashrc_extra] Workspace overlay not found: /ros2_ws/install/setup.bash"
fi

# Add your custom shell commands, aliases, or environment variables below
17 changes: 17 additions & 0 deletions vortex_image_segmentation/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
16 changes: 16 additions & 0 deletions vortex_image_segmentation/launch/yolo_segmentation.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():
return LaunchDescription([
Node(
package='vortex_image_segmentation',
executable='yolo_seg_node',
name='yolo_segmentation_node',
output='screen',
parameters=[
'/ros2_ws/vortex_image_segmentation/params/yolo_params.yaml'
]
)
])
21 changes: 21 additions & 0 deletions vortex_image_segmentation/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>vortex_image_segmentation</name>
<version>0.0.0</version>
<description>Package for image segmentation nodes</description>
<maintainer email="mjengesv@ntnu.no">Mads Engesvoll</maintainer>
<license>MIT</license>

<depend>rclpy</depend>
<depend>std_msgs</depend>

<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>

<export>
<build_type>ament_python</build_type>
</export>
</package>
10 changes: 10 additions & 0 deletions vortex_image_segmentation/params/yolo_params.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
yolo_segmentation_node:
ros__parameters:
model_path: "/ros2_ws/yolo_roboflow_training/results/custom_yolov89/weights/last.pt"
device: "cpu"
imgsz: 640
confidence_threshold: 0.2
max_detections: 1
compile: True

debug: True
Empty file.
4 changes: 4 additions & 0 deletions vortex_image_segmentation/setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[develop]
script_dir=$base/lib/vortex_image_segmentation
[install]
install_scripts=$base/lib/vortex_image_segmentation
Loading
Loading