Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* @wentywenty
* @Luo1imasi
34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: Bug / Issue
about: 报告问题或提出需求 / Report a bug or request a feature
labels: triage
---

<!-- 请勾选类型 / Check the issue type -->
- [ ] 🔨 构建问题 Build issue(deb 编译失败、版本不一致 / compile fail, version mismatch)
- [ ] 📦 APT 源问题 APT repo issue(同步失败 / sync fail, 403)
- [ ] 🛠️ 新功能 / 新包请求 Feature request / new package

## 环境 / Environment

- 架构 Arch: [amd64 / arm64]
- 系统 OS: [RobopiOS 1.0.6 / RobopiOS 1.2.7 / Ubuntu 22.04 / Ubuntu 24.04]
- 包名和版本 Package & version: <!-- roboparty-navigation 1.0.0-1 -->

## 现象 / What happened

<!-- 发生了什么?截图/日志/命令输出 -->
<!-- What went wrong? Screenshots, logs, command output -->

## 复现步骤 / Steps to reproduce

1.
2.
3.

## 期望行为 / Expected behavior

<!-- 你期望的正确结果 / What should happen instead -->

> ⚠️ **禁止使用 AI 生成 Issues。AI 生成的 Issue 将被直接关闭。**
> **Do not use AI to generate Issues. AI-generated issues will be closed immediately.**
33 changes: 33 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: Pull Request
about: 提交代码变更 / Submit a code change
---

<!-- 请勾选类型 / Check the PR type -->
- [ ] 🐛 Bug fix 修复
- [ ] ✨ New feature 新功能
- [ ] 📦 Packaging 打包(debian/ 变更)
- [ ] 📝 Docs 文档
- [ ] 🔧 CI / workflow 变更

## 变更说明 / Description

<!-- 简述改了什么 / Briefly describe what this PR does -->

## 版本检查 / Version check

<!-- 如果这会影响包的版本,请确认 / Confirm if version is affected -->

- [ ] 本次变更不需要改版本号 / This change does NOT bump version
- [ ] 已更新 debian/changelog
- [ ] 已同步 package.xml(仅 ROS 包 / ROS packages only)
- [ ] changelog 和 package.xml 版本一致 / Versions match

## 测试 / Testing

- [ ] 构建通过 / Build passes: `dpkg-buildpackage -us -uc -b`
- [ ] 已在 [amd64 / arm64] 上测试
- [ ] 其他说明 / Notes:

> ⚠️ **禁止使用 AI 生成 PR 描述。AI 生成的 PR 将被直接关闭。**
> **Do not use AI to generate PR descriptions. AI-generated PRs will be closed immediately.**
204 changes: 204 additions & 0 deletions .github/workflows/build-deb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
name: Build RoboParty Navigation Deb Packages

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: write

env:
ROS_DISTRO: ${{ vars.ROS_DISTRO || 'jazzy' }}

jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
os: ubuntu-24.04
- arch: arm64
os: [self-hosted, Linux, ARM64, "24.04"]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: false

- name: Checkout submodules
run: |
git submodule sync --recursive
for attempt in 1 2 3 4 5; do
if git submodule update --init --force --recursive --depth=1; then
exit 0
fi
echo "::warning::submodule checkout failed (attempt $attempt)"
git submodule deinit -f --all || true
sleep 15
done
echo "::error::submodule checkout failed after retries"
exit 1

- name: Version check (package.xml vs changelog)
run: |
PKG_XML_VERSION=$(grep -oP '<version>\K[^<]+' nav2_localization_adapter/package.xml)
CHANGELOG_VERSION=$(head -1 debian/changelog | grep -oP '\((.*?)\)' | tr -d '()' | cut -d'-' -f1)

echo "package.xml version: $PKG_XML_VERSION"
echo "changelog version: $CHANGELOG_VERSION"

if [ "$PKG_XML_VERSION" != "$CHANGELOG_VERSION" ]; then
echo "::error::Version mismatch! package.xml=$PKG_XML_VERSION, changelog=$CHANGELOG_VERSION"
exit 1
fi

echo "✅ Version check passed: $PKG_XML_VERSION"

- name: Tag vs changelog version check
if: startsWith(github.ref, 'refs/tags/v')
run: |
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
CHANGELOG_VERSION=$(head -1 debian/changelog | grep -oP '\((.*?)\)' | tr -d '()' | cut -d'-' -f1)

echo "Tag version: $TAG_VERSION"
echo "Changelog version: $CHANGELOG_VERSION"

if [ "$TAG_VERSION" != "$CHANGELOG_VERSION" ]; then
echo "::error::Version mismatch! tag=v$TAG_VERSION, changelog=$CHANGELOG_VERSION"
exit 1
fi

echo "✅ Tag matches changelog: v$TAG_VERSION"

- name: Setup ROS 2
if: matrix.arch == 'amd64'
uses: ros-tooling/setup-ros@v0.7
with:
required-ros-distributions: ${{ env.ROS_DISTRO }}

- name: Add RoboParty APT source
run: |
keyring="/tmp/roboparty-archive-keyring-${GITHUB_RUN_ID}.gpg"
sources="/tmp/roboparty-apt-${GITHUB_RUN_ID}"
curl -fsSL https://apt.roboparty.com/roboparty.gpg | gpg --dearmor > "$keyring"
chmod 644 "$keyring"
rm -rf "$sources"
mkdir -p "$sources"
chmod 755 "$sources"
cp /etc/apt/sources.list.d/*.list "$sources"/ 2>/dev/null || true
cp /etc/apt/sources.list.d/*.sources "$sources"/ 2>/dev/null || true
if [ -s /etc/apt/sources.list ]; then
cp /etc/apt/sources.list "$sources/ubuntu.list"
fi
echo "deb [arch=$(dpkg --print-architecture) signed-by=$keyring] https://apt.roboparty.com common main" > "$sources/roboparty.list"
chmod 644 "$sources"/* 2>/dev/null || true
echo "APT_OPTS=-o Dir::Etc::sourcelist=/dev/null -o Dir::Etc::sourceparts=$sources" >> "$GITHUB_ENV"

- name: Install build tools
run: |
sudo apt-get $APT_OPTS update -q
sudo apt-get $APT_OPTS install -y --no-install-recommends \
build-essential cmake ccache dpkg-dev debhelper devscripts \
git wget pkg-config python3-colcon-common-extensions \
libpcl-dev libeigen3-dev libceres-dev libfmt-dev libyaml-cpp-dev \
libboost-all-dev libapr1-dev python3-dev libpython3-dev \
python3-yaml python3-numpy \
ros-${ROS_DISTRO}-ament-cmake-auto ros-${ROS_DISTRO}-rclcpp \
ros-${ROS_DISTRO}-rclcpp-components ros-${ROS_DISTRO}-std-msgs \
ros-${ROS_DISTRO}-nav-msgs ros-${ROS_DISTRO}-sensor-msgs \
ros-${ROS_DISTRO}-geometry-msgs ros-${ROS_DISTRO}-visualization-msgs \
ros-${ROS_DISTRO}-std-srvs ros-${ROS_DISTRO}-tf2 \
ros-${ROS_DISTRO}-tf2-ros ros-${ROS_DISTRO}-tf2-geometry-msgs \
ros-${ROS_DISTRO}-pcl-ros ros-${ROS_DISTRO}-pcl-conversions \
ros-${ROS_DISTRO}-sophus ros-${ROS_DISTRO}-rosidl-default-generators \
ros-${ROS_DISTRO}-common-interfaces ros-${ROS_DISTRO}-rosbag2 \
ros-${ROS_DISTRO}-nav2-bringup ros-${ROS_DISTRO}-nav2-map-server \
ros-${ROS_DISTRO}-nav2-lifecycle-manager ros-${ROS_DISTRO}-nav2-msgs

- name: Download RoboParty SDK debs
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
out="/tmp/roboparty-debs-${GITHUB_RUN_ID}"
rm -rf "$out"
mkdir -p "$out"
chmod 755 "$out"
DEB_ARCH=$(dpkg --print-architecture) OUT_DIR="$out" python3 - <<'PY'
import json, os, pathlib, shutil, time, urllib.request

arch = os.environ["DEB_ARCH"]
out = pathlib.Path(os.environ["OUT_DIR"])
headers = {"Accept": "application/vnd.github+json"}
token = os.environ.get("GH_TOKEN")
if token:
headers["Authorization"] = f"Bearer {token}"

def download(url, dest):
for attempt in range(1, 6):
try:
with urllib.request.urlopen(url, timeout=90) as response, open(dest, "wb") as target:
shutil.copyfileobj(response, target)
return
except Exception as exc:
print(f"download failed (attempt {attempt}): {exc}")
time.sleep(10)
raise RuntimeError(f"could not download {url}")

repos = {
"Roboparty/nlink_parser_ros2": "nlink-parser-ros2",
"Roboparty/livox_ros_driver2": "livox-ros-driver2",
"Roboparty/Livox-SDK2": "livox-sdk2",
"Roboparty/serial": "ros-jazzy-serial",
}
for repo, prefix in repos.items():
req = urllib.request.Request(
f"https://api.github.com/repos/{repo}/releases/latest", headers=headers)
with urllib.request.urlopen(req, timeout=90) as response:
data = json.load(response)
for asset in data.get("assets", []):
name = asset["name"]
if name.startswith(prefix) and name.endswith(f"_{arch}.deb"):
print(f"download {name}")
download(asset["browser_download_url"], out / name)
PY
chmod 644 "$out"/*

- name: Install RoboParty SDK debs
run: |
sudo apt-get $APT_OPTS install -y --no-install-recommends roboparty-base
sudo apt-get $APT_OPTS install -y /tmp/roboparty-debs-${GITHUB_RUN_ID}/*.deb

- name: Python syntax checks
run: |
python3 -m py_compile \
nav2_localization_adapter/scripts/*.py \
robots_localization_ros2/script/*.py

- name: Build deb packages
run: |
. /opt/ros/${ROS_DISTRO}/setup.sh
dpkg-buildpackage -us -uc -b
mv ../*.deb .
VERSION=$(dpkg-parsechangelog -S Version | cut -d'-' -f1 || echo "unknown")
echo "PKG_VERSION=$VERSION" >> $GITHUB_ENV

- name: Upload deb artifacts
uses: actions/upload-artifact@v4
with:
name: roboparty-navigation-v${{ env.PKG_VERSION }}-${{ matrix.arch }}
path: "*.deb"

- name: Collect release files
if: startsWith(github.ref, 'refs/tags/v')
run: |
mkdir -p release
cp roboparty-localization_*.deb roboparty-navigation_*.deb release/

- name: Upload to GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v2
with:
files: release/*.deb
10 changes: 10 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
roboparty-navigation (1.0.0-1) stable; urgency=medium

* Initial packaging.
* Split the runtime into roboparty-localization (FAST-LIO based
localization, no Nav2 dependency) and roboparty-navigation (Nav2
adapter).
* Keep both packages on the shared install prefix (default /opt/roboparty) so
roboparty-base/setup.bash discovers them automatically.

-- RoboParty <2321901849@qq.com> Sat, 07 Nov 2026 00:00:00 +0800
2 changes: 2 additions & 0 deletions debian/cmake/deps.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
find_package(fmt REQUIRED)
find_package(Boost REQUIRED COMPONENTS system thread)
78 changes: 78 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
Source: roboparty-navigation
Section: misc
Priority: optional
Maintainer: RoboParty <2321901849@qq.com>
Build-Depends: debhelper-compat (= 13),
cmake,
build-essential,
pkg-config,
python3,
python3-colcon-common-extensions,
python3-yaml,
libpcl-dev,
libeigen3-dev,
libceres-dev,
libfmt-dev,
libyaml-cpp-dev,
libboost-all-dev,
python3-dev,
libpython3-dev,
ros-jazzy-ament-cmake,
ros-jazzy-rclcpp,
ros-jazzy-rclcpp-components,
ros-jazzy-std-msgs,
ros-jazzy-nav-msgs,
ros-jazzy-sensor-msgs,
ros-jazzy-geometry-msgs,
ros-jazzy-visualization-msgs,
ros-jazzy-std-srvs,
ros-jazzy-tf2,
ros-jazzy-tf2-ros,
ros-jazzy-tf2-geometry-msgs,
ros-jazzy-pcl-ros,
ros-jazzy-pcl-conversions,
ros-jazzy-sophus,
ros-jazzy-rosidl-default-generators,
ros-jazzy-common-interfaces,
ros-jazzy-rosbag2,
livox-sdk2-dev,
livox-ros-driver2,
nlink-parser-ros2
Standards-Version: 4.6.0

Package: roboparty-localization
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
roboparty-base (>= 1.0.0),
ros-jazzy-ros-base,
ros-jazzy-common-interfaces,
ros-jazzy-pcl-ros,
ros-jazzy-pcl-conversions,
ros-jazzy-tf2,
ros-jazzy-tf2-ros,
ros-jazzy-tf2-geometry-msgs,
ros-jazzy-rosidl-default-runtime,
livox-ros-driver2,
livox-sdk2,
nlink-parser-ros2
Description: RoboParty LiDAR-inertial localization
FAST-LIO based localization for RoboParty robots, providing odometry,
point-cloud mapping and the robots_localization ROS 2 interface.
This package does not depend on Nav2.

Package: roboparty-navigation
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
roboparty-base (>= 1.0.0),
roboparty-localization (= ${binary:Version}),
ros-jazzy-nav2-bringup,
ros-jazzy-nav2-map-server,
ros-jazzy-nav2-lifecycle-manager,
ros-jazzy-nav2-msgs,
python3-yaml,
python3-numpy
Recommends: ros-jazzy-rviz2
Description: RoboParty Nav2 navigation stack
Nav2 adapter for RoboParty robots.
Loading
Loading