diff --git a/.github/scripts/summarize_rattler_build.py b/.github/scripts/summarize_rattler_build.py new file mode 100755 index 000000000..008ca3c4f --- /dev/null +++ b/.github/scripts/summarize_rattler_build.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Write a compact rattler-build diagnostic for the GitHub job summary.""" + +from __future__ import annotations + +import argparse +import os +import re +from pathlib import Path + + +ANSI_ESCAPE = re.compile(r"\x1b(?:[@-_][0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1b\\))") +TIMESTAMP = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s*") +DIAGNOSTIC = re.compile( + r"(?:Error:\s+×|fatal error(?:\s+[A-Z]+\d+)?:|\berror(?:\s+[A-Z]+\d+)?:|" + r"CMake Error(?::|\s+at\b)|FAILED:|Patch application error|" + r"Failed to resolve dependencies|Cannot solve the request)", + re.IGNORECASE, +) +RECIPE_START = re.compile(r"Running build for recipe:|Build variant:") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--log", type=Path, required=True) + parser.add_argument("--platform", required=True) + parser.add_argument("--outcome", required=True) + return parser.parse_args() + + +def clean(line: str) -> str: + cleaned = TIMESTAMP.sub("", ANSI_ESCAPE.sub("", line)).rstrip() + if len(cleaned) > 1_000: + return cleaned[:1_000] + " … [line truncated]" + return cleaned + + +def diagnostic_excerpt(lines: list[str]) -> list[str]: + matches = [index for index, line in enumerate(lines) if DIAGNOSTIC.search(line)] + if not matches: + return [] + + # Keep context around the last diagnostics. This includes multiline solver + # explanations without flooding the GitHub summary with the complete log. + selected: set[int] = set() + for index in matches[-20:]: + selected.update(range(max(0, index - 2), min(len(lines), index + 14))) + + # Name the recipe that produced the final diagnostic even when dependency + # solver output has pushed its heading far outside the context window. + first_diagnostic = matches[max(0, len(matches) - 20)] + for index in range(first_diagnostic, -1, -1): + if RECIPE_START.search(lines[index]): + selected.add(index) + break + + excerpt: list[str] = [] + previous = -2 + for index in sorted(selected): + if previous >= 0 and index > previous + 1: + excerpt.append("...") + excerpt.append(lines[index]) + previous = index + return excerpt[-160:] + + +def main() -> None: + args = parse_args() + run_url = ( + f"{os.environ.get('GITHUB_SERVER_URL', 'https://github.com')}/" + f"{os.environ.get('GITHUB_REPOSITORY', '')}/actions/runs/" + f"{os.environ.get('GITHUB_RUN_ID', '')}" + ) + symbol = "✅" if args.outcome == "success" else "❌" + + print(f"## {symbol} rattler-build: `{args.platform}`") + print() + print(f"Outcome: **{args.outcome}** · [Open workflow run]({run_url})") + + if not args.log.is_file(): + print("\nNo build log was produced.") + return + + lines = [clean(line) for line in args.log.read_text(encoding="utf-8", errors="replace").splitlines()] + excerpt = diagnostic_excerpt(lines) + if not excerpt: + print("\nNo error diagnostics were found in the build log.") + return + + print("\n### Final diagnostics\n") + print("```text") + print("\n".join(excerpt)) + print("```") + print("\nThe complete `rattler-build.log` is available in this run's artifacts.") + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/testpr.yml b/.github/workflows/testpr.yml index 221a4959e..d06cba379 100644 --- a/.github/workflows/testpr.yml +++ b/.github/workflows/testpr.yml @@ -2,6 +2,14 @@ on: pull_request: workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + actions: read + contents: read + env: ROS_VERSION: 2 PYTHONIOENCODING: utf-8 @@ -19,9 +27,10 @@ jobs: persist-credentials: false fetch-depth: 0 - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@v0.10.2 with: frozen: true + pixi-version: v0.75.0 - name: Check sorting run: | @@ -56,9 +65,10 @@ jobs: persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token fetch-depth: 0 # otherwise, you will failed to push refs to dest repo - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@v0.10.2 with: frozen: true + pixi-version: v0.75.0 - name: Long paths workarounds for win-64 shell: bash -l {0} @@ -68,6 +78,27 @@ jobs: echo "CONDA_BLD_PATH=C:\\bld\\" >> $GITHUB_ENV mkdir /c/bld + - name: Enable Windows long path support + if: matrix.platform == 'win-64' + shell: pwsh + run: | + # MSVC/MSBuild (VS 2019 16.0+, which windows-2022's toolset is well past) + # honor the Win32 long-path opt-in via this registry key. Without it, + # cl.exe can fail with a cryptic "fatal error C1083: Cannot open + # compiler generated file: ''" once a target's generated intermediate + # (.obj/.tlog) path exceeds the legacy 260-char MAX_PATH, which is easy + # to hit given how deeply nested and long rosidl-generated target names + # can get even under the shortened C:\bld\ prefix above. + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force + + - name: Exclude build directories from Windows Defender scanning + if: matrix.platform == 'win-64' + shell: pwsh + run: | + # Avoids Defender real-time scanning silently stalling heavy win-64 I/O. + Add-MpPreference -ExclusionPath "${{ github.workspace }}" + Add-MpPreference -ExclusionPath "C:\bld" + # Workaround for https://github.com/RoboStack/ros-humble/pull/141#issuecomment-1941919816 - name: Clean up PATH if: contains(matrix.os, 'windows') @@ -77,10 +108,8 @@ jobs: # git in C:\Program Files\Git\bin is used by pip install git+ dirs: 'C:\Program Files\Git\usr\bin;C:\Program Files\Git\bin;C:\Program Files\Git\cmd;C:\Program Files\Git\mingw64\bin' - # For some reason, the Strawberry perl's pkg-config is found - # instead of the conda's one, so let's delete the /c/Strawberry directory - # Furthermore, we also need to remove an older SDK that is used and can result in compilation problems - - name: Debug pkg-config problem + # Strawberry Perl's pkg-config and an older Windows SDK can get picked up ahead of conda's. + - name: Remove problematic files of GitHub Actions images if: contains(matrix.os, 'windows') shell: bash -l {0} run: | @@ -94,9 +123,24 @@ jobs: - name: Generate recipes shell: bash -l {0} + env: + # Raises vinca's raw.githubusercontent.com rate limit for package.xml fetches. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - mkdir -p recipes - pixi run -v vinca --platform ${{ matrix.platform }} -m -n + set -e + for attempt in 1 2 3; do + rm -rf recipes + mkdir -p recipes + if pixi run -v vinca --platform ${{ matrix.platform }} -m -n; then + break + fi + if [[ "${attempt}" == "3" ]]; then + echo "Recipe generation failed after ${attempt} attempts" >&2 + exit 1 + fi + echo "Recipe generation attempt ${attempt} failed; retrying..." >&2 + sleep 15 + done - name: Check patches shell: bash -l {0} @@ -123,9 +167,12 @@ jobs: - name: Delete specific outdated cache entries shell: bash -l {0} run: | - # You can uncomment/modify the line below in case the cache for some packages becomes corrupted and needs to be regenerated. - # Make sure you don't merge these changes, though! - # rm -rf ${{ matrix.folder_cache }}/ros-rolling-moveit-core* ${{ matrix.folder_cache }}/ros2-moveit-core* 2>/dev/null || true + # Uncomment to force-rebuild a package with a corrupted cache entry. + # rm -rf ${{ matrix.folder_cache }}/* 2>/dev/null || true + # Corrupt ~53KB cached artifact (missing its installed cmake config) -- + # moveit_setup_framework's find_package(moveit_ros_visualization) failed + # against it on win-64. + rm -rf ${{ matrix.folder_cache }}/ros2-moveit-ros-visualization* ${{ matrix.folder_cache }}/ros-rolling-moveit-ros-visualization* 2>/dev/null || true mkdir -p ${{ matrix.folder_cache }} pixi run rattler-index fs ${{ matrix.folder_cache }}/.. --force @@ -138,7 +185,41 @@ jobs: id: build-recipes shell: bash -l {0} run: | - pixi run rattler-build build --recipe-dir recipes --target-platform ${{ matrix.platform }} -m ./conda_build_config.yaml -c https://prefix.dev/conda-forge -c https://prefix.dev/robostack-rolling --skip-existing + set +e + EXTRA_BUILD_ARGS="" + if [ "${{ matrix.platform }}" == "win-64" ]; then + # Drop the timestamp suffix from the per-package build work dir + # (rattler-build__ -> rattler-build_) to claw + # back headroom under Windows' MAX_PATH for long package names, e.g. + # rosbag2_performance_benchmarking_msgs's generated rosidl Python + # typesupport targets (see error C1083 "Cannot open compiler + # generated file: ''"). + EXTRA_BUILD_ARGS="--no-build-id" + fi + # --channel-priority disabled: resolvo would otherwise refuse a just-built local package once any other-channel build of the same name exists. + pixi run rattler-build build --recipe-dir recipes --target-platform ${{ matrix.platform }} -m ./conda_build_config.yaml -c conda-forge -c robostack-rolling --skip-existing --channel-priority disabled $EXTRA_BUILD_ARGS 2>&1 | tee rattler-build.log + build_status=${PIPESTATUS[0]} + echo "exit-code=${build_status}" >> "$GITHUB_OUTPUT" + exit "$build_status" + + - name: Summarize build result + if: always() + shell: bash -l {0} + run: | + pixi run python .github/scripts/summarize_rattler_build.py \ + --log rattler-build.log \ + --platform "${{ matrix.platform }}" \ + --outcome "${{ steps.build-recipes.outcome }}" \ + >> "$GITHUB_STEP_SUMMARY" + + - name: Upload build log + if: always() + uses: actions/upload-artifact@v6 + with: + name: build-log-${{ matrix.platform }}-${{ github.run_id }}-${{ github.run_attempt }} + path: rattler-build.log + if-no-files-found: warn + retention-days: 7 - name: See packages that will be saved in cache shell: bash -l {0} @@ -158,7 +239,7 @@ jobs: - name: Generate GitHub Actions workflows to catch post-PR problems shell: bash -l {0} run: | - pixi run vinca-gha --platform ${{ matrix.platform }} --trigger-branch dummy_build_branch_as_it_is_unused -d ./recipes + pixi run vinca-gha --platform ${{ matrix.platform }} --trigger-branch dummy_build_branch_as_it_is_unused -d ./recipes --batch_size 25 - name: Upload build cache as artifact # Keep artifacts consistent with the cache: retain partial output from failed or cancelled builds, but not skipped builds. diff --git a/AGENTS.md b/AGENTS.md index 55879bb9c..7ce5cabd7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -169,6 +169,14 @@ Rules: - Run parallel lanes only for packages that do not depend on each other. - If unsure, serialize the builds. +## Cross-distribution sync + +- Work from the clean checked-out heads of rolling, lyrical, kilted, jazzy, and humble; create `codex/cross-distro-sync` in each repo and never merge their independent histories. +- Classify every candidate before editing: portable shared tooling/CI/metadata, conditional package fix requiring a compatible source and refreshed patch, or excluded distro-owned state. +- Keep rosdistro snapshots, mutex/build numbers, ABI/compiler/Python pins, channels/upload targets, package selection, generated recipes, and temporary rebuild controls distro-owned. +- Port patches only for an existing compatible package, using `patch/ros-$DISTRO-.patch` and matching recipe wiring; do not copy a patch solely because its filename exists elsewhere. +- Validate changed patch metadata with `pixi run check-patches` and each changed package with `pixi run build-one ros-$DISTRO-`; inspect final diffs for protected state. + ## Inspect a built conda package ```bash diff --git a/build_gap_report.py b/build_gap_report.py index 47c671996..774c02f34 100644 --- a/build_gap_report.py +++ b/build_gap_report.py @@ -2,18 +2,43 @@ """Report gaps between generated recipes and built conda artifacts. Default behavior is platform-agnostic: it inspects all output/ folders that -contain conda artifacts and reports gaps per platform. +contain conda artifacts and reports gaps per platform. Only artifacts built with the +CURRENT build_number (and, for the mutex package, its own build_number) are counted — +older-build_number leftovers from a previous full rebuild are ignored, since counting +them makes the report claim far more packages are done than the current build actually +has. """ from __future__ import annotations import argparse +import re from pathlib import Path from typing import Iterable, Set CONDA_SUFFIX = ".conda" TARBZ2_SUFFIX = ".tar.bz2" +# Matches known conda platform directory names (osx-arm64, linux-64, win-64, …) +_PLATFORM_RE = re.compile(r'^(osx|linux|win|emscripten)-') + +# Strips distro prefix so ros-jazzy-rclcpp, ros2-rclcpp, ros-kilted-rclcpp all +# normalise to "rclcpp" for cross-naming-style comparison. +# Handles two forms: ros-- and ros- +_DISTRO_PREFIX_RE = re.compile(r'^(?:ros-[a-z]+-|ros\d+-)') + +# check_patches_clean_apply.py builds throwaway "-check-patches[-]" +# packages into this same output/ folder to verify patches apply (the +# platform suffix was added later; older leftover artifacts may lack it). They +# never have a matching recipes/ directory and would otherwise show up as false +# "built but no recipe" gaps. +_CHECK_PATCHES_RE = re.compile(r'-check-patches(?:-(?:linux|osx|win|emscripten|any))?$') + +_TOP_LEVEL_BUILD_NUMBER_RE = re.compile(r'^build_number:\s*(\d+)\s*$') +_MUTEX_HEADER_RE = re.compile(r'^mutex_package:\s*$') +_MUTEX_NAME_RE = re.compile(r'^\s+name:\s*"?([\w.-]+)"?\s*$') +_MUTEX_BUILD_NUMBER_RE = re.compile(r'^\s+build_number:\s*(\d+)\s*$') + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( @@ -41,9 +66,38 @@ def parse_args() -> argparse.Namespace: "If omitted, all detected platform folders are inspected." ), ) + parser.add_argument( + "--vinca-yaml", + default="vinca.yaml", + help="vinca.yaml to read the current build_number/mutex from (default: vinca.yaml)", + ) + parser.add_argument( + "--build-number", + type=int, + default=None, + help="Override the build_number to filter artifacts by (default: parsed from --vinca-yaml)", + ) + parser.add_argument( + "--any-build-number", + action="store_true", + help="Don't filter by build_number at all (count every artifact regardless of age)", + ) + parser.add_argument( + "--pkg-additional-info", + default="pkg_additional_info.yaml", + help=( + "pkg_additional_info.yaml to read per-package build_number overrides from " + "(default: pkg_additional_info.yaml)" + ), + ) return parser.parse_args() +def normalize_name(name: str) -> str: + """Strip ros-- / ros2- prefix for cross-naming-style comparison.""" + return _DISTRO_PREFIX_RE.sub("", name) + + def is_conda_artifact(filename: str) -> bool: return filename.endswith(CONDA_SUFFIX) or filename.endswith(TARBZ2_SUFFIX) @@ -60,7 +114,109 @@ def package_name_from_artifact(filename: str) -> str | None: parts = stem.rsplit("-", 2) if len(parts) != 3: return None - return parts[0] + name = parts[0] + if _CHECK_PATCHES_RE.search(name): + return None + return name + + +def build_number_from_artifact(filename: str) -> int | None: + """Extract the trailing _ build number from a conda artifact's build string.""" + stem = filename + if stem.endswith(CONDA_SUFFIX): + stem = stem[: -len(CONDA_SUFFIX)] + elif stem.endswith(TARBZ2_SUFFIX): + stem = stem[: -len(TARBZ2_SUFFIX)] + else: + return None + + parts = stem.rsplit("-", 2) + if len(parts) != 3: + return None + build_string = parts[2] + suffix = build_string.rsplit("_", 1)[-1] + return int(suffix) if suffix.isdigit() else None + + +def read_vinca_config(vinca_yaml: Path) -> tuple[int | None, str | None, int | None]: + """Parse (build_number, mutex_package_name, mutex_build_number) out of vinca.yaml + without requiring a YAML library, since this script has no other dependencies.""" + if not vinca_yaml.is_file(): + return None, None, None + + build_number: int | None = None + mutex_name: str | None = None + mutex_build_number: int | None = None + in_mutex_block = False + + for line in vinca_yaml.read_text().splitlines(): + if in_mutex_block: + if line.startswith((" ", "\t")): + m = _MUTEX_NAME_RE.match(line) + if m: + mutex_name = m.group(1) + m = _MUTEX_BUILD_NUMBER_RE.match(line) + if m: + mutex_build_number = int(m.group(1)) + continue + in_mutex_block = False # fall through: this line starts the next top-level key + + m = _TOP_LEVEL_BUILD_NUMBER_RE.match(line) + if m: + build_number = int(m.group(1)) + continue + if _MUTEX_HEADER_RE.match(line): + in_mutex_block = True + + return build_number, mutex_name, mutex_build_number + + +_PKG_INFO_TOP_LEVEL_KEY_RE = re.compile(r'^([A-Za-z0-9_.]+):\s*(?:#.*)?$') +_PKG_INFO_BUILD_NUMBER_RE = re.compile(r'^\s+build_number:\s*(\d+)\s*$') + + +def read_pkg_build_number_overrides(pkg_info_yaml: Path) -> dict[str, int]: + """Parse per-package `build_number:` overrides out of pkg_additional_info.yaml — + a surgical way to force a rebuild of just one package without bumping vinca.yaml's + global build_number for everything. Keyed by the ROS package name as written there + (underscores), same convention as normalize_name(...).replace('-', '_').""" + overrides: dict[str, int] = {} + if not pkg_info_yaml.is_file(): + return overrides + + current_key: str | None = None + for line in pkg_info_yaml.read_text().splitlines(): + if not line.strip() or line.lstrip().startswith("#"): + continue + if not line[0].isspace(): + m = _PKG_INFO_TOP_LEVEL_KEY_RE.match(line) + current_key = m.group(1) if m else None + continue + if current_key is None: + continue + m = _PKG_INFO_BUILD_NUMBER_RE.match(line) + if m: + overrides[current_key] = int(m.group(1)) + + return overrides + + +def expected_build_number( + norm_name: str, + build_number: int | None, + mutex_norm_name: str | None, + mutex_build_number: int | None, + pkg_build_number_overrides: dict[str, int], +) -> int | None: + """The build_number a package's artifact must carry to count as "current": + the mutex's own build_number for the mutex package, a per-package override from + pkg_additional_info.yaml if one exists for it, otherwise the global build_number.""" + if mutex_norm_name is not None and norm_name == mutex_norm_name and mutex_build_number is not None: + return mutex_build_number + override = pkg_build_number_overrides.get(norm_name.replace("-", "_")) + if override is not None: + return override + return build_number def discover_platform_dirs(output_root: Path) -> list[str]: @@ -71,6 +227,8 @@ def discover_platform_dirs(output_root: Path) -> list[str]: for child in sorted(output_root.iterdir()): if not child.is_dir(): continue + if not _PLATFORM_RE.match(child.name): + continue try: has_artifact = any( entry.is_file() and is_conda_artifact(entry.name) @@ -84,7 +242,14 @@ def discover_platform_dirs(output_root: Path) -> list[str]: return platforms -def built_packages_for_platform(output_root: Path, platform: str) -> Set[str]: +def built_packages_for_platform( + output_root: Path, + platform: str, + build_number: int | None, + mutex_norm_name: str | None, + mutex_build_number: int | None, + pkg_build_number_overrides: dict[str, int], +) -> Set[str]: platform_dir = output_root / platform packages: Set[str] = set() if not platform_dir.exists() or not platform_dir.is_dir(): @@ -94,8 +259,19 @@ def built_packages_for_platform(output_root: Path, platform: str) -> Set[str]: if not artifact.is_file() or not is_conda_artifact(artifact.name): continue package_name = package_name_from_artifact(artifact.name) - if package_name: - packages.add(package_name) + if not package_name: + continue + norm_name = normalize_name(package_name) + + if build_number is not None: + artifact_build_number = build_number_from_artifact(artifact.name) + expected = expected_build_number( + norm_name, build_number, mutex_norm_name, mutex_build_number, pkg_build_number_overrides + ) + if artifact_build_number != expected: + continue + + packages.add(norm_name) return packages @@ -132,22 +308,62 @@ def main() -> int: ) return 1 + if args.any_build_number: + build_number, mutex_name, mutex_build_number = None, None, None + pkg_build_number_overrides: dict[str, int] = {} + else: + build_number, mutex_name, mutex_build_number = read_vinca_config(Path(args.vinca_yaml)) + if args.build_number is not None: + build_number = args.build_number + if build_number is None: + print( + f"Warning: could not read build_number from {args.vinca_yaml} " + "(pass --build-number or --any-build-number) — counting artifacts " + "from every build_number, including stale ones from earlier rebuilds.\n" + ) + pkg_build_number_overrides = read_pkg_build_number_overrides(Path(args.pkg_additional_info)) + mutex_norm_name = normalize_name(mutex_name) if mutex_name else None + + if build_number is not None: + mutex_note = ( + f", mutex build_number {mutex_build_number}" if mutex_build_number is not None else "" + ) + override_note = ( + f", {len(pkg_build_number_overrides)} per-package override(s) from {args.pkg_additional_info}" + if pkg_build_number_overrides + else "" + ) + print(f"Filtering to build_number {build_number}{mutex_note}{override_note}\n") + for idx, platform in enumerate(selected_platforms): - built = built_packages_for_platform(output_root, platform) + built = built_packages_for_platform( + output_root, platform, build_number, mutex_norm_name, mutex_build_number, pkg_build_number_overrides + ) + + # Normalize recipe names for comparison so ros-jazzy-X and ros2-X match. + # Iterate in sorted (not set-hash) order so the displayed name for a + # dual-named package is deterministic across runs, not whichever of the + # two happens to come last per Python's randomized set iteration order — + # "ros2-X" sorts after "ros--X" (- < digit in ASCII) so the + # shared ros2- convention consistently wins when both exist. + norm_to_recipe: dict[str, str] = {normalize_name(r): r for r in sorted(recipes)} + norm_recipes = set(norm_to_recipe) print(f"Platform: {platform}") - print_list( - "Built package artifacts without matching recipe directory", - built - recipes, - ) + extra_norm = built - norm_recipes + extra_display = sorted(extra_norm) + print(f"Built package artifacts without matching recipe directory: {len(extra_display)}") + for name in extra_display: + print(f" - {name}") print() - missing = recipes - built + missing_norm = norm_recipes - built + missing_display = sorted(norm_to_recipe[n] for n in missing_norm) print( - f"Recipe directories without built artifact on this platform: " - f"{len(missing)} out of {len(recipes)}" + f"Recipe directories without built artifact on {platform} platform: " + f"{len(missing_display)} out of {len(norm_recipes)}" ) - if missing: - for recipe in sorted(missing): + if missing_display: + for recipe in missing_display: print(f" - {recipe}") if idx != len(selected_platforms) - 1: diff --git a/check_dependency_compat.py b/check_dependency_compat.py new file mode 100644 index 000000000..fec282555 --- /dev/null +++ b/check_dependency_compat.py @@ -0,0 +1,1032 @@ +#!/usr/bin/env python3 +"""Detect incompatible dependency pins before (or after) building ROS packages. + +Three modes, all platform-agnostic (default platform: the current machine): + +1. ``solve`` (default): collect every non-ROS ``host``/``run`` dependency from the + generated ``recipes/`` tree, add the ``mutex_package.run_constraints`` from + ``vinca.yaml`` as hard requirements, write them into a single fake recipe and + solve it with ``rattler-build --render-only --with-solve`` against the real + ``conda_build_config.yaml``. Nothing is built or downloaded except repodata. + If the solve fails, the offending dependencies are removed iteratively so that + *all* conflicts are reported, each with a focused explanation and the list of + generated recipes that need it. + +2. ``--migrations`` (on by default when conflicts are found): for every conflict, + look up which conda-forge migration touches the pinned library and where the + culprit's feedstock stands in that migration (done / in-pr / awaiting-parents …). + This is the to-do list for conda-forge. + +3. ``--stale``: inspect already-built artifacts (``output//repodata.json`` + or a channel URL) and list ROS packages whose ``depends`` cannot be satisfied + under the current mutex constraints / pins. With ``--delete`` the local + artifacts are removed (and the local index refreshed) so that a subsequent + ``pixi run build`` (``--skip-existing``) rebuilds only those packages. A + ``pkg_additional_info.yaml`` build-number snippet is printed for the case where + the stale builds are already on the channel. + +Run inside the pixi environment, e.g. ``pixi run python check_dependency_compat.py``. +""" + +from __future__ import annotations + +import argparse +import json +import os +import platform as _platform +import re +import shutil +import subprocess +import sys +import tomllib +from collections import defaultdict +from pathlib import Path +from typing import Any, Iterable, Iterator, Optional +from urllib.request import urlopen + +import ruamel.yaml + +ROS_PREFIXES = ("ros-", "ros2-") +DEFAULT_CHANNELS = ["https://repo.prefix.dev/conda-forge"] +FAKE_PACKAGE_NAME = "robostack-dependency-compat-check" +DEFAULT_GLIBC = "2.17" # fallback when c_stdlib_version is not in the variant config +DEFAULT_OSX = "15.0" +# "Platform: linux-64 [__unix=0=0, __linux=0=0, __glibc=0=0, ...]" -> a version of 0 means the +# virtual package is unknown for this (foreign) platform and every solve is meaningless. +_MISSING_VIRTUAL_RE = re.compile(r"Platform: \S+ \[[^\]]*?(__glibc|__osx|__cuda)=0=0") +_GLIBC_NEED_RE = re.compile(r"__glibc >=([0-9.]+)") +STATUS_CATEGORIES = ( + "done", + "in-pr", + "awaiting-pr", + "awaiting-parents", + "not-solvable", + "bot-error", +) + + +# --------------------------------------------------------------------------- utils +def _yaml() -> ruamel.yaml.YAML: + yaml = ruamel.yaml.YAML() + yaml.width = 4096 + yaml.indent(mapping=2, sequence=4, offset=2) + return yaml + + +def load_yaml(path: Path) -> Any: + with path.open(encoding="utf-8") as stream: + return _yaml().load(stream) or {} + + +def detect_platform() -> str: + machine = _platform.machine() + if sys.platform.startswith("linux"): + return "linux-aarch64" if machine == "aarch64" else "linux-64" + if sys.platform == "darwin": + return "osx-arm64" if machine == "arm64" else "osx-64" + if sys.platform == "win32": + return "win-64" + raise RuntimeError(f"Cannot detect conda platform for {sys.platform}/{machine}") + + +def normalized(name: str) -> str: + return name.lower().replace("_", "-") + + +def spec_name(spec: str) -> str: + return spec.split()[0] + + +def is_ros_dependency(name: str) -> bool: + return name.startswith(ROS_PREFIXES) + + +def channels_from_pixi(pixi_toml: Path) -> list[str]: + """Take the channels of the ``build`` task so the check matches real builds.""" + try: + with pixi_toml.open("rb") as stream: + data = tomllib.load(stream) + cmd = data["tasks"]["build"]["cmd"] + if isinstance(cmd, list): + cmd = " ".join(cmd) + except (OSError, KeyError, tomllib.TOMLDecodeError): + return list(DEFAULT_CHANNELS) + channels = re.findall(r"(?:^|\s)-c\s+(\S+)", cmd) + return channels or list(DEFAULT_CHANNELS) + + +def platform_flags(platform: str) -> dict[str, Any]: + """Selector namespace for the v0-style ``# [sel]`` comments in conda_build_config.yaml.""" + try: + from vinca.v1_selectors import _platform_flags # type: ignore + + flags: dict[str, Any] = dict(_platform_flags(platform)) + except ImportError: + os_name, _, arch = platform.partition("-") + flags = { + "target_platform": platform, + "linux": os_name == "linux", + "osx": os_name == "osx", + "win": os_name == "win", + "unix": os_name in ("linux", "osx", "emscripten"), + "emscripten": os_name == "emscripten", + "wasm32": arch == "wasm32", + "x86_64": arch == "64", + "x86": arch == "64", + "aarch64": arch in ("aarch64", "arm64"), + "arm64": arch in ("aarch64", "arm64"), + "ppc64le": arch == "ppc64le", + "riscv64": arch == "riscv64", + } + flags.setdefault("win64", platform == "win-64") + flags.setdefault("os", os) + return flags + + +def eval_selector(selector: str, flags: dict[str, Any]) -> bool: + try: + from vinca.v1_selectors import _eval_condition # type: ignore + + return bool(_eval_condition(selector, flags)) + except Exception: # fall back to a plain python eval of the selector + try: + return bool(eval(selector, {"__builtins__": {}}, dict(flags))) # noqa: S307 + except Exception: + return False + + +# ----------------------------------------------------------------- requirements +def walk_requirements( + value: Any, condition: Optional[str] = None +) -> Iterator[tuple[Optional[str], str]]: + """Yield ``(condition, spec)`` for every requirement, keeping if/then/else.""" + if isinstance(value, str): + yield condition, value.strip() + elif isinstance(value, list): + for item in value: + yield from walk_requirements(item, condition) + elif isinstance(value, dict): + if "if" in value: + cond = str(value["if"]).strip() + then_cond = cond if condition is None else f"({condition}) and ({cond})" + else_cond = f"not ({cond})" if condition is None else f"({condition}) and not ({cond})" + yield from walk_requirements(value.get("then"), then_cond) + if value.get("else") is not None: + yield from walk_requirements(value.get("else"), else_cond) + else: + for item in value.values(): + yield from walk_requirements(item, condition) + + +def collect_requirements( + recipes_dir: Path, sections: Iterable[str] = ("host", "run") +) -> dict[tuple[Optional[str], str], set[str]]: + """Map ``(condition, spec)`` to the recipe names that require it.""" + yaml = _yaml() + requirements: dict[tuple[Optional[str], str], set[str]] = defaultdict(set) + for recipe_path in sorted(recipes_dir.glob("*/recipe.yaml")): + with recipe_path.open(encoding="utf-8") as stream: + recipe = yaml.load(stream) or {} + name = recipe.get("package", {}).get("name", recipe_path.parent.name) + reqs = recipe.get("requirements", {}) or {} + for section in sections: + for condition, spec in walk_requirements(reqs.get(section)): + if not spec or "${{" in spec: + continue + if is_ros_dependency(spec_name(spec)): + continue + requirements[(condition, spec)].add(name) + return requirements + + +def mutex_constraints(vinca_conf: dict[str, Any]) -> list[str]: + mutex = vinca_conf.get("mutex_package") + if isinstance(mutex, dict): + return [str(item) for item in mutex.get("run_constraints", []) or []] + return [] + + +def write_fake_recipe( + path: Path, + pins: list[str], + requirements: Iterable[tuple[Optional[str], str]], + version: str = "0.0.0", +) -> None: + grouped: dict[Optional[str], list[str]] = defaultdict(list) + for condition, spec in requirements: + if spec not in grouped[condition]: + grouped[condition].append(spec) + host: list[Any] = list(pins) + host.extend(sorted(grouped.pop(None, []))) + for condition in sorted(grouped, key=str): + host.append({"if": condition, "then": sorted(grouped[condition])}) + recipe = { + "package": {"name": FAKE_PACKAGE_NAME, "version": version}, + "build": {"number": 0, "script": ""}, + "requirements": {"build": [], "host": host, "run": []}, + "about": { + "summary": "Synthetic package used to check that all RoboStack " + "dependencies are co-installable under the current pins. Never built." + }, + } + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", encoding="utf-8") as stream: + _yaml().dump(recipe, stream) + + +# ------------------------------------------------------------------------ solve +def glibc_floor(variant_config: Path, platform: str) -> str: + """The glibc floor the packages are built for (``c_stdlib_version`` on linux).""" + if os.environ.get("CONDA_OVERRIDE_GLIBC"): + return os.environ["CONDA_OVERRIDE_GLIBC"] + try: + return variant_pins(variant_config, platform).get("c-stdlib-version", DEFAULT_GLIBC) + except OSError: + return DEFAULT_GLIBC + + +def rattler_build_executable() -> list[str]: + exe = shutil.which("rattler-build") + if exe: + return [exe] + if shutil.which("pixi"): + return ["pixi", "run", "rattler-build"] + raise SystemExit("rattler-build not found; run this script via `pixi run python ...`") + + +def run_solve( + recipe: Path, + variant_config: Path, + channels: list[str], + platform: str, + output_dir: Path, + *, + verbose: bool = False, +) -> tuple[bool, str]: + cmd = rattler_build_executable() + [ + "build", + "--recipe", + str(recipe), + "-m", + str(variant_config), + "--render-only", + "--with-solve", + "--target-platform", + platform, + "--build-platform", + platform, + "--output-dir", + str(output_dir), + "--color", + "never", + ] + for channel in channels: + cmd += ["-c", channel] + env = dict(os.environ, COLUMNS="500", NO_COLOR="1", RATTLER_BUILD_NO_SPINNER="1") + # Solving for a foreign platform yields __glibc=0 / __osx=0 virtual packages, which + # makes every package look uninstallable. Provide sane defaults unless overridden. + if platform.startswith("linux"): + env.setdefault("CONDA_OVERRIDE_GLIBC", glibc_floor(variant_config, platform)) + elif platform.startswith("osx") and sys.platform != "darwin": + env.setdefault("CONDA_OVERRIDE_OSX", DEFAULT_OSX) + if verbose: + print(" $", " ".join(cmd), file=sys.stderr) + proc = subprocess.run(cmd, capture_output=True, text=True, env=env) + text = proc.stdout + "\n" + proc.stderr + failed = proc.returncode != 0 or "Cannot solve the request" in text + return (not failed), text + + +_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m") +_TREE_RE = re.compile(r"^(?P[\s│]*)(?:├─|└─)\s+(?P[A-Za-z0-9_.+-]+)") + + +def solver_block(text: str) -> str: + """Return the final 'Cannot solve the request because of:' tree, cleaned.""" + text = _ANSI_RE.sub("", text) + marker = "Cannot solve the request because of:" + index = text.rfind(marker) + if index == -1: + return text.strip() + return text[index:].strip() + + +def collapse_versions(text: str) -> str: + """Collapse '7.6.0 | 7.6.0 | 7.6.0 ...' noise into '7.6.0 (x12)'.""" + + def repl(match: re.Match[str]) -> str: + items = [item.strip() for item in match.group(0).split("|")] + return f"{items[0]} (x{len(items)})" + + return re.sub(r"(\S+)(?:\s*\|\s*\1)+", repl, text) + + +def parse_culprits(text: str, candidates: set[str], protected: set[str]) -> set[str]: + """Names of directly requested (top-level) specs that the solver blames.""" + block = solver_block(text) + lines = block.splitlines() + entries: list[tuple[int, str]] = [] + for line in lines[1:]: + match = _TREE_RE.match(line) + if match: + entries.append((len(match.group("indent")), match.group("name"))) + culprits: set[str] = set() + if entries: + # Top level of the tree = the requested specs the solver blames. + min_indent = min(indent for indent, _ in entries) + for indent, name in entries: + if indent == min_indent and name in candidates and name not in protected: + culprits.add(name) + # The first line names one requested spec too ("because of: ... cannot be + # installed"), unless it is the generic "The following packages are incompatible". + first = re.match(r"Cannot solve the request because of:\s*([A-Za-z0-9_.+-]+)", lines[0]) if lines else None + if first and first.group(1) in candidates and first.group(1) not in protected: + culprits.add(first.group(1)) + # "No candidates were found for " (spec does not exist at all on the channels). + for match in re.finditer(r"No candidates were found for\s+([A-Za-z0-9_.+-]+)", block): + if match.group(1) in candidates and match.group(1) not in protected: + culprits.add(match.group(1)) + if not culprits: + # Fallback: any requested dependency the solver mentions as uninstallable. + for match in re.finditer(r"([A-Za-z0-9_.+-]+)\s+\S[^\n]*?cannot be installed", block): + name = match.group(1) + if name in candidates and name not in protected: + culprits.add(name) + return culprits + + +def pin_consistency(pins: list[str], variant: dict[str, str]) -> list[tuple[str, str]]: + """Mutex run_constraints that contradict the rendered conda_build_config.yaml pins.""" + problems = [] + for spec in pins: + parts = spec.split() + if len(parts) < 2: + continue + pinned = variant.get(normalized(parts[0])) + if pinned is not None and not constraint_compatible(parts[1], pinned): + problems.append((spec, f"{parts[0]} {pinned}")) + return problems + + +def _by_name(requirements: Iterable[tuple[Optional[str], str]]) -> dict[str, list[tuple[Optional[str], str]]]: + grouped: dict[str, list[tuple[Optional[str], str]]] = defaultdict(list) + for condition, spec in requirements: + grouped[spec_name(spec)].append((condition, spec)) + return grouped + + +class Solver: + """Thin wrapper that writes a fake recipe and solves it with rattler-build.""" + + def __init__(self, args: argparse.Namespace, channels: list[str], workdir: Path) -> None: + self.args = args + self.channels = channels + self.workdir = workdir + self.calls = 0 + + def solve(self, label: str, pins: list[str], requirements: Iterable[tuple[Optional[str], str]]) -> tuple[bool, str]: + recipe = self.workdir / label / "recipe.yaml" + write_fake_recipe(recipe, pins, requirements) + self.calls += 1 + return run_solve( + recipe, + Path(self.args.variant_config), + self.channels, + self.args.platform, + self.workdir / "output", + verbose=self.args.verbose, + ) + + def find_partner( + self, + culprit: str, + culprit_specs: list[tuple[Optional[str], str]], + pins: list[str], + others: dict[str, list[tuple[Optional[str], str]]], + ) -> Optional[list[str]]: + """Bisect the other dependencies down to the (few) names the culprit clashes with.""" + candidates = sorted(others) + + def fails(names: list[str]) -> bool: + specs = list(culprit_specs) + for name in names: + specs.extend(others[name]) + ok, _ = self.solve(f"bisect-{culprit}", pins, specs) + return not ok + + if not fails(candidates): + return None + while len(candidates) > 1: + half = len(candidates) // 2 + first, second = candidates[:half], candidates[half:] + if fails(first): + candidates = first + elif fails(second): + candidates = second + else: + return candidates # the clash needs members of both halves + return candidates + + +def solve_mode(args: argparse.Namespace) -> int: + recipes_dir = Path(args.recipes_dir) + if not any(recipes_dir.glob("*/recipe.yaml")): + raise SystemExit( + f"No recipes found in {recipes_dir}; run `pixi run generate-recipes` first." + ) + vinca_conf = load_yaml(Path(args.vinca)) + pins = mutex_constraints(vinca_conf) + list(args.pin) + variant = variant_pins(Path(args.variant_config), args.platform) + requirements = collect_requirements(recipes_dir) + names = {spec_name(spec) for _, spec in requirements} + channels = args.channel or channels_from_pixi(Path("pixi.toml")) + workdir = Path(args.workdir) + workdir.mkdir(parents=True, exist_ok=True) + solver = Solver(args, channels, workdir) + + print(f"Platform: {args.platform}") + print(f"Channels: {' '.join(channels)}") + print(f"Variant config: {args.variant_config} ({len(variant)} single-valued pins)") + print(f"Recipes: {len(list(recipes_dir.glob('*/recipe.yaml')))} in {recipes_dir}") + print(f"Dependencies: {len(names)} distinct non-ROS packages, {len(requirements)} specs") + print(f"Hard pins: {', '.join(pins) if pins else '(none)'}") + print() + + # 1. static check: mutex constraints vs. rendered conda_build_config.yaml + pin_conflicts: dict[str, dict[str, Any]] = {} + for spec, pinned in pin_consistency(pins, variant): + print(f"PIN MISMATCH: mutex run_constraint '{spec}' vs {args.variant_config} '{pinned}'") + pin_conflicts[spec_name(spec)] = {"mutex": spec, "variant": pinned, "explanation": "static"} + if pin_conflicts: + print(" -> align mutex_package.run_constraints in vinca.yaml with the rendered pins" + " (or drop the migration from vinca_pinning.yaml).\n") + + # 2. iterative solve of the whole dependency set + protected = {spec_name(spec) for spec in pins} + active_pins = list(pins) + excluded: dict[str, str] = {} + active = dict(requirements) + solved = False + for iteration in range(1, args.max_iterations + 1): + count = len({spec_name(s) for _, s in active}) + print(f"[{iteration}] solving {count} dependencies + {len(active_pins)} pins ...", flush=True) + ok, text = solver.solve(FAKE_PACKAGE_NAME, active_pins, active.keys()) + if ok: + solved = True + break + virtual = _MISSING_VIRTUAL_RE.search(_ANSI_RE.sub("", text)) + if virtual: + print(f"\nThe solver lacks the virtual package {virtual.group(1)} for {args.platform}.") + print("Set CONDA_OVERRIDE_GLIBC / CONDA_OVERRIDE_OSX / CONDA_OVERRIDE_CUDA and retry.\n") + return 2 + blamed = parse_culprits(text, names | protected, set()) + removable = blamed - protected + blamed_pins = blamed & protected + if removable: + for culprit in sorted(removable): + print(f" conflict: {culprit}") + excluded[culprit] = text + active = {key: value for key, value in active.items() if spec_name(key[1]) != culprit} + elif blamed_pins: + for name in sorted(blamed_pins): + mutex_spec = next(s for s in active_pins if spec_name(s) == name) + print(f" pin conflict: {mutex_spec} (dropping it to continue)") + pin_conflicts.setdefault(name, {"mutex": mutex_spec, "variant": variant.get(normalized(name))}) + pin_conflicts[name]["explanation"] = collapse_versions(solver_block(text)) + active_pins = [s for s in active_pins if spec_name(s) != name] + protected.discard(name) + else: + print("\nSolver failed but no removable culprit could be identified:\n") + print(collapse_versions(solver_block(text))) + break + else: + print(f"Stopped after {args.max_iterations} iterations; raise --max-iterations.") + + print() + if solved and not excluded and not pin_conflicts: + print("OK: every dependency is co-installable under the current pins.") + return 0 + + report_conflicts(args, solver, excluded, pin_conflicts, requirements, active_pins, variant, solved) + return 1 + + +def report_conflicts( + args: argparse.Namespace, + solver: Solver, + excluded: dict[str, str], + pin_conflicts: dict[str, dict[str, Any]], + requirements: dict[tuple[Optional[str], str], set[str]], + pins: list[str], + variant: dict[str, str], + solved: bool, +) -> None: + protected = {spec_name(spec) for spec in pins} + if pin_conflicts: + print(f"{len(pin_conflicts)} mutex constraint(s) contradict {args.variant_config}:") + for name, info in pin_conflicts.items(): + if info.get("variant") is None: + print(f"== {info['mutex']} was blamed by the solver for {args.platform} (no rendered pin to compare):") + else: + print(f"== {info['mutex']} vs {info['variant']}") + if info.get("explanation") not in (None, "static"): + for line in info["explanation"].splitlines()[: args.max_lines]: + print(" | " + line) + print() + if solved: + print(f"Dependencies solvable only after removing {len(excluded)} package(s):") + else: + print(f"Unsolvable; {len(excluded)} conflicting package(s) identified so far:") + print() + + by_name = _by_name(requirements) + details: dict[str, dict[str, Any]] = {} + for culprit in sorted(excluded): + specs = by_name[culprit] + recipes = sorted(set().union(*(requirements[key] for key in specs))) + ok, text = solver.solve(f"focus-{culprit}", pins, specs) + partners: list[str] = [] + partner_specs: list[tuple[Optional[str], str]] = [] + if ok: + others = {name: by_name[name] for name in by_name if name != culprit and name not in excluded} + print(f" {culprit}: installs alone; bisecting {len(others)} other dependencies for the clash ...", flush=True) + partners = solver.find_partner(culprit, specs, pins, others) or [] + partner_specs = [spec for name in partners for spec in by_name[name]] + ok, text = solver.solve(f"focus-{culprit}", pins, specs + partner_specs) + block = collapse_versions(solver_block(text)) if not ok else ( + "(no clash reproducible in isolation; it only appears in the full set)" + ) + # Precise attribution: which single mutex pin, when dropped, makes it solvable? + blamed_pins: list[str] = [] + if not ok: + for pin in pins: + relaxed = [other for other in pins if other != pin] + if solver.solve(f"attr-{culprit}", relaxed, specs + partner_specs)[0]: + blamed_pins.append(spec_name(pin)) + if not blamed_pins: # several pins at once, or a pin-independent problem + blamed_pins = sorted( + name for name in protected + if re.search(rf"(? 8 else ''}") + if clash: + print(f" clashes with: {'; '.join(clash)}") + if any(len(spec.split()) > 1 for _, spec in specs): + print(" note: the spec is version-restricted (dummy package in pkg_additional_info.yaml?);" + " a newer conda-forge version may already be built against the pinned libraries.") + glibc_needs = sorted({m.group(1) for m in _GLIBC_NEED_RE.finditer(block)}, key=version_tuple) + if glibc_needs and args.platform.startswith("linux"): + floor = glibc_floor(Path(args.variant_config), args.platform) + print(f" note: needs glibc >= {glibc_needs[-1]} but the build floor (c_stdlib_version /" + f" CONDA_OVERRIDE_GLIBC) is {floor}; conda-forge is moving to a newer sysroot.") + lines = block.splitlines() + for line in lines[: args.max_lines]: + print(" | " + line) + if len(lines) > args.max_lines: + print(f" | … ({len(lines) - args.max_lines} more lines)") + print() + + if args.json: + Path(args.json).write_text( + json.dumps({"pin_conflicts": pin_conflicts, "conflicts": details}, indent=2), encoding="utf-8" + ) + print(f"Wrote {args.json}") + print(f"({solver.calls} solver runs)") + + if args.migrations: + report_migrations(details, pin_conflicts, pins, Path(args.pinning)) + + +# ------------------------------------------------------------------- migrations +def _fetch_json(url: str) -> Optional[Any]: + try: + with urlopen(url, timeout=60) as response: # noqa: S310 + return json.load(response) + except Exception: + return None + + +def report_migrations( + details: dict[str, dict[str, Any]], + pin_conflicts: dict[str, dict[str, Any]], + pins: list[str], + pinning_path: Path, +) -> None: + try: + from vinca.pinning import ( # type: ignore + _migration_pin_keys, + download_pinning_package, + get_migration_status, + package_feedstocks, + ) + except ImportError: + print("vinca is not importable; skipping conda-forge migration lookup.") + return + if not pinning_path.exists(): + print(f"{pinning_path} not found; skipping conda-forge migration lookup.") + return + spec = load_yaml(pinning_path) + version = str(spec.get("conda_forge_pinning_version", "")) + applied = {str(name).removesuffix(".yaml") for name in spec.get("migrations", []) or []} + print(f"conda-forge migration status (conda-forge-pinning {version}):") + try: + _, payloads = download_pinning_package(version) + except Exception as exc: + print(f" could not download conda-forge-pinning {version}: {exc}") + return + migration_keys = {name: _migration_pin_keys(payload) for name, payload in payloads.items()} + status_cache: dict[str, Optional[dict[str, Any]]] = {} + + for name, info in pin_conflicts.items(): + if info.get("variant") is None: + print(f" mutex '{info['mutex']}' has no installable candidate together with the other pins and" + " dependencies (see explanation above); relax or drop the constraint, or fix the feedstock.") + continue + lib = normalized(name) + setters = sorted( + migration for migration, keys in migration_keys.items() + if any(key == lib or key.startswith(lib + "-") for key in keys) + ) + origin = ", ".join( + f"{m} ({'applied' if m in applied else 'not applied'} in {pinning_path.name})" for m in setters + ) or "the conda-forge-pinning base file" + print(f" mutex '{info['mutex']}' vs rendered pin '{info['variant']}' set by {origin}") + print(f" -> either update mutex_package.run_constraints in vinca.yaml to '{name} " + f"{str(info['variant']).split()[-1]}.*' (mutex build-number bump), or remove the migration.") + + for culprit, info in details.items(): + libs = [normalized(name) for name in info["pins"]] or [normalized(spec_name(p)) for p in pins] + relevant = sorted( + name + for name, keys in migration_keys.items() + if any(key == lib or key.startswith(lib + "-") or key.startswith(lib + "_") for key in keys for lib in libs) + ) + feedstocks = sorted(package_feedstocks(culprit)) + print(f" {culprit} (feedstock: {', '.join(feedstocks)}; pinned libs: {', '.join(libs)})") + if not relevant: + print( + " no active conda-forge migration touches these pins -> the feedstock's latest " + "build is simply behind; it needs a rerender/rebuild or version bump on conda-forge." + ) + for feedstock in feedstocks: + print(f" https://github.com/conda-forge/{feedstock}-feedstock") + continue + for migration in relevant: + if migration not in status_cache: + try: + status_cache[migration] = get_migration_status(migration) + except Exception: + status_cache[migration] = None + status = status_cache[migration] + tag = "applied locally" if migration in applied else "NOT applied locally" + if status is None: + print(f" {migration} [{tag}]: no status record on conda-forge") + continue + for feedstock in feedstocks: + category = next( + (cat for cat in STATUS_CATEGORIES if feedstock in {normalized(n) for n in status.get(cat, [])}), + None, + ) + pr_url = (status.get("_feedstock_status", {}).get(feedstock) or {}).get("pr_url", "") + where = category or "not part of this migration" + print(f" {migration} [{tag}]: {feedstock} -> {where} {pr_url}".rstrip()) + print() + print("Legend: 'done' but still conflicting = the pin here is ahead of/behind conda-forge;") + print(" 'in-pr'/'awaiting-parents' = wait for or help land the conda-forge PR;") + print(" no migration = open a rebuild/version-bump PR on the feedstock.") + + +# ----------------------------------------------------------------------- stale +_VERSION_PART_RE = re.compile(r"^(\d+)(.*)$") + + +def version_tuple(version: str) -> tuple[int, ...]: + parts: list[int] = [] + for part in version.strip().split("."): + match = _VERSION_PART_RE.match(part) + if not match: + break + parts.append(int(match.group(1))) + if match.group(2): # pre-release suffix such as '0a0': stop here + break + return tuple(parts) + + +def _pad(t: tuple[int, ...], n: int) -> tuple[int, ...]: + return t + (0,) * (n - len(t)) + + +def _cmp(a: tuple[int, ...], b: tuple[int, ...]) -> int: + n = max(len(a), len(b)) + a, b = _pad(a, n), _pad(b, n) + return (a > b) - (a < b) + + +def pin_range(pin_version: str) -> tuple[tuple[int, ...], tuple[int, ...], bool]: + """Return (lowest, upper_exclusive, exact) for a pin such as '1.90', '7.35.1.*' or '11.*'.""" + text = pin_version.strip() + exact = not text.endswith(".*") and "*" not in text + prefix = version_tuple(text.rstrip("*").rstrip(".")) + if not prefix: + return (0,), (10**9,), False + upper = prefix[:-1] + (prefix[-1] + 1,) + return prefix, upper, exact + + +def constraint_compatible(constraint: str, pin_version: str) -> bool: + """Whether some version can satisfy both the dependency constraint and the pin.""" + low, upper_excl, _ = pin_range(pin_version) + constraint = constraint.strip() + if constraint in ("", "*"): + return True + if "|" in constraint: + return any(constraint_compatible(part, pin_version) for part in constraint.split("|")) + for clause in [c.strip() for c in constraint.split(",") if c.strip()]: + if clause.startswith(">="): + if _cmp(upper_excl, version_tuple(clause[2:])) <= 0: + return False + elif clause.startswith(">"): + if _cmp(upper_excl, version_tuple(clause[1:])) <= 0: + return False + elif clause.startswith("<="): + if _cmp(low, version_tuple(clause[2:])) > 0: + return False + elif clause.startswith("<"): + if _cmp(low, version_tuple(clause[1:])) >= 0: + return False + elif clause.startswith("!="): + continue + else: + other = clause[2:] if clause.startswith("==") else clause + other_low, other_upper, _ = pin_range(other) + n = max(len(low), len(other_low)) + a, b = _pad(low, n), _pad(other_low, n) + k = min(len(low), len(other_low)) + if a[:k] != b[:k]: + return False + return True + + +_CBC_KEY_RE = re.compile(r"^([A-Za-z0-9_.-]+):\s*(?:#\s*\[(.+?)\])?\s*$") +_CBC_ITEM_RE = re.compile(r"^\s+-\s*(?P.*?)\s*(?:#\s*\[(?P.+?)\])?\s*$") + + +def variant_pins(variant_config: Path, platform: str) -> dict[str, str]: + """Single-valued pins from conda_build_config.yaml for this platform, keyed by dep name. + + The file is scanned line by line (not YAML-loaded) so that values such as ``2.10`` + keep their exact spelling and the ``# [selector]`` comments stay attached. + """ + flags = platform_flags(platform) + pins: dict[str, str] = {} + key: Optional[str] = None + key_active = False + chosen: list[str] = [] + + def flush() -> None: + if key and key_active and len(chosen) == 1: + pins[normalized(key)] = chosen[0].split()[0] + + for raw in variant_config.read_text(encoding="utf-8").splitlines(): + line = raw.rstrip() + if not line or line.lstrip().startswith("#"): + continue + key_match = _CBC_KEY_RE.match(line) + if key_match: + flush() + key, key_selector = key_match.group(1), key_match.group(2) + key_active = not key.startswith(("__", "zip_keys", "pin_run_as_build", "channel")) and ( + not key_selector or eval_selector(key_selector, flags) + ) + chosen = [] + continue + item_match = _CBC_ITEM_RE.match(line) + if item_match and key_active: + selector = item_match.group("sel") + if selector and not eval_selector(selector, flags): + continue + value = item_match.group("value").strip().strip("'\"") + if value and not value.startswith(("-", "[", "{")): + chosen.append(value) + flush() + return pins + + +def load_repodata(source: str, platform: str) -> tuple[dict[str, Any], bool]: + remote = "://" in source + if remote: + url = source.rstrip("/") + if not url.endswith("repodata.json"): + url = f"{url}/{platform}/repodata.json" + with urlopen(url, timeout=300) as response: # noqa: S310 + data = json.load(response) + else: + path = Path(source) + if path.is_dir(): + path = path / "repodata.json" + data = json.loads(path.read_text(encoding="utf-8")) + packages = dict(data.get("packages", {})) + packages.update(data.get("packages.conda", {})) + return packages, remote + + +def ros_name_map(vinca_conf: dict[str, Any]) -> dict[str, str]: + """Map normalized conda suffix (e.g. 'cartographer-ros') to ROS names ('cartographer_ros').""" + mapping: dict[str, str] = {} + for key in ("rosdistro_snapshot", "rosdistro_additional_recipes"): + path = vinca_conf.get(key) + if path and Path(path).exists(): + for ros_name in load_yaml(Path(path)): + mapping[normalized(str(ros_name))] = str(ros_name) + return mapping + + +def stale_mode(args: argparse.Namespace) -> int: + vinca_conf = load_yaml(Path(args.vinca)) + distro = vinca_conf.get("ros_distro", "") + prefix = f"ros-{distro}-" + pins: dict[str, str] = {} + if not args.mutex_only: + pins.update(variant_pins(Path(args.variant_config), args.platform)) + mutex_pins = {} + for spec in mutex_constraints(vinca_conf) + list(args.pin): + parts = spec.split() + if len(parts) >= 2: + mutex_pins[normalized(parts[0])] = parts[1] + pins.update(mutex_pins) # mutex constraints win + mutex_name = (vinca_conf.get("mutex_package") or {}).get("name") if isinstance( + vinca_conf.get("mutex_package"), dict) else None + + source = args.repodata or f"output/{args.platform}" + packages, remote = load_repodata(source, args.platform) + packages = { + filename: record + for filename, record in packages.items() + if record.get("name", "").startswith(prefix) or record.get("name") == mutex_name + } + if not args.all_builds: + # Only the newest build of every package matters for what users install now. + newest: dict[str, int] = defaultdict(lambda: -1) + for record in packages.values(): + newest[record["name"]] = max(newest[record["name"]], int(record.get("build_number", 0))) + packages = { + filename: record + for filename, record in packages.items() + if int(record.get("build_number", 0)) == newest[record["name"]] + } + scope = "all build numbers" if args.all_builds else "newest build of each package (see --all-builds)" + print(f"Platform: {args.platform} repodata: {source} {distro} packages: {len(packages)} ({scope})") + print(f"Pins checked: {', '.join(f'{k} {v}' for k, v in sorted(mutex_pins.items()))}") + if not args.mutex_only: + print(f" + {len(pins) - len(mutex_pins)} single-valued pins from {args.variant_config}") + print() + + stale: dict[str, list[tuple[str, str, str]]] = {} + for filename, record in sorted(packages.items()): + name = record.get("name", "") + problems = [] + for dep in record.get("depends", []) + record.get("constrains", []): + parts = dep.split() + if len(parts) < 2: + continue + key = normalized(parts[0]) + pin = pins.get(key) + if pin is None or is_ros_dependency(parts[0]): + continue + if not constraint_compatible(parts[1], pin): + severity = "CONFLICT" if key in mutex_pins else "drift" + problems.append((dep, f"{parts[0]} {pin}", severity)) + if problems: + stale[filename] = problems + + if not stale: + print("OK: no built package conflicts with the current pins.") + return 0 + + print(f"{len(stale)} stale artifact(s) whose dependencies conflict with the current pins") + print("(CONFLICT = violates a mutex run_constraint, i.e. not installable next to the new mutex;") + print(" drift = built against an older conda_build_config.yaml pin, rebuild recommended):\n") + by_dep: dict[str, int] = defaultdict(int) + for filename, problems in stale.items(): + print(f" {filename}") + for dep, pin, severity in problems: + print(f" {severity:8s} has: {dep:45s} pin: {pin}") + by_dep[pin] += 1 + print() + print("Summary by pin: " + ", ".join(f"{pin} ({count})" for pin, count in sorted(by_dep.items()))) + print() + + names = sorted({packages[f]["name"] for f in stale}) + mapping = ros_name_map(vinca_conf) + ros_names = [] + for name in names: + if name == mutex_name: + continue + suffix = name[len(prefix):] if name.startswith(prefix) else name + ros_names.append(mapping.get(normalized(suffix), suffix.replace("-", "_"))) + + build_number = int(vinca_conf.get("build_number", 0)) + 1 + print("Rebuild only these packages") + print("---------------------------") + print("A) artifacts only exist locally: delete them (see --delete) and run `pixi run build`;") + print(" --skip-existing then rebuilds exactly the missing packages.") + print("B) artifacts are already on the channel: bump the build number of just these packages") + print(" (and of the mutex, so its run_constraints are refreshed) and rebuild, then remove the") + print(" old files from the channel. pkg_additional_info.yaml snippet:\n") + for ros_name in ros_names: + print(f"{ros_name}:\n build_number: {build_number}") + if mutex_name: + print(f"\n# vinca.yaml -> mutex_package:\n# build_number: {build_number}") + print() + if remote: + channel = source.split("://", 1)[1].split("/")[1] if "anaconda.org" in source else source + print("Channel removal commands (anaconda.org):") + for filename in stale: + record = packages[filename] + print(f" anaconda remove {channel}/{record['name']}/{record['version']}/{args.platform}/{filename}") + print() + + if args.delete: + if remote: + print("--delete only removes local artifacts; use the commands above for the channel.") + return 1 + root = Path(source) + root = root if root.is_dir() else root.parent + removed = 0 + for filename in stale: + target = root / filename + if target.exists(): + target.unlink() + removed += 1 + print(f"deleted {target}") + print(f"\nDeleted {removed} artifact(s) from {root}.") + index_root = root.parent + rattler_index = shutil.which("rattler-index") + if rattler_index: + subprocess.run([rattler_index, "fs", str(index_root), "--force"], check=False) + print(f"Re-indexed {index_root}.") + else: + print(f"Run `pixi run rattler-index fs {index_root} --force` to refresh the local index.") + print("Now run `pixi run build` (skip-existing rebuilds only the deleted packages).") + return 1 + + +# ------------------------------------------------------------------------- main +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument("--platform", default=detect_platform(), help="conda platform (default: current machine)") + parser.add_argument("--recipes-dir", default="recipes") + parser.add_argument("--vinca", default="vinca.yaml") + parser.add_argument("--variant-config", default="conda_build_config.yaml") + parser.add_argument("--pinning", default="vinca_pinning.yaml", help="used for migration lookup") + parser.add_argument("--channel", "-c", action="append", default=[], help="override channels (repeatable)") + parser.add_argument("--pin", action="append", default=[], help="extra hard pin, e.g. 'libboost 1.90.*'") + parser.add_argument("--workdir", default="output/compat_check", help="where fake recipes are written") + parser.add_argument("--max-iterations", type=int, default=25) + parser.add_argument("--max-lines", type=int, default=30, help="solver explanation lines per conflict") + parser.add_argument("--json", help="write conflict details to this JSON file") + parser.add_argument("--no-migrations", dest="migrations", action="store_false", help="skip conda-forge lookups") + parser.add_argument("--verbose", action="store_true") + parser.add_argument("--stale", action="store_true", help="check built artifacts instead of recipes") + parser.add_argument("--repodata", help="repodata source for --stale: output/, a channel URL or repodata.json") + parser.add_argument("--delete", action="store_true", help="with --stale: delete stale local artifacts") + parser.add_argument( + "--all-builds", + action="store_true", + help="with --stale: inspect every build number, not just the current vinca.yaml build_number", + ) + parser.add_argument( + "--mutex-only", + action="store_true", + help="with --stale: only check the mutex run_constraints, ignore conda_build_config.yaml drift", + ) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + if args.stale: + return stale_mode(args) + return solve_mode(args) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/check_orphaned_platform_patches.py b/check_orphaned_platform_patches.py new file mode 100644 index 000000000..3f3ff0de7 --- /dev/null +++ b/check_orphaned_platform_patches.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +""" +check_orphaned_platform_patches.py +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Detect patch files in ``patch/`` that vinca will silently never wire +into any recipe's ``patches:`` list. + +Background +---------- +vinca (see ``vinca/main.py`` around the ``patch_dir`` glob, and +``vinca/utils.py::add_package_name_variants``) builds a dict keyed by +the patch filename's prefix (everything before an optional +``.osx``/``.win``/``.linux``/``.unix``/``.emscripten`` suffix), then +cross-links name-prefix variants of the *same* logical package +(``X`` <-> ``ros-X`` <-> ``ros2-X`` <-> ``ros--X``) via +``dict.setdefault()``. + +``setdefault`` only fills in a key that is still *absent*. If a +package has a plain patch under one prefix (say ``ros2-foo.patch``) +and a platform-specific patch under a *different* prefix (say +``ros-jazzy-foo.osx.patch``), both prefixes already exist as their own +dict entries by the time the cross-link step runs, so the two never +merge. Whichever prefix vinca does *not* resolve as the package's +final conda name for a given recipe simply never appears in that +recipe's ``patches:`` list -- with no error and no warning. This +exact bug orphaned ``ros-jazzy-sick-scan-xd.osx.patch`` for months +before it was renamed to ``ros2-sick-scan-xd.osx.patch`` (matching the +prefix jazzy actually resolves sick_scan_xd's own patch under). + +``check_patches_clean_apply.py`` does not catch this: it verifies that +every patch file on disk applies cleanly to source, but never checks +whether vinca's real name-resolution would actually attach that file +to any package's generated recipe at all. + +What this script does +---------------------- +Replicates vinca's exact patch-dict-construction and +``add_package_name_variants`` shortname-stripping logic (kept in sync +with whatever revision this repo's ``pixi.toml`` pins vinca to -- if +that mechanism ever changes upstream, re-check this script). It groups +patch-file prefixes by their computed "shortname" and flags any group +where more than one *distinct* literal prefix was actually used by a +file on disk: only one of those prefixes can ever be the resolved +package name for a given recipe, so content under the others is dead. + +Exit code is non-zero (and the offending groups are printed) if any +such collision is found. +""" + +from __future__ import annotations + +import glob +import os +import re +import sys +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parent +PATCH_DIR = REPO_ROOT / "patch" + +_ROS_DISTRO_RE = re.compile(r"^ros_distro:\s*(\S+)\s*$", re.MULTILINE) + + +def get_ros_distro() -> str: + vinca_yaml = (REPO_ROOT / "vinca.yaml").read_text() + match = _ROS_DISTRO_RE.search(vinca_yaml) + if not match: + print("Could not find 'ros_distro:' in vinca.yaml", file=sys.stderr) + sys.exit(2) + return match.group(1) + + +def build_patches_dict(patch_dir: Path) -> dict[str, dict[str, list[str]]]: + """Mirrors the glob loop in vinca/main.py that builds vinca_conf['_patches'].""" + patches: dict[str, dict[str, list[str]]] = {} + for x in sorted(glob.glob(os.path.join(str(patch_dir), "*.patch"))): + splitted = os.path.basename(x).split(".") + if splitted[0] not in patches: + patches[splitted[0]] = { + "any": [], + "osx": [], + "linux": [], + "win": [], + "emscripten": [], + } + if len(splitted) == 3: + if splitted[1] in ("osx", "linux", "win", "emscripten"): + patches[splitted[0]][splitted[1]].append(x) + continue + if splitted[1] == "unix": + patches[splitted[0]]["linux"].append(x) + patches[splitted[0]]["osx"].append(x) + continue + patches[splitted[0]]["any"].append(x) + return patches + + +def shortname_of(name: str, ros_distro: str) -> str: + """Mirrors the prefix-stripping in vinca/utils.py::add_package_name_variants.""" + legacy_prefix = f"ros-{ros_distro}-" + if name.startswith(legacy_prefix): + return name[len(legacy_prefix):] + elif name.startswith("ros2-"): + return name[len("ros2-"):] + elif name.startswith("ros-"): + return name[len("ros-"):] + else: + return name + + +def main() -> int: + ros_distro = get_ros_distro() + patches = build_patches_dict(PATCH_DIR) + + groups: dict[str, list[str]] = {} + for prefix in patches: + groups.setdefault(shortname_of(prefix, ros_distro), []).append(prefix) + + collisions = { + shortname: prefixes + for shortname, prefixes in groups.items() + if len(prefixes) > 1 + } + + if not collisions: + print(f"OK: no orphaned platform-specific patches ({len(patches)} patch-file prefixes scanned).") + return 0 + + print( + "ORPHANED PLATFORM PATCH RISK: the following packages have patch files " + "spread across more than one name-prefix variant. vinca's " + "add_package_name_variants() cross-links prefix variants via " + "dict.setdefault(), which is a no-op once a variant already exists as its " + "own entry -- so only ONE of the prefixes below will end up attached to " + "the package's real generated recipe; any platform-specific patch under " + "the others is silently never applied.\n", + file=sys.stderr, + ) + for shortname, prefixes in sorted(collisions.items()): + print(f" {shortname}:", file=sys.stderr) + for prefix in sorted(prefixes): + files = [ + os.path.basename(f) + for platform_files in patches[prefix].values() + for f in platform_files + ] + print(f" {prefix}: {', '.join(sorted(files))}", file=sys.stderr) + print( + "\nFix: rename the patch file(s) so every file for a given package shares " + "the SAME name prefix (matching whichever prefix that package's own " + "recipe.yaml actually resolves to -- check recipes//*/recipe.yaml's " + "source.patches entries, or regenerate recipes locally and inspect).", + file=sys.stderr, + ) + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/check_patches_clean_apply.py b/check_patches_clean_apply.py index b5fe8e906..eb38b1b6f 100644 --- a/check_patches_clean_apply.py +++ b/check_patches_clean_apply.py @@ -189,6 +189,12 @@ def run_rattler_build_individually(recipes: List[Path]) -> None: print("\n Running:", " ".join(cmd), "\n", flush=True) try: proc = subprocess.run(cmd, text=True, capture_output=True, errors="replace", encoding="utf-8") + # rattler-build's shared Git source cache can occasionally retain + # tag refs whose objects were not fetched. Retry from a clean Git + # cache rather than reporting a spurious patch failure. + if proc.returncode != 0 and "Git error: Git fetch failed" in proc.stderr: + shutil.rmtree(ROOT_DIR / "output" / "src_cache" / "git", ignore_errors=True) + proc = subprocess.run(cmd, text=True, capture_output=True, errors="replace", encoding="utf-8") success = proc.returncode == 0 results.append( { diff --git a/conda_build_config.yaml b/conda_build_config.yaml index 8bbf15cea..2b0ba3424 100644 --- a/conda_build_config.yaml +++ b/conda_build_config.yaml @@ -1,79 +1,1180 @@ -numpy: - - 2 -assimp: - - 6.0.5 -libprotobuf: - - 7.35.1 -protobuf: - - 7.35.1 -spdlog: - - 1.17 -pugixml: - - '1.15' -libopencv: - - 4.13.0 -libxml2: - - 2.14.* -graphviz: - - 14.* -libgdal: - - '3.13' -libgdal_core: - - '3.13' -# Mitigation for -# https://github.com/RoboStack/ros-jazzy/pull/126#issuecomment-3515455380 -libcap: - - 2.78 -libtheora: - - '1.2' -fmt: - - 12.1 -lua: - - 5.4 -tbb: - - '2023' -tbb_devel: - - '2023' -jsoncpp: - - 1.9.8 -eigen_abi_devel: - - 5.0.1 - -cdt_name: # [linux] - - conda # [linux] - -python: - - 3.14.* *_cp314 -python_impl: - - cpython - +# Generated by vinca-pinning-render from vinca_pinning.yaml. +# Do not edit this file directly. c_compiler: - gcc # [linux] - clang # [osx] - vs2022 # [win] +# Please remember to update gcc_compiler_version & clang_compiler_version too. c_compiler_version: # [unix] - - 14 # [linux] - - 19 # [osx] + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] c_stdlib: - sysroot # [linux] - macosx_deployment_target # [osx] - vs # [win] +m2w64_c_stdlib: # [win] + - m2w64-sysroot # [win] +m2w64_c_stdlib_version: # [win] + - 12 # [win] c_stdlib_version: # [unix] - - 2.28 # [linux] - - 14.0 # [osx and x86_64] - - 14.0 # [osx and arm64] + - 2.28 # [linux and not riscv64] + - 2.39 # [linux and riscv64] + - 2.28 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - 14.0 # [osx] cxx_compiler: - gxx # [linux] - clangxx # [osx] - vs2022 # [win] +# Please remember to update gxx_compiler_version & clangxx_compiler_version too. cxx_compiler_version: # [unix] - - 14 # [linux] - - 19 # [osx] + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] +llvm_openmp: # [osx] + - 21 # [osx] +fortran_compiler: # [unix or win] + - gfortran # [unix] + - flang # [win] +fortran_compiler_version: # [unix or win] + - 15 # [unix] + - 5 # [win64] + - 22 # [win and arm64] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] +m2w64_c_compiler: # [win] + - gcc # [win] +m2w64_c_compiler_version: # [win] + - 15 # [win] +m2w64_cxx_compiler: # [win] + - gxx # [win] +m2w64_cxx_compiler_version: # [win] + - 15 # [win] +m2w64_fortran_compiler: # [win] + - gfortran # [win] +m2w64_fortran_compiler_version: # [win] + - 15 # [win] + +# enable `{{ compiler("gcc") }}`, `{{ compiler("clang") }}` & co. +gcc_compiler: + - gcc +gcc_compiler_version: + - 15 +gxx_compiler: + - gxx +gxx_compiler_version: + - 15 +clang_compiler: + - clang # [unix] + # stay compatible with MSVC + - clang-cl # [win] +clang_compiler_version: + - 21 +clangxx_compiler: + - clangxx # [unix] + # stay compatible with MSVC + - clang-cl # [win] +clangxx_compiler_version: + - 21 + +cuda_compiler: + - cuda-nvcc +cuda_compiler_version: + - None + - 12.9 # [((linux and (x86_64 or aarch64)) or win64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] +cuda_compiler_version_min: + - None # [not ((linux and (x86_64 or aarch64)) or win64)] + - 12.9 # [((linux and (x86_64 or aarch64)) or win64)] + +arm_variant_type: # [aarch64 and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - sbsa # [aarch64 and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + +_libgcc_mutex: + - 0.1 conda_forge +# +# Go Compiler Options +# + +# The basic go-compiler with CGO disabled, +# It generates fat binaries without libc dependencies +# The activation scripts will set your CC,CXX and related flags +# to invalid values. +go_compiler: + - go-nocgo +# The go compiler build with CGO enabled. +# It can generate fat binaries that depend on conda's libc. +# You should use this compiler if the underlying +# program needs to link against other C libraries, in which +# case make sure to add 'c,cpp,fortran_compiler' for unix +# and the m2w64 equivalent for windows. +cgo_compiler: + - go-cgo +# The following are helpful variables to simplify go meta.yaml files. +target_goos: + - linux # [linux] + - darwin # [osx] + - windows # [win] +target_goarch: + - amd64 # [x86_64] + - arm64 # [arm64 or aarch64] + - ppc64le # [ppc64le] +target_goexe: + - # [unix] + - .exe # [win] +target_gobin: + - ${PREFIX}/bin/ # [unix] + - '%PREFIX%\bin\' # [win] + +# Rust Compiler Options +rust_compiler: + - rust +# the numbers here are the Darwin Kernel version for macOS 10.9 & 11.0; +# this is used to form our target triple on osx, and nothing else. After +# we bumped the minimum macOS version to 10.13, this was left unchanged, +# since it is not essential, and long-term we'd like to remove the version. +# see https://github.com/conda-forge/conda-forge.github.io/issues/2695 +macos_machine: # [osx] + - x86_64-apple-darwin13.4.0 # [osx and x86_64] + - arm64-apple-darwin20.0.0 # [osx and arm64] + +VERBOSE_AT: + - V=1 +VERBOSE_CM: + - VERBOSE=1 + +channel_sources: +channel_targets: +cdt_name: # [linux] + - conda # [linux] + +docker_image: # [os.environ.get("BUILD_PLATFORM", "").startswith("linux-")] + # builds on CentOS 7 + - quay.io/condaforge/linux-anvil-x86_64:cos7 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "cos7"] + - quay.io/condaforge/linux-anvil-aarch64:cos7 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "cos7"] + - quay.io/condaforge/linux-anvil-ppc64le:cos7 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "cos7"] + + # builds on AlmaLinux 8 + - quay.io/condaforge/linux-anvil-x86_64:alma8 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") in ("alma8", "ubi8")] + - quay.io/condaforge/linux-anvil-aarch64:alma8 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") in ("alma8", "ubi8")] + - quay.io/condaforge/linux-anvil-ppc64le:alma8 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") in ("alma8", "ubi8")] + + # builds on AlmaLinux 9 + - quay.io/condaforge/linux-anvil-x86_64:alma9 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma9"] + - quay.io/condaforge/linux-anvil-aarch64:alma9 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma9"] + - quay.io/condaforge/linux-anvil-ppc64le:alma9 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma9"] + + # builds on AlmaLinux 10 + - quay.io/condaforge/linux-anvil-x86_64:alma10 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma10"] + - quay.io/condaforge/linux-anvil-aarch64:alma10 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma10"] + - quay.io/condaforge/linux-anvil-ppc64le:alma10 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma10"] + +zip_keys: + # [unix] + - - c_compiler_version # [unix] + - cxx_compiler_version # [unix] + - fortran_compiler_version # [unix] + # CUDA 13.x requires newer glibc than our current baseline + - c_stdlib_version # [linux and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - cuda_compiler_version # [linux and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - - python + - is_python_min + - - libarrow + - libarrow_all + - - root_base + - root_cxx_standard + +# armv7l specifics because conda-build sets many things to centos 6 +# this can probably be removed when conda-build gets updated defaults +# for aarch64 +cdt_arch: armv7l # [armv7l] +BUILD: armv7-conda_cos7-linux-gnueabihf # [armv7l] + +pin_run_as_build: + libblst: + max_pin: x.x + netcdf-cxx4: + max_pin: x.x + vlfeat: + max_pin: x.x.x + +# Pinning packages + +# blas +libblas: + - 3.9.* *netlib +libcblas: + - 3.9.* *netlib +liblapack: + - 3.9.* *netlib +liblapacke: + - 3.9.* *netlib +blas_impl: + - openblas + - mkl # [x86 or x86_64] + - blis # [x86 or x86_64] + +ace: + - 8.0.6 +alsa_lib: + - '1.2' +antic: + - 0.2 +aom: + - '3.14' +arb: + - '2.23' +arpack: + - '3.9' +assimp: + - 6 +attr: + - 2.5 +aws_c_auth: + - 0.10.4 +aws_c_cal: + - 0.9.15 +aws_c_common: + - 0.14.3 +aws_c_compression: + - 0.3.2 +aws_c_event_stream: + - 0.7.1 +aws_c_http: + - 0.11.0 +aws_c_io: + - 0.27.5 +aws_c_mqtt: + - 0.16.0 +aws_c_s3: + - 0.13.1 +aws_c_sdkutils: + - 0.2.7 +aws_checksums: + - 0.2.10 +aws_crt_cpp: + - 0.42.3 +aws_sdk_cpp: + - 1.11.833 +azure_core_cpp: + - 1.16.3 +azure_identity_cpp: + - 1.13.3 +azure_storage_blobs_cpp: + - 12.18.0 +azure_storage_common_cpp: + - 12.14.0 +azure_storage_files_datalake_cpp: + - 12.16.0 +azure_storage_files_shares_cpp: + - 12.18.0 +azure_storage_queues_cpp: + - 12.7.0 +brotli: + - '1.2' +bullet_cpp: + - 3.25 +bxdecay0: + - 1.2.0 +bzip2: + - 1 +c_ares: + - 1 +c_blosc2: + - '3.3' +cairo: + - 1 +calchep: + - '3.8' +capnproto: + - 1.5.0 +casadi: + - 3.7 +ccr: + - 1.3 +cfitsio: + - 4.6.4 +clhep: + - 2.4.4.0 + - 2.4.7.1 + - 2.4.7.2 +cmocka: + - 2.0.1 +coin_or_cbc: + - 2.10 +coincbc: + - 2.10 +coin_or_cgl: + - 0.60 +coin_or_clp: + - 1.17 +coin_or_osi: + - 0.108 +coin_or_utils: + - 2.11 +collier: + - '1.2' +console_bridge: + - 1.0 +cran_mirror: + - https://cloud.r-project.org +# match with libcudnn-dev +cudnn: + - '9' +cutensor: + - 2 +curl: + - 8 +dartsim_cpp: + - '6.19' +dav1d: + - 1.2.1 +dav1d_devel: + - 1.2.1 +davix: + - '0.8' +dbus: + - 1 +dcap: + - 2.47 +delphes: + - 3.5.1 +eclib: + - '20250627' +eigen_abi_devel: + - 5.0.1 +elfutils: + - '0.194' +emela: + - '1.0' +exiv2: + - '0.28' +expat: + - 2 +fastbdt: + - '5.6' +fastjet_contrib: + - '1' +fastjet_cxx: + - '3.5' +feynhiggs: + - '2.19' +ffmpeg: + - '9' +fftw: + - 3 +flann: + - 1.9.2 +flatbuffers: + - 25.9.23 +fmt: + - '12.1' +fontconfig: + - 2 +freetype: + - 2 +gaudi: + - '40.4' +gct: + - 6.2.1705709074 +gf2x: + - '1.3' +gdk_pixbuf: + - 2 +gnuradio_core: + - 3.10.12 +gnutls: + - '3.8' +gsl: + - 2.7 +gsoap: + - 2.8.123 +gstreamer: + - '1.28' +gst_plugins_base: + - '1.28' +gdal: + - '3.13' +libgdal: + - '3.13' +libgdal_core: + - '3.13' +geant4: + - 11.4.2 +geos: + - 3.14.1 +geotiff: + - '1.7' +gfal2: + - '2.23' +gflags: + - '2.3' +giflib: + - '6' +givaro: + - 4.2.2 +glew: + - '2.3' +glib: + - '2' +glog: + - '0.7' +glpk: + - '5.0' +gm2calc: + - '2.3' +gmp: + - 6 +google_cloud_cpp: + - '3.8' +google_cloud_cpp_common: + - 0.25.0 +googleapis_cpp: + - '0.10' +gpgme: + - '1.24' +graphviz: + - '14' +# Harfbuzz guarantees total ABI compatibiblity +# The first version to have this new ABI pin is 11.0.1 +# https://github.com/conda-forge/harfbuzz-feedstock/pull/125 +# But as of 2025/08/03, 11.0.1 is quite "old" and it is pretty safe +# to release the pin +# We are leaving this comment here to discourage others from adding +# a harfbuzz global pin, as it is not needed. +# harfbuzz: +# - '11' +hepmc2: + - '2.06' +hepmc3: + - '3.3' +hdf4: + - 4.2.15 +hdf5: + - '2' + - 1.14.6 +hdrhistogram_c: + - 0.11.9 +icu: + - '78' +idyntree: + - '15' +imath: + - 3.2.2 +impi_devel: + - 2021.16.0 +ipopt: + - 3.14.19 +isl: + - '0.26' +jasper: + - 4 +jpeg: + - 9 +lcms2: + - 2 +lerc: + - '4' +lhapdf: + - '6.5' +libjpeg_turbo: + - '3' +libjxl: + - '0.12' +libev: + - 4.33 +json_c: + - '0.18' +jsoncpp: + - 1.9.8 +kealib: + - '2.0' +krb5: + - '1.22' +ldas_tools_framecpp: + - '2.9' +libabseil: + - 20260526 +libaec: + - '1' +libamd: + - '3' +libarchive: + - '3.8' +libarrow: + - '25.0' + - '24.0' + - '23.0' + - '22.0' +libarrow_all: + - '25.0' + - '24.0' + - '23.0' + - '22.0' +libattr: + - 2.6 +libavif: + - 1 +libblitz: + - 1.0.2 +libblst: + - '0.3' +libboost_devel: + - '1.90' +libboost_headers: + - '1.90' +libboost_python_devel: + - '1.90' +libbrotlicommon: + - '1.2' +libbrotlidec: + - '1.2' +libbrotlienc: + - '1.2' +libbtf: + - '2' +libcamd: + - '3' +libcap: + - '2.78' +libcint: + - '6.1' +libccolamd: + - '3' +libcholmod: + - '5' +libcolamd: + - '3' +libcurl: + - 8 +# match with cudnn +libcudnn_dev: + - '9' +libcrc32c: + - 1.1 +libcxsparse: + - '4' +libdap4: + - 3.20.6 +libdeflate: + - '1.25' +libdovi: + - '3' +libduckdb_devel: + - '1' +libeantic: + - '2' +libevent: + - 2.1.12 +libexactreal: + - '4' +libffi: + - '3.5' +libflac: + - '1.5' +libflatsurf: + - 3 +libflint: + - '3.5' +libframel: + - '8.41' +# hmaarrfk - Aug 30, 2025 +# https://github.com/conda-forge/libfuse-feedstock/pull/29 +# Although some libfuse packages exist with version 3, we decided +# to pin libfuse to 2 to allow co-installation between libfuse (version 2) and libfuse3 +libfuse: + - '2' +libfuse3: + - '3' +libgit2: + - '1.9' +libgoogle_cloud: + - '3.8' +libgoogle_cloud_devel: + - '3.8' +libgoogle_cloud_all_devel: + - '3.8' +libgoogle_cloud_aiplatform_devel: + - '3.8' +libgoogle_cloud_automl_devel: + - '3.8' +libgoogle_cloud_bigquery_devel: + - '3.8' +libgoogle_cloud_bigtable_devel: + - '3.8' +libgoogle_cloud_compute_devel: + - '3.8' +libgoogle_cloud_dialogflow_cx_devel: + - '3.8' +libgoogle_cloud_dialogflow_es_devel: + - '3.8' +libgoogle_cloud_discoveryengine_devel: + - '3.8' +libgoogle_cloud_dlp_devel: + - '3.8' +libgoogle_cloud_iam_devel: + - '3.8' +libgoogle_cloud_oauth2_devel: + - '3.8' +libgoogle_cloud_policytroubleshooter_devel: + - '3.8' +libgoogle_cloud_pubsub_devel: + - '3.8' +libgoogle_cloud_spanner_devel: + - '3.8' +libgoogle_cloud_speech_devel: + - '3.8' +libgoogle_cloud_storage_devel: + - '3.8' +libgrpc: + - '1.82' +libgsasl: + - '2' +libheif: + - '1.23' +libhugetlbfs: + - 2 +libhwloc: + - 2.13.0 +libhwy: + - '1.4' +libiconv: + - 1 +libidn2: + - 2 +libintervalxt: + - 3 +libitk_devel: + - 5.4 +libklu: + - '2' +libkml: + - 1.3 +libkml_devel: + - 1.3 +liblzma_devel: + - 5 +libiio: + - 0 +libldl: + - '3' +libmagma: + - 2.10.0 +libmagma_devel: + - 2.10.0 +libmagma_sparse: + - 2.10.0 +libmed: + - '4.2' +libmatio: + - 1.5.30 +libmatio_cpp: + - 0.3.0 +libmicrohttpd: + - '1.0' +libnetcdf: + - 4.10.1 +libntlm: + - 1 +libode: + - 0.16.6 +libogg: + - 1.3 +libopencolorio: + - '2.5' +libopenimageio: + - '3.1' +libopencv: + - 5.0.0 +libopentelemetry_cpp: + - '1.27' +libosqp: + - 1.0.0 +libopenvino: + - 2026.3.1 +libopenvino_dev: + - 2026.3.1 +libparu: + - '1' +libpcap: + - '1.10' +libplacebo: + - '7.360' +libpnetcdf: + - 1.15.0 +libpng: + - 1.6 +libprotobuf: + - 7.35.1 +libpq: + - '18' +libpsl: + - '0.23' +libpulsar: + - 4.2.0 +libraqm: + - '0.11' +libraqm_devel: + - '0.11' +libraw: + - '0.22' +librbio: + - '4' +librdkafka: + - '2.15' +librdkit: + - 2026.03.2 +librealsense: + - '2.58' +librerun_sdk: + - 0.35.0 +librsvg: + - 2 +libsecret: + - '0.21' +libsentencepiece: + - 0.2.1 +libsndfile: + - '1.2' +libsodium: + - 1.0.22 +libsoup: + - 3 +libspatialindex: + - 2.1.0 +libspex: + - '3' +libspqr: + - '4' +libsuitesparseconfig: + - '7' +libsuperiso: + - '5.0' +libssh: + - '0.12' +libssh2: + - 1 +libsvm: + - '337' +libsqlite: + - 3 +libsystemd: + - '257' +libtensorflow: + - '2.16' +libtensorflow_cc: + - '2.16' +libtheora: + - '1.2' +libthrift: + - 0.22.0 +libtiff: + - '4.7' +libtorch: + - '2.12' +libudev: + - '257' +libumfpack: + - '6' +libunwind: + - '1.8' +libutf8proc: + - '2.11' +libv8: + - 8.9.83 +libvigra: + - '1.12' +libvips: + - 8 +libvpl: + - '2.16' +libwebp: + - 1 +libwebp_base: + - 1 +libx86emu: + - 3.7 +libxcb: + - '1' +libxml2: + - '2.15' +libxml2_devel: + - '2.15' +libxrootd_devel: + - '6' +libxsmm: + - '2' +liburing: + - 2.14 +libuuid: + - 2 +libyarp: + - 3.12.2 +libzip: + - 1 +lmdb: + - '0.9' +log4cxx: + - 1.8.0 +lol_html: + - 3.0.1 +ls_hpack: + - 2.3.5 +lwtnn: + - '2.14' +lz4_c: + - '1.10' +lzo: + - 2 +magma: + - '2.9' +metis: + - 5.1.0 +mimalloc: + - 3.4.1 +mkl: + - '2026' # [not osx] + - '2023' # [osx] +mkl_devel: + - '2026' # [not osx] + - '2023' # [osx] +mpg123: + - '1.33' +mpich: + - 4 +mpfr: + - 4 +mpfun90: + - '2026' +mppp: + - '2.0' +msgpack_c: + - 6 +msgpack_cxx: + - '7' +mumps_mpi: + - 5.8.2 +mumps_seq: + - 5.8.2 +mysql_devel: + - '9.7' +nccl: + - 2 +ncurses: + - 6 +netcdf_cxx4: + - 4.3 +netcdf_fortran: + - '4.6' +nettle: + - '3.10' +ninja_hep_ph: + - '1.2' +nodejs: + - '26' + - '24' +nss: + - 3 +nspr: + - 4 +nlopt: + - '2.11' +ntl: + - 11.6.0 +# we build using the latest minor version; numpy has generous backwards compatibility +# even so, and this is reflected through the run-exports of the package; see also +# https://github.com/conda-forge/conda-forge-pinning-feedstock/issues/4816 +numpy: + - 2 +obake_devel: + - '0.9' +occt: + - 8.0.0 +oneloop: + - '3.7' +openblas: + - 0.3.* +openexr: + - '3.4' +openh264: + - 2.6.0 +openjpeg: + - '2' +openjph: + - '0.31' +openmpi: + - '5' +openslide: + - 4 +# although openssl follows SemVer for ABI/API stability, we stay on +# LTS version at build time to avoid forcing newer version at runtime +openssl: + - '3.5' +orc: + - 2.3.1 +osqp_eigen: + - '0.11' +pango: + - '1' +pari: + - 2.17.* *_pthread +pcl: + - 1.15.1 +perl: + - 5.32.1 +petsc: + - '3.25' +petsc4py: + - '3.25' +plutovg: + - 1.3.3 +plutosvg: + - 0.0.8 +pugixml: + - '1.15' +slepc: + - '3.25' +slepc4py: + - '3.25' +svt_av1: + - 4.2.0 +p11_kit: + - '0.26' +pcre: + - '8' +pcre2: + - '10.47' +pdal: + - '2.10' +libpdal: + - '2.10' +libpdal_core: + - '2.10' +pixman: + - 0 +poco: + - 1.15.3 +poppler: + - '26.07' +portaudio: + - '19.7' +postgresql: + - '18' +postgresql_plpython: + - '18' +proj: + - '9.8' +pulseaudio: + - '17.0' +pulseaudio_client: + - '17.0' +pulseaudio_daemon: + - '17.0' +pybind11_abi: + - '11' +pythia8: + - '8.312' +python: + # conda-forge supports only 3.14+ for win-arm64 and linux-riscv64 + # part of a zip_keys: python, is_python_min + - 3.14.* *_cp314 +python_impl: + - cpython + +python_min: + # minimum supported python version per CFEP-25 + # bump to next minor version when we drop python versions + - '3.11' # [not ((win and arm64) or riscv64)] + - '3.14' # [(win and arm64) or riscv64] +is_freethreading: + - false +is_python_min: + # part of a zip_keys: python, is_python_min + - false +is_abi3: + - true +pytorch: + - '2.12' +pyqt: + - 5.15 +pyqtwebengine: + - 5.15 +pyqtchart: + - 5.15 +qcdloop: + - '2.1' +qhull: + - 2020.2 +qpdf: + - '12' +qt: + - 5.15 +qt_main: + - 5.15 +qt6_main: + - '6' +qtkeychain: + - '0.17' +rav1e: + - '0.8' +rdma_core: + - '63' +re2: + - 2025.11.05 +readline: + - '8' +rivet: + - '4.1' +rocksdb: + - '11.0' +root_base: + - 6.36.10 + - 6.38.4 + - 6.38.4 + - 6.40.2 + - 6.40.2 +root_cxx_standard: + - 20 + - 20 + - 23 + - 20 + - 23 +r_base: + - 4.4 + - 4.5 +libscotch: + - 7.0.11 +libptscotch: + - 7.0.11 +scotch: + - 7.0.11 +ptscotch: + - 7.0.11 +s2geography: + - 0.1.2 +s2geometry: + - '0.14' +s2n: + - 1.7.6 +sdl2: + - '2' +sdl2_image: + - '2' +sdl2_mixer: + - '2' +sdl2_net: + - '2' +sdl2_ttf: + - '2' +shaderc: + - '2026.3' +sherpa: + - '3.0' +singular: + - 4.4.1 +siscone: + - '3.1' +snappy: + - 1.2 +soapysdr: + - '0.8' +softsusy: + - '4.1' +sox: + - 14.4.2 +spdlog: + - '1.17' +spirv_tools: + - '2026' +sqlite: + - 3 +srm_ifce: + - 1.24.6 +starlink_ast: + - 9.3.1 +suitesparse: + - '7' +suitesparse_mongoose: + - '3' +sundials: + - '7.8' +superlu_dist: + - '9' +swig_abi: + - '5' +tbb: + - '2023' +tbb_devel: + - '2023' +tensorflow: + - '2.16' +thrift_cpp: + - 0.22.0 +tinyxml2: + - '11.0' +tk: + - 8.6 # [not ppc64le] +tiledb: + - '2.30' +ucc: + - 1 +ucx: + - '1.22' +uhd: + - 4.10.0 +urdfdom: + - '6' +vc: # [win] + - 14 # [win] +vgm: + - '5.4' +vigra: + - '1.12' +vlfeat: + - 0.9.21 +vmc: + - '2.2' +volk: + - '3.3' +vtk: + - 9.7.0 +vtk_base: + - 9.7.0 +wcslib: + - '8' +wxwidgets: + - 3.3.3 +x264: + - 1!164.* +x265: + - '3.5' +xerces_c: + - '3.3' +xrootd: + - '6' +xxhash: + - 0.8.3 +xz: + - 5 +yoda: + - '2.1' +zeromq: + - 4.3.5 +zfp: + - 1.0 +zlib: + - 1 +zlib_ng: + - '2.3' +zstd: + - '1.5' libzenohc: - 1.9.0 libzenohcxx: - 1.9.0 - -libhwloc: - - 2.13.0 + # conda-forge published sip 6.16.1 on 2026-09-08, which broke ABI targeting for + # packages like qt_gui_cpp_sip that build against PyQt-sip's fixed ABI v12 + # (hit this on humble/jazzy first; rolling also builds qt_gui_cpp via + # pyqt6/sip so it's equally exposed). Pin back to the last known-good line + # until upstream fixes it. +sip: + - 6.15 diff --git a/patch/dependencies.yaml b/patch/dependencies.yaml index b083ac71d..1607ce002 100644 --- a/patch/dependencies.yaml +++ b/patch/dependencies.yaml @@ -5,7 +5,11 @@ foxglove_bridge: ros_ign_interfaces: add_host: ["ros-rolling-rcl-interfaces"] cartographer_ros: - add_host: ["cartographer 2.*", "libboost-devel", "ceres-solver * cpu*"] + # Drop the ros2-cartographer dummy dep (vinca doesn't dedupe it against the direct conda-forge dep below); ceres-solver pinned to cpu since RoboStack disables CUDA. + remove_host: ["ros2-cartographer"] + remove_run: ["ros2-cartographer"] + add_host: ["cartographer 2.*", "libboost-devel", "ceres-solver * cpu*", "ros2-pcl-conversions"] + add_run: ["ros2-pcl-conversions"] libyaml_vendor: add_host: ["yaml-cpp", "yaml"] add_run: ["yaml-cpp", "yaml"] @@ -74,7 +78,7 @@ tvm_vendor: libphidget22: add_host: ["libusb"] libg2o: - add_host: ["qt", "${{ 'libglu' if linux }}", "${{ 'freeglut' if not osx }}"] + add_host: ["${{ 'libglu' if linux }}", "${{ 'freeglut' if not osx }}"] fmilibrary_vendor: add_host: ["fmilib"] mrpt2: @@ -87,7 +91,7 @@ ros1_rosbag_storage_vendor: popf: add_host: ["perl"] rtabmap: - add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "ceres-solver", "libdc1394", "libusb", "vtk"] + add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "ceres-solver", "${{ 'libdc1394' if not win }}", "libusb", "vtk"] backward_ros: add_host: ["${{ 'binutils' if linux }}", "${{ 'elfutils' if linux }}", "ros-rolling-ament-cmake-libraries"] ompl: @@ -96,10 +100,12 @@ pybind11_vendor: add_host: ["pybind11"] add_run: ["pybind11"] python_qt_binding: - add_host: ["pyqt-builder", "qt6-main", "pyqt6"] + # sip <6.16: conda_build_config's variant pin doesn't apply transitively here; 6.16.x regressed ABI targeting for PyQt-based bindings. + add_host: ["pyqt-builder", "qt6-main", "pyqt6", "sip <6.16"] add_run: ["pyqt-builder", "qt6-main", "pyqt6"] qt_gui_cpp: - add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "pyqt-builder", "qt6-main", "pyqt6"] + # sip pinned directly for the same reason as python_qt_binding above. + add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "pyqt-builder", "qt6-main", "pyqt6", "sip <6.16"] add_run: ["pyqt-builder", "qt6-main", "pyqt6"] rqt_gui_cpp: add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}"] @@ -166,9 +172,7 @@ uncrustify_vendor: mimick_vendor: add_build: ["vcstool"] gz_cmake_vendor: - # https://github.com/gazebo-release/gz_cmake_vendor/blob/rolling/CMakeLists.txt#L6 for select the right major version - # (this is true for all gz-* vendor packages) or https://github.com/gazebo-tooling/gazebodistro/blob/master/collection-harmonic.yaml - # See https://gazebosim.org/docs/latest/ros_installation/#summary-of-compatible-ros-and-gazebo-combinations for mapping between ROS2 and Gazebo distros + # Major version pin selects the Gazebo release matching rolling (applies to all gz-* vendor packages). add_host: ["gz-cmake"] add_run: ["gz-cmake"] gz_common_vendor: @@ -296,8 +300,24 @@ zstd_point_cloud_transport: add_host: ["ros-rolling-zstd-cmake-module", "zstd"] mujoco_vendor: add_host: ["libmujoco"] +mujoco_ros2_control_plugins: + add_host: + - if: linux + then: ["libegl-devel"] roboplan_ros_examples: - # package.xml only declares ament_cmake_python, but CMakeLists.txt does - # find_package(ament_cmake REQUIRED) and build_type is ament_cmake. - # Fixed for roboplan_ros 0.7.0, so it can be removed when this releases. add_host: ["ros-rolling-ament-cmake"] +yasmin_pcl: + add_host: ["ros2-pcl-conversions"] + add_run: ["ros2-pcl-conversions"] +rmf_fleet_adapter_python: + add_host: ["pybind11_json"] +rmf_visualization_schedule: + remove_host: ["openssl"] + remove_run: ["openssl"] + # asio <1.33: our patch below still uses asio::io_service, removed upstream in asio 1.33.0 (github.com/chriskohlhoff/asio@49fcd034); conda-forge has no 1.30-1.35 builds, so this and <1.30 resolve identically today. + add_host: ["openssl >=3.6.4", "asio <1.33"] + add_run: ["openssl >=3.6.4", "asio <1.33"] +rmf_websocket: + # asio <1.33, same reason as rmf_visualization_schedule above. websocketpp's own get_io_service->get_io_context rename (see the patch below) is a separate, already-fixed issue upstream (conda-forge/websocketpp-feedstock#8). + add_host: ["asio <1.33"] + add_run: ["asio <1.33"] diff --git a/patch/ros-rolling-apriltag-mit.patch b/patch/ros-rolling-apriltag-mit.patch new file mode 100644 index 000000000..c051ce447 --- /dev/null +++ b/patch/ros-rolling-apriltag-mit.patch @@ -0,0 +1,51 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -12,12 +12,20 @@ + # set(CMAKE_CXX_CLANG_TIDY clang-tidy) + + find_package(Eigen3 REQUIRED) +-find_package(OpenCV REQUIRED core calib3d) ++find_package(OpenCV REQUIRED core imgproc) ++if(OpenCV_VERSION VERSION_LESS 5) ++ find_package(OpenCV REQUIRED calib3d) ++ set(APRILTAG_MIT_OPENCV_CALIB opencv_calib3d) ++else() ++ # OpenCV 5 moved findHomography into the geometry module ++ find_package(OpenCV REQUIRED geometry) ++ set(APRILTAG_MIT_OPENCV_CALIB opencv_geometry) ++endif() + find_package(Boost REQUIRED headers) + + file(GLOB CC_FILES ${PROJECT_SOURCE_DIR}/src/*.cc) + add_library(${PROJECT_NAME} SHARED ${CC_FILES}) +-target_link_libraries(${PROJECT_NAME} PUBLIC opencv_core opencv_calib3d Eigen3::Eigen Boost::headers) ++target_link_libraries(${PROJECT_NAME} PUBLIC opencv_core opencv_imgproc ${APRILTAG_MIT_OPENCV_CALIB} Eigen3::Eigen Boost::headers) + set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14) + + target_include_directories( +diff -ruN a/src/Quad.cc b/src/Quad.cc +--- a/src/Quad.cc ++++ b/src/Quad.cc +@@ -2,7 +2,7 @@ + #include "apriltag_mit/AprilTags/Line2D.h" + #include "apriltag_mit/AprilTags/MathUtil.h" + #include "apriltag_mit/AprilTags/Segment.h" +-#include ++#include + + namespace AprilTags { + +diff -ruN a/src/TagDetection.cc b/src/TagDetection.cc +--- a/src/TagDetection.cc ++++ b/src/TagDetection.cc +@@ -1,6 +1,9 @@ + #include "apriltag_mit/AprilTags/TagDetection.h" + #include "apriltag_mit/AprilTags/MathUtil.h" + #include "opencv2/opencv.hpp" ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + #include + + namespace AprilTags { diff --git a/patch/ros-rolling-apriltag-ros.patch b/patch/ros-rolling-apriltag-ros.patch new file mode 100644 index 000000000..60b9af822 --- /dev/null +++ b/patch/ros-rolling-apriltag-ros.patch @@ -0,0 +1,30 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 75d5822..8eb328e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -41,7 +41,15 @@ find_package(image_transport REQUIRED) + find_package(cv_bridge REQUIRED) + find_package(Eigen3 REQUIRED NO_MODULE) + find_package(Threads REQUIRED) +-find_package(OpenCV REQUIRED COMPONENTS core calib3d) ++find_package(OpenCV REQUIRED COMPONENTS core) ++if(OpenCV_VERSION_MAJOR GREATER 4) ++ # calib3d was split into "calib" + "geometry" in OpenCV 5. ++ find_package(OpenCV REQUIRED COMPONENTS calib geometry) ++ set(APRILTAG_ROS_OPENCV_CALIB_LIBS opencv_calib opencv_geometry) ++else() ++ find_package(OpenCV REQUIRED COMPONENTS calib3d) ++ set(APRILTAG_ROS_OPENCV_CALIB_LIBS opencv_calib3d) ++endif() + find_package(apriltag 3.2 REQUIRED) + + if(cv_bridge_VERSION VERSION_GREATER_EQUAL 3.3.0) +@@ -98,7 +106,7 @@ target_link_libraries(pose_estimation + PUBLIC + apriltag::apriltag + Eigen3::Eigen +- opencv_calib3d ++ ${APRILTAG_ROS_OPENCV_CALIB_LIBS} + conversion + ${geometry_msgs_TARGETS} + tf2::tf2 diff --git a/patch/ros-rolling-async-web-server-cpp.patch b/patch/ros-rolling-async-web-server-cpp.patch index 03958773c..2185a58d9 100644 --- a/patch/ros-rolling-async-web-server-cpp.patch +++ b/patch/ros-rolling-async-web-server-cpp.patch @@ -1,51 +1,24 @@ diff --git a/include/async_web_server_cpp/http_connection.hpp b/include/async_web_server_cpp/http_connection.hpp -index 62ccd89..646359e 100644 --- a/include/async_web_server_cpp/http_connection.hpp +++ b/include/async_web_server_cpp/http_connection.hpp -@@ -40,7 +40,7 @@ public: - ReadHandler; - typedef std::shared_ptr ResourcePtr; - -- explicit HttpConnection(boost::asio::io_service& io_service, -+ explicit HttpConnection(boost::asio::io_context& io_context, - HttpServerRequestHandler request_handler); - - boost::asio::ip::tcp::socket& socket(); @@ -79,7 +79,7 @@ private: void handle_write(const boost::system::error_code& e, std::vector resources); -- boost::asio::io_service::strand strand_; +- boost::asio::io_context::strand strand_; + boost::asio::strand strand_; boost::asio::ip::tcp::socket socket_; HttpServerRequestHandler request_handler_; boost::array buffer_; -diff --git a/include/async_web_server_cpp/http_server.hpp b/include/async_web_server_cpp/http_server.hpp -index f772f55..ee99c72 100644 ---- a/include/async_web_server_cpp/http_server.hpp -+++ b/include/async_web_server_cpp/http_server.hpp -@@ -40,7 +40,7 @@ private: - - void handle_accept(const boost::system::error_code& e); - -- boost::asio::io_service io_service_; -+ boost::asio::io_context io_context_; - boost::asio::ip::tcp::acceptor acceptor_; - std::size_t thread_pool_size_; - std::vector> threads_; diff --git a/src/http_connection.cpp b/src/http_connection.cpp -index bcb77d4..17a02ad 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp -@@ -6,9 +6,9 @@ - namespace async_web_server_cpp - { +@@ -8,7 +8,7 @@ namespace async_web_server_cpp --HttpConnection::HttpConnection(boost::asio::io_service& io_service, -+HttpConnection::HttpConnection(boost::asio::io_context& io_context, + HttpConnection::HttpConnection(boost::asio::io_context& io_service, HttpServerRequestHandler handler) - : strand_(io_service), socket_(io_service), request_handler_(handler), -+ : strand_(io_context.get_executor()), socket_(io_context), request_handler_(handler), ++ : strand_(io_service.get_executor()), socket_(io_service), request_handler_(handler), write_in_progress_(false) { } @@ -60,50 +33,11 @@ index bcb77d4..17a02ad 100644 callback, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); diff --git a/src/http_server.cpp b/src/http_server.cpp -index 2c1c4ea..502cf4b 100644 --- a/src/http_server.cpp +++ b/src/http_server.cpp -@@ -8,14 +8,12 @@ namespace async_web_server_cpp - HttpServer::HttpServer(const std::string& address, const std::string& port, - HttpServerRequestHandler request_handler, - std::size_t thread_pool_size) -- : acceptor_(io_service_), thread_pool_size_(thread_pool_size), -+ : acceptor_(io_context_), thread_pool_size_(thread_pool_size), - request_handler_(request_handler) - { +@@ -13,7 +13,7 @@ HttpServer::HttpServer(const std::string& address, const std::string& port, -- boost::asio::ip::tcp::resolver resolver(io_service_); -- boost::asio::ip::tcp::resolver::query query( -- address, port, boost::asio::ip::resolver_query_base::flags()); -- boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); -+ boost::asio::ip::tcp::resolver resolver(io_context_); + boost::asio::ip::tcp::resolver resolver(io_service_); +- boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(address, port).begin(); + boost::asio::ip::tcp::endpoint endpoint = resolver.resolve(address, port).begin()->endpoint(); acceptor_.open(endpoint.protocol()); - acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - acceptor_.bind(endpoint); -@@ -33,14 +31,14 @@ void HttpServer::run() - for (std::size_t i = 0; i < thread_pool_size_; ++i) - { - boost::shared_ptr thread(new boost::thread( -- boost::bind(&boost::asio::io_service::run, &io_service_))); -+ boost::bind(&boost::asio::io_context::run, &io_context_))); - threads_.push_back(thread); - } - } - - void HttpServer::start_accept() - { -- new_connection_.reset(new HttpConnection(io_service_, request_handler_)); -+ new_connection_.reset(new HttpConnection(io_context_, request_handler_)); - acceptor_.async_accept(new_connection_->socket(), - boost::bind(&HttpServer::handle_accept, this, - boost::asio::placeholders::error)); -@@ -62,7 +60,7 @@ void HttpServer::stop() - acceptor_.cancel(); - acceptor_.close(); - } -- io_service_.stop(); -+ io_context_.stop(); - // Wait for all threads in the pool to exit. - for (std::size_t i = 0; i < threads_.size(); ++i) - threads_[i]->join(); diff --git a/patch/ros-rolling-avt-vimba-camera.patch b/patch/ros-rolling-avt-vimba-camera.patch new file mode 100644 index 000000000..3cbac1dc6 --- /dev/null +++ b/patch/ros-rolling-avt-vimba-camera.patch @@ -0,0 +1,46 @@ +diff --git a/include/VimbaC/Include/VmbCommonTypes.h b/include/VimbaC/Include/VmbCommonTypes.h +index 0000000..0000000 100644 +--- a/include/VimbaC/Include/VmbCommonTypes.h ++++ b/include/VimbaC/Include/VmbCommonTypes.h +@@ -237,9 +237,9 @@ + VmbPixelFormatYuv411 = VmbPixelColor | VmbPixelOccupy12Bit | 0x001E, // YUV 411 with 8 bits (GEV:YUV411Packed) + VmbPixelFormatYuv422 = VmbPixelColor | VmbPixelOccupy16Bit | 0x001F, // YUV 422 with 8 bits (GEV:YUV422Packed) + VmbPixelFormatYuv444 = VmbPixelColor | VmbPixelOccupy24Bit | 0x0020, // YUV 444 with 8 bits (GEV:YUV444Packed) +- VmbPixelFormatYCbCr411_8_CbYYCrYY = VmbPixelColor | VmbPixelOccupy12Bit | 0x003C, // YCbCr 411 with 8 bits (PFNC:YCbCr411_8_CbYYCrYY) - identical to VmbPixelFormatYuv411 +- VmbPixelFormatYCbCr422_8_CbYCrY = VmbPixelColor | VmbPixelOccupy16Bit | 0x0043, // YCbCr 422 with 8 bits (PFNC:YCbCr422_8_CbYCrY) - identical to VmbPixelFormatYuv422 +- VmbPixelFormatYCbCr8_CbYCr = VmbPixelColor | VmbPixelOccupy24Bit | 0x003A, // YCbCr 444 with 8 bits (PFNC:YCbCr8_CbYCr) - identical to VmbPixelFormatYuv444 ++ VmbPixelFormatYCbCr411_8_CbYYCrYY = VmbPixelColor | VmbPixelOccupy12Bit | 0x003C, // Y'CbCr 411 with 8 bits (PFNC:YCbCr411_8_CbYYCrYY) - identical to VmbPixelFormatYuv411 ++ VmbPixelFormatYCbCr422_8_CbYCrY = VmbPixelColor | VmbPixelOccupy16Bit | 0x0043, // Y'CbCr 422 with 8 bits (PFNC:YCbCr422_8_CbYCrY) - identical to VmbPixelFormatYuv422 ++ VmbPixelFormatYCbCr8_CbYCr = VmbPixelColor | VmbPixelOccupy24Bit | 0x003A, // Y'CbCr 444 with 8 bits (PFNC:YCbCr8_CbYCr) - identical to VmbPixelFormatYuv444 + VmbPixelFormatLast, + } VmbPixelFormatType; + typedef VmbUint32_t VmbPixelFormat_t; // Type for the pixel format; for values see VmbPixelFormatType +diff --git a/src/mono_camera_node.cpp b/src/mono_camera_node.cpp +index 0000000..0000000 100644 +--- a/src/mono_camera_node.cpp ++++ b/src/mono_camera_node.cpp +@@ -37,7 +37,7 @@ + MonoCameraNode::MonoCameraNode() : Node("camera"), api_(this->get_logger()), cam_(std::shared_ptr(dynamic_cast(this))) + { + // Set the image publisher before streaming +- camera_info_pub_ = image_transport::create_camera_publisher(this, "~/image", rmw_qos_profile_system_default); ++ camera_info_pub_ = image_transport::create_camera_publisher(*this, "~/image", rclcpp::SystemDefaultsQoS()); + + // Set the frame callback + cam_.setCallback(std::bind(&avt_vimba_camera::MonoCameraNode::frameCallback, this, std::placeholders::_1)); +diff --git a/src/avt_vimba_camera.cpp b/src/avt_vimba_camera.cpp +index 0000000..0000000 100644 +--- a/src/avt_vimba_camera.cpp ++++ b/src/avt_vimba_camera.cpp +@@ -72,8 +72,9 @@ + return; + + frame_id_ = frame_id; +- info_man_ = std::shared_ptr( +- new camera_info_manager::CameraInfoManager(nh_.get(), frame_id, camera_info_url)); ++ info_man_ = std::make_shared( ++ nh_->get_node_base_interface(), nh_->get_node_services_interface(), ++ nh_->get_node_logging_interface(), frame_id, camera_info_url); + updater_.broadcast(0, "Starting device with IP:" + ip_str + " or GUID:" + guid_str); + + // Determine which camera to use. Try IP first diff --git a/patch/ros-rolling-cartographer-ros.patch b/patch/ros-rolling-cartographer-ros.patch index 27cb36826..d48e37b00 100644 --- a/patch/ros-rolling-cartographer-ros.patch +++ b/patch/ros-rolling-cartographer-ros.patch @@ -425,8 +425,21 @@ index eaa8422..1a37b59 100644 #include #include +diff --git a/src/node.cpp b/src/node.cpp +index 813ae4b..48ef1d5 100644 +--- a/src/node.cpp ++++ b/src/node.cpp +@@ -96,7 +96,7 @@ Node::Node( + : node_options_(node_options) + { + node_ = node; +- tf_broadcaster_ = std::make_shared(node_) ; ++ tf_broadcaster_ = std::make_shared(*node_) ; + map_builder_bridge_.reset(new cartographer_ros::MapBuilderBridge(node_options_, std::move(map_builder), tf_buffer.get())); + + absl::MutexLock lock(&mutex_); diff --git a/src/node_main.cpp b/src/node_main.cpp -index f403be0..bdf33b8 100644 +index f403be0..f1f074d 100644 --- a/src/node_main.cpp +++ b/src/node_main.cpp @@ -20,6 +20,7 @@ @@ -437,6 +450,15 @@ index f403be0..bdf33b8 100644 #include "tf2_ros/transform_listener.h" DEFINE_bool(collect_metrics, false, +@@ -55,7 +56,7 @@ void Run() { + std::make_shared( + cartographer_node->get_clock(), + tf2::durationFromSec(kTfBufferCacheTimeInSeconds), +- cartographer_node); ++ *cartographer_node); + + std::shared_ptr tf_listener = + std::make_shared(*tf_buffer); diff --git a/src/occupancy_grid_node_main.cpp b/src/occupancy_grid_node_main.cpp index 282b890..6139979 100644 --- a/src/occupancy_grid_node_main.cpp @@ -457,7 +479,7 @@ index 282b890..6139979 100644 std::string last_frame_id_; rclcpp::Time last_timestamp_; diff --git a/src/offline_node.cpp b/src/offline_node.cpp -index 94df3b0..4b3f60e 100644 +index 94df3b0..cd45ac0 100644 --- a/src/offline_node.cpp +++ b/src/offline_node.cpp @@ -31,7 +31,11 @@ @@ -472,6 +494,24 @@ index 94df3b0..4b3f60e 100644 #include "rclcpp/exceptions.hpp" #include #include +@@ -148,7 +152,7 @@ void RunOfflineNode(const MapBuilderFactory& map_builder_factory, + std::make_shared( + cartographer_offline_node->get_clock(), + tf2::durationFromSec(10), +- cartographer_offline_node); ++ *cartographer_offline_node); + + std::vector urdf_transforms; + +@@ -178,7 +182,7 @@ void RunOfflineNode(const MapBuilderFactory& map_builder_factory, + cartographer_offline_node->create_publisher( + kTfTopic, kLatestOnlyPublisherQueueSize); + +- ::tf2_ros::StaticTransformBroadcaster static_tf_broadcaster(cartographer_offline_node); ++ ::tf2_ros::StaticTransformBroadcaster static_tf_broadcaster(*cartographer_offline_node); + + rclcpp::Publisher::SharedPtr clock_publisher = + cartographer_offline_node->create_publisher( diff --git a/src/ros_log_sink.cpp b/src/ros_log_sink.cpp index 1396381..ba050f3 100644 --- a/src/ros_log_sink.cpp diff --git a/patch/ros-rolling-compressed-image-transport.patch b/patch/ros-rolling-compressed-image-transport.patch new file mode 100644 index 000000000..ee6e96cea --- /dev/null +++ b/patch/ros-rolling-compressed-image-transport.patch @@ -0,0 +1,38 @@ +diff -ruN a/src/compressed_subscriber.cpp b/src/compressed_subscriber.cpp +--- a/src/compressed_subscriber.cpp ++++ b/src/compressed_subscriber.cpp +@@ -140,28 +140,28 @@ + if (compressed_bgr_image) { + // if necessary convert colors from bgr to rgb + if ((image_encoding == enc::RGB8) || (image_encoding == enc::RGB16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2RGB); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_BGR2RGB); + } + + if ((image_encoding == enc::RGBA8) || (image_encoding == enc::RGBA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2RGBA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_BGR2RGBA); + } + + if ((image_encoding == enc::BGRA8) || (image_encoding == enc::BGRA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2BGRA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_BGR2BGRA); + } + } else { + // if necessary convert colors from rgb to bgr + if ((image_encoding == enc::BGR8) || (image_encoding == enc::BGR16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2BGR); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_RGB2BGR); + } + + if ((image_encoding == enc::BGRA8) || (image_encoding == enc::BGRA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2BGRA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_RGB2BGRA); + } + + if ((image_encoding == enc::RGBA8) || (image_encoding == enc::RGBA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2RGBA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_RGB2RGBA); + } + } + } diff --git a/patch/ros-rolling-cv-bridge.patch b/patch/ros-rolling-cv-bridge.patch new file mode 100644 index 000000000..87d014aa6 --- /dev/null +++ b/patch/ros-rolling-cv-bridge.patch @@ -0,0 +1,52 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -51,6 +51,15 @@ + CONFIG + ) + if(NOT OpenCV_FOUND) ++ find_package(OpenCV 5 QUIET ++ COMPONENTS ++ opencv_core ++ opencv_imgproc ++ opencv_imgcodecs ++ CONFIG ++ ) ++endif() ++if(NOT OpenCV_FOUND) + find_package(OpenCV 3 REQUIRED + COMPONENTS + opencv_core +diff -ruN a/include/cv_bridge/cv_bridge.hpp b/include/cv_bridge/cv_bridge.hpp +--- a/include/cv_bridge/cv_bridge.hpp ++++ b/include/cv_bridge/cv_bridge.hpp +@@ -42,7 +42,6 @@ + #include + #include + #include +-#include + #include + + #include +diff -ruN a/src/module_opencv4.cpp b/src/module_opencv4.cpp +--- a/src/module_opencv4.cpp ++++ b/src/module_opencv4.cpp +@@ -2,7 +2,6 @@ + + #include "module.hpp" + +-#include "opencv2/core/types_c.h" + + #include "opencv2/opencv_modules.hpp" + +@@ -99,8 +98,8 @@ + NumpyAllocator() {stdAllocator = Mat::getStdAllocator();} + ~NumpyAllocator() {} + +-// To compile openCV3 with OpenCV4 APIs. +-#ifndef OPENCV_VERSION_4 ++// To compile openCV3 with OpenCV4/5 APIs. ++#if CV_MAJOR_VERSION < 4 + #define AccessFlag int + #endif + diff --git a/patch/ros-rolling-depth-image-proc.patch b/patch/ros-rolling-depth-image-proc.patch index f692430a7..bd2aabda6 100644 --- a/patch/ros-rolling-depth-image-proc.patch +++ b/patch/ros-rolling-depth-image-proc.patch @@ -1,5 +1,5 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 5ed278fe..043f6526 100644 +index ea78923..a46f34d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,12 +13,7 @@ endif() @@ -16,3 +16,25 @@ index 5ed278fe..043f6526 100644 find_package(OpenCV REQUIRED) +diff --git a/src/crop_foremost.cpp b/src/crop_foremost.cpp +index 25eaea6..44037eb 100644 +--- a/src/crop_foremost.cpp ++++ b/src/crop_foremost.cpp +@@ -136,7 +136,7 @@ void CropForemostNode::depthCb(const sensor_msgs::msg::Image::ConstSharedPtr & r + case CV_8UC1: + case CV_8SC1: + case CV_32F: +- cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 0, CV_THRESH_TOZERO_INV); ++ cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 0, cv::THRESH_TOZERO_INV); + break; + case CV_16UC1: + case CV_16SC1: +@@ -144,7 +144,7 @@ void CropForemostNode::depthCb(const sensor_msgs::msg::Image::ConstSharedPtr & r + case CV_64F: + // 8 bit or 32 bit floating array is required to use cv::threshold + cv_ptr->image.convertTo(cv_ptr->image, CV_32F); +- cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 1, CV_THRESH_TOZERO_INV); ++ cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 1, cv::THRESH_TOZERO_INV); + + cv_ptr->image.convertTo(cv_ptr->image, imtype); + break; diff --git a/patch/ros-rolling-image-geometry.patch b/patch/ros-rolling-image-geometry.patch new file mode 100644 index 000000000..267b14f95 --- /dev/null +++ b/patch/ros-rolling-image-geometry.patch @@ -0,0 +1,33 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -15,7 +15,7 @@ + add_compile_options(-Wall -Wextra) + endif() + +-find_package(OpenCV REQUIRED COMPONENTS calib3d core highgui imgproc) ++find_package(OpenCV REQUIRED COMPONENTS calib core highgui imgproc) + find_package(sensor_msgs REQUIRED) + + add_library(${PROJECT_NAME} +@@ -26,7 +26,7 @@ + "$" + "$") + target_link_libraries(${PROJECT_NAME} PUBLIC +- opencv_calib3d ++ opencv_calib + opencv_core + opencv_highgui + opencv_imgproc +diff -ruN a/include/image_geometry/pinhole_camera_model.hpp b/include/image_geometry/pinhole_camera_model.hpp +--- a/include/image_geometry/pinhole_camera_model.hpp ++++ b/include/image_geometry/pinhole_camera_model.hpp +@@ -6,7 +6,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include diff --git a/patch/ros-rolling-image-proc.patch b/patch/ros-rolling-image-proc.patch new file mode 100644 index 000000000..46f64349a --- /dev/null +++ b/patch/ros-rolling-image-proc.patch @@ -0,0 +1,108 @@ +diff -ruN a/include/image_proc/track_marker.hpp b/include/image_proc/track_marker.hpp +--- a/include/image_proc/track_marker.hpp ++++ b/include/image_proc/track_marker.hpp +@@ -36,7 +36,11 @@ + + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#else + #include ++#endif + #include + #include + #include +@@ -60,6 +64,9 @@ + + cv::Ptr detector_params_; + cv::Ptr dictionary_; ++#if CV_VERSION_MAJOR >= 5 ++ cv::aruco::ArucoDetector detector_; ++#endif + + void imageCb( + const sensor_msgs::msg::Image::ConstSharedPtr & image_msg, +diff -ruN a/src/crop_non_zero.cpp b/src/crop_non_zero.cpp +--- a/src/crop_non_zero.cpp ++++ b/src/crop_non_zero.cpp +@@ -40,6 +40,9 @@ + + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + #include + #include + #include +@@ -112,7 +115,7 @@ + cv_ptr->image.convertTo(m, CV_8U, 255. / ra, -minVal * 255. / ra); + } + +- cv::findContours(m, cnt, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); ++ cv::findContours(m, cnt, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + + if (cnt.empty()) { + RCLCPP_WARN( +diff -ruN a/src/track_marker.cpp b/src/track_marker.cpp +--- a/src/track_marker.cpp ++++ b/src/track_marker.cpp +@@ -39,6 +39,9 @@ + #include + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + #include + #include + #include +@@ -75,6 +78,12 @@ + dictionary_ = cv::aruco::getPredefinedDictionary(dict_id); + #endif + ++ #if CV_VERSION_MAJOR >= 5 ++ // OpenCV 5 removed the free cv::aruco::detectMarkers() function in favor of ++ // the ArucoDetector class. ++ detector_ = cv::aruco::ArucoDetector(*dictionary_, *detector_params_); ++ #endif ++ + // Setup lazy subscriber using publisher connection callback + rclcpp::PublisherOptions pub_options; + pub_options.event_callbacks.matched_callback = +@@ -114,7 +123,11 @@ + + std::vector marker_ids; + std::vector> marker_corners; ++ #if CV_VERSION_MAJOR >= 5 ++ detector_.detectMarkers(cv_ptr->image, marker_corners, marker_ids); ++ #else + cv::aruco::detectMarkers(cv_ptr->image, dictionary_, marker_corners, marker_ids); ++ #endif + + for (size_t i = 0; i < marker_ids.size(); ++i) { + if (marker_ids[i] == marker_id_) { +@@ -131,9 +144,22 @@ + cv::Mat dist_coeffs(info_msg->d.size(), 1, CV_64FC1, reinterpret_cast(d.data())); + + // Estimate pose ++ #if CV_VERSION_MAJOR >= 5 ++ // OpenCV 5 removed cv::aruco::estimatePoseSingleMarkers(); solve for the ++ // marker pose directly against its known square corner geometry instead. ++ const std::vector obj_points{ ++ cv::Point3f(-marker_size_ / 2.f, marker_size_ / 2.f, 0), ++ cv::Point3f(marker_size_ / 2.f, marker_size_ / 2.f, 0), ++ cv::Point3f(marker_size_ / 2.f, -marker_size_ / 2.f, 0), ++ cv::Point3f(-marker_size_ / 2.f, -marker_size_ / 2.f, 0)}; ++ cv::Vec3d sp_rvec, sp_tvec; ++ cv::solvePnP(obj_points, corners[0], intrinsics, dist_coeffs, sp_rvec, sp_tvec); ++ std::vector rvecs{sp_rvec}, tvecs{sp_tvec}; ++ #else + std::vector rvecs, tvecs; + cv::aruco::estimatePoseSingleMarkers( + corners, marker_size_, intrinsics, dist_coeffs, rvecs, tvecs); ++ #endif + + // Publish pose of marker + geometry_msgs::msg::PoseStamped pose; diff --git a/patch/ros-rolling-image-rotate.patch b/patch/ros-rolling-image-rotate.patch new file mode 100644 index 000000000..bdc102c87 --- /dev/null +++ b/patch/ros-rolling-image-rotate.patch @@ -0,0 +1,34 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -14,9 +14,16 @@ + ament_auto_find_build_dependencies() + + find_package(OpenCV REQUIRED core imgproc) ++if(OpenCV_VERSION VERSION_LESS 5) ++ set(IMAGE_ROTATE_OPENCV_GEOMETRY) ++else() ++ # OpenCV 5 moved getRotationMatrix2D into the geometry module ++ find_package(OpenCV REQUIRED geometry) ++ set(IMAGE_ROTATE_OPENCV_GEOMETRY opencv_geometry) ++endif() + + ament_auto_add_library(${PROJECT_NAME} SHARED src/image_rotate_node.cpp) +-target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) ++target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES} ${IMAGE_ROTATE_OPENCV_GEOMETRY}) + rclcpp_components_register_nodes(${PROJECT_NAME} "${PROJECT_NAME}::ImageRotateNode") + set(node_plugins "${node_plugins}${PROJECT_NAME}::ImageRotateNode;$\n") + +diff -ruN a/src/image_rotate_node.cpp b/src/image_rotate_node.cpp +--- a/src/image_rotate_node.cpp ++++ b/src/image_rotate_node.cpp +@@ -54,6 +54,9 @@ + #include + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + + #include + #include diff --git a/patch/ros-rolling-imu-transformer.patch b/patch/ros-rolling-imu-transformer.patch new file mode 100644 index 000000000..3eda112d0 --- /dev/null +++ b/patch/ros-rolling-imu-transformer.patch @@ -0,0 +1,31 @@ +diff --git a/src/imu_transformer.cpp b/src/imu_transformer.cpp +index b1415ee..65cddfa 100644 +--- a/src/imu_transformer.cpp ++++ b/src/imu_transformer.cpp +@@ -13,9 +13,7 @@ namespace imu_transformer + tf2_buffer_ = std::make_unique(this->get_clock()); + // Create the timer interface before call to waitForTransform, + // to avoid a tf2_ros::CreateTimerInterfaceException exception +- auto timer_interface = std::make_shared( +- this->get_node_base_interface(), +- this->get_node_timers_interface()); ++ auto timer_interface = std::make_shared(*this); + tf2_buffer_->setCreateTimerInterface(timer_interface); + tf2_listener_ = std::make_unique(*tf2_buffer_); + +@@ -28,13 +26,13 @@ namespace imu_transformer + + std::chrono::duration buffer_timeout(1); + +- imu_filter_ = std::make_shared(imu_sub_, *tf2_buffer_, target_frame_, 10, this->get_node_logging_interface(), this->get_node_clock_interface(), buffer_timeout); ++ imu_filter_ = std::make_shared(imu_sub_, *tf2_buffer_, target_frame_, 10, *this, buffer_timeout); + imu_filter_->registerCallback(&ImuTransformer::imuCallback, this); + // function deactivated in foxy + //imu_filter_->registerFailureCallback&ImuTransformer::failureCb, this); + + mag_sub_.subscribe(this, "mag_in", 10); +- mag_filter_ = std::make_shared(mag_sub_, *tf2_buffer_, target_frame_, 10, this->get_node_logging_interface(), this->get_node_clock_interface(), buffer_timeout); ++ mag_filter_ = std::make_shared(mag_sub_, *tf2_buffer_, target_frame_, 10, *this, buffer_timeout); + mag_filter_->registerCallback(&ImuTransformer::magCallback, this); + // function deactivated in foxy + //mag_filter_->registerFailureCallback&ImuTransformer::failureCb, this); diff --git a/patch/ros-rolling-libg2o.patch b/patch/ros-rolling-libg2o.patch new file mode 100644 index 000000000..72a12db86 --- /dev/null +++ b/patch/ros-rolling-libg2o.patch @@ -0,0 +1,39 @@ +diff --git a/g2o/examples/sphere/create_sphere.cpp b/g2o/examples/sphere/create_sphere.cpp +index 7788dd9..45b0e92 100644 +--- a/g2o/examples/sphere/create_sphere.cpp ++++ b/g2o/examples/sphere/create_sphere.cpp +@@ -166,8 +166,8 @@ int main(int argc, char** argv) { + cerr << "using seeds:"; + for (size_t i = 0; i < seeds.size(); ++i) cerr << " " << seeds[i]; + cerr << endl; +- transSampler.seed(seeds[0]); +- rotSampler.seed(seeds[1]); ++ transSampler.seed(static_cast(seeds[0])); ++ rotSampler.seed(static_cast(seeds[1])); + } + + // noise for all the edges +diff --git a/g2o/solvers/csparse/CMakeLists.txt b/g2o/solvers/csparse/CMakeLists.txt +index 7d0e005..5b78e5a 100644 +--- a/g2o/solvers/csparse/CMakeLists.txt ++++ b/g2o/solvers/csparse/CMakeLists.txt +@@ -37,6 +37,7 @@ endif() + + target_include_directories(solver_csparse PUBLIC + $ ++ $ + $ + $) + target_compile_features(solver_csparse PUBLIC cxx_std_17) +diff --git a/g2o/stuff/misc.h b/g2o/stuff/misc.h +index 58a1afd..cd14ccc 100644 +--- a/g2o/stuff/misc.h ++++ b/g2o/stuff/misc.h +@@ -27,6 +27,7 @@ + #ifndef G2O_STUFF_MISC_H + #define G2O_STUFF_MISC_H + ++#include + #include + + /** @addtogroup utils **/ diff --git a/patch/ros-rolling-libmavconn.patch b/patch/ros-rolling-libmavconn.patch new file mode 100644 index 000000000..a4ef1c33d --- /dev/null +++ b/patch/ros-rolling-libmavconn.patch @@ -0,0 +1,50 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d349d81..607b852 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -15,8 +15,8 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # we dont use add_compile_options with pedantic in message packages + # because the Python C extensions dont comply with it + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcomment") + endif() +-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcomment") + + # Allow GNU extensions (-std=gnu++20) + set(CMAKE_C_EXTENSIONS ON) +diff --git a/include/mavconn/thread_utils.hpp b/include/mavconn/thread_utils.hpp +index d121768..654b8c9 100644 +--- a/include/mavconn/thread_utils.hpp ++++ b/include/mavconn/thread_utils.hpp +@@ -20,7 +20,9 @@ + #ifndef MAVCONN__THREAD_UTILS_HPP_ + #define MAVCONN__THREAD_UTILS_HPP_ + ++#ifndef _WIN32 + #include ++#endif + + #include + #include +@@ -74,14 +76,20 @@ std::string format(const std::string & fmt, Args... args) + template + bool set_this_thread_name(const std::string & name, Args && ... args) + { ++#ifdef _WIN32 ++ // No pthreads on Windows; naming the thread is a debugging convenience ++ // only, so silently no-op instead of failing to build. ++ (void)format(name, std::forward(args)...); ++ return false; ++#else + auto new_name = format(name, std::forward(args)...); +- + #ifdef __APPLE__ + return pthread_setname_np(new_name.c_str()) == 0; + #else + pthread_t pth = pthread_self(); + return pthread_setname_np(pth, new_name.c_str()) == 0; + #endif ++#endif + } + + /** diff --git a/patch/ros-rolling-libmavconn.win.patch b/patch/ros-rolling-libmavconn.win.patch new file mode 100644 index 000000000..52fa8a383 --- /dev/null +++ b/patch/ros-rolling-libmavconn.win.patch @@ -0,0 +1,13 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d349d81f..ac383dae 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,8 @@ + cmake_minimum_required(VERSION 3.10) + project(libmavconn) + ++set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) ++ + # Default to C11 + if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 11) diff --git a/patch/ros-rolling-lttngpy.patch b/patch/ros-rolling-lttngpy.patch new file mode 100644 index 000000000..75f70fb3f --- /dev/null +++ b/patch/ros-rolling-lttngpy.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f430f9d1..fcebc62e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -20,7 +20,11 @@ find_package(ament_cmake REQUIRED) + if(WIN32 OR APPLE OR ANDROID OR BSD) + set(DISABLED_DEFAULT ON) + else() +- set(DISABLED_DEFAULT OFF) ++ # conda-forge doesn't package liblttng-ctl (only lttng-ust), so disable ++ # lttng support unconditionally rather than just on ++ # WIN32/APPLE/ANDROID/BSD -- see RoboStack/ros-jazzy's own lttngpy patch ++ # for the same fix. ++ set(DISABLED_DEFAULT ON) + endif() + option( + LTTNGPY_DISABLED diff --git a/patch/ros-rolling-mavlink.osx.patch b/patch/ros-rolling-mavlink.osx.patch new file mode 100644 index 000000000..c41582e33 --- /dev/null +++ b/patch/ros-rolling-mavlink.osx.patch @@ -0,0 +1,20 @@ +diff --git a/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp b/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp +index a3956aa2..2abe2a5e 100644 +--- a/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp ++++ b/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp +@@ -4,7 +4,14 @@ + #include + #ifdef FREEBSD + #include +-#elif __APPLE__ ++#elif defined(__APPLE__) ++#include ++#define htole16(x) OSSwapHostToLittleInt16(x) ++#define htole32(x) OSSwapHostToLittleInt32(x) ++#define htole64(x) OSSwapHostToLittleInt64(x) ++#define le16toh(x) OSSwapLittleToHostInt16(x) ++#define le32toh(x) OSSwapLittleToHostInt32(x) ++#define le64toh(x) OSSwapLittleToHostInt64(x) + #include + #else + #include diff --git a/patch/ros-rolling-mavlink.patch b/patch/ros-rolling-mavlink.patch new file mode 100644 index 000000000..1b8be8ca9 --- /dev/null +++ b/patch/ros-rolling-mavlink.patch @@ -0,0 +1,77 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 30c9811..abea531 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -77,7 +77,7 @@ macro(generateMavlink_v10 definitions) + message(STATUS "processing v1.0: ${definitionAbsPath}") + add_custom_command( + OUTPUT include/v1.0/${definition}/${definition}.h +- COMMAND /usr/bin/env PYTHONPATH="${CMAKE_SOURCE_DIR}:$ENV{PYTHONPATH}" ++ COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH="${CMAKE_SOURCE_DIR}:$ENV{PYTHONPATH}" + ${Python_EXECUTABLE} ${mavgen_path} --lang=C --wire-protocol=1.0 + --output=include/v1.0 ${definitionAbsPath} + DEPENDS ${definitionAbsPath} ${common_xml_path} ${mavgen_path} +@@ -96,10 +96,10 @@ macro(generateMavlink_v20 definitions) + add_custom_command( + OUTPUT ${definition}-v2.0-cxx-stamp + #OUTPUT include/v2.0/${definition}/${definition}.hpp +- COMMAND /usr/bin/env PYTHONPATH="${CMAKE_SOURCE_DIR}:$ENV{PYTHONPATH}" ++ COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH="${CMAKE_SOURCE_DIR}:$ENV{PYTHONPATH}" + ${Python_EXECUTABLE} ${mavgen_path} --lang=C++11 --wire-protocol=2.0 + --output=include/v2.0 ${definitionAbsPath} +- COMMAND touch ${definition}-v2.0-cxx-stamp ++ COMMAND ${CMAKE_COMMAND} -E touch ${definition}-v2.0-cxx-stamp + DEPENDS ${definitionAbsPath} ${common_xml_path} ${mavgen_path} + ) + add_custom_target(${definition}.xml-v2.0 +diff --git a/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp b/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp +index a3956aa..91ce908 100644 +--- a/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp ++++ b/pymavlink/generator/CPP11/include_v2.0/msgmap.hpp +@@ -6,6 +6,19 @@ + #include + #elif __APPLE__ + #include ++#elif defined(_WIN32) ++// Windows has no , and every Windows target (x86, x64, ARM64) is ++// little-endian, so the little-endian <-> host conversions are no-ops. ++#include ++inline uint16_t htole16(uint16_t x) { return x; } ++inline uint32_t htole32(uint32_t x) { return x; } ++inline uint64_t htole64(uint64_t x) { return x; } ++inline uint16_t le16toh(uint16_t x) { return x; } ++inline uint32_t le32toh(uint32_t x) { return x; } ++inline uint64_t le64toh(uint64_t x) { return x; } ++// Also no POSIX ssize_t on MSVC. ++#include ++typedef ptrdiff_t ssize_t; + #else + #include + #endif +diff --git a/pymavlink/generator/CPP11/include_v2.0/message.hpp b/pymavlink/generator/CPP11/include_v2.0/message.hpp +index 4d6d424..c095ee7 100644 +--- a/pymavlink/generator/CPP11/include_v2.0/message.hpp ++++ b/pymavlink/generator/CPP11/include_v2.0/message.hpp +@@ -1,6 +1,22 @@ + + #pragma once + ++#ifdef _WIN32 ++// windows.h (pulled in transitively by asio/winsock on Windows) #defines ++// several plain object-like macros (ERROR from wingdi.h, NO_ERROR from ++// winerror.h, ...) that collide with enumerator names used throughout the ++// generated dialect headers (e.g. UAVCAN_NODE_HEALTH::ERROR, ++// MAV_PARAM_ERROR::NO_ERROR in common.hpp) -- the preprocessor rewrites ++// them before the compiler ever sees an enum. Undefine them here, before ++// any generated header's enums are parsed. ++#ifdef ERROR ++#undef ERROR ++#endif ++#ifdef NO_ERROR ++#undef NO_ERROR ++#endif ++#endif ++ + #include + #include + #include diff --git a/patch/ros-rolling-mavros-extras.patch b/patch/ros-rolling-mavros-extras.patch new file mode 100644 index 000000000..61c8fc91c --- /dev/null +++ b/patch/ros-rolling-mavros-extras.patch @@ -0,0 +1,29 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 8832292..dbee63e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -10,11 +10,15 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # we dont use add_compile_options with pedantic in message packages + # because the Python C extensions dont comply with it + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcomment") + endif() +-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcomment") + + # Allow GNU extensions (-std=gnu++20) + set(CMAKE_C_EXTENSIONS ON) + set(CMAKE_CXX_EXTENSIONS ON) + ++if(MSVC) ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + find_package(ament_cmake REQUIRED) +@@ -168,6 +172,7 @@ target_link_libraries(mavros_extras_plugins PUBLIC + tf2_ros::static_transform_broadcaster_node + tf2_ros::tf2_ros + ${mavros_LIBRARIES} ++ ${GeographicLib_LIBRARIES} + ) + pluginlib_export_plugin_description_file(mavros mavros_plugins.xml) + diff --git a/patch/ros-rolling-mavros.patch b/patch/ros-rolling-mavros.patch new file mode 100644 index 000000000..f7e811c73 --- /dev/null +++ b/patch/ros-rolling-mavros.patch @@ -0,0 +1,193 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 8e69fa09..24148d30 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -10,13 +10,17 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # we dont use add_compile_options with pedantic in message packages + # because the Python C extensions dont comply with it + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcomment") + endif() +-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcomment") + + # Allow GNU extensions (-std=gnu++20) + set(CMAKE_C_EXTENSIONS ON) + set(CMAKE_CXX_EXTENSIONS ON) + ++if(MSVC) ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + find_package(ament_cmake REQUIRED) + find_package(ament_cmake_python REQUIRED) + +@@ -125,6 +129,14 @@ add_library(mavros SHARED + src/lib/uas_timesync.cpp + # [[[end]]] (sum: MjnRb8h5gp) + ) ++# mavros_plugins (below) has far too many symbols for MSVC's linker to ++# auto-export all of them (LNK1189: library limit of 65535 objects ++# exceeded) -- it's loaded dynamically via pluginlib/class_loader and ++# never linked against directly, so it doesn't need an import library at ++# all. Only the core mavros library (linked by mavros_node and the unit ++# tests below) needs WINDOWS_EXPORT_ALL_SYMBOLS. ++set_target_properties(mavros PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++target_compile_definitions(mavros PRIVATE MAVROS_BUILDING_DLL) + target_link_libraries(mavros PUBLIC + ${mavros_msgs_TARGETS} + ${sensor_msgs_TARGETS} + +diff --git a/include/mavros/utils.hpp b/include/mavros/utils.hpp +index 1f3dc092..bef93350 100644 +--- a/include/mavros/utils.hpp ++++ b/include/mavros/utils.hpp +@@ -27,14 +27,24 @@ + #include "mavros_msgs/mavlink_convert.hpp" + #include "mavconn/mavlink_dialect.hpp" + +-// OS X compat: missing error codes +-#ifdef __APPLE__ ++// OS X / Windows compat: missing error codes (Linux-specific errno values ++// used by the FTP plugin's MAVLink-FTP error mapping) ++#if defined(__APPLE__) || defined(_WIN32) + #define EBADE 50 /* Invalid exchange */ + #define EBADFD 81 /* File descriptor in bad state */ + #define EBADRQC 54 /* Invalid request code */ + #define EBADSLT 55 /* Invalid slot */ + #endif + ++// Windows SDK headers define PASSTHROUGH as a numeric macro (used by some ++// print-related APIs), which corrupts the timesync_mode enum below if not ++// undefined first. ++#ifdef _WIN32 ++#ifdef PASSTHROUGH ++#undef PASSTHROUGH ++#endif ++#endif ++ + namespace mavros + { + namespace utils + +diff --git a/include/mavros/mavros_uas.hpp b/include/mavros/mavros_uas.hpp +index c1d10b1e..15d50971 100644 +--- a/include/mavros/mavros_uas.hpp ++++ b/include/mavros/mavros_uas.hpp +@@ -53,6 +53,20 @@ + #include "mavros/frame_tf.hpp" + #include "mavros/uas_executor.hpp" + ++// egm96_5 is a static data member shared across the mavros DLL boundary ++// (defined in uas_data.cpp, used by mavros_plugins) -- MSVC's ++// WINDOWS_EXPORT_ALL_SYMBOLS only auto-exports functions, not data, so ++// this needs an explicit dllexport/dllimport toggle on Windows. ++#ifdef _WIN32 ++#ifdef MAVROS_BUILDING_DLL ++#define MAVROS_UAS_DATA_EXPORT __declspec(dllexport) ++#else ++#define MAVROS_UAS_DATA_EXPORT __declspec(dllimport) ++#endif ++#else ++#define MAVROS_UAS_DATA_EXPORT ++#endif ++ + namespace mavros + { + namespace uas +@@ -158,7 +172,7 @@ public: + * + * That class loads egm96_5 dataset to RAM, it is about 24 MiB. + */ +- static std::shared_ptr egm96_5; ++ static MAVROS_UAS_DATA_EXPORT std::shared_ptr egm96_5; + + /** + * @brief Conversion from height above geoid (AMSL) + +diff --git a/src/lib/mavros_uas.cpp b/src/lib/mavros_uas.cpp +index 9a00f720..b6005641 100644 +--- a/src/lib/mavros_uas.cpp ++++ b/src/lib/mavros_uas.cpp +@@ -11,7 +11,52 @@ + * @author Vladimir Ermakov + */ + ++#ifdef _WIN32 ++// Windows has no ; provide a minimal case-insensitive glob ++// matcher supporting '*' and '?', sufficient for the plugin ++// blacklist/whitelist patterns matched below. ++#include ++#define FNM_NOMATCH 1 ++#define FNM_CASEFOLD 0 ++static int fnmatch(const char * pattern, const char * str, int) ++{ ++ while (*pattern) { ++ if (*pattern == '*') { ++ while (*pattern == '*') { ++ ++pattern; ++ } ++ if (!*pattern) { ++ return 0; ++ } ++ while (*str) { ++ if (fnmatch(pattern, str, 0) == 0) { ++ return 0; ++ } ++ ++str; ++ } ++ return FNM_NOMATCH; ++ } else if (*pattern == '?') { ++ if (!*str) { ++ return FNM_NOMATCH; ++ } ++ ++pattern; ++ ++str; ++ } else { ++ if (!*str || ++ std::tolower(static_cast(*pattern)) != ++ std::tolower(static_cast(*str))) ++ { ++ return FNM_NOMATCH; ++ } ++ ++pattern; ++ ++str; ++ } ++ } ++ return *str ? FNM_NOMATCH : 0; ++} ++#else + #include ++#endif + #include + #include + #include + +diff --git a/src/plugins/sys_time.cpp b/src/plugins/sys_time.cpp +index 42bd903e..7a015e5e 100644 +--- a/src/plugins/sys_time.cpp ++++ b/src/plugins/sys_time.cpp +@@ -14,6 +14,7 @@ + * https://github.com/mavlink/mavros/tree/master/LICENSE.md + */ + ++#include + #include + #include + +@@ -546,10 +547,11 @@ private: + + uint64_t get_monotonic_now(void) + { +- struct timespec spec; +- clock_gettime(CLOCK_MONOTONIC, &spec); +- +- return spec.tv_sec * 1000000000ULL + spec.tv_nsec; ++ // std::chrono::steady_clock is a portable monotonic clock available on ++ // all platforms, unlike POSIX clock_gettime()/CLOCK_MONOTONIC (not ++ // available on Windows). ++ auto now = std::chrono::steady_clock::now().time_since_epoch(); ++ return std::chrono::duration_cast(now).count(); + } + }; + + diff --git a/patch/ros-rolling-microstrain-inertial-driver.patch b/patch/ros-rolling-microstrain-inertial-driver.patch new file mode 100644 index 000000000..cb5214c3c --- /dev/null +++ b/patch/ros-rolling-microstrain-inertial-driver.patch @@ -0,0 +1,162 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 35e036fa..db513f68 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,14 @@ + cmake_minimum_required(VERSION 3.5) + project(microstrain_inertial_driver) + ++# Windows headers pulled in transitively by the MIP SDK's serial-port code ++# define min/max as function-like macros unless NOMINMAX is set first, ++# which corrupts any std::chrono::duration::max()/min() call downstream ++# (rcpputils/time.hpp, included via rclcpp) with cryptic syntax errors. ++if(WIN32) ++ add_compile_definitions(NOMINMAX) ++endif() ++ + # C++ 14 required + set(CMAKE_CXX_STANDARD 14) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +@@ -187,6 +195,14 @@ set(COMMON_INC_FILES + ) + set(COMMON_FILES ${COMMON_SRC_FILES} ${COMMON_INC_FILES}) + ++# ament_target_dependencies() was removed from ament_cmake_target_dependencies; ++# link against each dependency's exported _TARGETS instead. ++macro(link_ament_dependencies target) ++ foreach(_ament_dep ${ARGN}) ++ target_link_libraries(${target} ${${_ament_dep}_TARGETS}) ++ endforeach() ++endmacro() ++ + set(AMENT_COMMON_DEPENDENCIES + rclcpp + rclcpp_lifecycle +@@ -215,9 +231,7 @@ set(NODE_INC_FILES + ) + set(NODE_FILES ${NODE_SRC_FILES} ${NODE_INC_FILES}) + add_executable(${NODE_NAME} ${NODE_FILES} ${COMMON_FILES}) +-ament_target_dependencies(${NODE_NAME} +- ${AMENT_COMMON_DEPENDENCIES} +-) ++link_ament_dependencies(${NODE_NAME} ${AMENT_COMMON_DEPENDENCIES}) + + # Lifecycle node + set(LIFECYCLE_NAME ${PROJECT_NAME}_lifecycle_node) +@@ -231,12 +245,13 @@ set(LIFECYCLE_INC_FILES + set(LIFECYCLE_FILES ${LIFECYCLE_SRC_FILES} ${LIFECYCLE_INC_FILES}) + add_executable(${LIFECYCLE_NAME} ${LIFECYCLE_FILES} ${COMMON_FILES}) + target_compile_definitions(${LIFECYCLE_NAME} PUBLIC MICROSTRAIN_LIFECYCLE) +-ament_target_dependencies(${LIFECYCLE_NAME} +- ${AMENT_COMMON_DEPENDENCIES} +-) ++link_ament_dependencies(${LIFECYCLE_NAME} ${AMENT_COMMON_DEPENDENCIES}) + + # Annoying, but the ROS types don't match up with the MIP types for floats and doubles, so ignore those warnings for now +-set_source_files_properties(${COMMON_SRC_DIR}/services.cpp PROPERTIES COMPILE_OPTIONS "-Wno-narrowing") ++# (GCC/Clang-only flag; MSVC doesn't error on narrowing conversions by default anyway) ++if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") ++ set_source_files_properties(${COMMON_SRC_DIR}/services.cpp PROPERTIES COMPILE_OPTIONS "-Wno-narrowing") ++endif() + + # Tell the code the version of the driver that is being build + add_definitions(-DMICROSTRAIN_DRIVER_VERSION="${DRIVER_GIT_VERSION}") + +diff --git a/microstrain_inertial_driver_common/include/microstrain_inertial_driver_common/utils/ros_compat.h b/microstrain_inertial_driver_common/include/microstrain_inertial_driver_common/utils/ros_compat.h +index f1fe0879..5b866134 100644 +--- a/microstrain_inertial_driver_common/include/microstrain_inertial_driver_common/utils/ros_compat.h ++++ b/microstrain_inertial_driver_common/include/microstrain_inertial_driver_common/utils/ros_compat.h +@@ -779,7 +779,7 @@ inline TransformListenerType createTransformListener(TransformBufferType buffer) + */ + inline StaticTransformBroadcasterType createStaticTransformBroadcaster(RosNodeType* node) + { +- return std::make_shared(node); ++ return std::make_shared(*node); + } + + /** +@@ -789,7 +789,7 @@ inline StaticTransformBroadcasterType createStaticTransformBroadcaster(RosNodeTy + */ + inline TransformBroadcasterType createTransformBroadcaster(RosNodeType* node) + { +- return std::make_shared(node); ++ return std::make_shared(*node); + } + + /** +diff --git a/src/microstrain_inertial_driver.cpp b/src/microstrain_inertial_driver.cpp +index e679866b..eaea4f15 100644 +--- a/src/microstrain_inertial_driver.cpp ++++ b/src/microstrain_inertial_driver.cpp +@@ -18,7 +18,7 @@ + #include + #include + +-#include ++#include + + #include "lifecycle_msgs/msg/transition.hpp" + +diff --git a/src/microstrain_inertial_driver_lifecycle.cpp b/src/microstrain_inertial_driver_lifecycle.cpp +index 1e2a6757..f77bb1d9 100644 +--- a/src/microstrain_inertial_driver_lifecycle.cpp ++++ b/src/microstrain_inertial_driver_lifecycle.cpp +@@ -18,7 +18,7 @@ + #include + #include + +-#include ++#include + + #include "lifecycle_msgs/msg/transition.hpp" + +diff --git a/include/microstrain_inertial_driver/microstrain_inertial_driver.h b/include/microstrain_inertial_driver/microstrain_inertial_driver.h +index 8e9c2f0e..63edec08 100644 +--- a/include/microstrain_inertial_driver/microstrain_inertial_driver.h ++++ b/include/microstrain_inertial_driver/microstrain_inertial_driver.h +@@ -14,7 +14,9 @@ + #define _MICROSTRAIN_INERTIAL_DRIVER_MICROSTRAIN_INERTIAL_DRIVER_H + + #include ++#ifndef _WIN32 + #include ++#endif + #include + #include + #include + +diff --git a/include/microstrain_inertial_driver/microstrain_inertial_driver_lifecycle.h b/include/microstrain_inertial_driver/microstrain_inertial_driver_lifecycle.h +index c8ef84e9..931163c2 100644 +--- a/include/microstrain_inertial_driver/microstrain_inertial_driver_lifecycle.h ++++ b/include/microstrain_inertial_driver/microstrain_inertial_driver_lifecycle.h +@@ -14,7 +14,9 @@ + #define _MICROSTRAIN_INERTIAL_DRIVER_MICROSTRAIN_INERTIAL_DRIVER_LIFECYCLE_H + + #include ++#ifndef _WIN32 + #include ++#endif + #include + #include + #include + +diff --git a/microstrain_inertial_driver_common/src/utils/mip/ros_connection.cpp b/microstrain_inertial_driver_common/src/utils/mip/ros_connection.cpp +index e2eae441..826b8c24 100644 +--- a/microstrain_inertial_driver_common/src/utils/mip/ros_connection.cpp ++++ b/microstrain_inertial_driver_common/src/utils/mip/ros_connection.cpp +@@ -10,6 +10,14 @@ + + #include + ++#ifdef _WIN32 ++// POSIX localtime_r() has no Windows equivalent; localtime_s() is the ++// closest match, but takes its arguments in the opposite order (struct tm* ++// destination first, time_t* source second) and returns errno_t instead of ++// struct tm*, which the single call site below doesn't check anyway. ++#define localtime_r(timep, result) localtime_s(result, timep) ++#endif ++ + #include + #include + #include + diff --git a/patch/ros-rolling-mocap4r2-control.patch b/patch/ros-rolling-mocap4r2-control.patch index 4f32c987d..d9d16c849 100644 --- a/patch/ros-rolling-mocap4r2-control.patch +++ b/patch/ros-rolling-mocap4r2-control.patch @@ -1,5 +1,5 @@ diff --git a/mocap4r2_control/mocap4r2_control/CMakeLists.txt b/mocap4r2_control/mocap4r2_control/CMakeLists.txt -index 394d5e5..180975b 100644 +index 394d5e56..77b13d01 100644 --- a/mocap4r2_control/mocap4r2_control/CMakeLists.txt +++ b/mocap4r2_control/mocap4r2_control/CMakeLists.txt @@ -27,6 +27,12 @@ set(dependencies @@ -15,11 +15,16 @@ index 394d5e5..180975b 100644 include_directories(include) add_library(${PROJECT_NAME} SHARED -@@ -34,10 +40,10 @@ add_library(${PROJECT_NAME} SHARED +@@ -34,10 +40,15 @@ add_library(${PROJECT_NAME} SHARED src/mocap4r2_control/ControllerNode.cpp src/mocap4r2_control/AuxiliarNode.cpp ) -ament_target_dependencies(${PROJECT_NAME} ${dependencies}) ++# auxiliar_main (below) links against this library directly, so it needs ++# an import .lib on Windows -- this SHARED library has no ++# dllexport-annotated symbols, so without this MSVC produces the .dll but ++# no .lib (LNK1181: cannot open input file). ++set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) +target_link_libraries(${PROJECT_NAME} ${target_dependencies}) add_executable(auxiliar_main src/auxiliar_main.cpp) @@ -28,3 +33,4 @@ index 394d5e5..180975b 100644 target_link_libraries(auxiliar_main ${PROJECT_NAME}) install(DIRECTORY include/ + diff --git a/patch/ros-rolling-mocap4r2-dummy-driver.patch b/patch/ros-rolling-mocap4r2-dummy-driver.patch index a25f033c7..9c9adf1af 100644 --- a/patch/ros-rolling-mocap4r2-dummy-driver.patch +++ b/patch/ros-rolling-mocap4r2-dummy-driver.patch @@ -1,8 +1,8 @@ diff --git a/mocap4r2_dummy_driver/CMakeLists.txt b/mocap4r2_dummy_driver/CMakeLists.txt -index 8e8a863..b1569d7 100644 +index 8e8a8635..f48c10b2 100644 --- a/mocap4r2_dummy_driver/CMakeLists.txt +++ b/mocap4r2_dummy_driver/CMakeLists.txt -@@ -24,18 +24,25 @@ set(dependencies +@@ -24,18 +24,29 @@ set(dependencies mocap4r2_control ) @@ -20,6 +20,10 @@ index 8e8a863..b1569d7 100644 add_library(${PROJECT_NAME} src/mocap4r2_dummy_driver/mocap4r2_dummy_driver.cpp) -ament_target_dependencies(${PROJECT_NAME} ${dependencies}) ++# mocap4r2_dummy_driver_main (below) links against this library directly, ++# so it needs an import .lib on Windows -- same missing-dllexport-symbols ++# issue already fixed for mocap4r2_control. ++set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) +target_link_libraries(${PROJECT_NAME} ${target_dependencies}) add_executable(mocap4r2_dummy_driver_main @@ -30,3 +34,4 @@ index 8e8a863..b1569d7 100644 target_link_libraries(mocap4r2_dummy_driver_main ${PROJECT_NAME}) install(DIRECTORY + diff --git a/patch/ros-rolling-mocap4r2-marker-viz.patch b/patch/ros-rolling-mocap4r2-marker-viz.patch index 169d2a000..5aa073728 100644 --- a/patch/ros-rolling-mocap4r2-marker-viz.patch +++ b/patch/ros-rolling-mocap4r2-marker-viz.patch @@ -1,8 +1,18 @@ diff --git a/mocap4r2_marker_viz/mocap4r2_marker_viz/CMakeLists.txt b/mocap4r2_marker_viz/mocap4r2_marker_viz/CMakeLists.txt -index ce11de5..2ad03ac 100644 +index ce11de53..03b817f4 100644 --- a/mocap4r2_marker_viz/mocap4r2_marker_viz/CMakeLists.txt +++ b/mocap4r2_marker_viz/mocap4r2_marker_viz/CMakeLists.txt -@@ -34,7 +34,13 @@ target_include_directories(${PROJECT_NAME}_NODE +@@ -28,13 +28,23 @@ find_package(geometry_msgs REQUIRED) + add_executable(mocap4r2_marker_viz src/mocap4r2_marker_viz_main.cpp) + + add_library(${PROJECT_NAME}_NODE src/mocap4r2_marker_viz_node.cpp) ++# mocap4r2_marker_viz (below) links against this library directly, so it ++# needs an import .lib on Windows -- same missing-dllexport-symbols issue ++# already fixed for mocap4r2_control/mocap4r2_dummy_driver. ++set_target_properties(${PROJECT_NAME}_NODE PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + + target_include_directories(${PROJECT_NAME}_NODE + PUBLIC $ $) @@ -17,3 +27,4 @@ index ce11de5..2ad03ac 100644 target_link_libraries(mocap4r2_marker_viz ${PROJECT_NAME}_NODE) + diff --git a/patch/ros-rolling-mocap4r2-robot-gt.patch b/patch/ros-rolling-mocap4r2-robot-gt.patch index 3671948a8..96dcb5a73 100644 --- a/patch/ros-rolling-mocap4r2-robot-gt.patch +++ b/patch/ros-rolling-mocap4r2-robot-gt.patch @@ -1,5 +1,5 @@ diff --git a/mocap4r2_robot_gt/mocap4r2_robot_gt/CMakeLists.txt b/mocap4r2_robot_gt/mocap4r2_robot_gt/CMakeLists.txt -index 7c14e7e..8365d74 100644 +index 7c14e7e4..8e097dba 100644 --- a/mocap4r2_robot_gt/mocap4r2_robot_gt/CMakeLists.txt +++ b/mocap4r2_robot_gt/mocap4r2_robot_gt/CMakeLists.txt @@ -16,13 +16,13 @@ find_package(geometry_msgs REQUIRED) @@ -23,11 +23,15 @@ index 7c14e7e..8365d74 100644 ) include_directories( -@@ -30,19 +30,19 @@ include_directories( +@@ -30,19 +30,26 @@ include_directories( ) add_library(gt_component SHARED src/mocap4r2_robot_gt/gt_component.cpp) -ament_target_dependencies(gt_component ${dependencies}) ++# gt_program (below) links against this library directly, so it needs an ++# import .lib on Windows -- same missing-dllexport-symbols issue already ++# fixed for mocap4r2_control/mocap4r2_dummy_driver/mocap4r2_marker_viz. ++set_target_properties(gt_component PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) +target_link_libraries(gt_component ${dependencies}) rclcpp_components_register_nodes(gt_component "mocap4r2_robot_gt::GTNode") @@ -38,6 +42,9 @@ index 7c14e7e..8365d74 100644 add_library(set_gt_component SHARED src/mocap4r2_robot_gt/set_gt_component.cpp) -ament_target_dependencies(set_gt_component ${dependencies}) ++# set_gt_cli (below) links against this library directly, so it needs the ++# same import-library fix. ++set_target_properties(set_gt_component PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) +target_link_libraries(set_gt_component ${dependencies}) rclcpp_components_register_nodes(set_gt_component "mocap4r2_robot_gt::SetGTNode") @@ -47,3 +54,4 @@ index 7c14e7e..8365d74 100644 target_link_libraries(set_gt_cli set_gt_component) install(TARGETS + diff --git a/patch/ros-rolling-motion-capture-tracking.patch b/patch/ros-rolling-motion-capture-tracking.patch new file mode 100644 index 000000000..b69fc0927 --- /dev/null +++ b/patch/ros-rolling-motion-capture-tracking.patch @@ -0,0 +1,117 @@ +diff --git a/src/motion_capture_tracking_node.cpp b/src/motion_capture_tracking_node.cpp +index ace9626..5d99a63 100644 +--- a/src/motion_capture_tracking_node.cpp ++++ b/src/motion_capture_tracking_node.cpp +@@ -199,7 +199,7 @@ int main(int argc, char **argv) + tracker.setLogWarningCallback(std::bind(logWarn, node->get_logger(), std::placeholders::_1)); + + // prepare TF broadcaster +- tf2_ros::TransformBroadcaster tfbroadcaster(node); ++ tf2_ros::TransformBroadcaster tfbroadcaster(*node); + std::vector transforms; + + pcl::PointCloud::Ptr markers(new pcl::PointCloud); +diff --git a/deps/libmotioncapture/deps/vrpn/quat/CMakeLists.txt b/deps/libmotioncapture/deps/vrpn/quat/CMakeLists.txt +index e6009d9d..037befcc 100644 +--- a/deps/libmotioncapture/deps/vrpn/quat/CMakeLists.txt ++++ b/deps/libmotioncapture/deps/vrpn/quat/CMakeLists.txt +@@ -13,6 +13,11 @@ set(QUATLIB_HEADER quat.h) + + # Build the library itself and declare what bits need to be installed + add_library(quat ${QUATLIB_SOURCES} ${QUATLIB_HEADER}) ++# vrpn (the sibling library one level up) links against this library ++# directly, so it needs an import .lib on Windows -- this SHARED library ++# has no dllexport-annotated symbols, so without this MSVC produces the ++# .dll but no .lib (LNK1181: cannot open input file). ++set_target_properties(quat PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + if(UNIX) + target_link_libraries(quat -lm) + endif() + +diff --git a/deps/libmotioncapture/deps/vrpn/CMakeLists.txt b/deps/libmotioncapture/deps/vrpn/CMakeLists.txt +index 41ce8558..31f6d711 100644 +--- a/deps/libmotioncapture/deps/vrpn/CMakeLists.txt ++++ b/deps/libmotioncapture/deps/vrpn/CMakeLists.txt +@@ -1353,6 +1353,10 @@ endif() + + if(VRPN_BUILD_CLIENT_LIBRARY) + add_library(vrpn ${VRPN_CLIENT_SOURCES} ${VRPN_CLIENT_PUBLIC_HEADERS}) ++ # libmotioncapture (one level up) links against this library directly, ++ # so it needs an import .lib on Windows -- same missing-dllexport-symbols ++ # issue already fixed for the sibling quat library. ++ set_target_properties(vrpn PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + target_link_libraries(vrpn ${EXTRA_LIBS}) + set(VRPN_CLIENT_LIBRARY vrpn) + + +diff --git a/deps/libmotioncapture/CMakeLists.txt b/deps/libmotioncapture/CMakeLists.txt +index 61a4af9f..215732db 100644 +--- a/deps/libmotioncapture/CMakeLists.txt ++++ b/deps/libmotioncapture/CMakeLists.txt +@@ -19,7 +19,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + + find_package(Threads REQUIRED) +-find_package(Boost) # for optitrack ++find_package(Boost COMPONENTS filesystem) # filesystem needed for a transitive Windows link; also for optitrack + add_definitions( + -DBOOST_DATE_TIME_NO_LIB + -DBOOST_REGEX_NO_LIB +@@ -234,6 +234,10 @@ include_directories( + add_library(libmotioncapture + ${my_files} + ) ++# motion_capture_tracking_node (the top-level ROS node) links against this ++# library directly, so it needs an import .lib on Windows -- same ++# missing-dllexport-symbols issue already fixed for quat/vrpn. ++set_target_properties(libmotioncapture PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + + ## Specify libraries to link a library or executable target against + target_link_directories(libmotioncapture PUBLIC +@@ -243,6 +247,13 @@ target_link_libraries(libmotioncapture + Eigen3::Eigen + ${my_libraries} + ) ++# vicon-datastream-sdk's Boost::thread pulls in an unqualified ++# "boost_filesystem" reference on Windows that only resolves correctly ++# once Boost::filesystem's own imported target (with its library search ++# directory) is also linked here. ++if(Boost_FILESYSTEM_FOUND) ++ target_link_libraries(libmotioncapture Boost::filesystem) ++endif() + set_property(TARGET libmotioncapture PROPERTY POSITION_INDEPENDENT_CODE ON) + + if (LIBMOTIONCAPTURE_BUILD_PYTHON_BINDINGS) + +diff --git a/deps/librigidbodytracker/CMakeLists.txt b/deps/librigidbodytracker/CMakeLists.txt +index c23b4ee3..4a4b5981 100644 +--- a/deps/librigidbodytracker/CMakeLists.txt ++++ b/deps/librigidbodytracker/CMakeLists.txt +@@ -24,6 +24,10 @@ include_directories( + add_library(librigidbodytracker + src/rigid_body_tracker.cpp + ) ++# motion_capture_tracking_node (the top-level ROS node) links against this ++# library directly, so it needs an import .lib on Windows -- same ++# missing-dllexport-symbols issue already fixed for quat/vrpn/libmotioncapture. ++set_target_properties(librigidbodytracker PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + target_link_libraries(librigidbodytracker + ${PCL_LIBRARIES} + ) + +diff --git a/deps/libmotioncapture/deps/qualisys_cpp_sdk/CMakeLists.txt b/deps/libmotioncapture/deps/qualisys_cpp_sdk/CMakeLists.txt +index ea440917..97b65b28 100644 +--- a/deps/libmotioncapture/deps/qualisys_cpp_sdk/CMakeLists.txt ++++ b/deps/libmotioncapture/deps/qualisys_cpp_sdk/CMakeLists.txt +@@ -9,6 +9,10 @@ add_library(${PROJECT_NAME} + RTPacket.cpp + RTProtocol.cpp + ) ++# libmotioncapture (one level up) links against this library directly, so ++# it needs an import .lib on Windows -- same missing-dllexport-symbols ++# issue already fixed for quat/vrpn/libmotioncapture/librigidbodytracker. ++set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + diff --git a/patch/ros-rolling-moveit-hybrid-planning.patch b/patch/ros-rolling-moveit-hybrid-planning.patch new file mode 100644 index 000000000..d1b0818a5 --- /dev/null +++ b/patch/ros-rolling-moveit-hybrid-planning.patch @@ -0,0 +1,17 @@ +diff --git a/local_planner/local_planner_component/include/moveit/local_planner/feedback_types.hpp b/local_planner/local_planner_component/include/moveit/local_planner/feedback_types.hpp +index aa732a4b..5efec687 100644 +--- a/local_planner/local_planner_component/include/moveit/local_planner/feedback_types.hpp ++++ b/local_planner/local_planner_component/include/moveit/local_planner/feedback_types.hpp +@@ -63,7 +63,11 @@ enum LocalFeedbackEnum + case LOCAL_PLANNER_STUCK: + return "Local planner is stuck"; + default: ++#if defined(_MSC_VER) ++ __assume(0); ++#else + __builtin_unreachable(); ++#endif + } + } + } // namespace moveit::hybrid_planning + diff --git a/patch/ros-rolling-moveit-ros-perception.patch b/patch/ros-rolling-moveit-ros-perception.patch index 22973d5b0..8a26756a6 100644 --- a/patch/ros-rolling-moveit-ros-perception.patch +++ b/patch/ros-rolling-moveit-ros-perception.patch @@ -11,3 +11,40 @@ index 7ab437a75a..0f28d369a0 100644 tf_buffer_->setCreateTimerInterface(create_timer_interface); tf_listener_ = std::make_shared(*tf_buffer_); shape_mask_ = std::make_unique(); +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 761d53c8..0467358e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -5,6 +5,15 @@ project(moveit_ros_perception LANGUAGES CXX) + find_package(moveit_common REQUIRED) + moveit_package() + ++# MSVC reports the pre-C++11 __cplusplus value (199711L) by default ++# regardless of the actual /std: flag, unless this is set -- several ++# files here (e.g. lazy_free_space_updater.hpp) branch on ++# __cplusplus >= 201103L and fall through to removed std::tr1 types ++# without it. ++if(MSVC) ++ add_compile_options(/Zc:__cplusplus) ++endif() ++ + option(WITH_OPENGL "Build the parts that depend on OpenGL" ON) + + if(WITH_OPENGL) + +diff --git a/semantic_world/src/semantic_world.cpp b/semantic_world/src/semantic_world.cpp +index fb9b659b..cdddabf4 100644 +--- a/semantic_world/src/semantic_world.cpp ++++ b/semantic_world/src/semantic_world.cpp +@@ -43,6 +43,10 @@ + #include + // OpenCV + #include ++#if CV_MAJOR_VERSION >= 5 ++// pointPolygonTest moved to the geometry module in OpenCV 5. ++#include ++#endif + #include + #include + #include + diff --git a/patch/ros-rolling-moveit-task-constructor-capabilities.patch b/patch/ros-rolling-moveit-task-constructor-capabilities.patch new file mode 100644 index 000000000..988022485 --- /dev/null +++ b/patch/ros-rolling-moveit-task-constructor-capabilities.patch @@ -0,0 +1,14 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 76003192..c8d7adfe 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -20,7 +20,7 @@ add_library(${PROJECT_NAME} SHARED + src/execute_task_solution_capability.cpp + ) + target_link_libraries(${PROJECT_NAME} PUBLIC +- fmt ++ fmt::fmt + ${rclcpp_action_TARGETS} + ${moveit_core_TARGETS} + ${moveit_ros_move_group_TARGETS} + diff --git a/patch/ros-rolling-moveit-task-constructor-core.patch b/patch/ros-rolling-moveit-task-constructor-core.patch new file mode 100644 index 000000000..09b1c421c --- /dev/null +++ b/patch/ros-rolling-moveit-task-constructor-core.patch @@ -0,0 +1,189 @@ +diff --git a/include/moveit/task_constructor/properties.h b/include/moveit/task_constructor/properties.h +index e217ad60..d6e332f6 100644 +--- a/include/moveit/task_constructor/properties.h ++++ b/include/moveit/task_constructor/properties.h +@@ -90,7 +90,7 @@ public: + /// exception thrown when trying to set a value not matching the declared type + class type_error; + +- using SourceFlags = uint; ++ using SourceFlags = unsigned int; + /// function callback used to initialize property value from another PropertyMap + using InitializerFunction = std::function; + + +diff --git a/include/moveit/task_constructor/introspection.h b/include/moveit/task_constructor/introspection.h +index cf4dfb76..ae396128 100644 +--- a/include/moveit/task_constructor/introspection.h ++++ b/include/moveit/task_constructor/introspection.h +@@ -111,7 +111,7 @@ private: + /// retrieve or set id of given stage + uint32_t stageId(const moveit::task_constructor::Stage* const s); + /// retrieve solution with given id +- const SolutionBase* solutionFromId(uint id) const; ++ const SolutionBase* solutionFromId(unsigned int id) const; + }; + } // namespace task_constructor + } // namespace moveit + +diff --git a/src/introspection.cpp b/src/introspection.cpp +index 5dfed5d9..134588ea 100644 +--- a/src/introspection.cpp ++++ b/src/introspection.cpp +@@ -218,7 +218,7 @@ void Introspection::publishAllSolutions(bool wait) { + }; + } + +-const SolutionBase* Introspection::solutionFromId(uint id) const { ++const SolutionBase* Introspection::solutionFromId(unsigned int id) const { + auto it = impl->id_solution_bimap_.left.find(id); + if (it == impl->id_solution_bimap_.left.end()) + return nullptr; + +diff --git a/src/stages/generate_place_pose.cpp b/src/stages/generate_place_pose.cpp +index 76b9559f..04e2a8cc 100644 +--- a/src/stages/generate_place_pose.cpp ++++ b/src/stages/generate_place_pose.cpp +@@ -109,11 +109,11 @@ void GeneratePlacePose::compute() { + scene->getTransforms().transformPose(pose_msg.header.frame_id, target_pose, target_pose); + + // spawn the nominal target object pose, considering flip about z and rotations about z-axis +- auto spawner = [&s, &scene, &ik_frame, this](const Eigen::Isometry3d& nominal, uint z_flips, uint z_rotations = 10) { +- for (uint flip = 0; flip <= z_flips; ++flip) { ++ auto spawner = [&s, &scene, &ik_frame, this](const Eigen::Isometry3d& nominal, unsigned int z_flips, unsigned int z_rotations = 10) { ++ for (unsigned int flip = 0; flip <= z_flips; ++flip) { + // flip about object's x-axis + Eigen::Isometry3d object = nominal * Eigen::AngleAxisd(flip * M_PI, Eigen::Vector3d::UnitX()); +- for (uint i = 0; i < z_rotations; ++i) { ++ for (unsigned int i = 0; i < z_rotations; ++i) { + // rotate object at target pose about world's z-axis + Eigen::Vector3d pos = object.translation(); + object.pretranslate(-pos) +@@ -139,7 +139,7 @@ void GeneratePlacePose::compute() { + } + }; + +- uint z_flips = props.get("allow_z_flip") ? 1 : 0; ++ unsigned int z_flips = props.get("allow_z_flip") ? 1 : 0; + if (object && object->getShapes().size() == 1) { + switch (object->getShapes()[0]->type) { + case shapes::CYLINDER: + +diff --git a/src/solvers/pipeline_planner.cpp b/src/solvers/pipeline_planner.cpp +index 9e30131a..bad168ee 100644 +--- a/src/solvers/pipeline_planner.cpp ++++ b/src/solvers/pipeline_planner.cpp +@@ -59,7 +59,7 @@ PipelinePlanner::PipelinePlanner( + , stopping_criterion_callback_(stopping_criterion_callback) + , solution_selection_function_(solution_selection_function) { + // Declare properties of the MotionPlanRequest +- properties().declare("num_planning_attempts", 1u, "number of planning attempts"); ++ properties().declare("num_planning_attempts", 1u, "number of planning attempts"); + properties().declare( + "workspace_parameters", moveit_msgs::msg::WorkspaceParameters(), "allowed workspace of mobile base?"); + +@@ -182,7 +182,7 @@ PlannerInterface::Result PipelinePlanner::plan(const planning_scene::PlanningSce + request.planner_id = planner_id; + request.allowed_planning_time = timeout; + request.start_state.is_diff = true; // we don't specify an extra start state +- request.num_planning_attempts = properties().get("num_planning_attempts"); ++ request.num_planning_attempts = properties().get("num_planning_attempts"); + request.max_velocity_scaling_factor = properties().get("max_velocity_scaling_factor"); + request.max_acceleration_scaling_factor = properties().get("max_acceleration_scaling_factor"); + request.workspace_parameters = properties().get("workspace_parameters"); + +diff --git a/python/bindings/src/solvers.cpp b/python/bindings/src/solvers.cpp +index 7c6a12f4..f1d60b31 100644 +--- a/python/bindings/src/solvers.cpp ++++ b/python/bindings/src/solvers.cpp +@@ -73,7 +73,7 @@ void export_solvers(py::module& m) { + pipelinePlanner = core.PipelinePlanner(node, 'ompl', 'PRMkConfigDefault') + pipelinePlanner.num_planning_attempts = 10 + )") +- .property("num_planning_attempts", "int: Number of planning attempts") ++ .property("num_planning_attempts", "int: Number of planning attempts") + .property( + "workspace_parameters", + ":moveit_msgs:`WorkspaceParameters`: Specifies workspace box to be used for Cartesian sampling") + +diff --git a/src/container.cpp b/src/container.cpp +index 797a6fb6..d92a5a40 100644 +--- a/src/container.cpp ++++ b/src/container.cpp +@@ -57,7 +57,7 @@ namespace moveit { + namespace task_constructor { + + // for debugging of how children interfaces evolve over time +-__attribute__((unused)) // silent unused-function warning ++[[maybe_unused]] // silent unused-function warning + static void printChildrenInterfaces(const ContainerBasePrivate& container, bool success, const Stage& creator, + std::ostream& os = std::cerr) { + static unsigned int id = 0; + +diff --git a/python/bindings/src/properties.cpp b/python/bindings/src/properties.cpp +index a96b292e..10461494 100644 +--- a/python/bindings/src/properties.cpp ++++ b/python/bindings/src/properties.cpp +@@ -158,7 +158,9 @@ bool PropertyConverterBase::insert(const std::type_index& type_index, const std: + return REGISTRY_SINGLETON.insert(type_index, ros_msg_name, to, from); + } + ++#if defined(__GNUC__) || defined(__clang__) + __attribute__((visibility("default"))) // export this symbol as visible in the shared library ++#endif + void export_properties(py::module& m) { + // clang-format off + py::classh(m, "Property", "Holds an arbitrarily typed value and a default value") + +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 82e98756..18ccfc27 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -38,7 +38,7 @@ add_library(${PROJECT_NAME} SHARED + solvers/multi_planner.cpp + ) + target_link_libraries(${PROJECT_NAME} +- fmt ++ fmt::fmt + ${moveit_core_TARGETS} + ${moveit_ros_planning_TARGETS} + ${moveit_ros_planning_interface_TARGETS} +@@ -47,6 +47,11 @@ target_link_libraries(${PROJECT_NAME} + ${moveit_task_constructor_msgs_TARGETS} + ${visualization_msgs_TARGETS} + ) ++if(WIN32) ++ # introspection.cpp's gethostname() call is declared via ++ # but implemented in ws2_32.lib, which isn't linked by default. ++ target_link_libraries(${PROJECT_NAME} ws2_32) ++endif() + target_include_directories(${PROJECT_NAME} + PUBLIC $ + $ + +diff --git a/python/bindings/CMakeLists.txt b/python/bindings/CMakeLists.txt +index 26c86ac6..3d8eeb60 100644 +--- a/python/bindings/CMakeLists.txt ++++ b/python/bindings/CMakeLists.txt +@@ -7,6 +7,20 @@ target_link_libraries(${PROJECT_NAME}_python_tools PUBLIC ${PROJECT_NAME} + pybind11::pybind11 py_binding_tools::py_binding_tools) + # Use minimum-size optimization for pybind11 bindings + target_link_libraries(${PROJECT_NAME}_python_tools PUBLIC pybind11::opt_size) ++if(WIN32) ++ # py_binding_tools::py_binding_tools transitively pulls in conda's own ++ # (differently-versioned) system pybind11 include directory alongside ++ # this project's vendored smart_holder pybind11 fork. Angle-bracket ++ # includes like (e.g. from ++ # py_binding_tools/ros_msg_typecasters.h) resolve via the compiler's ++ # global include search order rather than "next to the including ++ # file", so whichever copy's directory comes first wins -- on Windows ++ # that ends up being conda's, causing both copies' headers to be ++ # processed in the same translation unit (ODR violations / "already ++ # defined" cascades). Force the vendored copy first. ++ target_include_directories(${PROJECT_NAME}_python_tools BEFORE PUBLIC ++ $) ++endif() + + # moveit.task_constructor + pybind11_add_module(pymoveit_mtc + diff --git a/patch/ros-rolling-moveit-task-constructor-visualization.patch b/patch/ros-rolling-moveit-task-constructor-visualization.patch new file mode 100644 index 000000000..936d64ff2 --- /dev/null +++ b/patch/ros-rolling-moveit-task-constructor-visualization.patch @@ -0,0 +1,221 @@ +diff --git a/motion_planning_tasks/utils/CMakeLists.txt b/motion_planning_tasks/utils/CMakeLists.txt +index 436145dc..82ad0bfd 100644 +--- a/motion_planning_tasks/utils/CMakeLists.txt ++++ b/motion_planning_tasks/utils/CMakeLists.txt +@@ -6,6 +6,16 @@ set(SOURCES + icon.cpp + ) + add_library(${MOVEIT_LIB_NAME} SHARED ${SOURCES}) ++if(WIN32) ++ # FlatMergeProxyModel/TreeMergeProxyModel are linked directly by ++ # motion_planning_tasks_rviz_plugin, so they need an import .lib on ++ # Windows. WINDOWS_EXPORT_ALL_SYMBOLS covers their plain member ++ # functions; the classes are also explicitly annotated with ++ # MOTION_PLANNING_TASKS_UTILS_EXPORT to cover the MOC-generated ++ # staticMetaObject static data member, which auto-export doesn't reach. ++ set_target_properties(${MOVEIT_LIB_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++ target_compile_definitions(${MOVEIT_LIB_NAME} PRIVATE MOTION_PLANNING_TASKS_UTILS_BUILDING_DLL) ++endif() + + target_link_libraries(${MOVEIT_LIB_NAME} + ${QT_LIBRARIES} + +diff --git a/motion_planning_tasks/utils/flat_merge_proxy_model.h b/motion_planning_tasks/utils/flat_merge_proxy_model.h +index feced7e4..ba7a0e19 100644 +--- a/motion_planning_tasks/utils/flat_merge_proxy_model.h ++++ b/motion_planning_tasks/utils/flat_merge_proxy_model.h +@@ -39,6 +39,21 @@ + #include + #include + ++// Qt's MOC-generated staticMetaObject is a static data member, which ++// CMake's WINDOWS_EXPORT_ALL_SYMBOLS (used for this library's plain ++// functions) does not auto-export -- an explicit dllexport/dllimport ++// is needed on the whole class to also cover its vtable and Qt ++// metaobject machinery. ++#ifdef _WIN32 ++#ifdef MOTION_PLANNING_TASKS_UTILS_BUILDING_DLL ++#define MOTION_PLANNING_TASKS_UTILS_EXPORT __declspec(dllexport) ++#else ++#define MOTION_PLANNING_TASKS_UTILS_EXPORT __declspec(dllimport) ++#endif ++#else ++#define MOTION_PLANNING_TASKS_UTILS_EXPORT ++#endif ++ + namespace moveit_rviz_plugin { + namespace utils { + +@@ -49,7 +64,7 @@ class FlatMergeProxyModelPrivate; + * Removing top-level items will remove the whole embedded model if all top-level items from + * this model are to be removed. Otherwise, removal is forwarded to the embedded model. + */ +-class FlatMergeProxyModel : public QAbstractItemModel ++class MOTION_PLANNING_TASKS_UTILS_EXPORT FlatMergeProxyModel : public QAbstractItemModel + { + Q_OBJECT + Q_DECLARE_PRIVATE(FlatMergeProxyModel) + +diff --git a/motion_planning_tasks/utils/tree_merge_proxy_model.h b/motion_planning_tasks/utils/tree_merge_proxy_model.h +index df43128b..72087ea0 100644 +--- a/motion_planning_tasks/utils/tree_merge_proxy_model.h ++++ b/motion_planning_tasks/utils/tree_merge_proxy_model.h +@@ -39,6 +39,21 @@ + #include + #include + ++// Qt's MOC-generated staticMetaObject is a static data member, which ++// CMake's WINDOWS_EXPORT_ALL_SYMBOLS (used for this library's plain ++// functions) does not auto-export -- an explicit dllexport/dllimport ++// is needed on the whole class to also cover its vtable and Qt ++// metaobject machinery. ++#ifdef _WIN32 ++#ifdef MOTION_PLANNING_TASKS_UTILS_BUILDING_DLL ++#define MOTION_PLANNING_TASKS_UTILS_EXPORT __declspec(dllexport) ++#else ++#define MOTION_PLANNING_TASKS_UTILS_EXPORT __declspec(dllimport) ++#endif ++#else ++#define MOTION_PLANNING_TASKS_UTILS_EXPORT ++#endif ++ + namespace moveit_rviz_plugin { + namespace utils { + +@@ -48,7 +63,7 @@ class TreeMergeProxyModelPrivate; + * Each embedded model becomes a top-level item (with a given name) + * and all the model's top-level items will appear as its children. + */ +-class TreeMergeProxyModel : public QAbstractItemModel ++class MOTION_PLANNING_TASKS_UTILS_EXPORT TreeMergeProxyModel : public QAbstractItemModel + { + Q_OBJECT + Q_DECLARE_PRIVATE(TreeMergeProxyModel) + +diff --git a/motion_planning_tasks/properties/CMakeLists.txt b/motion_planning_tasks/properties/CMakeLists.txt +index 8296b9ea..98c81c39 100644 +--- a/motion_planning_tasks/properties/CMakeLists.txt ++++ b/motion_planning_tasks/properties/CMakeLists.txt +@@ -9,6 +9,12 @@ find_package(libyaml_vendor REQUIRED) + find_package(yaml REQUIRED) + + add_library(${MOVEIT_LIB_NAME} SHARED ${SOURCES}) ++if(WIN32) ++ # Linked directly by motion_planning_tasks_rviz_plugin, so it needs ++ # an import .lib on Windows -- same missing-dllexport-symbols issue ++ # already fixed for motion_planning_tasks_utils. ++ set_target_properties(${MOVEIT_LIB_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() + + target_link_libraries(${MOVEIT_LIB_NAME} + ${QT_LIBRARIES} yaml + +diff --git a/visualization_tools/CMakeLists.txt b/visualization_tools/CMakeLists.txt +index bde4d614..a1971ed4 100644 +--- a/visualization_tools/CMakeLists.txt ++++ b/visualization_tools/CMakeLists.txt +@@ -18,6 +18,16 @@ add_library(${MOVEIT_LIB_NAME} SHARED + src/task_solution_visualization.cpp + ) + set_target_properties(${MOVEIT_LIB_NAME} PROPERTIES VERSION "${${PROJECT_NAME}_VERSION}") ++if(WIN32) ++ # Linked directly by motion_planning_tasks_rviz_plugin, so it needs ++ # an import .lib on Windows -- same missing-dllexport-symbols issue ++ # already fixed for motion_planning_tasks_utils/_properties. The ++ # MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT annotations on its Q_OBJECT ++ # classes cover their MOC-generated staticMetaObject data members, ++ # which WINDOWS_EXPORT_ALL_SYMBOLS's function-only auto-export misses. ++ set_target_properties(${MOVEIT_LIB_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++ target_compile_definitions(${MOVEIT_LIB_NAME} PRIVATE MOVEIT_TASK_VISUALIZATION_TOOLS_BUILDING_DLL) ++endif() + target_link_libraries(${MOVEIT_LIB_NAME} + ${QT_LIBRARIES} + rviz_ogre_vendor::OgreMain + +diff --git a/visualization_tools/include/moveit/visualization_tools/marker_visualization.h b/visualization_tools/include/moveit/visualization_tools/marker_visualization.h +index 1b3fcebe..e2da81f1 100644 +--- a/visualization_tools/include/moveit/visualization_tools/marker_visualization.h ++++ b/visualization_tools/include/moveit/visualization_tools/marker_visualization.h +@@ -95,7 +95,22 @@ private: + * The class remembers which MarkerVisualization instances are currently hosted + * and provides the user interaction to toggle marker visibility by namespace. + */ +-class MarkerVisualizationProperty : public rviz_common::properties::BoolProperty ++// Qt's MOC-generated staticMetaObject is a static data member, which ++// CMake's WINDOWS_EXPORT_ALL_SYMBOLS (used for this library's plain ++// functions) does not auto-export -- an explicit dllexport/dllimport ++// is needed on the whole class to also cover its vtable and Qt ++// metaobject machinery. ++#ifdef _WIN32 ++#ifdef MOVEIT_TASK_VISUALIZATION_TOOLS_BUILDING_DLL ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT __declspec(dllexport) ++#else ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT __declspec(dllimport) ++#endif ++#else ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT ++#endif ++ ++class MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT MarkerVisualizationProperty : public rviz_common::properties::BoolProperty + { + Q_OBJECT + + +diff --git a/visualization_tools/include/moveit/visualization_tools/task_solution_panel.h b/visualization_tools/include/moveit/visualization_tools/task_solution_panel.h +index 4e6e31ee..db7b77a5 100644 +--- a/visualization_tools/include/moveit/visualization_tools/task_solution_panel.h ++++ b/visualization_tools/include/moveit/visualization_tools/task_solution_panel.h +@@ -47,7 +47,22 @@ + #include + + namespace moveit_rviz_plugin { +-class TaskSolutionPanel : public rviz_common::Panel ++// Qt's MOC-generated staticMetaObject is a static data member, which ++// CMake's WINDOWS_EXPORT_ALL_SYMBOLS (used for this library's plain ++// functions) does not auto-export -- an explicit dllexport/dllimport ++// is needed on the whole class to also cover its vtable and Qt ++// metaobject machinery. ++#ifdef _WIN32 ++#ifdef MOVEIT_TASK_VISUALIZATION_TOOLS_BUILDING_DLL ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT __declspec(dllexport) ++#else ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT __declspec(dllimport) ++#endif ++#else ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT ++#endif ++ ++class MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT TaskSolutionPanel : public rviz_common::Panel + { + Q_OBJECT + + +diff --git a/visualization_tools/include/moveit/visualization_tools/task_solution_visualization.h b/visualization_tools/include/moveit/visualization_tools/task_solution_visualization.h +index c1a666b7..5265f27f 100644 +--- a/visualization_tools/include/moveit/visualization_tools/task_solution_visualization.h ++++ b/visualization_tools/include/moveit/visualization_tools/task_solution_visualization.h +@@ -90,7 +90,22 @@ MOVEIT_CLASS_FORWARD(DisplaySolution); + + class TaskSolutionPanel; + class MarkerVisualizationProperty; +-class TaskSolutionVisualization : public QObject ++// Qt's MOC-generated staticMetaObject is a static data member, which ++// CMake's WINDOWS_EXPORT_ALL_SYMBOLS (used for this library's plain ++// functions) does not auto-export -- an explicit dllexport/dllimport ++// is needed on the whole class to also cover its vtable and Qt ++// metaobject machinery. ++#ifdef _WIN32 ++#ifdef MOVEIT_TASK_VISUALIZATION_TOOLS_BUILDING_DLL ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT __declspec(dllexport) ++#else ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT __declspec(dllimport) ++#endif ++#else ++#define MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT ++#endif ++ ++class MOVEIT_TASK_VISUALIZATION_TOOLS_EXPORT TaskSolutionVisualization : public QObject + { + Q_OBJECT + + diff --git a/patch/ros-rolling-mujoco-3d-lidar.patch b/patch/ros-rolling-mujoco-3d-lidar.patch new file mode 100644 index 000000000..90473fe04 --- /dev/null +++ b/patch/ros-rolling-mujoco-3d-lidar.patch @@ -0,0 +1,50 @@ +diff --git a/include/mujoco_3d_lidar/3dlidar.h b/include/mujoco_3d_lidar/3dlidar.h +index e6f4810..64cceca 100644 +--- a/include/mujoco_3d_lidar/3dlidar.h ++++ b/include/mujoco_3d_lidar/3dlidar.h +@@ -29,7 +29,7 @@ + + #include + #include +-#include ++#include + #include + + namespace mujoco::plugin::lidar +diff --git a/src/3dlidar.cpp b/src/3dlidar.cpp +index c5e30d3..4a99208 100644 +--- a/src/3dlidar.cpp ++++ b/src/3dlidar.cpp +@@ -30,7 +30,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 1fe40b85..86d04647 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,18 @@ + cmake_minimum_required(VERSION 3.22) + project(mujoco_3d_lidar) + ++# mjspec.h uses std::byte and nested-namespace-definition syntax, both ++# C++17 features; without an explicit standard, MSVC doesn't enable ++# them by default (error C2429/C2039/C2065/C2923/C2976). ++if(NOT CMAKE_CXX_STANDARD) ++ set(CMAKE_CXX_STANDARD 17) ++ set(CMAKE_CXX_STANDARD_REQUIRED ON) ++endif() ++if(MSVC) ++ # 3dlidar.cpp uses bare M_PI, only defined by when this is set. ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + find_package(ament_cmake QUIET) + # Link MuJoCo via the vendor package + find_package(mujoco_vendor REQUIRED) + diff --git a/patch/ros-rolling-nlohmann-json-schema-validator-vendor.patch b/patch/ros-rolling-nlohmann-json-schema-validator-vendor.patch new file mode 100644 index 000000000..0a0098a94 --- /dev/null +++ b/patch/ros-rolling-nlohmann-json-schema-validator-vendor.patch @@ -0,0 +1,72 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 2115dd4..5021d26 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -7,7 +7,7 @@ find_package(ament_cmake REQUIRED) + macro(build_nlohmann_json_schema_validator) + + set(cmake_commands) +- set(cmake_configure_args -Wno-dev) ++ set(cmake_configure_args -Wno-dev -DCMAKE_POLICY_VERSION_MINIMUM=3.5) + + if(WIN32) + if(DEFINED CMAKE_GENERATOR) +@@ -20,8 +20,15 @@ macro(build_nlohmann_json_schema_validator) + + if(DEFINED CMAKE_BUILD_TYPE) + if(WIN32) +- build_command(_build_command CONFIGURATION ${CMAKE_BUILD_TYPE}) +- list(APPEND cmake_commands "BUILD_COMMAND ${_build_command}") ++ # build_command() returns ONE pre-quoted command-line string (meant ++ # for shell/execute_process use), not a token list. Appending it as ++ # a single BUILD_COMMAND argument makes the VS generator wrap that ++ # whole string in an extra layer of quotes, so cmd.exe then treats ++ # the entire quoted blob (cmake.exe path and all) as one program ++ # name ("... is not recognized as an internal or external command"). ++ # Build BUILD_COMMAND from separate tokens using ${CMAKE_COMMAND} ++ # directly instead, matching normal ExternalProject_Add usage. ++ list(APPEND cmake_commands BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE}) + else() + list(APPEND cmake_configure_args -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) + endif() +@@ -59,20 +66,35 @@ macro(build_nlohmann_json_schema_validator) + include(ExternalProject) + # HEAD of `main` branch on 2022-10-07 + set(nlohmann_json_schema_validator_version "5ef4f903af055550e06955973a193e17efded896") +- externalproject_add(nlohmann_json_schema_validator-${nlohmann_json_schema_validator_version} ++ # Use a short, fixed ExternalProject name/PREFIX rather than one ++ # embedding the full 40-char commit hash (repeated in both the ++ # "-prefix" and "src/" path components by CMake's default ++ # layout) -- combined with rattler-build's own already-deep Windows ++ # work directory, the resulting git clone target path exceeded ++ # Windows' MAX_PATH ("Filename too long"), and core.longpaths alone ++ # did not resolve it. ++ externalproject_add(nlohmann_json_schema_validator_ext ++ PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext + GIT_REPOSITORY https://github.com/pboettch/json-schema-validator.git + GIT_TAG ${nlohmann_json_schema_validator_version} +- GIT_CONFIG advice.detachedHead=false ++ GIT_CONFIG advice.detachedHead=false core.longpaths=true + # Suppress git update due to https://gitlab.kitware.com/cmake/cmake/-/issues/16419 + UPDATE_COMMAND "" + TIMEOUT 6000 +- PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_LIST_DIR}/patch_cmakelist ++ PATCH_COMMAND patch -p1 -i ${CMAKE_CURRENT_LIST_DIR}/patch_cmakelist + ${cmake_commands} + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${json_external_project_dir}/install/ + -DBUILD_SHARED_LIBS:BOOL=ON +- -DJSON_VALIDATOR_BUILD_TESTS:BOOL=OFF +- -DJSON_VALIDATOR_BUILD_EXAMPLES:BOOL=OFF ++ # This pinned commit's actual option names are BUILD_TESTS/ ++ # BUILD_EXAMPLES (no JSON_VALIDATOR_ prefix) -- the old names were ++ # silently ignored ("Manually-specified variables were not used by ++ # the project"), so tests/examples built ON by default. Harmless on ++ # Unix, but the vendored shared library doesn't export symbols for ++ # Windows, so the test executables then fail to link against it ++ # (LNK2019). ++ -DBUILD_TESTS:BOOL=OFF ++ -DBUILD_EXAMPLES:BOOL=OFF + ${cmake_configure_args} + ) + diff --git a/patch/ros-rolling-ouster-ros.patch b/patch/ros-rolling-ouster-ros.patch index 7947fd7e0..96cf04c0e 100644 --- a/patch/ros-rolling-ouster-ros.patch +++ b/patch/ros-rolling-ouster-ros.patch @@ -120,3 +120,54 @@ index 94d50eb..b1e05ce 100644 void declare_parameters() { node->declare_parameter("sensor_frame", "os_sensor"); +diff --git a/ouster-sdk/cmake/Findlibzip.cmake b/ouster-sdk/cmake/Findlibzip.cmake +index 0de2ad5..266cf93 100644 +--- a/ouster-sdk/cmake/Findlibzip.cmake ++++ b/ouster-sdk/cmake/Findlibzip.cmake +@@ -37,9 +37,11 @@ find_path(libzip_INCLUDE_DIRS + HINTS ${pkg_libzip_INCLUDE_DIRS}) + mark_as_advanced(libzip_INCLUDE_DIRS) + +-# Linux/macos only ++# conda-forge's libzip ships the Windows import lib as "zip.lib" (no ++# "lib" prefix, matching MSVC convention), so it's never found by the ++# Unix-only names below -- add it too. + find_library(libzip_LIBRARIES NAMES +- libzip libzip.so libzip.dylib ++ libzip libzip.so libzip.dylib zip + HINTS ${pkg_libzip_LIBRARY_DIRS}) + mark_as_advanced(libzip_LIBRARIES) + +diff --git a/ouster-sdk/ouster_client/CMakeLists.txt b/ouster-sdk/ouster_client/CMakeLists.txt +index f17eeb4..1cb5d2f 100644 +--- a/ouster-sdk/ouster_client/CMakeLists.txt ++++ b/ouster-sdk/ouster_client/CMakeLists.txt +@@ -64,7 +64,18 @@ if(WIN32) + target_link_libraries(ouster_client PUBLIC ws2_32) + endif() + +-target_include_directories(ouster_client ++# BEFORE: a conda-forge spdlog package (pulled in transitively by some ++# other linked/found dependency) can end up ahead of our own explicit ++# include dirs, so resolves to that *external* system ++# copy (built assuming external fmt) instead of our vendored one, while ++# logging.cpp's own (upstream spdlog's own ++# design, always included directly) can only ever resolve to our ++# vendored copy (the system package doesn't ship fmt/bundled/*). Mixing ++# those two in one translation unit collides on fmt::v10's template ++# declarations (MSVC C2990/C2955/C2011/...). Force our vendored ++# thirdparty dirs to the front of the search order so every ++# include resolves consistently to the vendored copy. ++target_include_directories(ouster_client BEFORE + PUBLIC + $ + $ +@@ -73,7 +84,7 @@ target_include_directories(ouster_client + $ + ) + +-target_include_directories(ouster_client SYSTEM ++target_include_directories(ouster_client SYSTEM BEFORE + PUBLIC + $ + $ diff --git a/patch/ros-rolling-ouster-ros.win.patch b/patch/ros-rolling-ouster-ros.win.patch deleted file mode 100644 index 97643f592..000000000 --- a/patch/ros-rolling-ouster-ros.win.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index e07dcf4..8d23997 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -23,13 +23,21 @@ find_package(pcl_conversions REQUIRED) - find_package(tf2_eigen REQUIRED) - - # ==== Options ==== --add_compile_options(-Wall -Wextra) -+if(MSVC) -+ add_compile_options(/W2) -+ add_compile_definitions(NOMINMAX _USE_MATH_DEFINES WIN32_LEAN_AND_MEAN) -+else() -+ add_compile_options(-Wall -Wextra) -+endif() -+ - if(NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - endif() - option(CMAKE_POSITION_INDEPENDENT_CODE "Build position independent code." ON) - -+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -+ - set(_ouster_ros_INCLUDE_DIRS - include - ouster-sdk/ouster_client/include diff --git a/patch/ros-rolling-plotjuggler-ros.win.patch b/patch/ros-rolling-plotjuggler-ros.win.patch new file mode 100644 index 000000000..6a3621422 --- /dev/null +++ b/patch/ros-rolling-plotjuggler-ros.win.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 506bbf9..b75e00d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -26,6 +26,12 @@ if (NOT WIN32) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fno-omit-frame-pointer") + endif() + ++if(MSVC) ++ # fmt (pulled in transitively via rclcpp/rcpputils) statically asserts ++ # that Unicode support requires compiling with /utf-8 on MSVC. ++ add_compile_options(/utf-8) ++endif() ++ + if(APPLE AND EXISTS /usr/local/opt/qt5) + # Homebrew installs Qt5 (up to at least 5.9.1) in + # /usr/local/qt5, ensure it can be found by CMake since diff --git a/patch/ros-rolling-plotjuggler.win.patch b/patch/ros-rolling-plotjuggler.win.patch index b95af508d..f175d09a2 100644 --- a/patch/ros-rolling-plotjuggler.win.patch +++ b/patch/ros-rolling-plotjuggler.win.patch @@ -3,7 +3,7 @@ index 6b650f1b..67ac7a9f 100644 --- a/3rdparty/Qt-Advanced-Docking/CMakeLists.txt +++ b/3rdparty/Qt-Advanced-Docking/CMakeLists.txt @@ -67,7 +67,9 @@ target_link_libraries(qt_advanced_docking PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets - + if(UNIX AND NOT APPLE) target_link_libraries(qt_advanced_docking PUBLIC Qt5::X11Extras) - target_link_libraries(qt_advanced_docking PRIVATE xcb) @@ -11,7 +11,7 @@ index 6b650f1b..67ac7a9f 100644 + target_link_libraries(qt_advanced_docking PRIVATE ${XCB_LIBRARIES}) + target_include_directories(qt_advanced_docking SYSTEM PUBLIC ${XCB_INCLUDE_DIRS}) endif() - + set_target_properties(qt_advanced_docking PROPERTIES diff --git a/CMakeLists.txt b/CMakeLists.txt index 385b7899..b1d6f2ab 100644 @@ -28,132 +28,199 @@ index 385b7899..b1d6f2ab 100644 - Qt5::OpenGL Qt5::WebSockets ) - -@@ -216,6 +214,7 @@ target_link_libraries(plotjuggler_base - PUBLIC - plotjuggler_qwt - PRIVATE -+ ${QT_LINK_LIBRARIES} - lua::lua - sol2::sol2 + +@@ -243,6 +241,22 @@ else() + ${PLOTJUGGLER_BASE_MOCS}) + endif() + ++if(WIN32) ++ # plotjuggler_base has no dllexport annotations at all. As a shared ++ # library on Windows with nothing explicitly exported, link.exe does ++ # not produce an import .lib, so every consumer (plotjuggler_app, every ++ # plotjuggler_plugins/* plugin) fails with LNK1181 "cannot open input ++ # file ...plotjuggler_base.lib" even though plotjuggler_base.dll itself ++ # built fine. Auto-export everything, same as every other Windows ++ # shared-library target fixed this session. ++ set_target_properties(plotjuggler_base PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++ # WINDOWS_EXPORT_ALL_SYMBOLS only auto-exports functions, not the ++ # static data members (like Qt MOC's staticMetaObject) that every ++ # Q_OBJECT class here needs -- see PJ_BASE_EXPORT usage in ++ # plotjuggler_base/include/PlotJuggler/pj_export.h and friends. ++ target_compile_definitions(plotjuggler_base PRIVATE PJ_BASE_BUILDING_DLL) ++endif() ++ + set(PJ_PLUGIN_INSTALL_DIRECTORY "${CMAKE_INSTALL_PREFIX}/${PJ_PLUGINS_DIRECTORY}") + + target_include_directories( + +diff --git a/3rdparty/qwt/src/CMakeLists.txt b/3rdparty/qwt/src/CMakeLists.txt +index 51e6f088..8971ecab 100644 +--- a/3rdparty/qwt/src/CMakeLists.txt ++++ b/3rdparty/qwt/src/CMakeLists.txt +@@ -201,6 +201,7 @@ target_link_libraries(plotjuggler_qwt + Qt5::Widgets + Qt5::Concurrent + Qt5::Svg ++ Qt5::Xml ) -diff --git a/plotjuggler_plugins/ParserProtobuf/CMakeLists.txt b/plotjuggler_plugins/ParserProtobuf/CMakeLists.txt -index 588c69ba..ab94a3df 100644 ---- a/plotjuggler_plugins/ParserProtobuf/CMakeLists.txt -+++ b/plotjuggler_plugins/ParserProtobuf/CMakeLists.txt -@@ -1,13 +1,6 @@ --if(BUILDING_WITH_CONAN) -- message(STATUS "Finding Protobuf with conan") -- set(Protobuf_LIBS protobuf::libprotobuf) --else() -- message(STATUS "Finding Protobuf without package managers") -- find_package(Protobuf QUIET) -- set(Protobuf_LIBS ${Protobuf_LIBRARIES}) --endif() -+set(Protobuf_LIBS protobuf::libprotobuf) - --find_package(Protobuf QUIET) -+find_package(Protobuf QUIET CONFIG) - if( Protobuf_FOUND) - -diff --git a/plotjuggler_plugins/ParserProtobuf/error_collectors.cpp b/plotjuggler_plugins/ParserProtobuf/error_collectors.cpp -index 761e0b73..b7ce4129 100644 ---- a/plotjuggler_plugins/ParserProtobuf/error_collectors.cpp -+++ b/plotjuggler_plugins/ParserProtobuf/error_collectors.cpp -@@ -2,38 +2,38 @@ - #include - #include - --void FileErrorCollector::AddError(const std::string& filename, int line, int, -- const std::string& message) -+void FileErrorCollector::RecordError(const absl::string_view filename, int line, int, -+ const absl::string_view message) + target_compile_definitions(plotjuggler_qwt PUBLIC QWT_MOC_INCLUDE) +diff --git a/plotjuggler_base/include/PlotJuggler/statepublisher_base.h b/plotjuggler_base/include/PlotJuggler/statepublisher_base.h +index 6b4bb61..b5e0e47 100644 +--- a/plotjuggler_base/include/PlotJuggler/statepublisher_base.h ++++ b/plotjuggler_base/include/PlotJuggler/statepublisher_base.h +@@ -14,10 +14,11 @@ + #include + #include "PlotJuggler/plotdata.h" + #include "PlotJuggler/pj_plugin.h" ++#include "PlotJuggler/pj_export.h" + + namespace PJ { - auto msg = QString("File: [%1] Line: [%2] Message: %3\n\n") -- .arg(QString::fromStdString(filename)) -+ .arg(QString::fromStdString(std::string(filename))) - .arg(line) -- .arg(QString::fromStdString(message)); -+ .arg(QString::fromStdString(std::string(message))); - - _errors.push_back(msg); - } - --void FileErrorCollector::AddWarning(const std::string& filename, int line, int, -- const std::string& message) -+void FileErrorCollector::RecordWarning(const absl::string_view filename, int line, int, -+ const absl::string_view message) +-class StatePublisher : public PlotJugglerPlugin ++class PJ_BASE_EXPORT StatePublisher : public PlotJugglerPlugin { - auto msg = QString("Warning [%1] line %2: %3") -- .arg(QString::fromStdString(filename)) -+ .arg(QString::fromStdString(std::string(filename))) - .arg(line) -- .arg(QString::fromStdString(message)); -+ .arg(QString::fromStdString(std::string(message))); - qDebug() << msg; - } - --void IoErrorCollector::AddError(int line, google::protobuf::io::ColumnNumber, -- const std::string& message) -+void IoErrorCollector::RecordError(int line, google::protobuf::io::ColumnNumber, -+ const absl::string_view message) + Q_OBJECT + + +diff --git a/plotjuggler_base/include/PlotJuggler/datastreamer_base.h b/plotjuggler_base/include/PlotJuggler/datastreamer_base.h +index 04f70f5..0c3f28f 100644 +--- a/plotjuggler_base/include/PlotJuggler/datastreamer_base.h ++++ b/plotjuggler_base/include/PlotJuggler/datastreamer_base.h +@@ -12,6 +12,7 @@ + #include "PlotJuggler/plotdata.h" + #include "PlotJuggler/pj_plugin.h" + #include "PlotJuggler/messageparser_base.h" ++#include "PlotJuggler/pj_export.h" + + namespace PJ { - _errors.push_back( -- QString("Line: [%1] Message: %2\n").arg(line).arg(QString::fromStdString(message))); -+ QString("Line: [%1] Message: %2\n").arg(line).arg(QString::fromStdString(std::string(message)))); - } - --void IoErrorCollector::AddWarning(int line, google::protobuf::io::ColumnNumber column, -- const std::string& message) -+void IoErrorCollector::RecordWarning(int line, google::protobuf::io::ColumnNumber column, -+ const absl::string_view message) +@@ -22,7 +23,7 @@ namespace PJ + * dataMap(), which share its elements with the main application, must be protected + * using the mutex(). + */ +-class DataStreamer : public PlotJugglerPlugin ++class PJ_BASE_EXPORT DataStreamer : public PlotJugglerPlugin { - qDebug() << QString("Line: [%1] Message: %2\n") - .arg(line) -- .arg(QString::fromStdString(message)); -+ .arg(QString::fromStdString(std::string(message))); - } -diff --git a/plotjuggler_plugins/ParserProtobuf/error_collectors.h b/plotjuggler_plugins/ParserProtobuf/error_collectors.h -index 8abfa5e0..7afe1fea 100644 ---- a/plotjuggler_plugins/ParserProtobuf/error_collectors.h -+++ b/plotjuggler_plugins/ParserProtobuf/error_collectors.h -@@ -3,17 +3,18 @@ - - #include - #include -+#include + Q_OBJECT + public: + +diff --git a/plotjuggler_base/include/PlotJuggler/transform_function.h b/plotjuggler_base/include/PlotJuggler/transform_function.h +index a04de1d..0059b90 100644 +--- a/plotjuggler_base/include/PlotJuggler/transform_function.h ++++ b/plotjuggler_base/include/PlotJuggler/transform_function.h +@@ -12,6 +12,7 @@ + #include + #include "PlotJuggler/plotdata.h" + #include "PlotJuggler/pj_plugin.h" ++#include "PlotJuggler/pj_export.h" + + namespace PJ + { +@@ -19,7 +20,7 @@ namespace PJ + * Contrariwise to other plugins, multiple instances of the this class might be created. + * For this reason, a TransformFactory is also defined + */ +-class TransformFunction : public PlotJugglerPlugin ++class PJ_BASE_EXPORT TransformFunction : public PlotJugglerPlugin + { + Q_OBJECT - #include +@@ -85,7 +86,7 @@ protected: + using TransformsMap = std::unordered_map>; - class IoErrorCollector : public google::protobuf::io::ErrorCollector + /// Simplified version with Single input and Single output +-class TransformFunction_SISO : public TransformFunction ++class PJ_BASE_EXPORT TransformFunction_SISO : public TransformFunction { + Q_OBJECT public: -- void AddError(int line, google::protobuf::io::ColumnNumber column, -- const std::string& message); -+ void RecordError(int line, google::protobuf::io::ColumnNumber column, -+ const absl::string_view message) override; - -- void AddWarning(int line, google::protobuf::io::ColumnNumber column, -- const std::string& message); -+ void RecordWarning(int line, google::protobuf::io::ColumnNumber column, -+ const absl::string_view message) override; + +diff --git a/plotjuggler_base/include/PlotJuggler/plotwidget_base.h b/plotjuggler_base/include/PlotJuggler/plotwidget_base.h +index 5591fa1..95342b3 100644 +--- a/plotjuggler_base/include/PlotJuggler/plotwidget_base.h ++++ b/plotjuggler_base/include/PlotJuggler/plotwidget_base.h +@@ -11,6 +11,7 @@ + #include + #include "plotdata.h" + #include "timeseries_qwt.h" ++#include "PlotJuggler/pj_export.h" + + class QwtPlot; + class QwtPlotCurve; +@@ -43,7 +44,7 @@ inline double dotWidthValue(LineWidth line_width) + return (lineWidthValue(line_width) * 1.5) + 2.0; + } - const QStringList& errors() - { -@@ -27,11 +28,11 @@ private: - class FileErrorCollector : public google::protobuf::compiler::MultiFileErrorCollector +-class PlotWidgetBase : public QWidget ++class PJ_BASE_EXPORT PlotWidgetBase : public QWidget { - public: -- void AddError(const std::string& filename, int line, int, -- const std::string& message) override; -+ void RecordError(const absl::string_view filename, int line, int, -+ const absl::string_view message) override; + Q_OBJECT + + +diff --git a/plotjuggler_base/include/PlotJuggler/range_slider.h b/plotjuggler_base/include/PlotJuggler/range_slider.h +index 38e6766..a2682ec 100644 +--- a/plotjuggler_base/include/PlotJuggler/range_slider.h ++++ b/plotjuggler_base/include/PlotJuggler/range_slider.h +@@ -7,7 +7,9 @@ -- void AddWarning(const std::string& filename, int line, int, -- const std::string& message) override; -+ void RecordWarning(const absl::string_view filename, int line, int, -+ const absl::string_view message) override; + #include - const QStringList& errors() - { +-class RangeSlider : public QWidget ++#include "PlotJuggler/pj_export.h" ++ ++class PJ_BASE_EXPORT RangeSlider : public QWidget + { + Q_OBJECT + Q_ENUMS(RangeSliderTypes) + +diff --git a/plotjuggler_base/include/PlotJuggler/toolbox_base.h b/plotjuggler_base/include/PlotJuggler/toolbox_base.h +index bc7b3d6..4ce5f51 100644 +--- a/plotjuggler_base/include/PlotJuggler/toolbox_base.h ++++ b/plotjuggler_base/include/PlotJuggler/toolbox_base.h +@@ -14,10 +14,11 @@ + #include "PlotJuggler/pj_plugin.h" + #include "PlotJuggler/transform_function.h" + #include "PlotJuggler/messageparser_base.h" ++#include "PlotJuggler/pj_export.h" + + namespace PJ + { +-class ToolboxPlugin : public PlotJugglerPlugin ++class PJ_BASE_EXPORT ToolboxPlugin : public PlotJugglerPlugin + { + Q_OBJECT + + +diff --git a/plotjuggler_base/include/PlotJuggler/pj_export.h b/plotjuggler_base/include/PlotJuggler/pj_export.h +new file mode 100644 +index 0000000..35cd616 +--- /dev/null ++++ b/plotjuggler_base/include/PlotJuggler/pj_export.h +@@ -0,0 +1,25 @@ ++/* ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at https://mozilla.org/MPL/2.0/. ++ */ ++ ++#ifndef PJ_EXPORT_H ++#define PJ_EXPORT_H ++ ++// WINDOWS_EXPORT_ALL_SYMBOLS only auto-exports functions, not the static ++// data members (like Qt MOC's staticMetaObject) that every Q_OBJECT class ++// in plotjuggler_base needs. Apply this macro to the whole class ++// declaration of each Q_OBJECT class so both the vtable and the ++// MOC-generated staticMetaObject get exported/imported together. ++#if defined(_WIN32) ++#if defined(PJ_BASE_BUILDING_DLL) ++#define PJ_BASE_EXPORT __declspec(dllexport) ++#else ++#define PJ_BASE_EXPORT __declspec(dllimport) ++#endif ++#else ++#define PJ_BASE_EXPORT ++#endif ++ ++#endif // PJ_EXPORT_H + diff --git a/patch/ros-rolling-pointcloud-to-laserscan.win.patch b/patch/ros-rolling-pointcloud-to-laserscan.win.patch new file mode 100644 index 000000000..fd003fb8f --- /dev/null +++ b/patch/ros-rolling-pointcloud-to-laserscan.win.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d13488c..ea62844 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -3,6 +3,12 @@ project(pointcloud_to_laserscan) + + find_package(ament_cmake REQUIRED) + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set (pointcloud_to_laserscan_node.cpp uses M_PI unconditionally). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + find_package(laser_geometry REQUIRED) + find_package(message_filters REQUIRED) + find_package(rclcpp REQUIRED) diff --git a/patch/ros-rolling-py-binding-tools.patch b/patch/ros-rolling-py-binding-tools.patch new file mode 100644 index 000000000..4c7b7022e --- /dev/null +++ b/patch/ros-rolling-py-binding-tools.patch @@ -0,0 +1,18 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index aee2f26a..eb358c39 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -12,6 +12,12 @@ add_library(${PROJECT_NAME} SHARED + src/ros_msg_typecasters.cpp + src/initializer.cpp + ) ++# The rclcpp pybind11 module (below) links against this library directly, ++# so it needs an import .lib on Windows for the plain py_binding_tools:: ++# namespace functions (init/add_node/shutdown) -- this SHARED library has ++# no dllexport annotations on them, so without this MSVC's .lib ends up ++# missing those specific symbols. ++set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + target_include_directories(${PROJECT_NAME} + PUBLIC + $ + diff --git a/patch/ros-rolling-rclc-examples.patch b/patch/ros-rolling-rclc-examples.patch new file mode 100644 index 000000000..09e9ce8fb --- /dev/null +++ b/patch/ros-rolling-rclc-examples.patch @@ -0,0 +1,105 @@ +diff --git a/src/example_executor.c b/src/example_executor.c +index cf40fda..0b6d8df 100644 +--- a/src/example_executor.c ++++ b/src/example_executor.c +@@ -36,7 +36,7 @@ void my_subscriber_callback(const void * msgin) + } + } + +-void my_timer_callback(rcl_timer_t * timer, int64_t last_call_time) ++void my_timer_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + rcl_ret_t rc; + RCLC_UNUSED(last_call_time); +diff --git a/src/example_executor_only_rcl.c b/src/example_executor_only_rcl.c +index a72202d..2837bf7 100644 +--- a/src/example_executor_only_rcl.c ++++ b/src/example_executor_only_rcl.c +@@ -36,7 +36,7 @@ void my_subscriber_callback(const void * msgin) + } + } + +-void my_timer_callback(rcl_timer_t * timer, int64_t last_call_time) ++void my_timer_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + rcl_ret_t rc; + RCLC_UNUSED(last_call_time); +diff --git a/src/example_executor_trigger.c b/src/example_executor_trigger.c +index 400260e..3cb0dac 100644 +--- a/src/example_executor_trigger.c ++++ b/src/example_executor_trigger.c +@@ -136,7 +136,7 @@ void my_int_subscriber_callback(const void * msgin) + + #define RCLC_UNUSED(x) (void)x + +-void my_timer_string_callback(rcl_timer_t * timer, int64_t last_call_time) ++void my_timer_string_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + rcl_ret_t rc; + rcl_allocator_t allocator = rcl_get_default_allocator(); +@@ -164,7 +164,7 @@ void my_timer_string_callback(rcl_timer_t * timer, int64_t last_call_time) + } + } + +-void my_timer_int_callback(rcl_timer_t * timer, int64_t last_call_time) ++void my_timer_int_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + rcl_ret_t rc; + RCLC_UNUSED(last_call_time); +diff --git a/src/example_parameter_server.c b/src/example_parameter_server.c +index 94fd8db..b125cd1 100644 +--- a/src/example_parameter_server.c ++++ b/src/example_parameter_server.c +@@ -24,7 +24,7 @@ + + rclc_parameter_server_t param_server; + +-void timer_callback(rcl_timer_t * timer, int64_t last_call_time) ++void timer_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + (void) timer; + (void) last_call_time; +diff --git a/src/example_pingpong.cpp b/src/example_pingpong.cpp +index 69fdfc7..ae19c5c 100644 +--- a/src/example_pingpong.cpp ++++ b/src/example_pingpong.cpp +@@ -55,7 +55,7 @@ public: + + /***************************** PING NODE CALLBACKS ***********************************/ + +-void ping_timer_callback(rcl_timer_t * timer, int64_t last_call_time) ++void ping_timer_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + rcl_ret_t rc; + RCLC_UNUSED(last_call_time); +@@ -99,7 +99,7 @@ void ping_subscription_callback(const void * msgin) + } + } + +-void pong_timer_callback(rcl_timer_t * timer, int64_t last_call_time) ++void pong_timer_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + rcl_ret_t rc; + RCLC_UNUSED(last_call_time); +diff --git a/src/example_short_timer_long_subscription.c b/src/example_short_timer_long_subscription.c +index 746b037..bfab2b6 100644 +--- a/src/example_short_timer_long_subscription.c ++++ b/src/example_short_timer_long_subscription.c +@@ -41,7 +41,7 @@ void my_subscriber_callback(const void * msgin) + } + } + +-void my_timer_callback(rcl_timer_t * timer, int64_t last_call_time) ++void my_timer_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + rcl_ret_t rc; + RCLC_UNUSED(last_call_time); +@@ -60,7 +60,7 @@ void my_timer_callback(rcl_timer_t * timer, int64_t last_call_time) + } + } + +-void short_timer_callback(rcl_timer_t * timer, int64_t last_call_time) ++void short_timer_callback(rcl_timer_t * timer, int64_t last_call_time, uintptr_t) + { + RCLC_UNUSED(timer); + RCLC_UNUSED(last_call_time); diff --git a/patch/ros-rolling-realsense2-camera.patch b/patch/ros-rolling-realsense2-camera.patch new file mode 100644 index 000000000..146e0e242 --- /dev/null +++ b/patch/ros-rolling-realsense2-camera.patch @@ -0,0 +1,21 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 470f8c3c..01fbff80 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -36,11 +36,14 @@ option(USE_LIFECYCLE_NODE "Enable lifecycle nodes (ON/OFF)" OFF) + # Compiler Defense Flags + if(UNIX OR APPLE) + # Linker flags. +- if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") ++ # NOTE: these are Linux/ELF-specific (-z is a GNU ld option; Apple's ld doesn't ++ # understand it at all and fails outright), so they must not apply on APPLE ++ # even though APPLE also sets UNIX. ++ if(NOT APPLE AND (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")) + # GCC specific flags. ICC is compatible with them. + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack -z relro -z now") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack -z relro -z now") +- elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") ++ elseif(NOT APPLE AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + # In Clang, -z flags are not compatible, they need to be passed to linker via -Wl. + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now") diff --git a/patch/ros-rolling-realsense2-camera.win.patch b/patch/ros-rolling-realsense2-camera.win.patch new file mode 100644 index 000000000..626ad3235 --- /dev/null +++ b/patch/ros-rolling-realsense2-camera.win.patch @@ -0,0 +1,42 @@ +diff --git a/src/rs_node_setup.cpp b/src/rs_node_setup.cpp +index 2103ad9..b11f8b1 100755 +--- a/src/rs_node_setup.cpp ++++ b/src/rs_node_setup.cpp +@@ -366,7 +366,15 @@ void BaseRealSenseNode::startPublishers(const std::vector& profi + _metadata_publishers[sip] = _node.create_publisher(topic_metadata, + rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(info_qos), info_qos)); + +- if (!((rs2::stream_profile)profile==(rs2::stream_profile)_base_profile)) ++ // rs2::stream_profile::operator== is a non-const member and MSVC ++ // reports it as ambiguous against another candidate here (C2666, ++ // "overloaded functions have similar conversions") even though ++ // GCC/Clang accept it. Compare the same fields the operator itself ++ // checks (all const accessors), sidestepping overload resolution. ++ if (!(profile.stream_index() == _base_profile.stream_index() && ++ profile.stream_type() == _base_profile.stream_type() && ++ profile.format() == _base_profile.format() && ++ profile.fps() == _base_profile.fps())) + { + + // intra-process do not support latched QoS, so we need to disable intra-process for this topic +diff --git a/src/ros_sensor.cpp b/src/ros_sensor.cpp +index fd95c72..b591a88 100644 +--- a/src/ros_sensor.cpp ++++ b/src/ros_sensor.cpp +@@ -332,7 +332,15 @@ bool profiles_equal(const rs2::stream_profile& a, const rs2::stream_profile& b) + auto vb = b.as(); + return (va == vb && va.width() == vb.width() && va.height() == vb.height()); + } +- return ((rs2::stream_profile)a==(rs2::stream_profile)b); ++ // rs2::stream_profile::operator== is a non-const member and MSVC ++ // reports it as ambiguous against another candidate here (C2666, ++ // "overloaded functions have similar conversions") even though ++ // GCC/Clang accept it. Compare the same fields the operator itself ++ // checks (all const accessors), sidestepping overload resolution. ++ return (a.stream_index() == b.stream_index() && ++ a.stream_type() == b.stream_type() && ++ a.format() == b.format() && ++ a.fps() == b.fps()); + } + + bool is_profiles_in_profiles(const std::vector& sub_profiles, const std::vector& all_profiles) diff --git a/patch/ros-rolling-rmf-api-msgs.win.patch b/patch/ros-rolling-rmf-api-msgs.win.patch new file mode 100644 index 000000000..dbe16fdd3 --- /dev/null +++ b/patch/ros-rolling-rmf-api-msgs.win.patch @@ -0,0 +1,45 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 27156a0..44d4528 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -83,11 +83,20 @@ install( + + # Generate python schemas mode whenever colcon is triggered + message(" Generating schema as py mods") ++# "eval" is a POSIX shell builtin, not a real command -- fails on Windows ++# with "'eval' is not recognized". Pass the command as plain CMake ++# arguments instead of a quoted shell string; portable everywhere. ++# conda-forge's Windows Python is "python.exe", not "python3.exe". ++if(WIN32) ++ set(PY_EXECUTABLE_NAME python) ++else() ++ set(PY_EXECUTABLE_NAME python3) ++endif() + ADD_CUSTOM_TARGET( + py_schemas_gen ALL +- COMMAND eval "python3 generate_py_schemas.py \ +- --schemas_dir ${CMAKE_CURRENT_LIST_DIR}/schemas \ +- --output_file ${CMAKE_CURRENT_LIST_DIR}/rmf_api_msgs/schemas.py" ++ COMMAND ${PY_EXECUTABLE_NAME} generate_py_schemas.py ++ --schemas_dir ${CMAKE_CURRENT_LIST_DIR}/schemas ++ --output_file ${CMAKE_CURRENT_LIST_DIR}/rmf_api_msgs/schemas.py + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/scripts) + + # Generate pydantic models according to schemas +@@ -97,11 +106,11 @@ if(PY_MODELGEN_AVAIL) + message(" Generating py models with 'datamodel-codegen'") + ADD_CUSTOM_TARGET( + py_models_gen ALL +- COMMAND eval "datamodel-codegen \ +- --disable-timestamp \ +- --input-file-type jsonschema \ +- --input ${CMAKE_CURRENT_LIST_DIR}/schemas \ +- --output ${CMAKE_CURRENT_LIST_DIR}/rmf_api_msgs/models" ++ COMMAND datamodel-codegen ++ --disable-timestamp ++ --input-file-type jsonschema ++ --input ${CMAKE_CURRENT_LIST_DIR}/schemas ++ --output ${CMAKE_CURRENT_LIST_DIR}/rmf_api_msgs/models + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/scripts) + else() + message( diff --git a/patch/ros-rolling-rmf-battery.win.patch b/patch/ros-rolling-rmf-battery.win.patch new file mode 100644 index 000000000..23919f7b1 --- /dev/null +++ b/patch/ros-rolling-rmf-battery.win.patch @@ -0,0 +1,37 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b00fb4c..c2c608e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -12,6 +12,13 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set. Used both in rmf_traffic's installed Interpolate.hpp ++ # (consumed here) and in this package's own test_battery_drain.cpp. ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + if(NOT CMAKE_BUILD_TYPE) + # Use the Release build type by default if the user has not specified one + set(CMAKE_BUILD_TYPE Release) +@@ -36,6 +43,16 @@ add_library(rmf_battery SHARED + ${core_lib_srcs} + ) + ++if(WIN32) ++ # rmf_battery has no dllexport annotations at all. As a shared library ++ # on Windows with nothing explicitly exported, link.exe does not ++ # produce an import .lib, so every consumer fails with LNK1181 ++ # "cannot open input file 'rmf_battery.lib'" even though ++ # rmf_battery.dll itself builds fine. Auto-export everything, same ++ # fix used for rmf_utils/rmf_traffic earlier in this package family. ++ set_target_properties(rmf_battery PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_link_libraries(rmf_battery + PUBLIC + rmf_utils::rmf_utils + rmf_traffic::rmf_traffic + ) diff --git a/patch/ros-rolling-rmf-building-map-tools.patch b/patch/ros-rolling-rmf-building-map-tools.patch new file mode 100644 index 000000000..94e081e31 --- /dev/null +++ b/patch/ros-rolling-rmf-building-map-tools.patch @@ -0,0 +1,16 @@ +diff --git a/building_map/level.py b/building_map/level.py +index fcb46b3..3c7ce1f 100644 +--- a/building_map/level.py ++++ b/building_map/level.py +@@ -430,7 +430,10 @@ class Level: + b.append(verts[i-1] - verts[i]) + # cross products of the four pairs of vectors. If the four cross + # products have the same sign, then the point is inside the rectangle +- cross = np.cross(a, np.array(b)) ++ # numpy>=2.0 removed support for 2D-vector cross products (used to ++ # return the scalar z-component); compute it directly instead. ++ b_arr = np.array(b) ++ cross = a[:, 0] * b_arr[:, 1] - a[:, 1] * b_arr[:, 0] + if np.all(cross >= 0) or np.all(cross <= 0): + return True + else: diff --git a/patch/ros-rolling-rmf-fleet-adapter-python.win.patch b/patch/ros-rolling-rmf-fleet-adapter-python.win.patch new file mode 100644 index 000000000..c43b7e574 --- /dev/null +++ b/patch/ros-rolling-rmf-fleet-adapter-python.win.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f71ed979..c28faa14 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -14,6 +14,12 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set (used via rmf_traffic's installed agv/Interpolate.hpp). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + if(NOT CMAKE_BUILD_TYPE) + # Use the Release build type by default if the user has not specified one + set(CMAKE_BUILD_TYPE Release) diff --git a/patch/ros-rolling-rmf-fleet-adapter.patch b/patch/ros-rolling-rmf-fleet-adapter.patch new file mode 100644 index 000000000..b9befe535 --- /dev/null +++ b/patch/ros-rolling-rmf-fleet-adapter.patch @@ -0,0 +1,248 @@ +diff --git a/src/door_supervisor/Node.cpp b/src/door_supervisor/Node.cpp +index 5b5f149..8cea0b4 100644 +--- a/src/door_supervisor/Node.cpp ++++ b/src/door_supervisor/Node.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include "Node.hpp" + + #include +diff --git a/src/full_control/main.cpp b/src/full_control/main.cpp +index 6cde76f..cd11f1c 100644 +--- a/src/full_control/main.cpp ++++ b/src/full_control/main.cpp +@@ -16,6 +16,7 @@ + */ + + // Internal implementation-specific headers ++#include + #include "../rmf_fleet_adapter/ParseArgs.hpp" + #include "../rmf_fleet_adapter/load_param.hpp" + +@@ -1039,8 +1040,12 @@ std::shared_ptr make_fleet( + request_msg->fleet_name.empty()) + return; + +- connections->fleet->open_lanes(request_msg->open_lanes); +- connections->fleet->close_lanes(request_msg->close_lanes); ++ connections->fleet->open_lanes( ++ std::vector( ++ request_msg->open_lanes.begin(), request_msg->open_lanes.end())); ++ connections->fleet->close_lanes( ++ std::vector( ++ request_msg->close_lanes.begin(), request_msg->close_lanes.end())); + + std::unordered_set newly_closed_lanes; + for (const auto& l : request_msg->close_lanes) +@@ -1093,7 +1098,9 @@ std::shared_ptr make_fleet( + requests.push_back(std::move(request)); + } + connections->fleet->limit_lane_speeds(requests); +- connections->fleet->remove_speed_limits(request_msg->remove_limits); ++ connections->fleet->remove_speed_limits( ++ std::vector( ++ request_msg->remove_limits.begin(), request_msg->remove_limits.end())); + }); + + connections->interrupt_request_sub = +diff --git a/src/mock_traffic_light/main.cpp b/src/mock_traffic_light/main.cpp +index 3955f2f..0784191 100644 +--- a/src/mock_traffic_light/main.cpp ++++ b/src/mock_traffic_light/main.cpp +@@ -16,6 +16,7 @@ + */ + + // Internal implementation-specific headers ++#include + #include "../rmf_fleet_adapter/ParseArgs.hpp" + #include "../rmf_fleet_adapter/load_param.hpp" + +diff --git a/src/mutex_group_supervisor/main.cpp b/src/mutex_group_supervisor/main.cpp +index 4f07df4..cdea608 100644 +--- a/src/mutex_group_supervisor/main.cpp ++++ b/src/mutex_group_supervisor/main.cpp +@@ -25,6 +25,7 @@ + #include + + #include ++#include + #include + #include + +diff --git a/src/rmf_fleet_adapter/LegacyTask.cpp b/src/rmf_fleet_adapter/LegacyTask.cpp +index bdbb184..191d04a 100644 +--- a/src/rmf_fleet_adapter/LegacyTask.cpp ++++ b/src/rmf_fleet_adapter/LegacyTask.cpp +@@ -22,7 +22,9 @@ + + #include + ++#if defined(__linux__) + #include ++#endif + + namespace rmf_fleet_adapter { + +@@ -157,7 +159,9 @@ void LegacyTask::_start_next_phase() + // + // TODO(MXG): Remove this when the planner has been made more + // memory-efficient. ++#if defined(__linux__) + malloc_trim(0); ++#endif + + return; + } +diff --git a/src/rmf_fleet_adapter/TaskManager.cpp b/src/rmf_fleet_adapter/TaskManager.cpp +index d674422..7fd7861 100644 +--- a/src/rmf_fleet_adapter/TaskManager.cpp ++++ b/src/rmf_fleet_adapter/TaskManager.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include "TaskManager.hpp" + #include "log_to_json.hpp" + +@@ -306,9 +307,9 @@ nlohmann::json& copy_phase_data( + phase_state["category"] = header.category(); + phase_state["detail"] = header.detail(); + phase_state["original_estimate_millis"] = +- std::max(0l, to_millis(header.original_duration_estimate()).count()); ++ std::max(0, to_millis(header.original_duration_estimate()).count()); + phase_state["estimate_millis"] = +- std::max(0l, to_millis(snapshot.estimate_remaining_time()).count()); ++ std::max(0, to_millis(snapshot.estimate_remaining_time()).count()); + phase_state["final_event_id"] = snapshot.final_event()->id(); + auto& event_states = phase_state["events"]; + +@@ -377,7 +378,7 @@ void copy_phase_data( + phase["category"] = header.category(); + phase["detail"] = header.detail(); + phase["estimate_millis"] = +- std::max(0l, to_millis(header.original_duration_estimate()).count()); ++ std::max(0, to_millis(header.original_duration_estimate()).count()); + } + + //============================================================================== +@@ -460,9 +461,9 @@ void TaskManager::ActiveTask::publish_task_state(TaskManager& mgr) + _state_msg["unix_millis_finish_time"] = + to_millis(finish_estimate.time_since_epoch()).count(); + _state_msg["original_estimate_millis"] = +- std::max(0l, to_millis(header.original_duration_estimate()).count()); ++ std::max(0, to_millis(header.original_duration_estimate()).count()); + _state_msg["estimate_millis"] = +- std::max(0l, to_millis(remaining_time_estimate).count()); ++ std::max(0, to_millis(remaining_time_estimate).count()); + copy_assignment(_state_msg["assigned_to"], *mgr._context); + _state_msg["status"] = + status_to_string(_task->status_overview()); +@@ -2355,7 +2356,7 @@ rmf_task::State TaskManager::_publish_pending_task( + + const auto estimate = + pending.finish_state().time().value() - pending.deployment_time(); +- t.original_estimate_millis = std::max(0l, to_millis(estimate).count()); ++ t.original_estimate_millis = std::max(0, to_millis(estimate).count()); + + pending_json["unix_millis_finish_time"] = t.unix_millis_finish_time; + pending_json["original_estimate_millis"] = t.original_estimate_millis; +diff --git a/src/rmf_fleet_adapter/agv/EasyFullControl.cpp b/src/rmf_fleet_adapter/agv/EasyFullControl.cpp +index 9ad2bfd..a3cd5db 100644 +--- a/src/rmf_fleet_adapter/agv/EasyFullControl.cpp ++++ b/src/rmf_fleet_adapter/agv/EasyFullControl.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + #include + #include +diff --git a/src/rmf_fleet_adapter/agv/internal_FleetUpdateHandle.hpp b/src/rmf_fleet_adapter/agv/internal_FleetUpdateHandle.hpp +index 0fa5764..fd42b15 100644 +--- a/src/rmf_fleet_adapter/agv/internal_FleetUpdateHandle.hpp ++++ b/src/rmf_fleet_adapter/agv/internal_FleetUpdateHandle.hpp +@@ -73,7 +73,9 @@ + #include + #include + #include ++#if defined(__linux__) + #include ++#endif + + namespace rmf_fleet_adapter { + namespace agv { +@@ -425,7 +427,11 @@ public: + // TODO(MXG): Remove this when the planner has been made more + // memory-efficient. + handle->_pimpl->memory_trim_timer = handle->_pimpl->node->create_wall_timer( +- std::chrono::minutes(5), []() { malloc_trim(0); }); ++ std::chrono::minutes(5), []() { ++#if defined(__linux__) ++ malloc_trim(0); ++#endif ++ }); + + // Create subs and pubs for bidding + auto transient_qos = rclcpp::QoS(10).transient_local(); +diff --git a/src/rmf_fleet_adapter/events/DynamicEvent.cpp b/src/rmf_fleet_adapter/events/DynamicEvent.cpp +index df79a76..755bc93 100644 +--- a/src/rmf_fleet_adapter/events/DynamicEvent.cpp ++++ b/src/rmf_fleet_adapter/events/DynamicEvent.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include "DynamicEvent.hpp" + #include "../log_to_json.hpp" + +diff --git a/src/rmf_fleet_adapter/events/ExecutePlan.cpp b/src/rmf_fleet_adapter/events/ExecutePlan.cpp +index 60bd109..d4b5e46 100644 +--- a/src/rmf_fleet_adapter/events/ExecutePlan.cpp ++++ b/src/rmf_fleet_adapter/events/ExecutePlan.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include "ExecutePlan.hpp" + #include "LegacyPhaseShim.hpp" + #include "WaitForTraffic.hpp" +@@ -119,7 +120,7 @@ void truncate_arrival( + std::size_t first_excluded_route = 0; + for (const auto& c : wp.arrival_checkpoints()) + { +- first_excluded_route = std::max(first_excluded_route, c.route_id+1); ++ first_excluded_route = std::max(first_excluded_route, static_cast(c.route_id+1)); + auto& r = previous_itinerary.at(c.route_id); + auto& t = r.trajectory(); + +diff --git a/src/rmf_fleet_adapter/events/PerformAction.cpp b/src/rmf_fleet_adapter/events/PerformAction.cpp +index 1b12997..d35177e 100644 +--- a/src/rmf_fleet_adapter/events/PerformAction.cpp ++++ b/src/rmf_fleet_adapter/events/PerformAction.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include "PerformAction.hpp" + + #include +diff --git a/src/rmf_fleet_adapter/services/ProgressEvaluator.cpp b/src/rmf_fleet_adapter/services/ProgressEvaluator.cpp +index 6bf830f..58934cc 100644 +--- a/src/rmf_fleet_adapter/services/ProgressEvaluator.cpp ++++ b/src/rmf_fleet_adapter/services/ProgressEvaluator.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include "ProgressEvaluator.hpp" + + namespace rmf_fleet_adapter { diff --git a/patch/ros-rolling-rmf-fleet-adapter.win.patch b/patch/ros-rolling-rmf-fleet-adapter.win.patch new file mode 100644 index 000000000..d1edac885 --- /dev/null +++ b/patch/ros-rolling-rmf-fleet-adapter.win.patch @@ -0,0 +1,825 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0588eeac..7155d63c 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -10,6 +10,13 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set (used across rmf_traffic/rmf_utils's installed headers and ++ # this package's own agv/RobotContext.hpp, agv/EasyFullControl.cpp). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + find_package(ament_cmake REQUIRED) + find_package(backward_ros REQUIRED) + find_package(Eigen3 REQUIRED) +@@ -84,6 +91,18 @@ add_library(rmf_fleet_adapter SHARED + ${rmf_fleet_adapter_srcs} + ) + ++if(MSVC) ++ # agv/Node.cpp exceeds the default object file section limit. ++ target_compile_options(rmf_fleet_adapter PRIVATE /bigobj) ++ ++ # WINDOWS_EXPORT_ALL_SYMBOLS overflows MSVC's import-lib 65535-object ++ # limit (LNK1189) on this heavily Eigen/nlohmann/rxcpp-templated ++ # library, same as rmf_traffic_ros2. Use explicit ++ # RMF_FLEET_ADAPTER_EXPORT annotations (detail/export.hpp) across ++ # the whole public API instead. ++ target_compile_definitions(rmf_fleet_adapter PRIVATE RMF_FLEET_ADAPTER_BUILDING_DLL) ++endif() ++ + target_link_libraries(rmf_fleet_adapter + PUBLIC + rclcpp::rclcpp +@@ -203,12 +222,25 @@ target_link_libraries(read_only_blockade + + add_executable(full_control src/full_control/main.cpp) + +-target_link_libraries(full_control +- PRIVATE +- rmf_fleet_adapter +- ${rmf_fleet_msgs_LIBRARIES} +- ${rmf_task_msgs_LIBRARIES} +-) ++if(WIN32) ++ # The raw ${..._LIBRARIES} variables below each recursively re-append ++ # their own dependencies' _LIBRARIES as plain strings with no ++ # deduplication, overflowing link.exe's response-file line limit ++ # (LNK1170) -- same issue and fix as rmf_traffic_ros2/rmf_task_ros2. ++ target_link_libraries(full_control ++ PRIVATE ++ rmf_fleet_adapter ++ rmf_fleet_msgs::rmf_fleet_msgs ++ rmf_task_msgs::rmf_task_msgs ++ ) ++else() ++ target_link_libraries(full_control ++ PRIVATE ++ rmf_fleet_adapter ++ ${rmf_fleet_msgs_LIBRARIES} ++ ${rmf_task_msgs_LIBRARIES} ++ ) ++endif() + + target_include_directories(full_control + PRIVATE +@@ -220,12 +252,21 @@ target_include_directories(full_control + + add_executable(mock_traffic_light src/mock_traffic_light/main.cpp) + +-target_link_libraries(mock_traffic_light +- PRIVATE +- rmf_fleet_adapter +- ${rmf_task_msgs_LIBRARIES} +- ${rmf_fleet_msgs_LIBRARIES} +-) ++if(WIN32) ++ target_link_libraries(mock_traffic_light ++ PRIVATE ++ rmf_fleet_adapter ++ rmf_task_msgs::rmf_task_msgs ++ rmf_fleet_msgs::rmf_fleet_msgs ++ ) ++else() ++ target_link_libraries(mock_traffic_light ++ PRIVATE ++ rmf_fleet_adapter ++ ${rmf_task_msgs_LIBRARIES} ++ ${rmf_fleet_msgs_LIBRARIES} ++ ) ++endif() + + target_include_directories(mock_traffic_light + PRIVATE +@@ -280,13 +321,29 @@ add_executable(experimental_lift_watchdog + src/experimental_lift_watchdog/main.cpp + ) + +-target_link_libraries(experimental_lift_watchdog +- PRIVATE +- ${rclcpp_LIBRARIES} +- ${rmf_fleet_msgs_LIBRARIES} +- ${std_msgs_LIBRARIES} +- Threads::Threads +-) ++if(WIN32) ++ # The raw ${..._LIBRARIES} variables below each recursively re-append ++ # their own dependencies' _LIBRARIES as plain strings with no ++ # deduplication, stacking up a lot of repeated full paths. On Windows ++ # CI the concatenated link.exe response-file line exceeded its ++ # ~131071-character limit (LNK1170) -- same issue and same fix as ++ # rmf_traffic_ros2/rmf_task_ros2 hit earlier. ++ target_link_libraries(experimental_lift_watchdog ++ PRIVATE ++ rclcpp::rclcpp ++ rmf_fleet_msgs::rmf_fleet_msgs ++ ${std_msgs_TARGETS} ++ Threads::Threads ++ ) ++else() ++ target_link_libraries(experimental_lift_watchdog ++ PRIVATE ++ ${rclcpp_LIBRARIES} ++ ${rmf_fleet_msgs_LIBRARIES} ++ ${std_msgs_LIBRARIES} ++ Threads::Threads ++ ) ++endif() + + target_include_directories(experimental_lift_watchdog + PRIVATE +@@ -302,12 +359,21 @@ add_executable(door_supervisor + src/door_supervisor/Node.cpp + ) + +-target_link_libraries(door_supervisor +- PRIVATE +- rmf_fleet_adapter +- ${rclcpp_LIBRARIES} +- ${rmf_door_msgs_LIBRARIES} +-) ++if(WIN32) ++ target_link_libraries(door_supervisor ++ PRIVATE ++ rmf_fleet_adapter ++ rclcpp::rclcpp ++ rmf_door_msgs::rmf_door_msgs ++ ) ++else() ++ target_link_libraries(door_supervisor ++ PRIVATE ++ rmf_fleet_adapter ++ ${rclcpp_LIBRARIES} ++ ${rmf_door_msgs_LIBRARIES} ++ ) ++endif() + + target_include_directories(door_supervisor + PRIVATE +@@ -321,6 +387,15 @@ add_library(robot_state_aggregator_main SHARED + src/robot_state_aggregator/RobotStateAggregator.cpp + ) + ++if(MSVC) ++ # COMPOSITION_BUILDING_DLL below is vestigial -- nothing in this ++ # package's sources actually branches on it for dllexport/dllimport, ++ # so this SHARED target has no explicit export annotations at all, ++ # and MSVC produces the .dll but no import .lib. ++ set_target_properties(robot_state_aggregator_main PROPERTIES ++ WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_include_directories(robot_state_aggregator_main + PRIVATE + include +@@ -421,12 +496,21 @@ add_executable(dump_fleet_states + test/dump_fleet_states.cpp + ) + +-target_link_libraries(dump_fleet_states +- PRIVATE +- rmf_fleet_adapter +- ${rclcpp_LIBRARIES} +- ${rmf_fleet_msgs_LIBRARIES} +-) ++if(WIN32) ++ target_link_libraries(dump_fleet_states ++ PRIVATE ++ rmf_fleet_adapter ++ rclcpp::rclcpp ++ rmf_fleet_msgs::rmf_fleet_msgs ++ ) ++else() ++ target_link_libraries(dump_fleet_states ++ PRIVATE ++ rmf_fleet_adapter ++ ${rclcpp_LIBRARIES} ++ ${rmf_fleet_msgs_LIBRARIES} ++ ) ++endif() + + target_include_directories(dump_fleet_states + PRIVATE +diff --git a/rmf_rxcpp/RxCpp-4.1.0/Rx/v2/src/rxcpp/rx-util.hpp b/rmf_rxcpp/RxCpp-4.1.0/Rx/v2/src/rxcpp/rx-util.hpp +index d76fa76a..a7e36281 100644 +--- a/rmf_rxcpp/RxCpp-4.1.0/Rx/v2/src/rxcpp/rx-util.hpp ++++ b/rmf_rxcpp/RxCpp-4.1.0/Rx/v2/src/rxcpp/rx-util.hpp +@@ -713,8 +713,12 @@ namespace detail { + + template + inline auto surely(const std::tuple& tpl) +- -> decltype(apply(tpl, detail::surely())) { +- return apply(tpl, detail::surely()); ++ -> decltype(rxcpp::util::apply(tpl, detail::surely())) { ++ // Fully qualified: an unqualified apply(tpl, ...) call here is ++ // subject to ADL bringing in std::apply (tpl is a std::tuple), and ++ // MSVC resolves the resulting ambiguity differently than GCC/Clang, ++ // instantiating std::tuple_size on the wrong type (C2027/C2131). ++ return rxcpp::util::apply(tpl, detail::surely()); + } + + namespace detail { +diff --git a/include/rmf_fleet_adapter/detail/export.hpp b/include/rmf_fleet_adapter/detail/export.hpp +new file mode 100644 +index 00000000..5847ec21 +--- /dev/null ++++ b/include/rmf_fleet_adapter/detail/export.hpp +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2026 Open Source Robotics Foundation ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++*/ ++ ++#ifndef RMF_FLEET_ADAPTER__DETAIL__EXPORT_HPP ++#define RMF_FLEET_ADAPTER__DETAIL__EXPORT_HPP ++ ++// Blanket WINDOWS_EXPORT_ALL_SYMBOLS overflows MSVC's import-lib ++// 65535-object limit for this heavily Eigen/nlohmann/rxcpp-templated ++// library (same pattern rmf_traffic_ros2 hit), so the public API is ++// exported explicitly instead via this macro. ++#if defined(_WIN32) ++ #if defined(RMF_FLEET_ADAPTER_BUILDING_DLL) ++ #define RMF_FLEET_ADAPTER_EXPORT __declspec(dllexport) ++ #else ++ #define RMF_FLEET_ADAPTER_EXPORT __declspec(dllimport) ++ #endif ++#else ++ #define RMF_FLEET_ADAPTER_EXPORT ++#endif ++ ++#endif // RMF_FLEET_ADAPTER__DETAIL__EXPORT_HPP +diff --git a/include/rmf_fleet_adapter/tasks/ParkRobotIndefinitely.hpp b/include/rmf_fleet_adapter/tasks/ParkRobotIndefinitely.hpp +index 01a2d315..569cdb1d 100644 +--- a/include/rmf_fleet_adapter/tasks/ParkRobotIndefinitely.hpp ++++ b/include/rmf_fleet_adapter/tasks/ParkRobotIndefinitely.hpp +@@ -20,13 +20,15 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace tasks { + + //============================================================================== + /// Use this task factory to make finisher tasks (idle tasks) that will move the + /// robot to a parking spot. +-class ParkRobotIndefinitely : public rmf_task::RequestFactory ++class RMF_FLEET_ADAPTER_EXPORT ParkRobotIndefinitely : public rmf_task::RequestFactory + { + public: + /// Constructor +diff --git a/include/rmf_fleet_adapter/agv/RobotCommandHandle.hpp b/include/rmf_fleet_adapter/agv/RobotCommandHandle.hpp +index 282f856a..6e5e97e5 100644 +--- a/include/rmf_fleet_adapter/agv/RobotCommandHandle.hpp ++++ b/include/rmf_fleet_adapter/agv/RobotCommandHandle.hpp +@@ -20,12 +20,14 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + + //============================================================================== + /// Implement this class to receive robot commands from RMF +-class RobotCommandHandle ++class RMF_FLEET_ADAPTER_EXPORT RobotCommandHandle + { + public: + +diff --git a/include/rmf_fleet_adapter/agv/parse_graph.hpp b/include/rmf_fleet_adapter/agv/parse_graph.hpp +index ad925bdc..c6226f0e 100644 +--- a/include/rmf_fleet_adapter/agv/parse_graph.hpp ++++ b/include/rmf_fleet_adapter/agv/parse_graph.hpp +@@ -23,6 +23,8 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + +@@ -30,6 +32,7 @@ namespace agv { + /// + /// \warning This will throw a std::runtime_error if the file has a syntax + /// error. ++RMF_FLEET_ADAPTER_EXPORT + rmf_traffic::agv::Graph parse_graph( + const std::string& filename, + const rmf_traffic::agv::VehicleTraits& vehicle_traits); +diff --git a/include/rmf_fleet_adapter/agv/Waypoint.hpp b/include/rmf_fleet_adapter/agv/Waypoint.hpp +index ffa92de7..34a7d5af 100644 +--- a/include/rmf_fleet_adapter/agv/Waypoint.hpp ++++ b/include/rmf_fleet_adapter/agv/Waypoint.hpp +@@ -24,11 +24,13 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + + //============================================================================== +-class Waypoint ++class RMF_FLEET_ADAPTER_EXPORT Waypoint + { + public: + +diff --git a/include/rmf_fleet_adapter/agv/Transformation.hpp b/include/rmf_fleet_adapter/agv/Transformation.hpp +index 9b8c5389..f203f065 100644 +--- a/include/rmf_fleet_adapter/agv/Transformation.hpp ++++ b/include/rmf_fleet_adapter/agv/Transformation.hpp +@@ -22,13 +22,15 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + + //============================================================================== + /// A Transformation object that stores the transformation data needed to + /// perform transformation between robot and RMF cartesian frames. +-class Transformation ++class RMF_FLEET_ADAPTER_EXPORT Transformation + { + public: + +diff --git a/include/rmf_fleet_adapter/agv/Adapter.hpp b/include/rmf_fleet_adapter/agv/Adapter.hpp +index c4d90ac6..7aa23875 100644 +--- a/include/rmf_fleet_adapter/agv/Adapter.hpp ++++ b/include/rmf_fleet_adapter/agv/Adapter.hpp +@@ -26,11 +26,13 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + + //============================================================================== +-class Adapter : public std::enable_shared_from_this ++class RMF_FLEET_ADAPTER_EXPORT Adapter : public std::enable_shared_from_this + { + public: + +diff --git a/include/rmf_fleet_adapter/agv/EasyTrafficLight.hpp b/include/rmf_fleet_adapter/agv/EasyTrafficLight.hpp +index 6db7d8b0..4af6b692 100644 +--- a/include/rmf_fleet_adapter/agv/EasyTrafficLight.hpp ++++ b/include/rmf_fleet_adapter/agv/EasyTrafficLight.hpp +@@ -21,11 +21,13 @@ + #include + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + + //============================================================================== +-class EasyTrafficLight : public std::enable_shared_from_this ++class RMF_FLEET_ADAPTER_EXPORT EasyTrafficLight : public std::enable_shared_from_this + { + public: + +diff --git a/include/rmf_fleet_adapter/agv/RobotUpdateHandle.hpp b/include/rmf_fleet_adapter/agv/RobotUpdateHandle.hpp +index 35f9e32e..7da4b9b8 100644 +--- b/include/rmf_fleet_adapter/agv/RobotUpdateHandle.hpp ++++ b/include/rmf_fleet_adapter/agv/RobotUpdateHandle.hpp +@@ -34,6 +34,8 @@ + #include + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + +@@ -41,7 +43,7 @@ namespace agv { + /// You will be given an instance of this class every time you add a new robot + /// to your fleet. Use that instance to send updates to RoMi-H about your + /// robot's state. +-class RobotUpdateHandle ++class RMF_FLEET_ADAPTER_EXPORT RobotUpdateHandle + { + public: + +@@ -149,7 +151,7 @@ public: + + /// Unique identifier for an activity that the robot is performing. Used by + /// the EasyFullControl API. +- class ActivityIdentifier ++ class RMF_FLEET_ADAPTER_EXPORT ActivityIdentifier + { + public: + +@@ -171,7 +173,7 @@ public: + /// + /// When the object is destroyed, the stubbornness will automatically be + /// released. +- class Stubbornness ++ class RMF_FLEET_ADAPTER_EXPORT Stubbornness + { + public: + /// Stop being stubborn +@@ -185,7 +187,7 @@ public: + + /// The ActionExecution class should be used to manage the execution of and + /// provide updates on ongoing actions. +- class ActionExecution ++ class RMF_FLEET_ADAPTER_EXPORT ActionExecution + { + public: + /// Update the amount of time remaining for this action. +@@ -308,7 +310,7 @@ public: + + /// An object to maintain an interruption of the current task. When this + /// object is destroyed, the task will resume. +- class Interruption ++ class RMF_FLEET_ADAPTER_EXPORT Interruption + { + public: + /// Call this function to resume the task while providing labels for +@@ -384,7 +386,7 @@ public: + /// An object to maintain an issue that is happening with the robot. When this + /// object is destroyed without calling resolve(), the issue will be + /// "dropped", which issues a warning to the log. +- class IssueTicket ++ class RMF_FLEET_ADAPTER_EXPORT IssueTicket + { + public: + +@@ -443,7 +445,7 @@ public: + + /// A description of whether the robot should accept dispatched and/or direct + /// tasks. +- class Commission ++ class RMF_FLEET_ADAPTER_EXPORT Commission + { + public: + /// Construct a Commission description with all default values. +@@ -500,7 +502,7 @@ public: + void reassign_dispatched_tasks(); + + /// Information about where the lift will be asked to go for a robot. +- class LiftDestination ++ class RMF_FLEET_ADAPTER_EXPORT LiftDestination + { + public: + /// Name of the lift that is being used. +@@ -523,7 +525,7 @@ public: + + /// This API is experimental and will not be supported in the future. Users + /// are to avoid relying on these feature for any integration. +- class Unstable ++ class RMF_FLEET_ADAPTER_EXPORT Unstable + { + public: + /// True if this robot is allowed to accept new tasks. False if the robot +diff --git a/include/rmf_fleet_adapter/agv/FleetUpdateHandle.hpp b/include/rmf_fleet_adapter/agv/FleetUpdateHandle.hpp +index 75d6945f..a9859f84 100644 +--- b/include/rmf_fleet_adapter/agv/FleetUpdateHandle.hpp ++++ b/include/rmf_fleet_adapter/agv/FleetUpdateHandle.hpp +@@ -39,11 +39,13 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + + //============================================================================== +-class FleetUpdateHandle : public std::enable_shared_from_this ++class RMF_FLEET_ADAPTER_EXPORT FleetUpdateHandle : public std::enable_shared_from_this + { + public: + /// Get the name of the fleet that his handle is managing. +@@ -83,7 +85,7 @@ public: + + /// Confirmation is a class used by the task acceptance callbacks to decide if + /// a task description should be accepted. +- class Confirmation ++ class RMF_FLEET_ADAPTER_EXPORT Confirmation + { + public: + +@@ -233,7 +235,7 @@ public: + std::string emergency_level_name); + + /// A class used to describe speed limit imposed on lanes. +- class SpeedLimitRequest ++ class RMF_FLEET_ADAPTER_EXPORT SpeedLimitRequest + { + public: + /// Constructor +@@ -452,6 +454,7 @@ private: + using FleetUpdateHandlePtr = std::shared_ptr; + using ConstFleetUpdateHandlePtr = std::shared_ptr; + ++RMF_FLEET_ADAPTER_EXPORT + FleetUpdateHandle::ConsiderRequest consider_all(); + + } // namespace agv +diff --git a/include/rmf_fleet_adapter/agv/EasyFullControl.hpp b/include/rmf_fleet_adapter/agv/EasyFullControl.hpp +index 77adf885..30f12e94 100644 +--- a/include/rmf_fleet_adapter/agv/EasyFullControl.hpp ++++ b/include/rmf_fleet_adapter/agv/EasyFullControl.hpp +@@ -44,6 +44,8 @@ + // System headers + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + +@@ -52,7 +54,7 @@ namespace agv { + /// To disable specific tasks, call the respective consider_*_requests() method + /// on the FleetUpdateHandle that can be accessed within this adapter. + //============================================================================== +-class EasyFullControl : public std::enable_shared_from_this ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl : public std::enable_shared_from_this + { + public: + +@@ -147,7 +149,7 @@ private: + using EasyFullControlPtr = std::shared_ptr; + + /// Handle used to update information about one robot +-class EasyFullControl::EasyRobotUpdateHandle ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl::EasyRobotUpdateHandle + { + public: + /// Recommended function for updating information about a robot in an +@@ -202,7 +204,7 @@ private: + }; + + /// The current state of a robot, passed into EasyRobotUpdateHandle::update +-class EasyFullControl::RobotState ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl::RobotState + { + public: + /// Constructor +@@ -247,7 +249,7 @@ private: + + /// The configuration of a robot. These are parameters that typically do not + /// change over time. +-class EasyFullControl::RobotConfiguration ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl::RobotConfiguration + { + public: + +@@ -334,7 +336,7 @@ private: + rmf_utils::impl_ptr _pimpl; + }; + +-class EasyFullControl::RobotCallbacks ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl::RobotCallbacks + { + public: + +@@ -377,7 +379,7 @@ private: + + /// Used by system integrators to give feedback on the progress of executing a + /// navigation or docking command. +-class EasyFullControl::CommandExecution ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl::CommandExecution + { + public: + +@@ -431,7 +433,7 @@ private: + rmf_utils::impl_ptr _pimpl; + }; + +-class EasyFullControl::Destination ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl::Destination + { + public: + /// The name of the map where the destination is located. +@@ -475,7 +477,7 @@ private: + + /// The Configuration class contains parameters necessary to initialize an + /// EasyFullControl fleet instance and add fleets to the adapter. +-class EasyFullControl::FleetConfiguration ++class RMF_FLEET_ADAPTER_EXPORT EasyFullControl::FleetConfiguration + { + public: + +diff --git a/include/rmf_fleet_adapter/agv/test/MockAdapter.hpp b/include/rmf_fleet_adapter/agv/test/MockAdapter.hpp +index 8ae80e1e..60cdb24f 100644 +--- a/include/rmf_fleet_adapter/agv/test/MockAdapter.hpp ++++ b/include/rmf_fleet_adapter/agv/test/MockAdapter.hpp +@@ -25,6 +25,8 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + namespace agv { + namespace test { +@@ -33,7 +35,7 @@ namespace test { + /// This class is an alternative to the Adapter class, but made specifically for + /// testing. It does not try to connect to a Schedule Node or to any Negotiation + /// topics. It keeps its database internal. +-class MockAdapter : public std::enable_shared_from_this ++class RMF_FLEET_ADAPTER_EXPORT MockAdapter : public std::enable_shared_from_this + { + public: + +diff --git a/src/rmf_fleet_adapter/load_param.hpp b/src/rmf_fleet_adapter/load_param.hpp +index 12663d1f..2dc8b738 100644 +--- a/src/rmf_fleet_adapter/load_param.hpp ++++ b/src/rmf_fleet_adapter/load_param.hpp +@@ -29,6 +29,8 @@ + #include + #include + ++#include ++ + namespace rmf_fleet_adapter { + + //============================================================================== +@@ -51,15 +53,18 @@ T get_parameter_or_default( + } + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + std::string get_fleet_name_parameter(rclcpp::Node& node); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + std::chrono::nanoseconds get_parameter_or_default_time( + rclcpp::Node& node, + const std::string& param_name, + const double default_value); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + rmf_traffic::agv::VehicleTraits get_traits_or_default( + rclcpp::Node& node, + const double default_v_nom, const double default_w_nom, +@@ -67,12 +72,14 @@ rmf_traffic::agv::VehicleTraits get_traits_or_default( + const double default_r_f, const double default_r_v); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + std::optional get_battery_system( + rclcpp::Node& node, + const double default_voltage, + const double default_capacity, + const double default_charging_current); + ++RMF_FLEET_ADAPTER_EXPORT + std::optional get_mechanical_system( + rclcpp::Node& node, + const double default_mass, +diff --git a/src/rmf_fleet_adapter/ScheduleManager.hpp b/src/rmf_fleet_adapter/ScheduleManager.hpp +index 006a9df1..3b249ce7 100644 +--- a/src/rmf_fleet_adapter/ScheduleManager.hpp ++++ b/src/rmf_fleet_adapter/ScheduleManager.hpp +@@ -30,10 +30,12 @@ + + #include + ++#include ++ + namespace rmf_fleet_adapter { + + //============================================================================== +-class ScheduleManager ++class RMF_FLEET_ADAPTER_EXPORT ScheduleManager + { + public: + +@@ -81,6 +83,7 @@ private: + }; + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + std::future make_schedule_manager( + rclcpp::Node& node, + rmf_traffic_ros2::schedule::Writer& writer, +@@ -88,6 +91,7 @@ std::future make_schedule_manager( + rmf_traffic::schedule::ParticipantDescription description); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + void async_make_schedule_manager( + rclcpp::Node& node, + rmf_traffic_ros2::schedule::Writer& writer, +diff --git a/src/rmf_fleet_adapter/make_trajectory.hpp b/src/rmf_fleet_adapter/make_trajectory.hpp +index a9f775e3..3bc0cfdb 100644 +--- a/src/rmf_fleet_adapter/make_trajectory.hpp ++++ b/src/rmf_fleet_adapter/make_trajectory.hpp +@@ -24,30 +24,37 @@ + + #include + ++#include ++ + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + rmf_traffic::Trajectory make_trajectory( + const rmf_fleet_msgs::msg::RobotState& state, + const rmf_traffic::agv::VehicleTraits& traits, + bool& is_sitting); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + rmf_traffic::Trajectory make_trajectory( + const rmf_traffic::Time start_time, + const std::vector& path, + const rmf_traffic::agv::VehicleTraits& traits); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + rmf_traffic::Trajectory make_timed_trajectory( + const std::vector& path, + const rmf_traffic::agv::VehicleTraits& traits); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + rmf_traffic::Route make_route( + const rmf_fleet_msgs::msg::RobotState& state, + const rmf_traffic::agv::VehicleTraits& traits, + bool& is_sitting); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + rmf_traffic::Trajectory make_hold( + const rmf_fleet_msgs::msg::Location& location, + const rmf_traffic::Time time, +diff --git a/src/rmf_fleet_adapter/estimation.hpp b/src/rmf_fleet_adapter/estimation.hpp +index 479516ca..54d8b824 100644 +--- a/src/rmf_fleet_adapter/estimation.hpp ++++ b/src/rmf_fleet_adapter/estimation.hpp +@@ -25,6 +25,8 @@ + + #include + ++#include ++ + //============================================================================== + struct TravelInfo + { +@@ -48,18 +50,21 @@ struct TravelInfo + }; + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + void check_path_finish( + rclcpp::Node* node, + const rmf_fleet_msgs::msg::RobotState& state, + TravelInfo& info); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + void estimate_path_traveling( + rclcpp::Node* node, + const rmf_fleet_msgs::msg::RobotState& state, + TravelInfo& info); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + void estimate_midlane_state( + const rmf_fleet_msgs::msg::Location& l, + rmf_utils::optional lane_start, +@@ -67,12 +72,14 @@ void estimate_midlane_state( + TravelInfo& info); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + void estimate_state( + rclcpp::Node* node, + const rmf_fleet_msgs::msg::Location& state, + TravelInfo& info); + + //============================================================================== ++RMF_FLEET_ADAPTER_EXPORT + void estimate_waypoint( + rclcpp::Node* node, + const rmf_fleet_msgs::msg::Location& state, diff --git a/patch/ros-rolling-rmf-task-ros2.win.patch b/patch/ros-rolling-rmf-task-ros2.win.patch new file mode 100644 index 000000000..c12276f53 --- /dev/null +++ b/patch/ros-rolling-rmf-task-ros2.win.patch @@ -0,0 +1,56 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 9dc2b82c..1d248be7 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -30,6 +30,16 @@ find_package(nlohmann_json_schema_validator REQUIRED) + file(GLOB_RECURSE core_lib_srcs "src/rmf_task_ros2/*.cpp") + add_library(rmf_task_ros2 SHARED ${core_lib_srcs}) + ++if(MSVC) ++ # No explicit dllexport annotations anywhere in this target, so ++ # without this MSVC produces the .dll but no companion .lib, and ++ # rmf_task_dispatcher/rmf_bidder_node fail with LNK1181. Only 5 ++ # source files here (vs. rmf_traffic_ros2's 26), so the LNK1189 ++ # 65535-object import-lib limit isn't a concern. ++ set_target_properties(rmf_task_ros2 PROPERTIES ++ WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_link_libraries(rmf_task_ros2 + PUBLIC + ${std_msgs_TARGETS} +@@ -37,12 +47,32 @@ target_link_libraries(rmf_task_ros2 + rmf_traffic::rmf_traffic + rmf_traffic_ros2::rmf_traffic_ros2 + rmf_websocket::rmf_websocket +- ${rmf_task_msgs_LIBRARIES} +- ${rclcpp_LIBRARIES} + nlohmann_json::nlohmann_json + nlohmann_json_schema_validator + ) + ++if(WIN32) ++ # The raw ${..._LIBRARIES} variables below each recursively re-append ++ # their own dependencies' _LIBRARIES as plain strings with no ++ # deduplication, stacking up a lot of repeated full paths. On Windows ++ # CI the concatenated link.exe response-file line exceeded its ++ # ~131071-character limit (LNK1170) -- same issue and same fix as ++ # rmf_traffic_ros2 hit earlier. The aggregate/imported targets let ++ # CMake's target-based link graph dedupe the transitive closure ++ # instead of relinking every path verbatim. ++ target_link_libraries(rmf_task_ros2 ++ PUBLIC ++ rmf_task_msgs::rmf_task_msgs ++ rclcpp::rclcpp ++ ) ++else() ++ target_link_libraries(rmf_task_ros2 ++ PUBLIC ++ ${rmf_task_msgs_LIBRARIES} ++ ${rclcpp_LIBRARIES} ++ ) ++endif() ++ + target_include_directories(rmf_task_ros2 + PUBLIC + $ diff --git a/patch/ros-rolling-rmf-task-sequence.win.patch b/patch/ros-rolling-rmf-task-sequence.win.patch new file mode 100644 index 000000000..3a9f7396d --- /dev/null +++ b/patch/ros-rolling-rmf-task-sequence.win.patch @@ -0,0 +1,32 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 9c585b57..834b5832 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -13,6 +13,12 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set (used via rmf_traffic's installed agv/Interpolate.hpp). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + if(NOT CMAKE_BUILD_TYPE) + # Use the Release build type by default if the user has not specified one + set(CMAKE_BUILD_TYPE Release) +@@ -38,6 +44,14 @@ add_library(rmf_task_sequence SHARED + ${lib_srcs} + ) + ++if(MSVC) ++ # No explicit dllexport annotations anywhere in this target, so ++ # without this MSVC produces the .dll but no companion .lib, and ++ # test_rmf_task_sequence/downstream consumers fail with LNK1181. ++ set_target_properties(rmf_task_sequence PROPERTIES ++ WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_link_libraries(rmf_task_sequence + PUBLIC + rmf_task::rmf_task diff --git a/patch/ros-rolling-rmf-task.patch b/patch/ros-rolling-rmf-task.patch new file mode 100644 index 000000000..2019760fc --- /dev/null +++ b/patch/ros-rolling-rmf-task.patch @@ -0,0 +1,168 @@ +diff --git a/include/rmf_task/Event.hpp b/include/rmf_task/Event.hpp +index 82a3e60..5771d9a 100644 +--- a/include/rmf_task/Event.hpp ++++ b/include/rmf_task/Event.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__EVENT_HPP + #define RMF_TASK__EVENT_HPP + ++#include + #include + #include + +diff --git a/include/rmf_task/Log.hpp b/include/rmf_task/Log.hpp +index f046442..f62062d 100644 +--- a/include/rmf_task/Log.hpp ++++ b/include/rmf_task/Log.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__LOG_HPP + #define RMF_TASK__LOG_HPP + ++#include + #include + + #include +diff --git a/include/rmf_task/Payload.hpp b/include/rmf_task/Payload.hpp +index 084da6a..f6448f7 100644 +--- a/include/rmf_task/Payload.hpp ++++ b/include/rmf_task/Payload.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__PAYLOAD_HPP + #define RMF_TASK__PAYLOAD_HPP + ++#include + #include + + #include +diff --git a/include/rmf_task/Phase.hpp b/include/rmf_task/Phase.hpp +index 666ca1b..cf024b6 100644 +--- a/include/rmf_task/Phase.hpp ++++ b/include/rmf_task/Phase.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__PHASE_HPP + #define RMF_TASK__PHASE_HPP + ++#include + #include + #include + +diff --git a/include/rmf_task/Task.hpp b/include/rmf_task/Task.hpp +index 6c5f419..3b8d83d 100644 +--- a/include/rmf_task/Task.hpp ++++ b/include/rmf_task/Task.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__TASK_HPP + #define RMF_TASK__TASK_HPP + ++#include + #include + #include + #include +diff --git a/include/rmf_task/TaskPlanner.hpp b/include/rmf_task/TaskPlanner.hpp +index 14488f6..ec5dd10 100644 +--- a/include/rmf_task/TaskPlanner.hpp ++++ b/include/rmf_task/TaskPlanner.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__AGV__TASKPLANNER_HPP + #define RMF_TASK__AGV__TASKPLANNER_HPP + ++#include + #include + #include + #include +diff --git a/include/rmf_task/detail/Backup.hpp b/include/rmf_task/detail/Backup.hpp +index 5a9ad72..c68e959 100644 +--- a/include/rmf_task/detail/Backup.hpp ++++ b/include/rmf_task/detail/Backup.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__DETAIL__BACKUP_HPP + #define RMF_TASK__DETAIL__BACKUP_HPP + ++#include + #include + + #include +diff --git a/include/rmf_task/events/SimpleEventState.hpp b/include/rmf_task/events/SimpleEventState.hpp +index c90d528..1496e2a 100644 +--- a/include/rmf_task/events/SimpleEventState.hpp ++++ b/include/rmf_task/events/SimpleEventState.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TASK__EVENTS__SIMPLEEVENTSTATE_HPP + #define RMF_TASK__EVENTS__SIMPLEEVENTSTATE_HPP + ++#include + #include + + namespace rmf_task { +diff --git a/src/rmf_task/BackupFileManager.cpp b/src/rmf_task/BackupFileManager.cpp +index 7afa25d..992489b 100644 +--- a/src/rmf_task/BackupFileManager.cpp ++++ b/src/rmf_task/BackupFileManager.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + #include + #include +diff --git a/src/rmf_task/Event.cpp b/src/rmf_task/Event.cpp +index 2cb42b8..b5ac0ca 100644 +--- a/src/rmf_task/Event.cpp ++++ b/src/rmf_task/Event.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + + namespace rmf_task { +diff --git a/src/rmf_task/Log.cpp b/src/rmf_task/Log.cpp +index 48c5883..84707a7 100644 +--- a/src/rmf_task/Log.cpp ++++ b/src/rmf_task/Log.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + + #include +diff --git a/src/rmf_task/Payload.cpp b/src/rmf_task/Payload.cpp +index 8d031ce..8413f1e 100644 +--- a/src/rmf_task/Payload.cpp ++++ b/src/rmf_task/Payload.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + #include + #include +diff --git a/src/rmf_task/detail/Backup.cpp b/src/rmf_task/detail/Backup.cpp +index f353157..9f0e66b 100644 +--- a/src/rmf_task/detail/Backup.cpp ++++ b/src/rmf_task/detail/Backup.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + + namespace rmf_task { +diff --git a/src/rmf_task/events/SimpleEventState.cpp b/src/rmf_task/events/SimpleEventState.cpp +index 1af9d68..0bc4bab 100644 +--- a/src/rmf_task/events/SimpleEventState.cpp ++++ b/src/rmf_task/events/SimpleEventState.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include + + namespace rmf_task { diff --git a/patch/ros-rolling-rmf-task.win.patch b/patch/ros-rolling-rmf-task.win.patch new file mode 100644 index 000000000..64218cd81 --- /dev/null +++ b/patch/ros-rolling-rmf-task.win.patch @@ -0,0 +1,86 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d4d1647..42ab1ee 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -13,6 +13,12 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set (used via rmf_traffic's installed Interpolate.hpp). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + if(NOT CMAKE_BUILD_TYPE) + # Use the Release build type by default if the user has not specified one + set(CMAKE_BUILD_TYPE Release) +@@ -39,6 +45,16 @@ add_library(rmf_task SHARED + ${lib_srcs} + ) + ++if(WIN32) ++ # rmf_task has no dllexport annotations at all. As a shared library on ++ # Windows with nothing explicitly exported, link.exe does not produce ++ # an import .lib, so every consumer fails with LNK1181 "cannot open ++ # input file 'rmf_task.lib'" even though rmf_task.dll itself builds ++ # fine. Auto-export everything, same fix as rmf_utils/rmf_traffic/ ++ # rmf_battery earlier in this package family. ++ set_target_properties(rmf_task PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_link_libraries(rmf_task + PUBLIC + rmf_battery::rmf_battery +diff --git a/src/rmf_task/BackupFileManager.cpp b/src/rmf_task/BackupFileManager.cpp +index 7afa25d..15bd7ad 100644 +--- a/src/rmf_task/BackupFileManager.cpp ++++ b/src/rmf_task/BackupFileManager.cpp +@@ -127,9 +127,14 @@ public: + std::optional last_seq; + const std::string backup_file_name = "backup"; + const std::string pre_backup_file_name = ".backup"; +- const std::string pre_backup_file_path = robot_directory / +- pre_backup_file_name; +- const std::string backup_file_path = robot_directory / backup_file_name; ++ // std::filesystem::path has no implicit conversion to std::string (only ++ // the explicit .string() member) -- GCC/libstdc++ tolerates constructing ++ // a string directly from a path here, but MSVC's STL correctly rejects ++ // it (C2665). Call .string() explicitly; portable everywhere. ++ const std::string pre_backup_file_path = (robot_directory / ++ pre_backup_file_name).string(); ++ const std::string backup_file_path = ++ (robot_directory / backup_file_name).string(); + + void write_if_new(const Task::Active::Backup& backup) + { +diff --git a/test/unit/test_Log.cpp b/test/unit/test_Log.cpp +index f15e519..0c3c69d 100644 +--- a/test/unit/test_Log.cpp ++++ b/test/unit/test_Log.cpp +@@ -95,9 +95,9 @@ SCENARIO("Multi-threaded read/write with synced view") + std::random_device r; + std::default_random_engine eng(r()); + std::uniform_real_distribution entry_dist(0, 1); +- std::uniform_int_distribution tier_dist( +- static_cast(rmf_task::Log::Tier::Info), +- static_cast(rmf_task::Log::Tier::Error)); ++ std::uniform_int_distribution tier_dist( ++ static_cast(rmf_task::Log::Tier::Info), ++ static_cast(rmf_task::Log::Tier::Error)); + + std::size_t counter = 0; + while (!test_finished->load()) +@@ -196,9 +196,9 @@ SCENARIO("Multi-threaded read/write without syncing") + std::random_device r; + std::default_random_engine eng(r()); + std::uniform_real_distribution entry_dist(0, 1); +- std::uniform_int_distribution tier_dist( +- static_cast(rmf_task::Log::Tier::Info), +- static_cast(rmf_task::Log::Tier::Error)); ++ std::uniform_int_distribution tier_dist( ++ static_cast(rmf_task::Log::Tier::Info), ++ static_cast(rmf_task::Log::Tier::Error)); + + std::size_t counter = 0; + while (!test_finished->load()) diff --git a/patch/ros-rolling-rmf-traffic-ros2.patch b/patch/ros-rolling-rmf-traffic-ros2.patch new file mode 100644 index 000000000..51425713d --- /dev/null +++ b/patch/ros-rolling-rmf-traffic-ros2.patch @@ -0,0 +1,39 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 9bfd3b5..a05ec3e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -180,6 +180,7 @@ add_library(rmf_traffic_ros2 SHARED ${core_lib_srcs}) + target_link_libraries(rmf_traffic_ros2 + PUBLIC + rmf_traffic::rmf_traffic ++ Eigen3::Eigen + nlohmann_json::nlohmann_json + ${rmf_traffic_msgs_LIBRARIES} + ${rmf_site_map_msgs_LIBRARIES} +diff --git a/cmake/FindLibUUID.cmake b/cmake/FindLibUUID.cmake +index 9bd1663..f1bccd7 100644 +--- a/cmake/FindLibUUID.cmake ++++ b/cmake/FindLibUUID.cmake +@@ -42,6 +42,22 @@ They may be set by end users to point at LibUUID components. + #]=======================================================================] + + #----------------------------------------------------------------------------- ++if(APPLE) ++ # macOS provides uuid_generate() etc. and uuid/uuid.h directly via the SDK's ++ # default system search paths (libSystem) -- there is no standalone ++ # libuuid.dylib to link, and no extra include dir is needed (adding the SDK's ++ # own usr/include explicitly confuses libc++'s header self-checks). Just ++ # declare an empty INTERFACE target so callers' target_link_libraries still ++ # resolves. ++ set(LibUUID_FOUND TRUE) ++ set(LIBUUID_FOUND TRUE) ++ set(LibUUID_INCLUDE_DIRS "") ++ set(LibUUID_LIBRARIES "") ++ if(NOT TARGET LibUUID::LibUUID) ++ add_library(LibUUID::LibUUID INTERFACE IMPORTED) ++ endif() ++ return() ++endif() + if(CYGWIN) + # Note: on current version of Cygwin, linking to libuuid.dll.a doesn't + # import the right symbols sometimes. Fix this by linking directly diff --git a/patch/ros-rolling-rmf-traffic-ros2.win.patch b/patch/ros-rolling-rmf-traffic-ros2.win.patch new file mode 100644 index 000000000..67b8830a5 --- /dev/null +++ b/patch/ros-rolling-rmf-traffic-ros2.win.patch @@ -0,0 +1,1056 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a05ec3e2..409ae76f 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -11,6 +11,13 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") + endif() + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set (used via rmf_traffic's installed Moderator.hpp and this ++ # package's own blockade/Node.cpp). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/cmake) + + include(GNUInstallDirs) +@@ -27,15 +34,29 @@ find_package(rclcpp REQUIRED) + find_package(yaml-cpp REQUIRED) + find_package(nlohmann_json REQUIRED) + find_package(ZLIB REQUIRED) +-find_package(LibUUID REQUIRED) ++if(NOT WIN32) ++ # libuuid is a Linux/macOS-only library (Windows has its own native ++ # UUID API, RPC's UuidCreate/UuidToStringA, used directly in ++ # schedule/Node.cpp instead). ++ find_package(LibUUID REQUIRED) ++endif() + find_package(rmf_reservation_msgs REQUIRED) + + +-# NOTE(MXG): libproj-dev does not currently distribute its cmake config-files +-# in Debian, so we can't use find_package and need to rely on pkg-config. +-# find_package(PROJ REQUIRED) +-find_package(PkgConfig REQUIRED) +-pkg_check_modules(PROJ REQUIRED IMPORTED_TARGET proj) ++if(WIN32) ++ # conda-forge's Windows proj package exports a proper CMake config ++ # with a PROJ::proj imported target using the correct absolute ++ # import-lib path; the pkg-config route below resolves to a bare ++ # "proj_9" name that MSVC's linker can't find (LNK1181). ++ find_package(PROJ CONFIG REQUIRED) ++else() ++ # NOTE(MXG): libproj-dev does not currently distribute its cmake ++ # config-files in Debian, so we can't use find_package and need to ++ # rely on pkg-config. ++ # find_package(PROJ REQUIRED) ++ find_package(PkgConfig REQUIRED) ++ pkg_check_modules(PROJ REQUIRED IMPORTED_TARGET proj) ++endif() + + if (rmf_traffic_FOUND) + message(STATUS "found rmf_traffic") +@@ -177,23 +198,78 @@ endif() + file(GLOB_RECURSE core_lib_srcs "src/rmf_traffic_ros2/*.cpp") + add_library(rmf_traffic_ros2 SHARED ${core_lib_srcs}) + ++if(MSVC) ++ # schedule/Node.cpp exceeds the default object file section limit. ++ target_compile_options(rmf_traffic_ros2 PRIVATE /bigobj) ++ ++ # WINDOWS_EXPORT_ALL_SYMBOLS overflows MSVC's import-lib 65535-object ++ # limit (LNK1189) on this heavily Eigen/nlohmann-templated library. ++ # Use explicit RMF_TRAFFIC_ROS2_EXPORT annotations (detail/export.hpp) ++ # on just the symbols this package's own executables need instead. ++ target_compile_definitions(rmf_traffic_ros2 PRIVATE RMF_TRAFFIC_ROS2_BUILDING_DLL) ++endif() ++ + target_link_libraries(rmf_traffic_ros2 + PUBLIC + rmf_traffic::rmf_traffic + Eigen3::Eigen + nlohmann_json::nlohmann_json +- ${rmf_traffic_msgs_LIBRARIES} +- ${rmf_site_map_msgs_LIBRARIES} +- ${rmf_building_map_msgs_LIBRARIES} +- ${rmf_reservation_msgs_LIBRARIES} +- ${rclcpp_LIBRARIES} +- yaml-cpp + ZLIB::ZLIB +- PkgConfig::PROJ +- PRIVATE +- LibUUID::LibUUID + ) + ++if(WIN32) ++ target_link_libraries(rmf_traffic_ros2 PRIVATE PROJ::proj) ++else() ++ target_link_libraries(rmf_traffic_ros2 PUBLIC PkgConfig::PROJ) ++endif() ++ ++if(WIN32) ++ # The bare "yaml-cpp" name only resolves for Unix linkers, which apply ++ # the implicit lib. convention; MSVC looks for a ++ # literal yaml-cpp.lib and fails with LNK1181. Use the actual ++ # imported target instead. ++ target_link_libraries(rmf_traffic_ros2 PUBLIC yaml-cpp::yaml-cpp) ++else() ++ target_link_libraries(rmf_traffic_ros2 PUBLIC yaml-cpp) ++endif() ++ ++if(WIN32) ++ # The raw ${..._LIBRARIES} variables below each recursively re-append ++ # their own dependencies' _LIBRARIES as plain strings with no ++ # deduplication, so linking four message packages plus rclcpp this ++ # way stacks up a lot of repeated full paths. On Windows CI the ++ # concatenated link.exe response-file line exceeded its ++ # ~131071-character limit (LNK1170). The :: aggregate ++ # imported targets (exported by rosidl/rclcpp specifically to ++ # replace the legacy _LIBRARIES variables) let CMake's target-based ++ # link graph dedupe the transitive closure instead. ++ target_link_libraries(rmf_traffic_ros2 ++ PUBLIC ++ rmf_traffic_msgs::rmf_traffic_msgs ++ rmf_site_map_msgs::rmf_site_map_msgs ++ rmf_building_map_msgs::rmf_building_map_msgs ++ rmf_reservation_msgs::rmf_reservation_msgs ++ rclcpp::rclcpp ++ ) ++else() ++ target_link_libraries(rmf_traffic_ros2 ++ PUBLIC ++ ${rmf_traffic_msgs_LIBRARIES} ++ ${rmf_site_map_msgs_LIBRARIES} ++ ${rmf_building_map_msgs_LIBRARIES} ++ ${rmf_reservation_msgs_LIBRARIES} ++ ${rclcpp_LIBRARIES} ++ ) ++endif() ++ ++if(NOT WIN32) ++ target_link_libraries(rmf_traffic_ros2 PRIVATE LibUUID::LibUUID) ++else() ++ # Windows' native UUID API (used directly in schedule/Node.cpp ++ # instead of libuuid) lives in rpcrt4. ++ target_link_libraries(rmf_traffic_ros2 PRIVATE rpcrt4) ++endif() ++ + target_include_directories(rmf_traffic_ros2 + PUBLIC + $ +@@ -219,6 +295,20 @@ ament_export_dependencies( + ZLIB + ) + ++if(WIN32) ++ # rmf_building_map_msgs::rmf_building_map_msgs and ++ # rmf_reservation_msgs::rmf_reservation_msgs (the aggregate targets ++ # used on Windows instead of the raw _LIBRARIES variables, see the ++ # LNK1170 fix above) are part of this package's PUBLIC link ++ # interface, but were never in ament_export_dependencies() -- on ++ # non-Windows this was harmless (raw path lists don't need ++ # find_dependency), but on Windows any downstream consumer's own ++ # find_package(rmf_traffic_ros2) needs these targets to already ++ # exist, or CMake's generate step fails with "target ... was not ++ # found" (first hit by rmf_task_ros2). ++ ament_export_dependencies(rmf_building_map_msgs rmf_reservation_msgs) ++endif() ++ + # TODO(MXG): Change these executables into shared libraries that can act as + # ROS2 node components + +diff --git a/include/rmf_traffic_ros2/detail/export.hpp b/include/rmf_traffic_ros2/detail/export.hpp +new file mode 100644 +index 00000000..a8117028 +--- /dev/null ++++ b/include/rmf_traffic_ros2/detail/export.hpp +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2026 Open Source Robotics Foundation ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++*/ ++ ++#ifndef RMF_TRAFFIC_ROS2__DETAIL__EXPORT_HPP ++#define RMF_TRAFFIC_ROS2__DETAIL__EXPORT_HPP ++ ++// Blanket WINDOWS_EXPORT_ALL_SYMBOLS overflows MSVC's import-lib ++// 65535-object limit for this heavily Eigen/nlohmann-templated library ++// (LNK1189), so the small set of symbols actually needed by this ++// package's own executables are exported explicitly instead. ++#if defined(_WIN32) ++ #if defined(RMF_TRAFFIC_ROS2_BUILDING_DLL) ++ #define RMF_TRAFFIC_ROS2_EXPORT __declspec(dllexport) ++ #else ++ #define RMF_TRAFFIC_ROS2_EXPORT __declspec(dllimport) ++ #endif ++#else ++ #define RMF_TRAFFIC_ROS2_EXPORT ++#endif ++ ++#endif // RMF_TRAFFIC_ROS2__DETAIL__EXPORT_HPP +diff --git a/src/rmf_traffic_ros2/schedule/Node.cpp b/src/rmf_traffic_ros2/schedule/Node.cpp +index 7b2902d4..ef950ef0 100644 +--- a/src/rmf_traffic_ros2/schedule/Node.cpp ++++ b/src/rmf_traffic_ros2/schedule/Node.cpp +@@ -17,6 +17,8 @@ + + #include "internal_Node.hpp" + ++#include ++ + #include + + #include +@@ -37,7 +39,26 @@ + #include + + #include ++#ifdef _WIN32 ++// libuuid (uuid/uuid.h) is Linux/macOS-only; use Windows' native RPC ++// UUID API instead (linked against rpcrt4 in CMakeLists.txt). ++// NOMINMAX/WIN32_LEAN_AND_MEAN/NOGDI keep windows.h (pulled in by rpc.h) ++// from defining min/max (collides with std::numeric_limits::max) and, ++// via wingdi.h, an ERROR macro (collides with ++// RequestChanges::Response::ERROR used later in this file). ++#ifndef NOMINMAX ++#define NOMINMAX ++#endif ++#ifndef WIN32_LEAN_AND_MEAN ++#define WIN32_LEAN_AND_MEAN ++#endif ++#ifndef NOGDI ++#define NOGDI ++#endif ++#include ++#else + #include ++#endif + + namespace rmf_traffic_ros2 { + namespace schedule { +@@ -46,17 +67,27 @@ namespace { + //============================================================================== + ScheduleNode::ScheduleId generate_node_id() + { ++#ifdef _WIN32 ++ UUID raw_uuid; ++ UuidCreate(&raw_uuid); ++ RPC_CSTR uuid_cstr = nullptr; ++ UuidToStringA(&raw_uuid, &uuid_cstr); ++ const std::string uuid(reinterpret_cast(uuid_cstr)); ++ RpcStringFreeA(&uuid_cstr); ++#else + uuid_t raw_uuid; + uuid_generate(raw_uuid); + // According to these docs, the size of the uuid string will be + // 36 bytes + '\n' so we make a buffer of 37. +- char uuid[37]; +- uuid_unparse(raw_uuid, uuid); ++ char uuid_buf[37]; ++ uuid_unparse(raw_uuid, uuid_buf); ++ const std::string uuid(uuid_buf); ++#endif + const rclcpp::Time time( + std::chrono::system_clock::now().time_since_epoch().count()); + + return rmf_traffic_msgs::build() +- .node_uuid(std::string(uuid)) ++ .node_uuid(uuid) + .timestamp(time); + } + +diff --git a/include/rmf_traffic_ros2/schedule/Negotiation.hpp b/include/rmf_traffic_ros2/schedule/Negotiation.hpp +index 318939ef..018f3bba 100644 +--- a/include/rmf_traffic_ros2/schedule/Negotiation.hpp ++++ b/include/rmf_traffic_ros2/schedule/Negotiation.hpp +@@ -26,12 +26,14 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace schedule { + + //============================================================================== + /// A ROS2 interface for negotiating solutions to schedule conflicts +-class Negotiation ++class RMF_TRAFFIC_ROS2_EXPORT Negotiation + { + public: + +@@ -109,7 +111,7 @@ public: + /// + /// \param[in] count + /// The number of negotiations to retain +- void set_retained_history_count(uint count); ++ void set_retained_history_count(unsigned int count); + + /// Register a negotiator with this Negotiation manager. + /// +diff --git a/src/rmf_traffic_ros2/schedule/Negotiation.cpp b/src/rmf_traffic_ros2/schedule/Negotiation.cpp +index 62f9307..1baa196 100644 +--- a/src/rmf_traffic_ros2/schedule/Negotiation.cpp ++++ b/src/rmf_traffic_ros2/schedule/Negotiation.cpp +@@ -303,7 +303,7 @@ public: + std::function; + StatusConclusionCallback conclusion_callback; + +- uint retained_history_count = 0; ++ unsigned int retained_history_count = 0; + std::map history; + + Implementation( +@@ -1031,7 +1031,7 @@ public: + for_participant, negotiators, failure_callbacks); + } + +- void set_retained_history_count(uint count) ++ void set_retained_history_count(unsigned int count) + { + retained_history_count = count; + } +@@ -1130,7 +1130,7 @@ Negotiation::TableViewPtr Negotiation::table_view( + } + + //============================================================================== +-void Negotiation::set_retained_history_count(uint count) ++void Negotiation::set_retained_history_count(unsigned int count) + { + return _pimpl->set_retained_history_count(count); + } +diff --git a/src/rmf_traffic_ros2/schedule/internal_MonitorNode.hpp b/src/rmf_traffic_ros2/schedule/internal_MonitorNode.hpp +index 8d666fed..807aa974 100644 +--- a/src/rmf_traffic_ros2/schedule/internal_MonitorNode.hpp ++++ b/src/rmf_traffic_ros2/schedule/internal_MonitorNode.hpp +@@ -42,7 +42,7 @@ using namespace std::chrono_literals; + class MonitorNode : public rclcpp::Node + { + public: +- static struct NoAutomaticSetup{} no_automatic_setup; ++ inline static struct NoAutomaticSetup{} no_automatic_setup; + + MonitorNode( + std::function)> callback, +diff --git a/src/rmf_traffic_ros2/schedule/internal_Node.hpp b/src/rmf_traffic_ros2/schedule/internal_Node.hpp +index c5c7a7ac..f8351722 100644 +--- a/src/rmf_traffic_ros2/schedule/internal_Node.hpp ++++ b/src/rmf_traffic_ros2/schedule/internal_Node.hpp +@@ -83,7 +83,7 @@ public: + using ScheduleId = rmf_traffic_msgs::msg::ScheduleIdentity; + ScheduleId node_id; + +- static struct NoAutomaticSetup{} no_automatic_setup; ++ inline static struct NoAutomaticSetup{} no_automatic_setup; + + ScheduleNode( + ScheduleId id, +diff --git a/include/rmf_traffic_ros2/schedule/Node.hpp b/include/rmf_traffic_ros2/schedule/Node.hpp +index 0ae4ccbc..8bf6d98e 100644 +--- a/include/rmf_traffic_ros2/schedule/Node.hpp ++++ b/include/rmf_traffic_ros2/schedule/Node.hpp +@@ -20,10 +20,13 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace schedule { + + /// Make a ScheduleNode instance ++RMF_TRAFFIC_ROS2_EXPORT + std::shared_ptr make_node( + const rclcpp::NodeOptions& options = rclcpp::NodeOptions()); + +diff --git a/include/rmf_traffic_ros2/schedule/MonitorNode.hpp b/include/rmf_traffic_ros2/schedule/MonitorNode.hpp +index 18da3ca7..83174457 100644 +--- a/include/rmf_traffic_ros2/schedule/MonitorNode.hpp ++++ b/include/rmf_traffic_ros2/schedule/MonitorNode.hpp +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + using namespace std::chrono_literals; + + namespace rmf_traffic_ros2 { +@@ -30,6 +32,7 @@ namespace schedule { + + /// Make a monitor node to monitor a heartbeat and restart a node when + /// the heartbeat is lost ++RMF_TRAFFIC_ROS2_EXPORT + std::shared_ptr make_monitor_node( + std::function)> callback, + const rclcpp::NodeOptions& options = rclcpp::NodeOptions(), +diff --git a/include/rmf_traffic_ros2/blockade/Node.hpp b/include/rmf_traffic_ros2/blockade/Node.hpp +index dd6379ab..0075c6d8 100644 +--- a/include/rmf_traffic_ros2/blockade/Node.hpp ++++ b/include/rmf_traffic_ros2/blockade/Node.hpp +@@ -20,14 +20,18 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace blockade { + + /// Make a blockade node instance ++RMF_TRAFFIC_ROS2_EXPORT + std::shared_ptr make_node( + const rclcpp::NodeOptions& options = rclcpp::NodeOptions()); + + /// Make a blockade node instance, specifying a node name ++RMF_TRAFFIC_ROS2_EXPORT + std::shared_ptr make_node( + const std::string& node_name, + const rclcpp::NodeOptions& options = rclcpp::NodeOptions()); +diff --git a/include/rmf_traffic_ros2/schedule/Writer.hpp b/include/rmf_traffic_ros2/schedule/Writer.hpp +index cf0cf625..13e17779 100644 +--- a/include/rmf_traffic_ros2/schedule/Writer.hpp ++++ b/include/rmf_traffic_ros2/schedule/Writer.hpp +@@ -23,13 +23,15 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace schedule { + + //============================================================================== + /// The Writer class provides an API that allows a Node to create schedule + /// Participants. +-class Writer : public std::enable_shared_from_this ++class RMF_TRAFFIC_ROS2_EXPORT Writer : public std::enable_shared_from_this + { + public: + +diff --git a/src/rmf_traffic_ros2/schedule/internal_YamlSerialization.hpp b/src/rmf_traffic_ros2/schedule/internal_YamlSerialization.hpp +index 028d6dc0..dc7cdc22 100644 +--- a/src/rmf_traffic_ros2/schedule/internal_YamlSerialization.hpp ++++ b/src/rmf_traffic_ros2/schedule/internal_YamlSerialization.hpp +@@ -25,6 +25,8 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace schedule { + +@@ -41,6 +43,7 @@ rmf_traffic_msgs::msg::ConvexShapeContext shape_context(YAML::Node node); + rmf_traffic::Profile profile(YAML::Node node); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + ParticipantDescription participant_description(YAML::Node node); + + //============================================================================== +diff --git a/include/rmf_traffic_ros2/Profile.hpp b/include/rmf_traffic_ros2/Profile.hpp +index d4c040ab..c6d7a649 100644 +--- a/include/rmf_traffic_ros2/Profile.hpp ++++ b/include/rmf_traffic_ros2/Profile.hpp +@@ -22,12 +22,16 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::Profile convert(const rmf_traffic_msgs::msg::Profile& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::Profile convert(const rmf_traffic::Profile& from); + + } // namespace rmf_traffic_ros2 +diff --git a/include/rmf_traffic_ros2/Route.hpp b/include/rmf_traffic_ros2/Route.hpp +index 19747349..f15a83b5 100644 +--- a/include/rmf_traffic_ros2/Route.hpp ++++ b/include/rmf_traffic_ros2/Route.hpp +@@ -19,19 +19,25 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::Route convert(const rmf_traffic_msgs::msg::Route& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::Route convert(const rmf_traffic::Route& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + std::vector convert( + const std::vector& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + std::vector convert( + const std::vector& from); + +diff --git a/include/rmf_traffic_ros2/Trajectory.hpp b/include/rmf_traffic_ros2/Trajectory.hpp +index 660d220b..7c86184d 100644 +--- a/include/rmf_traffic_ros2/Trajectory.hpp ++++ b/include/rmf_traffic_ros2/Trajectory.hpp +@@ -22,6 +22,8 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== +@@ -31,10 +33,12 @@ namespace rmf_traffic_ros2 { + /// describing the issue. + // TODO(MXG): Consider making conversion functions that do not require any + // allocation. ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::Trajectory convert(const rmf_traffic_msgs::msg::Trajectory& from); + + //============================================================================== + /// Convert from a Trajectory instance to a Trajectory message. ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::Trajectory convert(const rmf_traffic::Trajectory& from); + + } // namespace rmf_traffic_ros2 +diff --git a/include/rmf_traffic_ros2/agv/Graph.hpp b/include/rmf_traffic_ros2/agv/Graph.hpp +index 9603ab94..8959df45 100644 +--- a/include/rmf_traffic_ros2/agv/Graph.hpp ++++ b/include/rmf_traffic_ros2/agv/Graph.hpp +@@ -26,9 +26,12 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::agv::Graph convert(const rmf_site_map_msgs::msg::SiteMap& from, + int graph_idx = 0, double wp_tolerance = 1e-3); + +@@ -36,6 +39,7 @@ rmf_traffic::agv::Graph convert(const rmf_site_map_msgs::msg::SiteMap& from, + /// Convert a valid rmf_building_map_msgs::msg::Graph message to an + /// rmf_traffic::agv::Graph object. + /// Returns nullopt if required fields are missing. ++RMF_TRAFFIC_ROS2_EXPORT + std::optional convert( + const rmf_building_map_msgs::msg::Graph& from); + +@@ -43,6 +47,7 @@ std::optional convert( + /// Convert a valid rmf_traffic::agv::Graph object to an + /// rmf_building_map_msgs::msg::Graph message. + /// Returns nullptr if required fields are missing or fleet_name is empty. ++RMF_TRAFFIC_ROS2_EXPORT + std::unique_ptr convert( + const rmf_traffic::agv::Graph& from, const std::string& fleet_name); + +diff --git a/include/rmf_traffic_ros2/blockade/Writer.hpp b/include/rmf_traffic_ros2/blockade/Writer.hpp +index f6b771bc..70b7e87c 100644 +--- a/include/rmf_traffic_ros2/blockade/Writer.hpp ++++ b/include/rmf_traffic_ros2/blockade/Writer.hpp +@@ -22,13 +22,15 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace blockade { + + //============================================================================== + /// The Writer class provides an API that allows a Node to create blockade + /// Participants. +-class Writer : public std::enable_shared_from_this ++class RMF_TRAFFIC_ROS2_EXPORT Writer : public std::enable_shared_from_this + { + public: + +diff --git a/include/rmf_traffic_ros2/geometry/Circle.hpp b/include/rmf_traffic_ros2/geometry/Circle.hpp +index cb3d888d..b3813ec2 100644 +--- a/include/rmf_traffic_ros2/geometry/Circle.hpp ++++ b/include/rmf_traffic_ros2/geometry/Circle.hpp +@@ -22,13 +22,17 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::Circle convert( + const rmf_traffic::geometry::Circle& circle); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::geometry::Circle convert( + const rmf_traffic_msgs::msg::Circle& circle); + +diff --git a/include/rmf_traffic_ros2/geometry/ConvexShape.hpp b/include/rmf_traffic_ros2/geometry/ConvexShape.hpp +index 403b2e60..2f33ac18 100644 +--- a/include/rmf_traffic_ros2/geometry/ConvexShape.hpp ++++ b/include/rmf_traffic_ros2/geometry/ConvexShape.hpp +@@ -23,11 +23,13 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace geometry { + + //============================================================================== +-class ConvexShapeContext ++class RMF_TRAFFIC_ROS2_EXPORT ConvexShapeContext + { + public: + +@@ -47,10 +49,12 @@ private: + } // namespace geometry + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + geometry::ConvexShapeContext convert( + const rmf_traffic_msgs::msg::ConvexShapeContext& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ConvexShapeContext convert( + const geometry::ConvexShapeContext& from); + +diff --git a/include/rmf_traffic_ros2/geometry/Shape.hpp b/include/rmf_traffic_ros2/geometry/Shape.hpp +index 4b5ec19a..f926cc20 100644 +--- a/include/rmf_traffic_ros2/geometry/Shape.hpp ++++ b/include/rmf_traffic_ros2/geometry/Shape.hpp +@@ -23,11 +23,13 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace geometry { + + //============================================================================== +-class ShapeContext ++class RMF_TRAFFIC_ROS2_EXPORT ShapeContext + { + public: + +@@ -47,10 +49,12 @@ private: + } // namespace geometry + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + geometry::ShapeContext convert( + const rmf_traffic_msgs::msg::ShapeContext& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ShapeContext convert( + const geometry::ShapeContext& from); + +diff --git a/include/rmf_traffic_ros2/schedule/Change.hpp b/include/rmf_traffic_ros2/schedule/Change.hpp +index 644d7ee8..8d1485b9 100644 +--- a/include/rmf_traffic_ros2/schedule/Change.hpp ++++ b/include/rmf_traffic_ros2/schedule/Change.hpp +@@ -25,41 +25,52 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Change::Add::Item convert( + const rmf_traffic_msgs::msg::ScheduleChangeAddItem& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleChangeAddItem convert( + const rmf_traffic::schedule::Change::Add::Item& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Change::Add convert( + const rmf_traffic_msgs::msg::ScheduleChangeAdd& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleChangeAdd convert( + const rmf_traffic::schedule::Change::Add& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Change::Delay convert( + const rmf_traffic_msgs::msg::ScheduleChangeDelay& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleChangeDelay convert( + const rmf_traffic::schedule::Change::Delay& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::ParticipantId convert( + const rmf_traffic::schedule::Change::UnregisterParticipant& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Change::Cull convert( + const rmf_traffic_msgs::msg::ScheduleChangeCull& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleChangeCull convert( + const rmf_traffic::schedule::Change::Cull& from); + +diff --git a/include/rmf_traffic_ros2/schedule/Inconsistencies.hpp b/include/rmf_traffic_ros2/schedule/Inconsistencies.hpp +index aea4d026..bbc0e397 100644 +--- a/include/rmf_traffic_ros2/schedule/Inconsistencies.hpp ++++ b/include/rmf_traffic_ros2/schedule/Inconsistencies.hpp +@@ -22,9 +22,12 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleInconsistency convert( + const rmf_traffic::schedule::Inconsistencies::Element& from, + const rmf_traffic::schedule::ProgressVersion progress_version); +diff --git a/include/rmf_traffic_ros2/schedule/Itinerary.hpp b/include/rmf_traffic_ros2/schedule/Itinerary.hpp +index 90d74c82..7a420d98 100644 +--- a/include/rmf_traffic_ros2/schedule/Itinerary.hpp ++++ b/include/rmf_traffic_ros2/schedule/Itinerary.hpp +@@ -23,17 +23,22 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + std::vector convert( + const rmf_traffic::schedule::Itinerary& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + std::vector convert( + const std::vector& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + std::vector convert( + const std::vector& from); + +diff --git a/include/rmf_traffic_ros2/schedule/MirrorManager.hpp b/include/rmf_traffic_ros2/schedule/MirrorManager.hpp +index d3153c92..857c4531 100644 +--- a/include/rmf_traffic_ros2/schedule/MirrorManager.hpp ++++ b/include/rmf_traffic_ros2/schedule/MirrorManager.hpp +@@ -23,16 +23,18 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace schedule { + + //============================================================================== +-class MirrorManager ++class RMF_TRAFFIC_ROS2_EXPORT MirrorManager + { + public: + + /// Options for the MirrorManager +- class Options ++ class RMF_TRAFFIC_ROS2_EXPORT Options + { + public: + +@@ -96,7 +98,7 @@ private: + }; + + //============================================================================== +-class MirrorManagerFuture ++class RMF_TRAFFIC_ROS2_EXPORT MirrorManagerFuture + { + public: + +@@ -153,6 +155,7 @@ private: + /// + // TODO(MXG): Use std::optional here instead of std::unique_ptr when C++17 can + // be supported. ++RMF_TRAFFIC_ROS2_EXPORT + MirrorManagerFuture make_mirror( + const std::shared_ptr& node, + rmf_traffic::schedule::Query query, +diff --git a/include/rmf_traffic_ros2/schedule/ParticipantRegistry.hpp b/include/rmf_traffic_ros2/schedule/ParticipantRegistry.hpp +index 6601639f..c7536ce6 100644 +--- a/include/rmf_traffic_ros2/schedule/ParticipantRegistry.hpp ++++ b/include/rmf_traffic_ros2/schedule/ParticipantRegistry.hpp +@@ -26,6 +26,8 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace schedule { + +@@ -48,7 +50,7 @@ struct AtomicOperation + + //============================================================================= + /// This is the base class for the persistence logger. +-class AbstractParticipantLogger ++class RMF_TRAFFIC_ROS2_EXPORT AbstractParticipantLogger + { + public: + /// Called when we wish to commit an operation to disk +@@ -64,7 +66,7 @@ public: + + //============================================================================= + /// YAML logger class. Logs everything to YAML buffers on disk +-class YamlLogger : public AbstractParticipantLogger ++class RMF_TRAFFIC_ROS2_EXPORT YamlLogger : public AbstractParticipantLogger + { + public: + /// Constructor +@@ -97,7 +99,7 @@ private: + /// Internally, this class implements a an append only journal. This makes it + /// independent of any id generation inside the database, as long as the said + /// database id generation algorithm is deterministic. +-class ParticipantRegistry ++class RMF_TRAFFIC_ROS2_EXPORT ParticipantRegistry + { + public: + /// Constructor +diff --git a/include/rmf_traffic_ros2/schedule/Patch.hpp b/include/rmf_traffic_ros2/schedule/Patch.hpp +index 63915f3e..5bc62fba 100644 +--- a/include/rmf_traffic_ros2/schedule/Patch.hpp ++++ b/include/rmf_traffic_ros2/schedule/Patch.hpp +@@ -22,21 +22,27 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleParticipantPatch convert( + const rmf_traffic::schedule::Patch::Participant& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Patch::Participant convert( + const rmf_traffic_msgs::msg::ScheduleParticipantPatch& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::SchedulePatch convert( + const rmf_traffic::schedule::Patch& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Patch convert( + const rmf_traffic_msgs::msg::SchedulePatch& from); + +diff --git a/include/rmf_traffic_ros2/schedule/Query.hpp b/include/rmf_traffic_ros2/schedule/Query.hpp +index 43ccb53d..8b13f0c5 100644 +--- a/include/rmf_traffic_ros2/schedule/Query.hpp ++++ b/include/rmf_traffic_ros2/schedule/Query.hpp +@@ -22,29 +22,37 @@ + + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Query::Spacetime convert( + const rmf_traffic_msgs::msg::ScheduleQuerySpacetime& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleQuerySpacetime convert( + const rmf_traffic::schedule::Query::Spacetime& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Query::Participants convert( + const rmf_traffic_msgs::msg::ScheduleQueryParticipants& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleQueryParticipants convert( + const rmf_traffic::schedule::Query::Participants& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::Query convert( + const rmf_traffic_msgs::msg::ScheduleQuery& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ScheduleQuery convert( + const rmf_traffic::schedule::Query& from); + +diff --git a/include/rmf_traffic_ros2/schedule/ScheduleIdentity.hpp b/include/rmf_traffic_ros2/schedule/ScheduleIdentity.hpp +index 168f5d34..4550fc59 100644 +--- a/include/rmf_traffic_ros2/schedule/ScheduleIdentity.hpp ++++ b/include/rmf_traffic_ros2/schedule/ScheduleIdentity.hpp +@@ -21,6 +21,8 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + namespace schedule { + +@@ -30,12 +32,14 @@ namespace schedule { + /// the data of the new incoming message and the function will return true. If + /// no reconnection should happen then the previous argument will not be + /// modified and the function will return false. ++RMF_TRAFFIC_ROS2_EXPORT + bool reconnect_schedule( + rmf_traffic_msgs::msg::ScheduleIdentity& previous, + const rmf_traffic_msgs::msg::ScheduleIdentity& incoming); + + /// Same as its overload, but it accepts an optional for previous. When previous + /// is nullopt, this will save incoming and return true. ++RMF_TRAFFIC_ROS2_EXPORT + bool reconnect_schedule( + std::optional& previous, + const rmf_traffic_msgs::msg::ScheduleIdentity& incoming); +@@ -43,6 +47,7 @@ bool reconnect_schedule( + //============================================================================== + /// Equivalent to reconnect_schedule, but it does not modify the previous + /// argument. ++RMF_TRAFFIC_ROS2_EXPORT + bool need_reconnection( + const rmf_traffic_msgs::msg::ScheduleIdentity& previous, + const rmf_traffic_msgs::msg::ScheduleIdentity& incoming); +diff --git a/include/rmf_traffic_ros2/schedule/ParticipantDescription.hpp b/include/rmf_traffic_ros2/schedule/ParticipantDescription.hpp +index 6536cc22..ac62c068 100644 +--- a/include/rmf_traffic_ros2/schedule/ParticipantDescription.hpp ++++ b/include/rmf_traffic_ros2/schedule/ParticipantDescription.hpp +@@ -23,21 +23,27 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::ParticipantDescription convert( + const rmf_traffic_msgs::msg::ParticipantDescription& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::ParticipantDescription convert( + const rmf_traffic::schedule::ParticipantDescription& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::schedule::ParticipantDescriptionsMap convert( + const rmf_traffic_msgs::msg::Participants& from); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic_msgs::msg::Participants convert( + const rmf_traffic::schedule::ParticipantDescriptionsMap& from); + +diff --git a/src/rmf_traffic_ros2/schedule/MonitorNode.cpp b/src/rmf_traffic_ros2/schedule/MonitorNode.cpp +index daf4e1dd..8bde4caf 100644 +--- a/src/rmf_traffic_ros2/schedule/MonitorNode.cpp ++++ b/src/rmf_traffic_ros2/schedule/MonitorNode.cpp +@@ -19,6 +19,7 @@ + + #include "internal_Node.hpp" + ++#include + #include + #include + +diff --git a/include/rmf_traffic_ros2/Time.hpp b/include/rmf_traffic_ros2/Time.hpp +index 34675318..963bc6d6 100644 +--- a/include/rmf_traffic_ros2/Time.hpp ++++ b/include/rmf_traffic_ros2/Time.hpp +@@ -23,24 +23,32 @@ + #include + #include + ++#include ++ + namespace rmf_traffic_ros2 { + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + builtin_interfaces::msg::Time convert(rmf_traffic::Time time); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::Time convert(builtin_interfaces::msg::Time time); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rclcpp::Time to_ros2(rmf_traffic::Time time); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::Time convert(rclcpp::Time time); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rclcpp::Duration convert(rmf_traffic::Duration duration); + + //============================================================================== ++RMF_TRAFFIC_ROS2_EXPORT + rmf_traffic::Duration convert(rclcpp::Duration duration); + + } // namespace rmf_traffic_ros2 diff --git a/patch/ros-rolling-rmf-traffic.patch b/patch/ros-rolling-rmf-traffic.patch new file mode 100644 index 000000000..0281cbd2f --- /dev/null +++ b/patch/ros-rolling-rmf-traffic.patch @@ -0,0 +1,288 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ad05ac1..b677893 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -97,6 +97,7 @@ endif() + target_link_libraries(rmf_traffic + PUBLIC + rmf_utils::rmf_utils ++ Eigen3::Eigen + Threads::Threads + PRIVATE + ${FCL_LIBRARIES} +diff --git a/src/rmf_traffic/blockade/geometry.cpp b/src/rmf_traffic/blockade/geometry.cpp +index 049351e..d69a999 100644 +--- a/src/rmf_traffic/blockade/geometry.cpp ++++ b/src/rmf_traffic/blockade/geometry.cpp +@@ -17,6 +17,7 @@ + + #include "geometry.hpp" + ++#include + #include + + namespace rmf_traffic { +diff --git a/thirdparty/fcl/include/fcl/broadphase/default_broadphase_callbacks.h b/thirdparty/fcl/include/fcl/broadphase/default_broadphase_callbacks.h +index 1c9b4fe..76f3bde 100644 +--- a/thirdparty/fcl/include/fcl/broadphase/default_broadphase_callbacks.h ++++ b/thirdparty/fcl/include/fcl/broadphase/default_broadphase_callbacks.h +@@ -37,6 +37,7 @@ + #ifndef FCL_BROADPHASE_DEFAULTBROADPHASECALLBACKS_H + #define FCL_BROADPHASE_DEFAULTBROADPHASECALLBACKS_H + ++#include + #include "fcl/narrowphase/collision.h" + #include "fcl/narrowphase/collision_request.h" + #include "fcl/narrowphase/collision_result.h" +diff --git a/thirdparty/fcl/include/fcl/broadphase/detail/morton.h b/thirdparty/fcl/include/fcl/broadphase/detail/morton.h +index 6b430c4..9a79cf0 100644 +--- a/thirdparty/fcl/include/fcl/broadphase/detail/morton.h ++++ b/thirdparty/fcl/include/fcl/broadphase/detail/morton.h +@@ -39,6 +39,7 @@ + #ifndef FCL_MORTON_H + #define FCL_MORTON_H + ++#include + #include "fcl/common/types.h" + #include "fcl/math/bv/AABB.h" + +diff --git a/thirdparty/fcl/include/fcl/geometry/octree/octree-inl.h b/thirdparty/fcl/include/fcl/geometry/octree/octree-inl.h +index f50fe81..04781f8 100644 +--- a/thirdparty/fcl/include/fcl/geometry/octree/octree-inl.h ++++ b/thirdparty/fcl/include/fcl/geometry/octree/octree-inl.h +@@ -38,6 +38,7 @@ + #ifndef FCL_OCTREE_INL_H + #define FCL_OCTREE_INL_H + ++#include + #include "fcl/geometry/octree/octree.h" + + #include "fcl/config.h" +diff --git a/thirdparty/fcl/include/fcl/geometry/shape/convex-inl.h b/thirdparty/fcl/include/fcl/geometry/shape/convex-inl.h +index 10adc69..c50b53f 100644 +--- a/thirdparty/fcl/include/fcl/geometry/shape/convex-inl.h ++++ b/thirdparty/fcl/include/fcl/geometry/shape/convex-inl.h +@@ -39,6 +39,7 @@ + #ifndef FCL_SHAPE_CONVEX_INL_H + #define FCL_SHAPE_CONVEX_INL_H + ++#include + #include + #include + #include +diff --git a/thirdparty/fcl/include/fcl/math/bv/kDOP-inl.h b/thirdparty/fcl/include/fcl/math/bv/kDOP-inl.h +index 371fdb6..15737b0 100644 +--- a/thirdparty/fcl/include/fcl/math/bv/kDOP-inl.h ++++ b/thirdparty/fcl/include/fcl/math/bv/kDOP-inl.h +@@ -38,6 +38,7 @@ + #ifndef FCL_BV_KDOP_INL_H + #define FCL_BV_KDOP_INL_H + ++#include + #include "fcl/math/bv/kDOP.h" + + #include "fcl/common/unused.h" +diff --git a/thirdparty/fcl/include/fcl/math/bv/utility-inl.h b/thirdparty/fcl/include/fcl/math/bv/utility-inl.h +index 333ec15..ab9a6f5 100644 +--- a/thirdparty/fcl/include/fcl/math/bv/utility-inl.h ++++ b/thirdparty/fcl/include/fcl/math/bv/utility-inl.h +@@ -38,6 +38,7 @@ + #ifndef FCL_MATH_BV_UTILITY_INL_H + #define FCL_MATH_BV_UTILITY_INL_H + ++#include + #include "fcl/math/bv/utility.h" + + #include "fcl/common/unused.h" +diff --git a/thirdparty/fcl/include/fcl/math/constants.h b/thirdparty/fcl/include/fcl/math/constants.h +index ba24176..dfdf569 100644 +--- a/thirdparty/fcl/include/fcl/math/constants.h ++++ b/thirdparty/fcl/include/fcl/math/constants.h +@@ -37,6 +37,7 @@ + #ifndef FCL_MATH_CONSTANTS_ + #define FCL_MATH_CONSTANTS_ + ++#include + #include "fcl/common/types.h" + + #include +diff --git a/thirdparty/fcl/include/fcl/math/motion/taylor_model/taylor_model-inl.h b/thirdparty/fcl/include/fcl/math/motion/taylor_model/taylor_model-inl.h +index 861f72d..f304d5d 100644 +--- a/thirdparty/fcl/include/fcl/math/motion/taylor_model/taylor_model-inl.h ++++ b/thirdparty/fcl/include/fcl/math/motion/taylor_model/taylor_model-inl.h +@@ -41,6 +41,7 @@ + #ifndef FCL_CCD_TAYLOR_MODEL_INL_H + #define FCL_CCD_TAYLOR_MODEL_INL_H + ++#include + #include "fcl/math/motion/taylor_model/taylor_model.h" + + namespace fcl +diff --git a/thirdparty/fcl/include/fcl/math/rng-inl.h b/thirdparty/fcl/include/fcl/math/rng-inl.h +index 1ba9da7..0e04dcd 100644 +--- a/thirdparty/fcl/include/fcl/math/rng-inl.h ++++ b/thirdparty/fcl/include/fcl/math/rng-inl.h +@@ -38,6 +38,7 @@ + #ifndef FCL_MATH_RNG_INL_H + #define FCL_MATH_RNG_INL_H + ++#include + #include "fcl/math/rng.h" + + namespace fcl +diff --git a/thirdparty/fcl/include/fcl/narrowphase/detail/convexity_based_algorithm/gjk_libccd-inl.h b/thirdparty/fcl/include/fcl/narrowphase/detail/convexity_based_algorithm/gjk_libccd-inl.h +index 60fd0ad..0ddc589 100644 +--- a/thirdparty/fcl/include/fcl/narrowphase/detail/convexity_based_algorithm/gjk_libccd-inl.h ++++ b/thirdparty/fcl/include/fcl/narrowphase/detail/convexity_based_algorithm/gjk_libccd-inl.h +@@ -38,6 +38,7 @@ + #ifndef FCL_NARROWPHASE_DETAIL_GJKLIBCCD_INL_H + #define FCL_NARROWPHASE_DETAIL_GJKLIBCCD_INL_H + ++#include + #include "fcl/narrowphase/detail/convexity_based_algorithm/gjk_libccd.h" + #include "fcl/narrowphase/detail/failed_at_this_configuration.h" + +diff --git a/thirdparty/fcl/include/fcl/narrowphase/distance-inl.h b/thirdparty/fcl/include/fcl/narrowphase/distance-inl.h +index 115b710..7011975 100644 +--- a/thirdparty/fcl/include/fcl/narrowphase/distance-inl.h ++++ b/thirdparty/fcl/include/fcl/narrowphase/distance-inl.h +@@ -38,6 +38,7 @@ + #ifndef FCL_DISTANCE_INL_H + #define FCL_DISTANCE_INL_H + ++#include + #include "fcl/narrowphase/distance.h" + + #include "fcl/narrowphase/collision.h" +diff --git a/include/rmf_traffic/DetectConflict.hpp b/include/rmf_traffic/DetectConflict.hpp +index e0aa706..64f0d61 100644 +--- a/include/rmf_traffic/DetectConflict.hpp ++++ b/include/rmf_traffic/DetectConflict.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__DETECTCONFLICT_HPP + #define RMF_TRAFFIC__DETECTCONFLICT_HPP + ++#include + #include + #include + #include +diff --git a/include/rmf_traffic/Route.hpp b/include/rmf_traffic/Route.hpp +index c3825ed..840aa84 100644 +--- a/include/rmf_traffic/Route.hpp ++++ b/include/rmf_traffic/Route.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__ROUTE_HPP + #define RMF_TRAFFIC__ROUTE_HPP + ++#include + #include + + #include +diff --git a/include/rmf_traffic/agv/VehicleTraits.hpp b/include/rmf_traffic/agv/VehicleTraits.hpp +index 416ee30..325e902 100644 +--- a/include/rmf_traffic/agv/VehicleTraits.hpp ++++ b/include/rmf_traffic/agv/VehicleTraits.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__AGV__VEHICLETRAITS_HPP + #define RMF_TRAFFIC__AGV__VEHICLETRAITS_HPP + ++#include + #include + #include + +diff --git a/include/rmf_traffic/schedule/Change.hpp b/include/rmf_traffic/schedule/Change.hpp +index bca4c5d..2328183 100644 +--- a/include/rmf_traffic/schedule/Change.hpp ++++ b/include/rmf_traffic/schedule/Change.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__SCHEDULE__CHANGE_HPP + #define RMF_TRAFFIC__SCHEDULE__CHANGE_HPP + ++#include + #include + #include + #include +diff --git a/include/rmf_traffic/schedule/Itinerary.hpp b/include/rmf_traffic/schedule/Itinerary.hpp +index eb6a0ab..fbf25e9 100644 +--- a/include/rmf_traffic/schedule/Itinerary.hpp ++++ b/include/rmf_traffic/schedule/Itinerary.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__SCHEDULE__ITINERARY_HPP + #define RMF_TRAFFIC__SCHEDULE__ITINERARY_HPP + ++#include + #include + #include + +diff --git a/include/rmf_traffic/schedule/ParticipantDescription.hpp b/include/rmf_traffic/schedule/ParticipantDescription.hpp +index 74d272c..3ce72cd 100644 +--- a/include/rmf_traffic/schedule/ParticipantDescription.hpp ++++ b/include/rmf_traffic/schedule/ParticipantDescription.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__SCHEDULE__PARTICIPANTDESCRIPTION_HPP + #define RMF_TRAFFIC__SCHEDULE__PARTICIPANTDESCRIPTION_HPP + ++#include + #include + #include + +diff --git a/include/rmf_traffic/schedule/Query.hpp b/include/rmf_traffic/schedule/Query.hpp +index aa6d3ab..bb3a924 100644 +--- a/include/rmf_traffic/schedule/Query.hpp ++++ b/include/rmf_traffic/schedule/Query.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__SCHEDULE__QUERY_HPP + #define RMF_TRAFFIC__SCHEDULE__QUERY_HPP + ++#include + #include + + #include +diff --git a/include/rmf_traffic/schedule/Writer.hpp b/include/rmf_traffic/schedule/Writer.hpp +index f536114..473b2db 100644 +--- a/include/rmf_traffic/schedule/Writer.hpp ++++ b/include/rmf_traffic/schedule/Writer.hpp +@@ -18,6 +18,7 @@ + #ifndef RMF_TRAFFIC__SCHEDULE__WRITER_HPP + #define RMF_TRAFFIC__SCHEDULE__WRITER_HPP + ++#include + #include + #include + +diff --git a/src/rmf_traffic/Route.cpp b/src/rmf_traffic/Route.cpp +index debd648..de68354 100644 +--- a/src/rmf_traffic/Route.cpp ++++ b/src/rmf_traffic/Route.cpp +@@ -15,6 +15,7 @@ + * + */ + ++#include + #include "internal_Route.hpp" + + #include +diff --git a/src/rmf_traffic/internal_Route.hpp b/src/rmf_traffic/internal_Route.hpp +index 8bb220b..112ed34 100644 +--- a/src/rmf_traffic/internal_Route.hpp ++++ b/src/rmf_traffic/internal_Route.hpp +@@ -18,6 +18,7 @@ + #ifndef SRC__RMF_TRAFFIC__INTERNAL_ROUTE_HPP + #define SRC__RMF_TRAFFIC__INTERNAL_ROUTE_HPP + ++#include + #include + + namespace rmf_traffic { +diff --git a/src/rmf_traffic/schedule/Timeline.hpp b/src/rmf_traffic/schedule/Timeline.hpp +index b190242..94f9719 100644 +--- a/src/rmf_traffic/schedule/Timeline.hpp ++++ b/src/rmf_traffic/schedule/Timeline.hpp +@@ -18,6 +18,7 @@ + #ifndef SRC__RMF_TRAFFIC__SCHEDULE__TIMELINE_HPP + #define SRC__RMF_TRAFFIC__SCHEDULE__TIMELINE_HPP + ++#include + #include "../DetectConflictInternal.hpp" + + #include diff --git a/patch/ros-rolling-rmf-traffic.win.patch b/patch/ros-rolling-rmf-traffic.win.patch new file mode 100644 index 000000000..d04eeee7f --- /dev/null +++ b/patch/ros-rolling-rmf-traffic.win.patch @@ -0,0 +1,195 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ad05ac1..45af2de 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -13,6 +13,12 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++if(MSVC) ++ # M_PI et al. are non-standard extensions MSVC only defines when this ++ # is set (Spline.cpp uses M_PI unconditionally). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + if(NOT CMAKE_BUILD_TYPE) + # Use the Release build type by default if the user has not specified one + set(CMAKE_BUILD_TYPE Release) +@@ -50,6 +56,17 @@ add_library(rmf_traffic SHARED + ${core_lib_srcs} + ) + ++if(WIN32) ++ # rmf_traffic has no dllexport annotations at all. As a shared library ++ # on Windows with nothing explicitly exported, link.exe does not ++ # produce an import .lib, so every consumer fails with LNK1181 ++ # "cannot open input file 'rmf_traffic.lib'" even though ++ # rmf_traffic.dll itself builds fine. Auto-export everything, same ++ # fix used for every other Windows shared-library target this ++ # session (including rmf_utils earlier in this same package family). ++ set_target_properties(rmf_traffic PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + find_package(ament_cmake_catch2 QUIET) + find_package(ament_cmake_uncrustify QUIET) + if(BUILD_TESTING AND ament_cmake_catch2_FOUND AND ament_cmake_uncrustify_FOUND) +diff --git a/src/rmf_traffic/Trajectory.cpp b/src/rmf_traffic/Trajectory.cpp +index 3f29c7d..be98311 100644 +--- a/src/rmf_traffic/Trajectory.cpp ++++ b/src/rmf_traffic/Trajectory.cpp +@@ -798,7 +798,12 @@ bool Trajectory::base_iterator::operator>=( + + //============================================================================== + template +-Trajectory::base_iterator::operator const_iterator() const ++// MSVC fails to resolve the unqualified "const_iterator" here (a member ++// alias of the enclosing Trajectory class, not of base_iterator itself) ++// in this out-of-line nested-class-template conversion operator (C2833). ++// GCC/Clang already resolve it via the enclosing scope; qualifying it ++// explicitly is equivalent and portable everywhere. ++Trajectory::base_iterator::operator Trajectory::const_iterator() const + { + return _pimpl->make_iterator(_pimpl->raw_iterator); + } +diff --git a/src/rmf_traffic/agv/SimpleNegotiator.cpp b/src/rmf_traffic/agv/SimpleNegotiator.cpp +index 7657152..7aee6d8 100644 +--- a/src/rmf_traffic/agv/SimpleNegotiator.cpp ++++ b/src/rmf_traffic/agv/SimpleNegotiator.cpp +@@ -26,9 +26,11 @@ namespace rmf_traffic { + namespace agv { + + //============================================================================== +-// This line tells the linker to take care of defining the value of this field +-// inside of this translation unit. +-const double SimpleNegotiator::Options::DefaultMaxCostLeeway; ++// C++17's static constexpr members are implicitly inline, so this ++// out-of-class definition (needed pre-C++17 for ODR-use) is redundant ++// now that this project targets C++17 -- and MSVC rejects it outright ++// (C2734: "'const' object must be initialized if not 'extern'"), even ++// though GCC/Clang tolerate the redundant redeclaration. Just remove it. + + //============================================================================== + class SimpleNegotiator::Options::Implementation +diff --git a/src/rmf_traffic/agv/Planner.cpp b/src/rmf_traffic/agv/Planner.cpp +index 983f0c2..d9925b2 100644 +--- a/src/rmf_traffic/agv/Planner.cpp ++++ b/src/rmf_traffic/agv/Planner.cpp +@@ -25,9 +25,11 @@ namespace rmf_traffic { + namespace agv { + + //============================================================================== +-// This line tells the linker to take care of defining the value of this field +-// inside of this translation unit. +-const Duration Planner::Options::DefaultMinHoldingTime; ++// C++17's static constexpr members are implicitly inline, so this ++// out-of-class definition (needed pre-C++17 for ODR-use) is redundant ++// now that this project targets C++17 -- and MSVC rejects it outright ++// (C2734: "'const' object must be initialized if not 'extern'"), even ++// though GCC/Clang tolerate the redundant redeclaration. Just remove it. + + //============================================================================== + class Planner::Configuration::Implementation +diff --git a/src/rmf_traffic/agv/planning/CacheManager.hpp b/src/rmf_traffic/agv/planning/CacheManager.hpp +index 2bdce0e..879269d 100644 +--- a/src/rmf_traffic/agv/planning/CacheManager.hpp ++++ b/src/rmf_traffic/agv/planning/CacheManager.hpp +@@ -188,7 +188,26 @@ private: + + CacheManager( + std::shared_ptr generator, +- std::function storage_initializer = []() { return Storage(); }); ++ // MSVC cannot compile a lambda used as a default argument value ++ // here when the lambda references this class template's dependent ++ // Storage member alias: unqualified "Storage" fails to resolve ++ // (C3861), fully qualifying as CacheManager::Storage ++ // fails because CacheArg itself isn't found in that context ++ // (C2065), and the injected-class-name form CacheManager::Storage ++ // is rejected outright ("requires template argument list", C2955). ++ // Default to nullptr (no name lookup needed at all) and resolve ++ // the real default inside default_storage_initializer()'s body ++ // instead, where normal class/template scoping applies with none ++ // of these restrictions. ++ std::function storage_initializer = nullptr); ++ ++ static std::function default_storage_initializer( ++ std::function storage_initializer) ++ { ++ if (storage_initializer) ++ return storage_initializer; ++ return []() { return Storage(); }; ++ } + + template friend class Cache; + std::shared_ptr _upstream; +@@ -214,7 +233,18 @@ public: + + CacheManagerMap( + std::shared_ptr factory, +- std::function storage_initializer = []() { return Storage(); }); ++ // Same MSVC default-argument-lambda restriction as CacheManager's ++ // constructor above -- default to nullptr and resolve the real ++ // default inside default_storage_initializer()'s body instead. ++ std::function storage_initializer = nullptr); ++ ++ static std::function default_storage_initializer( ++ std::function storage_initializer) ++ { ++ if (storage_initializer) ++ return storage_initializer; ++ return []() { return Storage(); }; ++ } + + CacheManagerPtr get(std::size_t goal_index) const; + +@@ -329,8 +359,10 @@ CacheManager::CacheManager( + std::shared_ptr generator, + std::function storage_initializer) + : _upstream( +- std::make_shared(storage_initializer, std::move(generator))), +- _storage_initializer(std::move(storage_initializer)) ++ std::make_shared( ++ default_storage_initializer(storage_initializer), std::move(generator))), ++ _storage_initializer( ++ default_storage_initializer(std::move(storage_initializer))) + { + // Do nothing + } +@@ -356,7 +388,8 @@ CacheManagerMap::CacheManagerMap( + std::shared_ptr factory, + std::function storage_initializer) + : _generator_factory(std::move(factory)), +- _storage_initializer(std::move(storage_initializer)) ++ _storage_initializer( ++ default_storage_initializer(std::move(storage_initializer))) + { + // Do nothing + } +diff --git a/src/rmf_traffic/agv/planning/DifferentialDriveMap.hpp b/src/rmf_traffic/agv/planning/DifferentialDriveMap.hpp +index 27e3df8..bca545d 100644 +--- a/src/rmf_traffic/agv/planning/DifferentialDriveMap.hpp ++++ b/src/rmf_traffic/agv/planning/DifferentialDriveMap.hpp +@@ -213,6 +213,14 @@ struct DifferentialDriveMapTypes + + struct KeyHash + { ++ // MSVC's / implementation instantiates ++ // code paths requiring the hasher to be default-constructible even ++ // though real usage always passes N_lanes explicitly (GCC/Clang's ++ // libstdc++/libc++ don't need this). The members are left ++ // uninitialized here since this constructor is never actually ++ // invoked in practice. ++ KeyHash() = default; ++ + KeyHash(std::size_t N_lanes) + { + const std::size_t lane_shift = std::ceil(std::log2(N_lanes)); +@@ -245,6 +253,9 @@ struct DifferentialDriveMapTypes + + struct EntryHash + { ++ // Same MSVC default-constructibility requirement as KeyHash above. ++ EntryHash() = default; ++ + EntryHash(std::size_t N_lanes) + { + _orientation_shift = std::ceil(std::log2(N_lanes)); diff --git a/patch/ros-rolling-rmf-utils.win.patch b/patch/ros-rolling-rmf-utils.win.patch new file mode 100644 index 000000000..9c79859cc --- /dev/null +++ b/patch/ros-rolling-rmf-utils.win.patch @@ -0,0 +1,21 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a93554f..3ec361d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -15,6 +15,16 @@ include(GNUInstallDirs) + file(GLOB_RECURSE lib_srcs "src/rmf_utils/*.cpp") + add_library(rmf_utils SHARED ${lib_srcs}) + ++if(WIN32) ++ # rmf_utils has no dllexport annotations at all. As a shared library on ++ # Windows with nothing explicitly exported, link.exe does not produce ++ # an import .lib, so every consumer (rmf-traffic here) fails with ++ # LNK1181 "cannot open input file 'rmf_utils.lib'" even though ++ # rmf_utils.dll itself builds fine. Auto-export everything, same fix ++ # used for every other Windows shared-library target this session. ++ set_target_properties(rmf_utils PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_include_directories(rmf_utils + PUBLIC + $ diff --git a/patch/ros-rolling-rmf-visualization-floorplans.patch b/patch/ros-rolling-rmf-visualization-floorplans.patch new file mode 100644 index 000000000..1ae964f56 --- /dev/null +++ b/patch/ros-rolling-rmf-visualization-floorplans.patch @@ -0,0 +1,26 @@ +diff --git a/src/FloorplanVisualizer.cpp b/src/FloorplanVisualizer.cpp +index 15c07c0..6c6035e 100644 +--- a/src/FloorplanVisualizer.cpp ++++ b/src/FloorplanVisualizer.cpp +@@ -74,7 +74,9 @@ FloorplanVisualizer::FloorplanVisualizer(const rclcpp::NodeOptions& options) + continue; + + cv::Mat cv_img = cv::imdecode( +- cv::Mat(level.images[0].data), cv::IMREAD_GRAYSCALE); ++ cv::Mat(std::vector( ++ level.images[0].data.begin(), level.images[0].data.end())), ++ cv::IMREAD_GRAYSCALE); + auto it = level.images.begin(); + ++it; + // We blend all the other images into the first image +@@ -84,7 +86,9 @@ FloorplanVisualizer::FloorplanVisualizer(const rclcpp::NodeOptions& options) + for (; it != level.images.end(); ++it) + { + cv::Mat next_img = cv::imdecode( +- cv::Mat(it->data), cv::IMREAD_GRAYSCALE); ++ cv::Mat(std::vector( ++ it->data.begin(), it->data.end())), ++ cv::IMREAD_GRAYSCALE); + cv::addWeighted(cv_img, 0.7, next_img, 0.3, 0.0, cv_img); + } + const auto& image = level.images[0]; diff --git a/patch/ros-rolling-rmf-visualization-floorplans.win.patch b/patch/ros-rolling-rmf-visualization-floorplans.win.patch new file mode 100644 index 000000000..e52533c6a --- /dev/null +++ b/patch/ros-rolling-rmf-visualization-floorplans.win.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f498d456..7427243c 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -5,6 +5,12 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++if(MSVC) ++ # M_PI is a non-standard extension MSVC only defines when this is ++ # set (used in src/FloorplanVisualizer.cpp). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + include(GNUInstallDirs) + + find_package(eigen3_cmake_module REQUIRED) diff --git a/patch/ros-rolling-rmf-visualization-schedule.patch b/patch/ros-rolling-rmf-visualization-schedule.patch new file mode 100644 index 000000000..6c1c2f5d0 --- /dev/null +++ b/patch/ros-rolling-rmf-visualization-schedule.patch @@ -0,0 +1,16 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0000000..0000000 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,11 @@ + cmake_minimum_required(VERSION 3.5) + project(rmf_visualization_schedule) + set(CMAKE_EXPORT_COMPILE_COMMANDS on) ++ ++# websocketpp 0.8.2 requires Asio APIs (io_service et al.) that Boost 1.90 ++# removed. Use the actively-maintained standalone Asio instead (matching ++# RoboStack/ros-lyrical#41's fix), which still provides io_service. ++add_compile_definitions(ASIO_STANDALONE) + + # Default to C++17 + if(NOT CMAKE_CXX_STANDARD) diff --git a/patch/ros-rolling-rmf-visualization-schedule.win.patch b/patch/ros-rolling-rmf-visualization-schedule.win.patch new file mode 100644 index 000000000..9fc9fdb80 --- /dev/null +++ b/patch/ros-rolling-rmf-visualization-schedule.win.patch @@ -0,0 +1,52 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e2fe859f..6ea64723 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -7,6 +7,19 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS on) + # RoboStack/ros-lyrical#41's fix), which still provides io_service. + add_compile_definitions(ASIO_STANDALONE) + ++if(MSVC) ++ # MSVC doesn't update __cplusplus to reflect the actual C++ standard ++ # in use unless told to, so websocketpp's __cplusplus >= 201103L ++ # feature-detection in common/cpp11.hpp always fails, falling back ++ # to boost::is_same -- which recent Boost versions no longer provide ++ # (C2039/C2873 in websocketpp/common/type_traits.hpp). ++ add_compile_options(/Zc:__cplusplus) ++ ++ # M_PI_2 et al. are non-standard extensions MSVC only defines when ++ # this is set (used in test/SubmitTrajectory.cpp). ++ add_compile_definitions(_USE_MATH_DEFINES) ++endif() ++ + # Default to C++17 + if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) +@@ -53,6 +66,14 @@ endif() + file(GLOB_RECURSE core_lib_srcs "src/rmf_visualization_schedule/*.cpp") + add_library(rmf_visualization_schedule SHARED ${core_lib_srcs}) + ++if(MSVC) ++ # No explicit dllexport annotations anywhere in this small target ++ # (2 source files), so without this MSVC produces the .dll but no ++ # import .lib, and schedule_visualizer fails with LNK1181. ++ set_target_properties(rmf_visualization_schedule PROPERTIES ++ WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_link_libraries(rmf_visualization_schedule + PUBLIC + rmf_traffic::rmf_traffic +diff --git a/src/ScheduleVisualizer.cpp b/src/ScheduleVisualizer.cpp +index 961c512b..7a7bc2f9 100644 +--- a/src/ScheduleVisualizer.cpp ++++ b/src/ScheduleVisualizer.cpp +@@ -107,7 +107,7 @@ ScheduleVisualizer::ScheduleVisualizer( + "Setting parameter port to %d", port + ); + +- uint retained_history_count = this->declare_parameter( ++ unsigned int retained_history_count = this->declare_parameter( + "retained_history_count", 0); + RCLCPP_INFO( + this->get_logger(), diff --git a/patch/ros-rolling-rmf-websocket.patch b/patch/ros-rolling-rmf-websocket.patch new file mode 100644 index 000000000..022d6b14f --- /dev/null +++ b/patch/ros-rolling-rmf-websocket.patch @@ -0,0 +1,102 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0368593..38a9279 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.5) + + project(rmf_websocket) + ++# websocketpp 0.8.2 requires Asio APIs (io_service et al.) that Boost 1.90 ++# removed. Use the actively-maintained standalone Asio instead (matching ++# RoboStack/ros-lyrical#41's fix), which still provides io_service. ++add_compile_definitions(ASIO_STANDALONE) ++ + if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) + endif() +@@ -21,7 +26,6 @@ find_package(nlohmann_json REQUIRED) + find_package(nlohmann_json_schema_validator_vendor REQUIRED) + find_package(nlohmann_json_schema_validator REQUIRED) + find_package(websocketpp REQUIRED) +-find_package(Boost COMPONENTS system REQUIRED) + find_package(Threads) + + +@@ -39,7 +43,6 @@ target_link_libraries(rmf_websocket + nlohmann_json::nlohmann_json + nlohmann_json_schema_validator + PRIVATE +- Boost::system + Threads::Threads + ) + +diff --git a/src/rmf_websocket/BroadcastClient.cpp b/src/rmf_websocket/BroadcastClient.cpp +index 01d3ac1..250f5b1 100644 +--- a/src/rmf_websocket/BroadcastClient.cpp ++++ b/src/rmf_websocket/BroadcastClient.cpp +@@ -217,7 +217,7 @@ private: + } + // create pimpl + std::string _uri; +- boost::asio::io_service _io_service; ++ asio::io_service _io_service; + std::shared_ptr _node; + RingBuffer _queue; + ProvideJsonUpdates _get_json_updates_cb; +diff --git a/src/rmf_websocket/BroadcastServer.cpp b/src/rmf_websocket/BroadcastServer.cpp +index e29bf9e..6f9b58b 100644 +--- a/src/rmf_websocket/BroadcastServer.cpp ++++ b/src/rmf_websocket/BroadcastServer.cpp +@@ -128,7 +128,7 @@ public: + _logger_interface->get_logger(), "Stopping BroadcastServer"); + } + +- _data->echo_server.get_io_service().post( ++ _data->echo_server.get_io_context().post( + [data = _data]() + { + data->echo_server.stop_listening(); +diff --git a/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp b/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp +index 99a823b..cc37fe8 100644 +--- a/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp ++++ b/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp +@@ -41,7 +41,7 @@ void ConnectionMetadata::on_fail(WsClient* c, websocketpp::connection_hdl hdl) + WsClient::connection_ptr con = c->get_con_from_hdl(hdl); + _server = con->get_response_header("Server"); + _error_reason = con->get_ec().message(); +- c->get_io_service().post(_reconnection_cb); ++ c->get_io_context().post(_reconnection_cb); + } + + //============================================================================= +@@ -54,7 +54,7 @@ void ConnectionMetadata::on_close(WsClient* c, websocketpp::connection_hdl hdl) + << websocketpp::close::status::get_string(con->get_remote_close_code()) + << "), close reason: " << con->get_remote_close_reason(); + _error_reason = s.str(); +- c->get_io_service().post(_reconnection_cb); ++ c->get_io_context().post(_reconnection_cb); + } + + //============================================================================= +@@ -144,7 +144,7 @@ websocketpp::lib::error_code ClientWebSocketEndpoint::connect() + "> Reconnecting in 1s\n" + "> Host: %s", _uri.c_str()); + _endpoint->stop_perpetual(); +- auto io_service = &_endpoint->get_io_service(); ++ auto io_service = &_endpoint->get_io_context(); + _endpoint = std::make_unique(); + _endpoint->clear_access_channels(websocketpp::log::alevel::all); + _endpoint->clear_error_channels(websocketpp::log::elevel::all); +diff --git a/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp b/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp +index 55f7105..6c0cd4b 100644 +--- a/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp ++++ b/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp +@@ -101,7 +101,7 @@ public: + ClientWebSocketEndpoint( + std::string const& uri, + std::shared_ptr node, +- boost::asio::io_service* io_service, ++ asio::io_service* io_service, + ConnectionCallback cb); + + /// Delete move constructor diff --git a/patch/ros-rolling-rmf-websocket.win.patch b/patch/ros-rolling-rmf-websocket.win.patch new file mode 100644 index 000000000..aaacbb548 --- /dev/null +++ b/patch/ros-rolling-rmf-websocket.win.patch @@ -0,0 +1,35 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 38a92790..9db1d821 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -7,6 +7,15 @@ project(rmf_websocket) + # RoboStack/ros-lyrical#41's fix), which still provides io_service. + add_compile_definitions(ASIO_STANDALONE) + ++if(MSVC) ++ # MSVC doesn't update __cplusplus to reflect the actual C++ standard ++ # in use unless told to, so websocketpp's __cplusplus >= 201103L ++ # feature-detection in common/cpp11.hpp always fails, falling back ++ # to boost::is_same -- which recent Boost versions no longer provide ++ # (C2039/C2873 in websocketpp/common/type_traits.hpp). ++ add_compile_options(/Zc:__cplusplus) ++endif() ++ + if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) + endif() +@@ -35,6 +44,14 @@ add_library(rmf_websocket SHARED + src/rmf_websocket/BroadcastServer.cpp + ) + ++if(MSVC) ++ # No explicit dllexport annotations anywhere in this small target, so ++ # without this MSVC produces the .dll but no companion .lib, and ++ # example_client fails with LNK1181. ++ set_target_properties(rmf_websocket PROPERTIES ++ WINDOWS_EXPORT_ALL_SYMBOLS ON) ++endif() ++ + target_link_libraries(rmf_websocket + PUBLIC + ${rclcpp_LIBRARIES} diff --git a/patch/ros-rolling-rmw-stats-shim.patch b/patch/ros-rolling-rmw-stats-shim.patch index bbde5ae09..b57096f6d 100644 --- a/patch/ros-rolling-rmw-stats-shim.patch +++ b/patch/ros-rolling-rmw-stats-shim.patch @@ -1,8 +1,21 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 8dbdc3b..c2fba66 100644 +index 2d6e10f..5d10e0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -31,6 +31,7 @@ find_package(rmw REQUIRED) +@@ -21,7 +21,11 @@ endif() + + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +- add_link_options("-Wl,--no-undefined") ++ # --no-undefined is a GNU ld long option; Apple's ld doesn't understand it ++ # even though Clang matches this branch on macOS too. ++ if(NOT APPLE) ++ add_link_options("-Wl,--no-undefined") ++ endif() + endif() + + find_package(ament_cmake REQUIRED) +@@ -31,6 +35,7 @@ find_package(rmw REQUIRED) find_package(rosgraph_monitor_msgs REQUIRED) find_package(rosidl_runtime_cpp REQUIRED) find_package(rosidl_typesupport_cpp REQUIRED) @@ -10,10 +23,11 @@ index 8dbdc3b..c2fba66 100644 add_library(${PROJECT_NAME} SHARED src/shim.cpp -@@ -46,6 +47,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC +@@ -45,6 +50,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC rmw::rmw rosidl_runtime_cpp::rosidl_runtime_cpp rosidl_typesupport_cpp::rosidl_typesupport_cpp + Threads::Threads ${rosgraph_monitor_msgs_TARGETS} ) + diff --git a/patch/ros-rolling-robotiq-controllers.patch b/patch/ros-rolling-robotiq-controllers.patch new file mode 100644 index 000000000..42ef69a8e --- /dev/null +++ b/patch/ros-rolling-robotiq-controllers.patch @@ -0,0 +1,47 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 5e955f0..1feb6c6 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -10,6 +10,14 @@ find_package(ament_cmake REQUIRED) + find_package(controller_interface REQUIRED) + find_package(std_srvs REQUIRED) + ++# ament_target_dependencies() was removed from ament_cmake_target_dependencies; ++# link against each dependency's exported _TARGETS instead. ++macro(link_ament_dependencies target) ++ foreach(_ament_dep ${ARGN}) ++ target_link_libraries(${target} ${${_ament_dep}_TARGETS}) ++ endforeach() ++endmacro() ++ + set(THIS_PACKAGE_INCLUDE_DEPENDS + controller_interface + std_srvs +@@ -25,9 +33,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE + include + ) + +-ament_target_dependencies(${PROJECT_NAME} +- ${THIS_PACKAGE_INCLUDE_DEPENDS} +-) ++link_ament_dependencies(${PROJECT_NAME} ${THIS_PACKAGE_INCLUDE_DEPENDS}) + + pluginlib_export_plugin_description_file(controller_interface controller_plugins.xml) + +diff --git a/src/robotiq_activation_controller.cpp b/src/robotiq_activation_controller.cpp +index 03c4fa8..b8ebb82 100644 +--- a/src/robotiq_activation_controller.cpp ++++ b/src/robotiq_activation_controller.cpp +@@ -106,10 +106,10 @@ bool RobotiqActivationController::reactivateGripper( + command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].set_value(ASYNC_WAITING); + command_interfaces_[REACTIVATE_GRIPPER_CMD].set_value(1.0); + +- while (command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_value() == ASYNC_WAITING) { ++ while (command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_optional().value_or(ASYNC_WAITING) == ASYNC_WAITING) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } +- resp->success = command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_value(); ++ resp->success = command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_optional().value_or(0.0); + + return resp->success; + } diff --git a/patch/ros-rolling-rosgraph-monitor.patch b/patch/ros-rolling-rosgraph-monitor.patch index acf3531aa..b8909735b 100644 --- a/patch/ros-rolling-rosgraph-monitor.patch +++ b/patch/ros-rolling-rosgraph-monitor.patch @@ -10,3 +10,20 @@ index 757fb41..a2e3d89 100644 #include #include #include +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 39e863d..7f12f8b 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -21,7 +21,11 @@ endif() + + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic -Werror=switch) +- add_link_options("-Wl,--no-undefined") ++ # --no-undefined is a GNU ld long option; Apple's ld doesn't understand it ++ # even though Clang matches this branch on macOS too. ++ if(NOT APPLE) ++ add_link_options("-Wl,--no-undefined") ++ endif() + endif() + + find_package(ament_cmake REQUIRED) diff --git a/patch/ros-rolling-rqt-image-view.patch b/patch/ros-rolling-rqt-image-view.patch new file mode 100644 index 000000000..e320383cb --- /dev/null +++ b/patch/ros-rolling-rqt-image-view.patch @@ -0,0 +1,27 @@ +diff --git a/src/rqt_image_view/image_view.cpp b/src/rqt_image_view/image_view.cpp +index f25f516..03f86d3 100644 +--- a/src/rqt_image_view/image_view.cpp ++++ b/src/rqt_image_view/image_view.cpp +@@ -601,7 +601,7 @@ void ImageView::callbackImage(const sensor_msgs::msg::Image::ConstSharedPtr & ms + conversion_mat_ = cv_ptr->image; + } else if (msg->encoding == "8UC1") { + // convert gray to rgb +- cv::cvtColor(cv_ptr->image, conversion_mat_, CV_GRAY2RGB); ++ cv::cvtColor(cv_ptr->image, conversion_mat_, cv::COLOR_GRAY2RGB); + } else if (msg->encoding == "16UC1" || msg->encoding == "32FC1") { + // scale / quantify + double min = 0; +@@ -625,11 +625,11 @@ void ImageView::callbackImage(const sensor_msgs::msg::Image::ConstSharedPtr & ms + // convert the scaled image to the selected color scheme; + // "Gray" (color scheme = -1) being a special case + if (color_scheme == -1) { +- cv::cvtColor(img_scaled_8u, conversion_mat_, CV_GRAY2RGB); ++ cv::cvtColor(img_scaled_8u, conversion_mat_, cv::COLOR_GRAY2RGB); + } else { + cv::Mat img_color_scheme; + cv::applyColorMap(img_scaled_8u, img_color_scheme, color_scheme); +- cv::cvtColor(img_color_scheme, conversion_mat_, CV_BGR2RGB); ++ cv::cvtColor(img_color_scheme, conversion_mat_, cv::COLOR_BGR2RGB); + } + } else { + qWarning("ImageView.callback_image() could not convert image from '%s' to 'rgb8' (%s)", diff --git a/patch/ros-rolling-rtabmap.patch b/patch/ros-rolling-rtabmap.patch new file mode 100644 index 000000000..b3b1777dd --- /dev/null +++ b/patch/ros-rolling-rtabmap.patch @@ -0,0 +1,2640 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b7d36de..80d7ea0 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,9 @@ + # Top-Level CmakeLists.txt +-cmake_minimum_required(VERSION 3.14) ++cmake_minimum_required(VERSION 3.18) + PROJECT( RTABMap ) ++if(POLICY CMP0167) ++ cmake_policy(SET CMP0167 NEW) ++endif() + SET(PROJECT_PREFIX rtabmap) + + # Catkin doesn't support multiarch library path, +@@ -84,12 +87,12 @@ IF(MINGW) + ENDIF(MINGW) + + # GCC 4 required +-IF(UNIX OR MINGW) +- EXEC_PROGRAM( gcc ARGS "-dumpversion" OUTPUT_VARIABLE GCC_VERSION ) +- IF(GCC_VERSION VERSION_LESS "4.0.0") +- MESSAGE(FATAL_ERROR "GCC ${GCC_VERSION} found, but version 4.x.x minimum is required") +- ENDIF(GCC_VERSION VERSION_LESS "4.0.0") +-ENDIF(UNIX OR MINGW) ++# IF(UNIX OR MINGW) ++# EXEC_PROGRAM( gcc ARGS "-dumpversion" OUTPUT_VARIABLE GCC_VERSION ) ++# IF(GCC_VERSION VERSION_LESS "4.0.0") ++# MESSAGE(FATAL_ERROR "GCC ${GCC_VERSION} found, but version 4.x.x minimum is required") ++# ENDIF(GCC_VERSION VERSION_LESS "4.0.0") ++# ENDIF(UNIX OR MINGW) + + #The CDT Error Parser cannot handle error messages that span + #more than one line, which is the default gcc behavior. +@@ -234,7 +237,25 @@ option(BUILD_WITH_RPATH_NOT_RUNPATH "Explicitly disable usage of RUNPATH for the + set(RTABMAP_QT_VERSION AUTO CACHE STRING "Force a specific Qt version.") + set_property(CACHE RTABMAP_QT_VERSION PROPERTY STRINGS AUTO 4 5 6) + +-FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS core calib3d imgproc highgui stitching photo video videoio OPTIONAL_COMPONENTS aruco objdetect xfeatures2d nonfree gpu cudafeatures2d cudaoptflow cudaimgproc) ++# OpenCV components. calib3d was split into "calib" + "geometry" in OpenCV 5. ++# These lists are reused below to generate RTABMapConfig.cmake so downstream ++# find_package(RTABMap) requests the same components this build used. ++SET(RTABMAP_OpenCV_COMPONENTS_5 core imgproc highgui stitching photo video videoio calib geometry) ++SET(RTABMAP_OpenCV_COMPONENTS_4 core imgproc highgui stitching photo video videoio calib3d) ++SET(RTABMAP_OpenCV_OPTIONAL_COMPONENTS_5 objdetect xfeatures2d nonfree gpu cudafeatures2d cudaoptflow cudaimgproc) ++SET(RTABMAP_OpenCV_OPTIONAL_COMPONENTS_4 aruco objdetect xfeatures2d nonfree gpu cudafeatures2d cudaoptflow cudaimgproc) ++ ++# Probe OpenCV without a version constraint first, then request the components ++# matching the detected major version. A version-constrained find that fails to ++# match (e.g. asking for 5 when only 4 is present) resets OpenCV_DIR to NOTFOUND, ++# which breaks toolchain builds that rely on a -DOpenCV_DIR hint (e.g. Android, ++# where CMAKE_FIND_ROOT_PATH restricts the search). ++FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS core) ++IF(OpenCV_VERSION_MAJOR GREATER 4) ++ FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_5} OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_5}) ++ELSE() ++ FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_4} OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_4}) ++ENDIF() + + IF(WITH_QT) + FIND_PACKAGE(PCL 1.7 REQUIRED QUIET COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization) +@@ -494,7 +515,10 @@ IF(WITH_DC1394) + ENDIF(WITH_DC1394) + + IF(WITH_G2O) ++ SET(_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG ${CMAKE_FIND_PACKAGE_PREFER_CONFIG}) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) + FIND_PACKAGE(g2o NO_MODULE) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG ${_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG}) + IF(g2o_FOUND) + MESSAGE(STATUS "Found g2o (targets)") + SET(G2O_FOUND ${g2o_FOUND}) +@@ -530,8 +554,10 @@ IF(WITH_G2O) + ENDIF(WITH_G2O) + + IF(WITH_GTSAM) +- # Force config mode to ignore PCL's findGTSAM.cmake file ++ SET(_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG ${CMAKE_FIND_PACKAGE_PREFER_CONFIG}) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) + FIND_PACKAGE(GTSAM CONFIG QUIET) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG ${_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG}) + ENDIF(WITH_GTSAM) + + IF(WITH_MRPT) +@@ -576,9 +602,9 @@ IF(WITH_POINTMATCHER) + ENDIF(WITH_POINTMATCHER) + + IF(libpointmatcher_FOUND OR GTSAM_FOUND) +- find_package(Boost COMPONENTS thread filesystem system program_options date_time REQUIRED) ++ find_package(Boost COMPONENTS thread filesystem program_options date_time REQUIRED) + IF(Boost_MINOR_VERSION GREATER 47) +- find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono timer serialization REQUIRED) ++ find_package(Boost COMPONENTS thread filesystem program_options date_time chrono timer serialization REQUIRED) + ENDIF(Boost_MINOR_VERSION GREATER 47) + IF(WIN32) + MESSAGE(STATUS "Boost_LIBRARY_DIRS=${Boost_LIBRARY_DIRS}") +@@ -1207,6 +1233,18 @@ install(EXPORT rtabmapTargets + #### + # Setup RTABMapConfig.cmake + #### ++IF(OpenCV_VERSION_MAJOR GREATER 4) ++ SET(CONF_OPENCV_COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_5}) ++ SET(CONF_OPENCV_OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_5}) ++ELSE() ++ SET(CONF_OPENCV_COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_4}) ++ SET(CONF_OPENCV_OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_4}) ++ENDIF() ++STRING(REPLACE ";" " " CONF_OPENCV_COMPONENTS "${CONF_OPENCV_COMPONENTS}") ++STRING(REPLACE ";" " " CONF_OPENCV_OPTIONAL_COMPONENTS "${CONF_OPENCV_OPTIONAL_COMPONENTS}") ++# Pin the OpenCV major version so downstream projects find the same major RTAB-Map was ++# built against ++SET(CONF_OPENCV_VERSION_MAJOR ${OpenCV_VERSION_MAJOR}) + include(CMakePackageConfigHelpers) + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" +diff --git a/RTABMapConfig.cmake.in b/RTABMapConfig.cmake.in +index 155ef3e..713359b 100644 +--- a/RTABMapConfig.cmake.in ++++ b/RTABMapConfig.cmake.in +@@ -1,7 +1,7 @@ + include(CMakeFindDependencyMacro) + + # Mandatory dependencies +-find_dependency(OpenCV COMPONENTS core calib3d imgproc highgui stitching photo video OPTIONAL_COMPONENTS aruco objdetect xfeatures2d nonfree gpu cudafeatures2d) ++find_dependency(OpenCV @CONF_OPENCV_VERSION_MAJOR@ COMPONENTS @CONF_OPENCV_COMPONENTS@ OPTIONAL_COMPONENTS @CONF_OPENCV_OPTIONAL_COMPONENTS@) + + if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/RTABMap_guiTargets.cmake") + find_dependency(PCL 1.7 COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization) +diff --git a/app/android/jni/point_cloud_drawable.cpp b/app/android/jni/point_cloud_drawable.cpp +index ca23e31..cf38ec1 100644 +--- a/app/android/jni/point_cloud_drawable.cpp ++++ b/app/android/jni/point_cloud_drawable.cpp +@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UConversion.h" +-#include ++#include + #include "util.h" + #include "pcl/common/transforms.h" + +diff --git a/corelib/include/rtabmap/core/DBDriverSqlite3.h b/corelib/include/rtabmap/core/DBDriverSqlite3.h +index 407ec7e..fbcd49b 100644 +--- a/corelib/include/rtabmap/core/DBDriverSqlite3.h ++++ b/corelib/include/rtabmap/core/DBDriverSqlite3.h +@@ -30,7 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines + #include "rtabmap/core/DBDriver.h" +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + + typedef struct sqlite3_stmt sqlite3_stmt; + typedef struct sqlite3 sqlite3; +diff --git a/corelib/include/rtabmap/core/EpipolarGeometry.h b/corelib/include/rtabmap/core/EpipolarGeometry.h +index e9408cd..fec9036 100644 +--- a/corelib/include/rtabmap/core/EpipolarGeometry.h ++++ b/corelib/include/rtabmap/core/EpipolarGeometry.h +@@ -31,7 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/core/Parameters.h" + #include "rtabmap/utilite/UStl.h" + #include +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif ++#endif + #include + #include + #include +diff --git a/corelib/include/rtabmap/core/Features2d.h b/corelib/include/rtabmap/core/Features2d.h +index f26f84b..9b064c1 100644 +--- a/corelib/include/rtabmap/core/Features2d.h ++++ b/corelib/include/rtabmap/core/Features2d.h +@@ -30,9 +30,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines + +-#include ++#include + #include +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + #include + #include + #include "rtabmap/core/Parameters.h" +@@ -70,6 +74,10 @@ class BriefDescriptorExtractor; + class SIFT; + #endif + class SURF; ++#if (CV_MAJOR_VERSION == 5) ++class BRISK; ++class KAZE; ++#endif + } + namespace cuda { + class FastFeatureDetector; +@@ -89,7 +97,13 @@ typedef cv::xfeatures2d::FREAK CV_FREAK; + typedef cv::xfeatures2d::DAISY CV_DAISY; + typedef cv::GFTTDetector CV_GFTT; + typedef cv::xfeatures2d::BriefDescriptorExtractor CV_BRIEF; ++#if (CV_MAJOR_VERSION < 5) + typedef cv::BRISK CV_BRISK; ++typedef cv::KAZE CV_KAZE; ++#else ++typedef cv::xfeatures2d::BRISK CV_BRISK; ++typedef cv::xfeatures2d::KAZE CV_KAZE; ++#endif + typedef cv::ORB CV_ORB; + typedef cv::cuda::SURF_CUDA CV_SURF_GPU; + typedef cv::cuda::ORB CV_ORB_GPU; +@@ -573,7 +587,7 @@ private: + int diffusivity_; + + #if CV_MAJOR_VERSION > 2 +- cv::Ptr kaze_; ++ cv::Ptr kaze_; + #endif + }; + +diff --git a/corelib/include/rtabmap/core/Memory.h b/corelib/include/rtabmap/core/Memory.h +index 39996d9..2fe3640 100644 +--- a/corelib/include/rtabmap/core/Memory.h ++++ b/corelib/include/rtabmap/core/Memory.h +@@ -41,7 +41,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include "rtabmap/utilite/UStl.h" + #include +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + #include + + namespace rtabmap { +diff --git a/corelib/include/rtabmap/core/OdometryInfo.h b/corelib/include/rtabmap/core/OdometryInfo.h +index 484692b..a3ec914 100644 +--- a/corelib/include/rtabmap/core/OdometryInfo.h ++++ b/corelib/include/rtabmap/core/OdometryInfo.h +@@ -34,7 +34,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/core/RegistrationInfo.h" + #include "rtabmap/core/CameraModel.h" + #include "rtabmap/core/LaserScan.h" +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + + namespace rtabmap { + +diff --git a/corelib/include/rtabmap/core/SensorCapture.h b/corelib/include/rtabmap/core/SensorCapture.h +index 20ee01b..13da904 100644 +--- a/corelib/include/rtabmap/core/SensorCapture.h ++++ b/corelib/include/rtabmap/core/SensorCapture.h +@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines + +-#include ++#include + #include + #include "rtabmap/core/SensorData.h" + #include +@@ -44,7 +44,7 @@ namespace rtabmap + + /** + * Class Camera +- * ++ * + */ + class RTABMAP_CORE_EXPORT SensorCapture + { +diff --git a/corelib/include/rtabmap/core/SensorData.h b/corelib/include/rtabmap/core/SensorData.h +index 18fc5d3..6688988 100644 +--- a/corelib/include/rtabmap/core/SensorData.h ++++ b/corelib/include/rtabmap/core/SensorData.h +@@ -34,7 +34,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + #include + #include + #include +diff --git a/corelib/include/rtabmap/core/Signature.h b/corelib/include/rtabmap/core/Signature.h +index 9dbbe53..35d438d 100644 +--- a/corelib/include/rtabmap/core/Signature.h ++++ b/corelib/include/rtabmap/core/Signature.h +@@ -31,8 +31,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include +-#include +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++#include + #include + #include + #include +@@ -62,7 +66,7 @@ public: + virtual ~Signature(); + + /** +- * Must return a value between >=0 and <=1 (1 means 100% similarity). ++ * Must return a value between >=0 and <=1 (1 means 100% similarity). + */ + float compareTo(const Signature & signature) const; + bool isBadSignature() const; +diff --git a/corelib/include/rtabmap/core/Statistics.h b/corelib/include/rtabmap/core/Statistics.h +index 61abdde..68491a8 100644 +--- a/corelib/include/rtabmap/core/Statistics.h ++++ b/corelib/include/rtabmap/core/Statistics.h +@@ -31,8 +31,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines + + #include +-#include +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++#include + #include + #include + #include +diff --git a/corelib/include/rtabmap/core/VWDictionary.h b/corelib/include/rtabmap/core/VWDictionary.h +index fbfa7ba..db7d4db 100644 +--- a/corelib/include/rtabmap/core/VWDictionary.h ++++ b/corelib/include/rtabmap/core/VWDictionary.h +@@ -29,9 +29,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines + +-#include ++#include + #include +-#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + #include + #include + #include "rtabmap/core/Parameters.h" +diff --git a/corelib/include/rtabmap/core/camera/CameraVideo.h b/corelib/include/rtabmap/core/camera/CameraVideo.h +index bdc90a1..ca65116 100644 +--- a/corelib/include/rtabmap/core/camera/CameraVideo.h ++++ b/corelib/include/rtabmap/core/camera/CameraVideo.h +@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #pragma once + +-#include ++#include + #include "rtabmap/core/Camera.h" + + namespace rtabmap +diff --git a/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h b/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h +index 2fc12a2..3361aab 100644 +--- a/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h ++++ b/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h +@@ -32,12 +32,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #ifndef CORELIB_SRC_OPENCV_STEREORECTIFYFISHEYE_H_ + #define CORELIB_SRC_OPENCV_STEREORECTIFYFISHEYE_H_ + ++// This header relies on the OpenCV C API (cvRodrigues2, cvProjectPoints2, ...) ++// which was removed in OpenCV 5. Pull in only the version macros (available in ++// all OpenCV versions) so we can fail early with a clear message rather than ++// with cryptic errors from the includes below. ++#include ++#if CV_MAJOR_VERSION >= 5 ++#error "stereoRectifyFisheye.h is not supported with OpenCV 5 or later (it uses the removed OpenCV C API). Use cv::fisheye::stereoRectify() instead, or guard your include with '#if CV_MAJOR_VERSION < 5'." ++#endif ++ + #include + #if CV_MAJOR_VERSION >= 3 +-#include + + #if CV_MAJOR_VERSION >= 4 + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + // Opencv4 doesn't expose those functions below anymore, we should recopy all of them! + int cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian CV_DEFAULT(0)) +diff --git a/corelib/include/rtabmap/core/util3d_correspondences.h b/corelib/include/rtabmap/core/util3d_correspondences.h +index 6bbaeb2..f50a98b 100644 +--- a/corelib/include/rtabmap/core/util3d_correspondences.h ++++ b/corelib/include/rtabmap/core/util3d_correspondences.h +@@ -32,7 +32,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include +-#include ++#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + #include + #include + #include +diff --git a/corelib/include/rtabmap/core/util3d_features.h b/corelib/include/rtabmap/core/util3d_features.h +index 2a02bf2..ac5cb75 100644 +--- a/corelib/include/rtabmap/core/util3d_features.h ++++ b/corelib/include/rtabmap/core/util3d_features.h +@@ -30,7 +30,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + ++#include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include +diff --git a/corelib/src/CameraModel.cpp b/corelib/src/CameraModel.cpp +index 3e80d25..bc37f40 100644 +--- a/corelib/src/CameraModel.cpp ++++ b/corelib/src/CameraModel.cpp +@@ -33,7 +33,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + namespace rtabmap { + +diff --git a/corelib/src/EpipolarGeometry.cpp b/corelib/src/EpipolarGeometry.cpp +index 38f1584..758a14a 100644 +--- a/corelib/src/EpipolarGeometry.cpp ++++ b/corelib/src/EpipolarGeometry.cpp +@@ -33,8 +33,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UMath.h" + + #include +-#include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + + namespace rtabmap +diff --git a/corelib/src/Features2d.cpp b/corelib/src/Features2d.cpp +index 90555db..cadafff 100644 +--- a/corelib/src/Features2d.cpp ++++ b/corelib/src/Features2d.cpp +@@ -36,7 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UMath.h" + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" +-#include + #include + #include + +@@ -857,7 +856,7 @@ std::vector Feature2D::generateKeypoints(const cv::Mat & image, co + cv::cornerSubPix( image, corners, + cv::Size( _subPixWinSize, _subPixWinSize ), + cv::Size( -1, -1 ), +- cv::TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, _subPixIterations, _subPixEps ) ); ++ cv::TermCriteria( cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, _subPixIterations, _subPixEps ) ); + + for(unsigned int i=0;i 4 ++#ifdef HAVE_OPENCV_XFEATURES2D ++ brisk_ = CV_BRISK::create(thresh_, octaves_, patternScale_); ++#else ++ UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so BRISK cannot be used!"); ++#endif ++#elif CV_MAJOR_VERSION < 3 + brisk_ = cv::Ptr(new CV_BRISK(thresh_, octaves_, patternScale_)); + #else + brisk_ = CV_BRISK::create(thresh_, octaves_, patternScale_); +@@ -2357,6 +2361,7 @@ std::vector BRISK::generateKeypointsImpl(const cv::Mat & image, co + { + UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); + std::vector keypoints; ++#if CV_MAJOR_VERSION < 5 || (CV_MAJOR_VERSION > 4 && defined(HAVE_OPENCV_XFEATURES2D)) + cv::Mat imgRoi(image, roi); + cv::Mat maskRoi; + if(!mask.empty()) +@@ -2364,6 +2369,9 @@ std::vector BRISK::generateKeypointsImpl(const cv::Mat & image, co + maskRoi = cv::Mat(mask, roi); + } + brisk_->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints ++#else ++ UWARN("RTAB-Map is not built with BRISK feature support!"); ++#endif + return keypoints; + } + +@@ -2371,7 +2379,11 @@ cv::Mat BRISK::generateDescriptorsImpl(const cv::Mat & image, std::vector 4 && defined(HAVE_OPENCV_XFEATURES2D)) + brisk_->compute(image, keypoints, descriptors); ++#else ++ UWARN("RTAB-Map is not built with BRISK feature support!"); ++#endif + return descriptors; + } + +@@ -2404,10 +2416,16 @@ void KAZE::parseParameters(const ParametersMap & parameters) + Parameters::parse(parameters, Parameters::kKAZENOctaveLayers(), nOctaveLayers_); + Parameters::parse(parameters, Parameters::kKAZEDiffusivity(), diffusivity_); + +-#if CV_MAJOR_VERSION > 3 +- kaze_ = cv::KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, (cv::KAZE::DiffusivityType)diffusivity_); ++#if CV_MAJOR_VERSION > 4 ++#ifdef HAVE_OPENCV_XFEATURES2D ++ kaze_ = CV_KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, (CV_KAZE::DiffusivityType)diffusivity_); ++#else ++ UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so KAZE cannot be used!"); ++#endif ++#elif CV_MAJOR_VERSION > 3 ++ kaze_ = CV_KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, (CV_KAZE::DiffusivityType)diffusivity_); + #elif CV_MAJOR_VERSION > 2 +- kaze_ = cv::KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, diffusivity_); ++ kaze_ = CV_KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, diffusivity_); + #else + UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!"); + #endif +@@ -2417,7 +2435,7 @@ std::vector KAZE::generateKeypointsImpl(const cv::Mat & image, con + { + UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); + std::vector keypoints; +-#if CV_MAJOR_VERSION > 2 ++#if (CV_MAJOR_VERSION > 2 && CV_MAJOR_VERSION < 5) || (CV_MAJOR_VERSION > 4 && defined(HAVE_OPENCV_XFEATURES2D)) + cv::Mat imgRoi(image, roi); + cv::Mat maskRoi; + if (!mask.empty()) +@@ -2426,7 +2444,7 @@ std::vector KAZE::generateKeypointsImpl(const cv::Mat & image, con + } + kaze_->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints + #else +- UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!"); ++ UWARN("RTAB-Map is not built with Kaze feature support!"); + #endif + return keypoints; + } +@@ -2435,10 +2453,10 @@ cv::Mat KAZE::generateDescriptorsImpl(const cv::Mat & image, std::vector 2 ++#if (CV_MAJOR_VERSION > 2 && CV_MAJOR_VERSION < 5) || (CV_MAJOR_VERSION > 4 && defined(HAVE_OPENCV_XFEATURES2D)) + kaze_->compute(image, keypoints, descriptors); + #else +- UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!"); ++ UWARN("RTAB-Map is not built with Kaze feature support!"); + #endif + return descriptors; + } +diff --git a/corelib/src/Memory.cpp b/corelib/src/Memory.cpp +index 0556312..2ea825f 100644 +--- a/corelib/src/Memory.cpp ++++ b/corelib/src/Memory.cpp +@@ -26,6 +26,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #include + #include + #include +@@ -62,7 +65,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + #include + + namespace rtabmap { +@@ -4930,7 +4932,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor + cv::Mat imageMono; + if(decimatedData.imageRaw().channels() == 3) + { +- cv::cvtColor(decimatedData.imageRaw(), imageMono, CV_BGR2GRAY); ++ cv::cvtColor(decimatedData.imageRaw(), imageMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -5239,7 +5241,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor + cv::Mat imageMono; + if(data.imageRaw().channels() == 3) + { +- cv::cvtColor(data.imageRaw(), imageMono, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), imageMono, cv::COLOR_BGR2GRAY); + } + else + { +diff --git a/corelib/src/RegistrationVis.cpp b/corelib/src/RegistrationVis.cpp +index 84f0101..dac3180 100644 +--- a/corelib/src/RegistrationVis.cpp ++++ b/corelib/src/RegistrationVis.cpp +@@ -43,7 +43,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#if CV_MAJOR_VERSION > 4 ++#include ++#endif + + #if defined(HAVE_OPENCV_XFEATURES2D) && (CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION==3 && CV_MINOR_VERSION >=4 && CV_SUBMINOR_VERSION >= 1)) + #include // For GMS matcher +@@ -52,6 +54,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #ifdef HAVE_OPENCV_CUDAOPTFLOW + #include + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #endif + + #include +@@ -2170,7 +2175,7 @@ Transform RegistrationVis::computeTransformationImpl( + if(!transform.isNull() && !pcaData.empty()) + { + cv::Mat pcaEigenVectors, pcaEigenValues; +- cv::PCA pca_analysis(pcaData, cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(pcaData, cv::Mat(), cv::PCA::DATA_AS_ROW); + // We take the second eigen value + info.inliersDistribution = pca_analysis.eigenvalues.at(0, 1); + +diff --git a/corelib/src/SensorCapture.cpp b/corelib/src/SensorCapture.cpp +index 5932787..a86708d 100644 +--- a/corelib/src/SensorCapture.cpp ++++ b/corelib/src/SensorCapture.cpp +@@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + +-#include ++#include + + #include + #include +diff --git a/corelib/src/SensorCaptureThread.cpp b/corelib/src/SensorCaptureThread.cpp +index 8941c3d..7d62f70 100644 +--- a/corelib/src/SensorCaptureThread.cpp ++++ b/corelib/src/SensorCaptureThread.cpp +@@ -39,7 +39,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/core/IMUFilter.h" + #include "rtabmap/core/Features2d.h" + #include "rtabmap/core/clams/discrete_depth_distortion_model.h" +-#include + #include + #include + #include +@@ -742,11 +741,11 @@ void SensorCaptureThread::postUpdate(SensorData * dataPtr, SensorCaptureInfo * i + else if(data.imageRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.imageRaw(), image, CV_BGR2YCrCb); ++ cv::cvtColor(data.imageRaw(), image, cv::COLOR_BGR2YCrCb); + cv::split(image, channels); + cv::equalizeHist(channels[0], channels[0]); + cv::merge(channels, 3, image); +- cv::cvtColor(image, image, CV_YCrCb2BGR); ++ cv::cvtColor(image, image, cv::COLOR_YCrCb2BGR); + } + if(!data.depthRaw().empty()) + { +@@ -762,11 +761,11 @@ void SensorCaptureThread::postUpdate(SensorData * dataPtr, SensorCaptureInfo * i + else if(data.rightRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.rightRaw(), right, CV_BGR2YCrCb); ++ cv::cvtColor(data.rightRaw(), right, cv::COLOR_BGR2YCrCb); + cv::split(right, channels); + cv::equalizeHist(channels[0], channels[0]); + cv::merge(channels, 3, right); +- cv::cvtColor(right, right, CV_YCrCb2BGR); ++ cv::cvtColor(right, right, cv::COLOR_YCrCb2BGR); + } + data.setStereoImage(image, right, data.stereoCameraModels()[0]); + } +@@ -781,11 +780,11 @@ void SensorCaptureThread::postUpdate(SensorData * dataPtr, SensorCaptureInfo * i + else if(data.imageRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.imageRaw(), image, CV_BGR2YCrCb); ++ cv::cvtColor(data.imageRaw(), image, cv::COLOR_BGR2YCrCb); + cv::split(image, channels); + clahe->apply(channels[0], channels[0]); + cv::merge(channels, 3, image); +- cv::cvtColor(image, image, CV_YCrCb2BGR); ++ cv::cvtColor(image, image, cv::COLOR_YCrCb2BGR); + } + if(!data.depthRaw().empty()) + { +@@ -801,11 +800,11 @@ void SensorCaptureThread::postUpdate(SensorData * dataPtr, SensorCaptureInfo * i + else if(data.rightRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.rightRaw(), right, CV_BGR2YCrCb); ++ cv::cvtColor(data.rightRaw(), right, cv::COLOR_BGR2YCrCb); + cv::split(right, channels); + clahe->apply(channels[0], channels[0]); + cv::merge(channels, 3, right); +- cv::cvtColor(right, right, CV_YCrCb2BGR); ++ cv::cvtColor(right, right, cv::COLOR_YCrCb2BGR); + } + data.setStereoImage(image, right, data.stereoCameraModels()[0]); + } +diff --git a/corelib/src/Signature.cpp b/corelib/src/Signature.cpp +index 32fca30..a7dc364 100644 +--- a/corelib/src/Signature.cpp ++++ b/corelib/src/Signature.cpp +@@ -29,7 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/core/EpipolarGeometry.h" + #include "rtabmap/core/Memory.h" + #include "rtabmap/core/Compression.h" +-#include ++#include + + #include + +diff --git a/corelib/src/StereoCameraModel.cpp b/corelib/src/StereoCameraModel.cpp +index 421d3f4..5b0e88b 100644 +--- a/corelib/src/StereoCameraModel.cpp ++++ b/corelib/src/StereoCameraModel.cpp +@@ -31,9 +31,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + +-#if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) ++#if (CV_MAJOR_VERSION > 2 and CV_MAJOR_VERSION < 5) or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) + #include + #endif + +@@ -179,12 +182,20 @@ void StereoCameraModel::updateStereoRectification() + { + cv::Vec4d D_left(left_.D_raw().at(0,0), left_.D_raw().at(0,1), left_.D_raw().at(0,4), left_.D_raw().at(0,5)); + cv::Vec4d D_right(right_.D_raw().at(0,0), right_.D_raw().at(0,1), right_.D_raw().at(0,4), right_.D_raw().at(0,5)); +- ++#if CV_MAJOR_VERSION < 5 + stereoRectifyFisheye( + left_.K_raw(), D_left, + right_.K_raw(), D_right, + left_.imageSize(), R_, T_, R1, R2, P1, P2, Q, + cv::CALIB_ZERO_DISPARITY, 0, left_.imageSize()); ++#else ++ double balance = 0.0, fov_scale = 1.0; ++ cv::fisheye::stereoRectify( ++ left_.K_raw(), D_left, ++ right_.K_raw(), D_right, ++ left_.imageSize(), R_, T_, R1, R2, P1, P2, Q, ++ cv::CALIB_ZERO_DISPARITY, left_.imageSize(), balance, fov_scale); ++#endif + + // Re-zoom to original focal distance + if(P1.at(0,0) < 0) +diff --git a/corelib/src/camera/CameraDepthAI.cpp b/corelib/src/camera/CameraDepthAI.cpp +index 9eb0179..a0d4699 100644 +--- a/corelib/src/camera/CameraDepthAI.cpp ++++ b/corelib/src/camera/CameraDepthAI.cpp +@@ -32,7 +32,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +- ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + + namespace rtabmap { + +diff --git a/corelib/src/camera/CameraFreenect.cpp b/corelib/src/camera/CameraFreenect.cpp +index 9d48215..a402c7b 100644 +--- a/corelib/src/camera/CameraFreenect.cpp ++++ b/corelib/src/camera/CameraFreenect.cpp +@@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_FREENECT + #include +@@ -183,7 +182,7 @@ private: + + if(color_) + { +- cv::cvtColor(rgbIrBuffer_, rgbIrLastFrame_, CV_RGB2BGR); ++ cv::cvtColor(rgbIrBuffer_, rgbIrLastFrame_, cv::COLOR_RGB2BGR); + } + else // IrDepth + { +diff --git a/corelib/src/camera/CameraFreenect2.cpp b/corelib/src/camera/CameraFreenect2.cpp +index 85f7bdf..1514311 100644 +--- a/corelib/src/camera/CameraFreenect2.cpp ++++ b/corelib/src/camera/CameraFreenect2.cpp +@@ -29,7 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_FREENECT2 + #include +@@ -430,11 +429,11 @@ SensorData CameraFreenect2::captureImage(SensorCaptureInfo * info) + cv::Mat rgbMat; // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatC4, rgbMat, CV_RGBA2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_RGBA2BGR); + + #else + +- cv::cvtColor(rgbMatC4, rgbMat, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgbMat, rgb, 1); +@@ -490,11 +489,11 @@ SensorData CameraFreenect2::captureImage(SensorCaptureInfo * info) + cv::Mat rgbMat; // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatC4, rgbMat, CV_RGB2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_RGB2BGR); + + #else + +- cv::cvtColor(rgbMatC4, rgbMat, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgbMat, rgb, 1); +@@ -607,11 +606,11 @@ SensorData CameraFreenect2::captureImage(SensorCaptureInfo * info) + // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatBGRA, rgb, CV_RGBA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_RGBA2BGR); + + #else + +- cv::cvtColor(rgbMatBGRA, rgb, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgb, rgb, 1); +@@ -629,11 +628,11 @@ SensorData CameraFreenect2::captureImage(SensorCaptureInfo * info) + // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatBGRA, rgb, CV_RGBA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_RGBA2BGR); + + #else + +- cv::cvtColor(rgbMatBGRA, rgb, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgb, rgb, 1); +diff --git a/corelib/src/camera/CameraImages.cpp b/corelib/src/camera/CameraImages.cpp +index 0591181..9109ac4 100644 +--- a/corelib/src/camera/CameraImages.cpp ++++ b/corelib/src/camera/CameraImages.cpp +@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include + #include + + namespace rtabmap +@@ -914,7 +914,7 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info) + { + UWARN("Conversion from 4 channels to 3 channels (file=%s)", imageFilePath.c_str()); + cv::Mat out; +- cv::cvtColor(img, out, CV_BGRA2BGR); ++ cv::cvtColor(img, out, cv::COLOR_BGRA2BGR); + img = out; + } + else if(!img.empty() && _bayerMode >= 0 && _bayerMode <=3) +@@ -922,7 +922,7 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info) + cv::Mat debayeredImg; + try + { +- cv::cvtColor(img, debayeredImg, CV_BayerBG2BGR + _bayerMode); ++ cv::cvtColor(img, debayeredImg, cv::COLOR_BayerBG2BGR + _bayerMode); + img = debayeredImg; + } + catch(const cv::Exception & e) +diff --git a/corelib/src/camera/CameraK4A.cpp b/corelib/src/camera/CameraK4A.cpp +index ad5714d..caf659b 100644 +--- a/corelib/src/camera/CameraK4A.cpp ++++ b/corelib/src/camera/CameraK4A.cpp +@@ -29,7 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_K4A + #include +@@ -508,7 +507,7 @@ SensorData CameraK4A::captureImage(SensorCaptureInfo * info) + CV_8UC4, + (void*)k4a_image_get_buffer(rgb_image_)); + +- cv::cvtColor(bgra, bgrCV, CV_BGRA2BGR); ++ cv::cvtColor(bgra, bgrCV, cv::COLOR_BGRA2BGR); + } + bgrCV = model_.rectifyImage(bgrCV); + +diff --git a/corelib/src/camera/CameraK4W2.cpp b/corelib/src/camera/CameraK4W2.cpp +index e289029..9a96251 100644 +--- a/corelib/src/camera/CameraK4W2.cpp ++++ b/corelib/src/camera/CameraK4W2.cpp +@@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_K4W2 + #include +@@ -486,11 +485,11 @@ SensorData CameraK4W2::captureImage(SensorCaptureInfo * info) + { + cv::Mat tmp; + cv::resize(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), tmp, cv::Size(), 0.5, 0.5, cv::INTER_AREA); +- cv::cvtColor(tmp, imageColor, CV_BGRA2BGR); ++ cv::cvtColor(tmp, imageColor, cv::COLOR_BGRA2BGR); + } + else + { +- cv::cvtColor(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), imageColor, CV_BGRA2BGR); ++ cv::cvtColor(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), imageColor, cv::COLOR_BGRA2BGR); + } + // loop over output pixels + for (int depthIndex = 0; depthIndex < (nDepthWidth*nDepthHeight); ++depthIndex) +diff --git a/corelib/src/camera/CameraOpenNI2.cpp b/corelib/src/camera/CameraOpenNI2.cpp +index 8be86b7..4d2ff1a 100644 +--- a/corelib/src/camera/CameraOpenNI2.cpp ++++ b/corelib/src/camera/CameraOpenNI2.cpp +@@ -29,7 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_OPENNI2 + #include +@@ -514,7 +513,7 @@ SensorData CameraOpenNI2::captureImage(SensorCaptureInfo * info) + cv::Mat tmp(h, w, CV_8UC3, (void *)colorFrame.getData()); + if(_type==kTypeColorDepth) + { +- cv::cvtColor(tmp, rgb, CV_RGB2BGR); ++ cv::cvtColor(tmp, rgb, cv::COLOR_RGB2BGR); + } + else // IR + { +diff --git a/corelib/src/camera/CameraOpenNICV.cpp b/corelib/src/camera/CameraOpenNICV.cpp +index 13536d6..1359561 100644 +--- a/corelib/src/camera/CameraOpenNICV.cpp ++++ b/corelib/src/camera/CameraOpenNICV.cpp +@@ -26,9 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include +-#if CV_MAJOR_VERSION > 3 +-#include +-#endif ++#include + + namespace rtabmap + { +@@ -59,30 +57,34 @@ bool CameraOpenNICV::init(const std::string & calibrationFolder, const std::stri + } + + ULOGGER_DEBUG("Camera::init()"); +- _capture.open( _asus?CV_CAP_OPENNI_ASUS:CV_CAP_OPENNI ); ++#if CV_MAJOR_VERSION < 5 ++ _capture.open( _asus?cv::CAP_OPENNI_ASUS:cv::CAP_OPENNI ); ++#else ++ _capture.open( _asus?cv::CAP_OPENNI2_ASUS:cv::CAP_OPENNI2 ); ++#endif + if(_capture.isOpened()) + { +- _capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ ); +- _depthFocal = _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ); ++ _capture.set( cv::CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, cv::CAP_OPENNI_VGA_30HZ ); ++ _depthFocal = _capture.get( cv::CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ); + // Print some avalible device settings. + UINFO("Depth generator output mode:"); +- UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_PROP_FRAME_WIDTH )); +- UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_PROP_FRAME_HEIGHT )); +- UINFO("FRAME_MAX_DEPTH %f mm", _capture.get( CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH )); +- UINFO("BASELINE %f mm", _capture.get( CV_CAP_PROP_OPENNI_BASELINE )); +- UINFO("FPS %f", _capture.get( CV_CAP_PROP_FPS )); +- UINFO("Focal %f", _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH )); +- UINFO("REGISTRATION %f", _capture.get( CV_CAP_PROP_OPENNI_REGISTRATION )); +- if(_capture.get( CV_CAP_PROP_OPENNI_REGISTRATION ) == 0.0) ++ UINFO("FRAME_WIDTH %f", _capture.get( cv::CAP_PROP_FRAME_WIDTH )); ++ UINFO("FRAME_HEIGHT %f", _capture.get( cv::CAP_PROP_FRAME_HEIGHT )); ++ UINFO("FRAME_MAX_DEPTH %f mm", _capture.get( cv::CAP_PROP_OPENNI_FRAME_MAX_DEPTH )); ++ UINFO("BASELINE %f mm", _capture.get( cv::CAP_PROP_OPENNI_BASELINE )); ++ UINFO("FPS %f", _capture.get( cv::CAP_PROP_FPS )); ++ UINFO("Focal %f", _capture.get( cv::CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH )); ++ UINFO("REGISTRATION %f", _capture.get( cv::CAP_PROP_OPENNI_REGISTRATION )); ++ if(_capture.get( cv::CAP_PROP_OPENNI_REGISTRATION ) == 0.0) + { + UERROR("Depth registration is not activated on this device!"); + } +- if( _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) ) ++ if( _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) ) + { + UINFO("Image generator output mode:"); +- UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_WIDTH )); +- UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_HEIGHT )); +- UINFO("FPS %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS )); ++ UINFO("FRAME_WIDTH %f", _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR+cv::CAP_PROP_FRAME_WIDTH )); ++ UINFO("FRAME_HEIGHT %f", _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR+cv::CAP_PROP_FRAME_HEIGHT )); ++ UINFO("FPS %f", _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR+cv::CAP_PROP_FPS )); + } + else + { +@@ -112,8 +114,8 @@ SensorData CameraOpenNICV::captureImage(SensorCaptureInfo * info) + { + _capture.grab(); + cv::Mat depth, rgb; +- _capture.retrieve(depth, CV_CAP_OPENNI_DEPTH_MAP ); +- _capture.retrieve(rgb, CV_CAP_OPENNI_BGR_IMAGE ); ++ _capture.retrieve(depth, cv::CAP_OPENNI_DEPTH_MAP ); ++ _capture.retrieve(rgb, cv::CAP_OPENNI_BGR_IMAGE ); + + depth = depth.clone(); + rgb = rgb.clone(); +diff --git a/corelib/src/camera/CameraOpenni.cpp b/corelib/src/camera/CameraOpenni.cpp +index 9fb8dc7..68cba16 100644 +--- a/corelib/src/camera/CameraOpenni.cpp ++++ b/corelib/src/camera/CameraOpenni.cpp +@@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_OPENNI + #include +@@ -94,7 +93,7 @@ void CameraOpenni::image_cb ( + + cv::Mat rgbFrame(rgb->getHeight(), rgb->getWidth(), CV_8UC3); + rgb->fillRGB(rgb->getWidth(), rgb->getHeight(), rgbFrame.data); +- cv::cvtColor(rgbFrame, rgb_, CV_RGB2BGR); ++ cv::cvtColor(rgbFrame, rgb_, cv::COLOR_RGB2BGR); + + depth_ = cv::Mat(rgb->getHeight(), rgb->getWidth(), CV_16UC1); + depth->fillDepthImageRaw(rgb->getWidth(), rgb->getHeight(), (unsigned short*)depth_.data); +diff --git a/corelib/src/camera/CameraRealSense.cpp b/corelib/src/camera/CameraRealSense.cpp +index 3f545bb..0136238 100644 +--- a/corelib/src/camera/CameraRealSense.cpp ++++ b/corelib/src/camera/CameraRealSense.cpp +@@ -29,7 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_REALSENSE + #include +@@ -938,7 +937,7 @@ SensorData CameraRealSense::captureImage(SensorCaptureInfo * info) + } + else + { +- cv::cvtColor(rgb, bgr, CV_RGB2BGR); ++ cv::cvtColor(rgb, bgr, cv::COLOR_RGB2BGR); + } + + bool rectified = false; +diff --git a/corelib/src/camera/CameraRealSense2.cpp b/corelib/src/camera/CameraRealSense2.cpp +index 4ddfc77..cc803c8 100644 +--- a/corelib/src/camera/CameraRealSense2.cpp ++++ b/corelib/src/camera/CameraRealSense2.cpp +@@ -30,7 +30,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_REALSENSE2 + #include +diff --git a/corelib/src/camera/CameraStereoDC1394.cpp b/corelib/src/camera/CameraStereoDC1394.cpp +index 691516b..2c21108 100644 +--- a/corelib/src/camera/CameraStereoDC1394.cpp ++++ b/corelib/src/camera/CameraStereoDC1394.cpp +@@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + + #ifdef RTABMAP_DC1394 + #include +@@ -295,8 +294,8 @@ public: + + //DC1394_COLOR_CODING_RAW16: + //DC1394_COLOR_FILTER_BGGR +- cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer), left, CV_BayerRG2BGR); +- cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer+image.total()), right, CV_BayerRG2GRAY); ++ cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer), left, cv::COLOR_BayerRG2BGR); ++ cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer+image.total()), right, cv::COLOR_BayerRG2GRAY); + + dc1394_capture_enqueue(camera_, frame); + +diff --git a/corelib/src/camera/CameraStereoImages.cpp b/corelib/src/camera/CameraStereoImages.cpp +index c50a3b8..e0dd643 100644 +--- a/corelib/src/camera/CameraStereoImages.cpp ++++ b/corelib/src/camera/CameraStereoImages.cpp +@@ -27,7 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include +-#include + + namespace rtabmap + { +@@ -184,7 +183,7 @@ SensorData CameraStereoImages::captureImage(SensorCaptureInfo * info) + if(rightImage.type() != CV_8UC1 && rightGrayScale_) + { + cv::Mat tmp; +- cv::cvtColor(rightImage, tmp, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, tmp, cv::COLOR_BGR2GRAY); + rightImage = tmp; + } + if(this->isImagesRectified() && stereoModel_.isValidForRectification()) +diff --git a/corelib/src/camera/CameraStereoTara.cpp b/corelib/src/camera/CameraStereoTara.cpp +index e4ea3cd..f4ec60a 100644 +--- a/corelib/src/camera/CameraStereoTara.cpp ++++ b/corelib/src/camera/CameraStereoTara.cpp +@@ -34,9 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#if CV_MAJOR_VERSION > 3 +-#include +-#endif ++#include + + namespace rtabmap + { +@@ -81,18 +79,18 @@ bool CameraStereoTara::init(const std::string & calibrationFolder, const std::st + + capture_.open(usbDevice_); + +- capture_.set(CV_CAP_PROP_FOURCC, CV_FOURCC('Y', '1', '6', ' ')); +- capture_.set(CV_CAP_PROP_FPS, 60); +- capture_.set(CV_CAP_PROP_FRAME_WIDTH, 752); +- capture_.set(CV_CAP_PROP_FRAME_HEIGHT, 480); +- capture_.set(CV_CAP_PROP_CONVERT_RGB,false); ++ capture_.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('Y', '1', '6', ' ')); ++ capture_.set(cv::CAP_PROP_FPS, 60); ++ capture_.set(cv::CAP_PROP_FRAME_WIDTH, 752); ++ capture_.set(cv::CAP_PROP_FRAME_HEIGHT, 480); ++ capture_.set(cv::CAP_PROP_CONVERT_RGB,false); + + ULOGGER_DEBUG("CameraStereoTara: Usb device initialization on device %d", usbDevice_); + + + if (cameraName_.empty()) + { +- unsigned int guid = (unsigned int)capture_.get(CV_CAP_PROP_GUID); ++ unsigned int guid = (unsigned int)capture_.get(cv::CAP_PROP_GUID); + if (guid != 0 && guid != 0xffffffff) + { + cameraName_ = uFormat("%08x", guid); +diff --git a/corelib/src/camera/CameraStereoVideo.cpp b/corelib/src/camera/CameraStereoVideo.cpp +index f31f40b..5de23a6 100644 +--- a/corelib/src/camera/CameraStereoVideo.cpp ++++ b/corelib/src/camera/CameraStereoVideo.cpp +@@ -28,13 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include +-#if CV_MAJOR_VERSION > 3 +-#include +-#if CV_MAJOR_VERSION > 4 +-#include +-#endif +-#endif ++#include + + namespace rtabmap + { +@@ -172,7 +166,7 @@ bool CameraStereoVideo::init(const std::string & calibrationFolder, const std::s + + if (cameraName_.empty()) + { +- unsigned int guid = (unsigned int)capture_.get(CV_CAP_PROP_GUID); ++ unsigned int guid = (unsigned int)capture_.get(cv::CAP_PROP_GUID); + if (guid != 0 && guid != 0xffffffff) + { + cameraName_ = uFormat("%08x", guid); +@@ -214,17 +208,17 @@ bool CameraStereoVideo::init(const std::string & calibrationFolder, const std::s + if(capture_.isOpened()) + { + bool resolutionSet = false; +- resolutionSet = capture_.set(CV_CAP_PROP_FRAME_WIDTH, stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2)); +- resolutionSet = resolutionSet && capture_.set(CV_CAP_PROP_FRAME_HEIGHT, stereoModel_.left().imageHeight()); ++ resolutionSet = capture_.set(cv::CAP_PROP_FRAME_WIDTH, stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2)); ++ resolutionSet = resolutionSet && capture_.set(cv::CAP_PROP_FRAME_HEIGHT, stereoModel_.left().imageHeight()); + if(capture2_.isOpened()) + { +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_WIDTH, stereoModel_.right().imageWidth()); +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_HEIGHT, stereoModel_.right().imageHeight()); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_WIDTH, stereoModel_.right().imageWidth()); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_HEIGHT, stereoModel_.right().imageHeight()); + } + + // Check if the resolution was set successfully +- int actualWidth = int(capture_.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(capture_.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(capture_.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(capture_.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || + actualWidth != stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2) || + actualHeight != stereoModel_.left().imageHeight()) +@@ -244,17 +238,17 @@ bool CameraStereoVideo::init(const std::string & calibrationFolder, const std::s + if(capture_.isOpened()) + { + bool resolutionSet = false; +- resolutionSet = capture_.set(CV_CAP_PROP_FRAME_WIDTH, _width*(capture2_.isOpened()?1:2)); +- resolutionSet = resolutionSet && capture_.set(CV_CAP_PROP_FRAME_HEIGHT, _height); ++ resolutionSet = capture_.set(cv::CAP_PROP_FRAME_WIDTH, _width*(capture2_.isOpened()?1:2)); ++ resolutionSet = resolutionSet && capture_.set(cv::CAP_PROP_FRAME_HEIGHT, _height); + if(capture2_.isOpened()) + { +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_WIDTH, _width); +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_HEIGHT, _height); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_WIDTH, _width); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_HEIGHT, _height); + } + + // Check if the resolution was set successfully +- int actualWidth = int(capture_.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(capture_.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(capture_.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(capture_.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || + actualWidth != _width*(capture2_.isOpened()?1:2) || + actualHeight != _height) +@@ -273,10 +267,10 @@ bool CameraStereoVideo::init(const std::string & calibrationFolder, const std::s + if (this->getFrameRate() > 0) + { + bool fpsSupported = false; +- fpsSupported = capture_.set(CV_CAP_PROP_FPS, this->getFrameRate()); ++ fpsSupported = capture_.set(cv::CAP_PROP_FPS, this->getFrameRate()); + if (capture2_.isOpened()) + { +- fpsSupported = fpsSupported && capture2_.set(CV_CAP_PROP_FPS, this->getFrameRate()); ++ fpsSupported = fpsSupported && capture2_.set(cv::CAP_PROP_FPS, this->getFrameRate()); + } + if(fpsSupported) + { +@@ -310,14 +304,14 @@ bool CameraStereoVideo::init(const std::string & calibrationFolder, const std::s + std::string fourccUpperCase = uToUpperCase(_fourcc); + int fourcc = cv::VideoWriter::fourcc(fourccUpperCase.at(0), fourccUpperCase.at(1), fourccUpperCase.at(2), fourccUpperCase.at(3)); + bool fourccSupported = false; +- fourccSupported = capture_.set(CV_CAP_PROP_FOURCC, fourcc); ++ fourccSupported = capture_.set(cv::CAP_PROP_FOURCC, fourcc); + if (capture2_.isOpened()) + { +- fourccSupported = fourccSupported && capture2_.set(CV_CAP_PROP_FOURCC, fourcc); ++ fourccSupported = fourccSupported && capture2_.set(cv::CAP_PROP_FOURCC, fourcc); + } + + // Check if the FOURCC was set successfully +- int actualFourcc = int(capture_.get(CV_CAP_PROP_FOURCC)); ++ int actualFourcc = int(capture_.get(cv::CAP_PROP_FOURCC)); + + if(!fourccSupported || actualFourcc != fourcc) + { +@@ -386,7 +380,7 @@ SensorData CameraStereoVideo::captureImage(SensorCaptureInfo * info) + if(rightImage.type() != CV_8UC1 && rightGrayScale_) + { + cv::Mat tmp; +- cv::cvtColor(rightImage, tmp, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, tmp, cv::COLOR_BGR2GRAY); + rightImage = tmp; + rightCvt = true; + } +diff --git a/corelib/src/camera/CameraStereoZedOC.cpp b/corelib/src/camera/CameraStereoZedOC.cpp +index 014976a..e3ba6d4 100644 +--- a/corelib/src/camera/CameraStereoZedOC.cpp ++++ b/corelib/src/camera/CameraStereoZedOC.cpp +@@ -38,6 +38,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include "SimpleIni.h" + ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif ++ + /////////////////////////////////////////////////////////////////////////// + // + // Copyright (c) 2018, STEREOLABS. +diff --git a/corelib/src/camera/CameraVideo.cpp b/corelib/src/camera/CameraVideo.cpp +index 9a0a70d..1776bca 100644 +--- a/corelib/src/camera/CameraVideo.cpp ++++ b/corelib/src/camera/CameraVideo.cpp +@@ -28,12 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#if CV_MAJOR_VERSION > 3 +-#include +-#if CV_MAJOR_VERSION > 4 +-#include +-#endif +-#endif ++#include + + namespace rtabmap + { +@@ -105,7 +100,7 @@ bool CameraVideo::init(const std::string & calibrationFolder, const std::string + { + if (_guid.empty()) + { +- unsigned int guid = (unsigned int)_capture.get(CV_CAP_PROP_GUID); ++ unsigned int guid = (unsigned int)_capture.get(cv::CAP_PROP_GUID); + if (guid != 0 && guid != 0xffffffff) + { + _guid = uFormat("%08x", guid); +@@ -143,12 +138,12 @@ bool CameraVideo::init(const std::string & calibrationFolder, const std::string + } + + bool resolutionSet = false; +- resolutionSet = _capture.set(CV_CAP_PROP_FRAME_WIDTH, _model.imageWidth()); +- resolutionSet = resolutionSet && _capture.set(CV_CAP_PROP_FRAME_HEIGHT, _model.imageHeight()); ++ resolutionSet = _capture.set(cv::CAP_PROP_FRAME_WIDTH, _model.imageWidth()); ++ resolutionSet = resolutionSet && _capture.set(cv::CAP_PROP_FRAME_HEIGHT, _model.imageHeight()); + + // Check if the resolution was set successfully +- int actualWidth = int(_capture.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(_capture.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(_capture.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(_capture.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || + actualWidth != _model.imageWidth() || + actualHeight != _model.imageHeight()) +@@ -165,12 +160,12 @@ bool CameraVideo::init(const std::string & calibrationFolder, const std::string + else if(_width > 0 && _height > 0) + { + int resolutionSet = false; +- resolutionSet = _capture.set(CV_CAP_PROP_FRAME_WIDTH, _width); +- resolutionSet = resolutionSet && _capture.set(CV_CAP_PROP_FRAME_HEIGHT, _height); ++ resolutionSet = _capture.set(cv::CAP_PROP_FRAME_WIDTH, _width); ++ resolutionSet = resolutionSet && _capture.set(cv::CAP_PROP_FRAME_HEIGHT, _height); + + // Check if the resolution was set successfully +- int actualWidth = int(_capture.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(_capture.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(_capture.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(_capture.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || actualWidth != _width || actualHeight != _height) + { + UWARN("Desired resolution (%dx%d) cannot be set to camera driver, " +@@ -182,7 +177,7 @@ bool CameraVideo::init(const std::string & calibrationFolder, const std::string + } + + // Set FPS +- if (this->getFrameRate() > 0 && _capture.set(CV_CAP_PROP_FPS, this->getFrameRate())) ++ if (this->getFrameRate() > 0 && _capture.set(cv::CAP_PROP_FPS, this->getFrameRate())) + { + // Check if the FPS was set successfully + double actualFPS = _capture.get(cv::CAP_PROP_FPS); +@@ -213,10 +208,10 @@ bool CameraVideo::init(const std::string & calibrationFolder, const std::string + std::string fourccUpperCase = uToUpperCase(_fourcc); + int fourcc = cv::VideoWriter::fourcc(fourccUpperCase.at(0), fourccUpperCase.at(1), fourccUpperCase.at(2), fourccUpperCase.at(3)); + +- bool fourccSupported = _capture.set(CV_CAP_PROP_FOURCC, fourcc); ++ bool fourccSupported = _capture.set(cv::CAP_PROP_FOURCC, fourcc); + + // Check if the FOURCC was set successfully +- int actualFourcc = int(_capture.get(CV_CAP_PROP_FOURCC)); ++ int actualFourcc = int(_capture.get(cv::CAP_PROP_FOURCC)); + + if(!fourccSupported || actualFourcc != fourcc) + { +diff --git a/corelib/src/clams/discrete_depth_distortion_model_helpers.cpp b/corelib/src/clams/discrete_depth_distortion_model_helpers.cpp +index 06c348d..dfbdc02 100644 +--- a/corelib/src/clams/discrete_depth_distortion_model_helpers.cpp ++++ b/corelib/src/clams/discrete_depth_distortion_model_helpers.cpp +@@ -28,8 +28,8 @@ RTAB-Map integration: Mathieu Labbe + */ + + #include +-#include +-#include ++#include ++#include + #include + #include + +diff --git a/corelib/src/clams/frame_projector.cpp b/corelib/src/clams/frame_projector.cpp +index 3230fcf..2634911 100644 +--- a/corelib/src/clams/frame_projector.cpp ++++ b/corelib/src/clams/frame_projector.cpp +@@ -31,8 +31,8 @@ RTAB-Map integration: Mathieu Labbe + #include + #include + #include +-#include +-#include ++#include ++#include + #include + + using namespace std; +diff --git a/corelib/src/odometry/OdometryDVO.cpp b/corelib/src/odometry/OdometryDVO.cpp +index 2f7190d..a1e425d 100644 +--- a/corelib/src/odometry/OdometryDVO.cpp ++++ b/corelib/src/odometry/OdometryDVO.cpp +@@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" +-#include + + #ifdef RTABMAP_DVO + #include +@@ -124,7 +123,7 @@ Transform OdometryDVO::computeTransform( + { + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), grey, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), grey, cv::COLOR_BGR2GRAY); + } + else + { +diff --git a/corelib/src/odometry/OdometryF2M.cpp b/corelib/src/odometry/OdometryF2M.cpp +index ba47ac1..92ac0fc 100644 +--- a/corelib/src/odometry/OdometryF2M.cpp ++++ b/corelib/src/odometry/OdometryF2M.cpp +@@ -42,7 +42,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UMath.h" + #include "rtabmap/utilite/UConversion.h" ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + +diff --git a/corelib/src/odometry/OdometryFovis.cpp b/corelib/src/odometry/OdometryFovis.cpp +index 673639a..c1f5a99 100644 +--- a/corelib/src/odometry/OdometryFovis.cpp ++++ b/corelib/src/odometry/OdometryFovis.cpp +@@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" +-#include + + #ifdef RTABMAP_FOVIS + #include +@@ -137,7 +136,7 @@ Transform OdometryFovis::computeTransform( + cv::Mat gray; + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), gray, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), gray, cv::COLOR_BGR2GRAY); + } + else if(data.imageRaw().type() == CV_8UC1) + { +@@ -302,7 +301,7 @@ Transform OdometryFovis::computeTransform( + } + if(data.rightRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.rightRaw(), right, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), right, cv::COLOR_BGR2GRAY); + } + else if(data.rightRaw().type() == CV_8UC1) + { +diff --git a/corelib/src/odometry/OdometryMSCKF.cpp b/corelib/src/odometry/OdometryMSCKF.cpp +index ac62c25..6b6737c 100644 +--- a/corelib/src/odometry/OdometryMSCKF.cpp ++++ b/corelib/src/odometry/OdometryMSCKF.cpp +@@ -26,13 +26,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include "rtabmap/core/odometry/OdometryMSCKF.h" ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #include "rtabmap/core/OdometryInfo.h" + #include "rtabmap/core/util3d_transforms.h" + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UThread.h" +-#include + + #ifdef RTABMAP_MSCKF_VIO + #include +@@ -867,7 +869,7 @@ Transform OdometryMSCKF::computeTransform( + + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), cam0.image, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), cam0.image, cv::COLOR_BGR2GRAY); + } + else + { +@@ -875,7 +877,7 @@ Transform OdometryMSCKF::computeTransform( + } + if(data.rightRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.rightRaw(), cam1.image, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), cam1.image, cv::COLOR_BGR2GRAY); + } + else + { +diff --git a/corelib/src/odometry/OdometryMono.cpp b/corelib/src/odometry/OdometryMono.cpp +index 7df312e..8cefcf7 100644 +--- a/corelib/src/odometry/OdometryMono.cpp ++++ b/corelib/src/odometry/OdometryMono.cpp +@@ -42,9 +42,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UConversion.h" + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UMath.h" +-#include ++#include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #include + + namespace rtabmap { +diff --git a/corelib/src/odometry/OdometryORBSLAM2.cpp b/corelib/src/odometry/OdometryORBSLAM2.cpp +index 1ae10bc..616678c 100644 +--- a/corelib/src/odometry/OdometryORBSLAM2.cpp ++++ b/corelib/src/odometry/OdometryORBSLAM2.cpp +@@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UDirectory.h" + #include +-#include + #include + + #if defined(RTABMAP_ORB_SLAM) and RTABMAP_ORB_SLAM == 2 +@@ -426,7 +425,7 @@ public: + } + else + { +- cvtColor(mImGray,mImGray,CV_BGR2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY); + } + } + else if(mImGray.channels()==4) +@@ -437,7 +436,7 @@ public: + } + else + { +- cvtColor(mImGray,mImGray,CV_BGRA2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGRA2GRAY); + } + } + if(imGrayRight.channels()==3) +@@ -448,7 +447,7 @@ public: + } + else + { +- cvtColor(imGrayRight,imGrayRight,CV_BGR2GRAY); ++ cvtColor(imGrayRight,imGrayRight,cv::COLOR_BGR2GRAY); + } + } + else if(imGrayRight.channels()==4) +@@ -459,7 +458,7 @@ public: + } + else + { +- cvtColor(imGrayRight,imGrayRight,CV_BGRA2GRAY); ++ cvtColor(imGrayRight,imGrayRight,cv::COLOR_BGRA2GRAY); + } + } + +@@ -480,14 +479,14 @@ public: + if(mbRGB) + cvtColor(mImGray,mImGray,CV_RGB2GRAY); + else +- cvtColor(mImGray,mImGray,CV_BGR2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY); + } + else if(mImGray.channels()==4) + { + if(mbRGB) + cvtColor(mImGray,mImGray,CV_RGBA2GRAY); + else +- cvtColor(mImGray,mImGray,CV_BGRA2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGRA2GRAY); + } + + UASSERT(imDepth.type()==CV_32F); +diff --git a/corelib/src/odometry/OdometryORBSLAM3.cpp b/corelib/src/odometry/OdometryORBSLAM3.cpp +index 7cde70a..ff87bce 100644 +--- a/corelib/src/odometry/OdometryORBSLAM3.cpp ++++ b/corelib/src/odometry/OdometryORBSLAM3.cpp +@@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UDirectory.h" + #include +-#include + #include + + #if defined(RTABMAP_ORB_SLAM) and RTABMAP_ORB_SLAM == 3 +@@ -450,12 +449,12 @@ Transform OdometryORBSLAM3::computeTransform( + cv::Mat leftMono = data.imageRaw(); + if(data.imageRaw().channels() == 3) { + leftMono = cv::Mat(); +- cv::cvtColor(data.imageRaw(), leftMono, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), leftMono, cv::COLOR_BGR2GRAY); + } + cv::Mat rightMono = data.rightRaw(); + if(data.rightRaw().channels() == 3) { + rightMono = cv::Mat(); +- cv::cvtColor(data.imageRaw(), rightMono, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), rightMono, cv::COLOR_BGR2GRAY); + } + Tcw = orbslam_->TrackStereo(leftMono, rightMono, data.stamp(), orbslamImus_); + orbslamImus_.clear(); +diff --git a/corelib/src/odometry/OdometryOkvis.cpp b/corelib/src/odometry/OdometryOkvis.cpp +index 10497b9..7c97e27 100644 +--- a/corelib/src/odometry/OdometryOkvis.cpp ++++ b/corelib/src/odometry/OdometryOkvis.cpp +@@ -34,7 +34,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UThread.h" + #include "rtabmap/utilite/UFile.h" + #include "rtabmap/utilite/UDirectory.h" +-#include + + #ifdef RTABMAP_OKVIS + #include +@@ -427,7 +426,7 @@ Transform OdometryOkvis::computeTransform( + cv::Mat gray; + if(images[i].type() == CV_8UC3) + { +- cv::cvtColor(images[i], gray, CV_BGR2GRAY); ++ cv::cvtColor(images[i], gray, cv::COLOR_BGR2GRAY); + } + else if(images[i].type() == CV_8UC1) + { +diff --git a/corelib/src/odometry/OdometryOpenVINS.cpp b/corelib/src/odometry/OdometryOpenVINS.cpp +index da81f7e..a14d74c 100644 +--- a/corelib/src/odometry/OdometryOpenVINS.cpp ++++ b/corelib/src/odometry/OdometryOpenVINS.cpp +@@ -32,7 +32,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include +-#include + + #ifdef RTABMAP_OPENVINS + #include "core/VioManager.h" +@@ -340,7 +339,7 @@ Transform OdometryOpenVINS::computeTransform( + + cv::Mat image; + if(data.imageRaw().type() == CV_8UC3) +- cv::cvtColor(data.imageRaw(), image, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), image, cv::COLOR_BGR2GRAY); + else if(data.imageRaw().type() == CV_8UC1) + image = data.imageRaw().clone(); + else +@@ -371,7 +370,7 @@ Transform OdometryOpenVINS::computeTransform( + if(!data.rightRaw().empty()) + { + if(data.rightRaw().type() == CV_8UC3) +- cv::cvtColor(data.rightRaw(), image, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), image, cv::COLOR_BGR2GRAY); + else if(data.rightRaw().type() == CV_8UC1) + image = data.rightRaw().clone(); + else +diff --git a/corelib/src/odometry/OdometryVINS.cpp b/corelib/src/odometry/OdometryVINS.cpp +index aa18393..bd8585d 100644 +--- a/corelib/src/odometry/OdometryVINS.cpp ++++ b/corelib/src/odometry/OdometryVINS.cpp +@@ -26,6 +26,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include "rtabmap/core/odometry/OdometryVINS.h" ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #include "rtabmap/core/OdometryInfo.h" + #include "rtabmap/core/util3d_transforms.h" + #include "rtabmap/utilite/ULogger.h" +@@ -33,7 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UThread.h" + #include "rtabmap/utilite/UDirectory.h" +-#include + + #ifdef RTABMAP_VINS + #include +@@ -388,7 +390,7 @@ Transform OdometryVINS::computeTransform( + cv::Mat right; + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), left, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), left, cv::COLOR_BGR2GRAY); + } + else if(data.imageRaw().type() == CV_8UC1) + { +@@ -400,7 +402,7 @@ Transform OdometryVINS::computeTransform( + } + if(data.rightRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.rightRaw(), right, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), right, cv::COLOR_BGR2GRAY); + } + else if(data.rightRaw().type() == CV_8UC1) + { +diff --git a/corelib/src/odometry/OdometryViso2.cpp b/corelib/src/odometry/OdometryViso2.cpp +index 808e763..dc6192b 100644 +--- a/corelib/src/odometry/OdometryViso2.cpp ++++ b/corelib/src/odometry/OdometryViso2.cpp +@@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" +-#include + + #ifdef RTABMAP_VISO2 + #include +@@ -131,7 +130,7 @@ Transform OdometryViso2::computeTransform( + cv::Mat leftGray; + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), leftGray, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), leftGray, cv::COLOR_BGR2GRAY); + } + else if(data.imageRaw().type() == CV_8UC1) + { +@@ -144,7 +143,7 @@ Transform OdometryViso2::computeTransform( + cv::Mat rightGray; + if(data.rightRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.rightRaw(), rightGray, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), rightGray, cv::COLOR_BGR2GRAY); + } + else if(data.rightRaw().type() == CV_8UC1) + { +diff --git a/corelib/src/opencv/ORBextractor.cc b/corelib/src/opencv/ORBextractor.cc +index 2d3cd7c..1197fb6 100644 +--- a/corelib/src/opencv/ORBextractor.cc ++++ b/corelib/src/opencv/ORBextractor.cc +@@ -63,9 +63,13 @@ + + + #include +-#include +-#include +-#include ++#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++#include + #include + #include + #include +diff --git a/corelib/src/opencv/ORBextractor.h b/corelib/src/opencv/ORBextractor.h +index 861ca05..82ede5b 100644 +--- a/corelib/src/opencv/ORBextractor.h ++++ b/corelib/src/opencv/ORBextractor.h +@@ -31,8 +31,6 @@ + + #include + #include +-#include +- + + namespace rtabmap + { +diff --git a/corelib/src/opencv/Orb.cpp b/corelib/src/opencv/Orb.cpp +index f56874e..c5034a7 100644 +--- a/corelib/src/opencv/Orb.cpp ++++ b/corelib/src/opencv/Orb.cpp +@@ -40,7 +40,6 @@ + + #include "opencv2/features2d/features2d.hpp" + #include "opencv2/imgproc/imgproc.hpp" +-#include "opencv2/imgproc/imgproc_c.h" + #include + #include + +@@ -252,7 +251,7 @@ static void computeOrbDescriptor(const KeyPoint& kpt, + } + } + else +- CV_Error( CV_StsBadSize, "Wrong WTA_K. It can be only 2, 3 or 4." ); ++ CV_Error( cv::Error::StsBadSize, "Wrong WTA_K. It can be only 2, 3 or 4." ); + + #undef GET_VALUE + } +@@ -752,7 +751,7 @@ void CV_ORB::operator()( InputArray _image, InputArray _mask, std::vectornlevels; + +diff --git a/corelib/src/opencv/Orb.h b/corelib/src/opencv/Orb.h +index e05ad9d..464ad16 100644 +--- a/corelib/src/opencv/Orb.h ++++ b/corelib/src/opencv/Orb.h +@@ -46,7 +46,7 @@ + #ifndef CORELIB_SRC_OPENCV_ORB_H_ + #define CORELIB_SRC_OPENCV_ORB_H_ + +-#include ++#include + + namespace rtabmap { + +diff --git a/corelib/src/opencv/five-point.cpp b/corelib/src/opencv/five-point.cpp +index 7e5c2c5..a389c9f 100644 +--- a/corelib/src/opencv/five-point.cpp ++++ b/corelib/src/opencv/five-point.cpp +@@ -30,6 +30,9 @@ + */ + + #include "solvepnp.h" ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + using namespace cv; + +diff --git a/corelib/src/opencv/five-point.h b/corelib/src/opencv/five-point.h +index 1a5b778..f1aa8c7 100644 +--- a/corelib/src/opencv/five-point.h ++++ b/corelib/src/opencv/five-point.h +@@ -8,6 +8,10 @@ + #ifndef CORELIB_SRC_OPENCV_FIVE_POINT_H_ + #define CORELIB_SRC_OPENCV_FIVE_POINT_H_ + ++#if CV_MAJOR_VERSION > 4 ++#include ++#endif ++ + namespace cv3 + { + +diff --git a/corelib/src/opencv/solvepnp.cpp b/corelib/src/opencv/solvepnp.cpp +index f5b3a07..ecd2be9 100644 +--- a/corelib/src/opencv/solvepnp.cpp ++++ b/corelib/src/opencv/solvepnp.cpp +@@ -53,7 +53,7 @@ class PnPRansacCallback : public PointSetRegistrator::Callback + + public: + +- PnPRansacCallback(Mat _cameraMatrix=Mat(3,3,CV_64F), Mat _distCoeffs=Mat(4,1,CV_64F), int _flags=CV_ITERATIVE, ++ PnPRansacCallback(Mat _cameraMatrix=Mat(3,3,CV_64F), Mat _distCoeffs=Mat(4,1,CV_64F), int _flags=cv::SOLVEPNP_ITERATIVE, + bool _useExtrinsicGuess=false, Mat _rvec=Mat(), Mat _tvec=Mat() ) + : cameraMatrix(_cameraMatrix), distCoeffs(_distCoeffs), flags(_flags), useExtrinsicGuess(_useExtrinsicGuess), + rvec(_rvec), tvec(_tvec) {} +@@ -142,12 +142,12 @@ bool solvePnPRansac(InputArray _opoints, InputArray _ipoints, + Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); + + int model_points = 6; +- int ransac_kernel_method = CV_EPNP; ++ int ransac_kernel_method = cv::SOLVEPNP_EPNP; + + if( npoints == 4 ) + { + model_points = 4; +- ransac_kernel_method = CV_P3P; ++ ransac_kernel_method = cv::SOLVEPNP_P3P; + } + + Ptr cb; // pointer to callback +@@ -178,7 +178,7 @@ bool solvePnPRansac(InputArray _opoints, InputArray _ipoints, + opoints_inliers.resize(npoints1); + ipoints_inliers.resize(npoints1); + result = solvePnP(opoints_inliers, ipoints_inliers, cameraMatrix, +- distCoeffs, rvec, tvec, useExtrinsicGuess, flags == CV_P3P ? CV_EPNP : flags) ? 1 : -1; ++ distCoeffs, rvec, tvec, useExtrinsicGuess, flags == cv::SOLVEPNP_P3P ? cv::SOLVEPNP_EPNP : flags) ? 1 : -1; + } + + if( result <= 0 || _local_model.rows <= 0) +@@ -213,7 +213,7 @@ bool solvePnPRansac(InputArray _opoints, InputArray _ipoints, + int RANSACUpdateNumIters( double p, double ep, int modelPoints, int maxIters ) + { + if( modelPoints <= 0 ) +- CV_Error( 0, "the number of model points should be positive" ); ++ CV_Error( cv::Error::Code::StsBadArg, "the number of model points should be positive" ); + + p = MAX(p, 0.); + p = MIN(p, 1.); +diff --git a/corelib/src/opencv/solvepnp.h b/corelib/src/opencv/solvepnp.h +index e88b570..382f9db 100644 +--- a/corelib/src/opencv/solvepnp.h ++++ b/corelib/src/opencv/solvepnp.h +@@ -45,9 +45,10 @@ + #define RTABMAP_CORELIB_SRC_OPENCV_SOLVEPNP_H_ + + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#else + #include +-#if CV_MAJOR_VERSION >= 3 +-#include + #endif + + namespace cv3 { +@@ -95,7 +96,7 @@ bool solvePnPRansac( cv::InputArray objectPoints, cv::InputArray imagePoints, + cv::OutputArray rvec, cv::OutputArray tvec, + bool useExtrinsicGuess = false, int iterationsCount = 100, + float reprojectionError = 8.0, double confidence = 0.99, +- cv::OutputArray inliers = cv::noArray(), int flags = CV_ITERATIVE ); ++ cv::OutputArray inliers = cv::noArray(), int flags = cv::SOLVEPNP_ITERATIVE ); + + int RANSACUpdateNumIters( double p, double ep, int modelPoints, int maxIters ); + +diff --git a/corelib/src/optimizer/OptimizerCeres.cpp b/corelib/src/optimizer/OptimizerCeres.cpp +index 046d401..d2d64c3 100644 +--- a/corelib/src/optimizer/OptimizerCeres.cpp ++++ b/corelib/src/optimizer/OptimizerCeres.cpp +@@ -26,6 +26,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include "rtabmap/core/Graph.h" + ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++ + #include + #include + #include +diff --git a/corelib/src/stereo/StereoBM.cpp b/corelib/src/stereo/StereoBM.cpp +index 1b390c6..356266e 100644 +--- a/corelib/src/stereo/StereoBM.cpp ++++ b/corelib/src/stereo/StereoBM.cpp +@@ -27,9 +27,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include +-#include +-#include ++#else ++#include ++#include ++#endif ++#include + + namespace rtabmap { + +@@ -88,7 +92,7 @@ cv::Mat StereoBM::computeDisparity( + cv::Mat leftMono; + if(leftImage.channels() == 3) + { +- cv::cvtColor(leftImage, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftImage, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -98,7 +102,7 @@ cv::Mat StereoBM::computeDisparity( + cv::Mat rightMono; + if(rightImage.channels() == 3) + { +- cv::cvtColor(rightImage, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff --git a/corelib/src/stereo/StereoSGBM.cpp b/corelib/src/stereo/StereoSGBM.cpp +index 6763aeb..291ba7f 100644 +--- a/corelib/src/stereo/StereoSGBM.cpp ++++ b/corelib/src/stereo/StereoSGBM.cpp +@@ -27,9 +27,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include +-#include +-#include ++#else ++#include ++#include ++#endif ++#include + + namespace rtabmap { + +@@ -77,7 +81,7 @@ cv::Mat StereoSGBM::computeDisparity( + cv::Mat leftMono; + if(leftImage.channels() == 3) + { +- cv::cvtColor(leftImage, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftImage, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -87,7 +91,7 @@ cv::Mat StereoSGBM::computeDisparity( + cv::Mat rightMono; + if(rightImage.channels() == 3) + { +- cv::cvtColor(rightImage, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff --git a/corelib/src/util2d.cpp b/corelib/src/util2d.cpp +index 604eaa3..3642e66 100644 +--- a/corelib/src/util2d.cpp ++++ b/corelib/src/util2d.cpp +@@ -34,16 +34,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include +-#include ++#include + #include +-#include +-#include ++#include + #include + #include + + #if CV_MAJOR_VERSION >= 3 +-#include ++#include ++#endif ++ ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include + #endif + + namespace rtabmap +@@ -747,7 +751,7 @@ cv::Mat disparityFromStereoImages( + cv::Mat leftMono; + if(leftImage.channels() == 3) + { +- cv::cvtColor(leftImage, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftImage, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -2042,8 +2046,8 @@ cv::Mat brightnessAndContrastAuto(const cv::Mat &src, const cv::Mat & mask, floa + //to calculate grayscale histogram + cv::Mat gray; + if (src.type() == CV_8UC1) gray = src; +- else if (src.type() == CV_8UC3) cvtColor(src, gray, CV_BGR2GRAY); +- else if (src.type() == CV_8UC4) cvtColor(src, gray, CV_BGRA2GRAY); ++ else if (src.type() == CV_8UC3) cvtColor(src, gray, cv::COLOR_BGR2GRAY); ++ else if (src.type() == CV_8UC4) cvtColor(src, gray, cv::COLOR_BGRA2GRAY); + if (clipLowHistPercent == 0 && clipHighHistPercent == 0) + { + // keep full available range +diff --git a/corelib/src/util3d.cpp b/corelib/src/util3d.cpp +index 563e22a..4619868 100644 +--- a/corelib/src/util3d.cpp ++++ b/corelib/src/util3d.cpp +@@ -40,8 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include +-#include ++#include + + namespace rtabmap + { +@@ -892,7 +891,7 @@ pcl::PointCloud::Ptr cloudFromStereoImages( + cv::Mat leftMono; + if(leftColor.channels() == 3) + { +- cv::cvtColor(leftColor, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftColor, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -902,7 +901,7 @@ pcl::PointCloud::Ptr cloudFromStereoImages( + cv::Mat rightMono; + if(rightColor.channels() == 3) + { +- cv::cvtColor(rightColor, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(rightColor, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -1038,7 +1037,7 @@ std::vector::Ptr> cloudsFromSensorData( + cv::Mat leftMono; + if(sensorData.imageRaw().channels() == 3) + { +- cv::cvtColor(sensorData.imageRaw(), leftMono, CV_BGR2GRAY); ++ cv::cvtColor(sensorData.imageRaw(), leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -1048,7 +1047,7 @@ std::vector::Ptr> cloudsFromSensorData( + cv::Mat rightMono; + if(sensorData.rightRaw().channels() == 3) + { +- cv::cvtColor(sensorData.rightRaw(), rightMono, CV_BGR2GRAY); ++ cv::cvtColor(sensorData.rightRaw(), rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff --git a/corelib/src/util3d_correspondences.cpp b/corelib/src/util3d_correspondences.cpp +index 5a81869..41cc1e6 100644 +--- a/corelib/src/util3d_correspondences.cpp ++++ b/corelib/src/util3d_correspondences.cpp +@@ -30,7 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + +diff --git a/corelib/src/util3d_motion_estimation.cpp b/corelib/src/util3d_motion_estimation.cpp +index 63ed9ac..41ea2a0 100644 +--- a/corelib/src/util3d_motion_estimation.cpp ++++ b/corelib/src/util3d_motion_estimation.cpp +@@ -26,6 +26,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include "rtabmap/core/util3d_motion_estimation.h" ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UMath.h" +diff --git a/corelib/src/util3d_surface.cpp b/corelib/src/util3d_surface.cpp +index bccae36..3625426 100644 +--- a/corelib/src/util3d_surface.cpp ++++ b/corelib/src/util3d_surface.cpp +@@ -39,8 +39,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UConversion.h" + #include "rtabmap/utilite/UMath.h" + #include "rtabmap/utilite/UTimer.h" +-#include +-#include + #include + #include + #include +@@ -1745,7 +1743,7 @@ cv::Mat mergeTextures( + if(resizedImage.type() == CV_8UC1) + { + cv::Mat resizedImageColor; +- cv::cvtColor(resizedImage, resizedImageColor, CV_GRAY2BGR); ++ cv::cvtColor(resizedImage, resizedImageColor, cv::COLOR_GRAY2BGR); + resizedImage = resizedImageColor; + } + UASSERT(resizedImage.type() == globalTextures.type()); +@@ -2609,7 +2607,7 @@ bool multiBandTexturing( + if(imageRoi.channels() == 1) + { + cv::Mat imageRoiColor; +- cv::cvtColor(imageRoi, imageRoiColor, CV_GRAY2BGR); ++ cv::cvtColor(imageRoi, imageRoiColor, cv::COLOR_GRAY2BGR); + imageRoi = imageRoiColor; + } + +@@ -3218,7 +3216,7 @@ float computeNormalsComplexity( + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3279,7 +3277,7 @@ float computeNormalsComplexity( + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3335,7 +3333,7 @@ float computeNormalsComplexity( + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3391,7 +3389,7 @@ float computeNormalsComplexity( + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3447,7 +3445,7 @@ float computeNormalsComplexity( + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +diff --git a/guilib/include/rtabmap/gui/DatabaseViewer.h b/guilib/include/rtabmap/gui/DatabaseViewer.h +index a11b4c9..28fbc38 100644 +--- a/guilib/include/rtabmap/gui/DatabaseViewer.h ++++ b/guilib/include/rtabmap/gui/DatabaseViewer.h +@@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include + #include + #include + #include +diff --git a/guilib/include/rtabmap/gui/ImageView.h b/guilib/include/rtabmap/gui/ImageView.h +index 8e8df85..eaf9134 100644 +--- a/guilib/include/rtabmap/gui/ImageView.h ++++ b/guilib/include/rtabmap/gui/ImageView.h +@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include + #include + #include "rtabmap/utilite/UCv2Qt.h" + #include +diff --git a/guilib/include/rtabmap/gui/KeypointItem.h b/guilib/include/rtabmap/gui/KeypointItem.h +index 7f4f9f6..11a896d 100644 +--- a/guilib/include/rtabmap/gui/KeypointItem.h ++++ b/guilib/include/rtabmap/gui/KeypointItem.h +@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include + + namespace rtabmap { + +diff --git a/guilib/src/CalibrationDialog.cpp b/guilib/src/CalibrationDialog.cpp +index dd4a052..8262210 100644 +--- a/guilib/src/CalibrationDialog.cpp ++++ b/guilib/src/CalibrationDialog.cpp +@@ -29,14 +29,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "ui_calibrationDialog.h" + + #include +-#include +-#include +-#include ++#include ++#include + #if CV_MAJOR_VERSION >= 3 +-#include + #endif +-#include +-#if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) ++#include ++#if (CV_MAJOR_VERSION > 2 and CV_MAJOR_VERSION < 5) or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) + #include + #endif + +@@ -736,7 +734,7 @@ void CalibrationDialog::processImages(const cv::Mat & imageLeft, const cv::Mat & + cv::Size boardSize(ui_->spinBox_boardWidth->value(), ui_->spinBox_boardHeight->value()); + if(!viewGray.empty()) + { +- int flags = CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE; ++ int flags = cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE; + + if(!viewGray.empty()) + { +@@ -747,7 +745,7 @@ void CalibrationDialog::processImages(const cv::Mat & imageLeft, const cv::Mat & + if( scale == 1 ) + timg = viewGray; + else +- cv::resize(viewGray, timg, cv::Size(), scale, scale, CV_INTER_CUBIC); ++ cv::resize(viewGray, timg, cv::Size(), scale, scale, cv::INTER_CUBIC); + + #ifdef HAVE_CHARUCO + if(ui_->comboBox_board_type->currentIndex() >= 1 ) +@@ -832,7 +830,7 @@ void CalibrationDialog::processImages(const cv::Mat & imageLeft, const cv::Mat & + float ratio = ui_->comboBox_board_type->currentIndex() >= 1 ?6.0f:2.0f; + float radius = minSquareDistance==-1.0f?5.0f:(minSquareDistance/ratio); + cv::cornerSubPix( viewGray, pointBuf[id], cv::Size(radius, radius), cv::Size(-1,-1), +- cv::TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1 )); ++ cv::TermCriteria( cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.1 )); + + // Filter points that drifted to far (caused by reflection or bad subpixel gradient) + float threshold = ui_->doubleSpinBox_subpixel_error->value(); +@@ -1121,7 +1119,7 @@ void CalibrationDialog::processImages(const cv::Mat & imageLeft, const cv::Mat & + int step = imageSize_[id].height/16; + for(int i=step; iimageRaw().channels() == 3) + { +- cv::cvtColor(data->imageRaw(), leftMono, CV_BGR2GRAY); ++ cv::cvtColor(data->imageRaw(), leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -5891,7 +5889,7 @@ void DatabaseViewer::updateStereo(const SensorData * data) + cv::Mat rightMono; + if(data->rightRaw().channels() == 3) + { +- cv::cvtColor(data->rightRaw(), rightMono, CV_BGR2GRAY); ++ cv::cvtColor(data->rightRaw(), rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff --git a/guilib/src/MainWindow.cpp b/guilib/src/MainWindow.cpp +index 86e6924..06cb82f 100644 +--- a/guilib/src/MainWindow.cpp ++++ b/guilib/src/MainWindow.cpp +@@ -126,6 +126,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #ifdef HAVE_OPENCV_ARUCO + #include + #endif ++#include + + #define LOG_FILE_NAME "LogRtabmap.txt" + #define SHARE_SHOW_LOG_FILE "share/rtabmap/showlogs.m" +diff --git a/tools/Camera/main.cpp b/tools/Camera/main.cpp +index e337030..c856d7b 100644 +--- a/tools/Camera/main.cpp ++++ b/tools/Camera/main.cpp +@@ -31,8 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UFile.h" + #include "rtabmap/utilite/UDirectory.h" + #include "rtabmap/utilite/UConversion.h" +-#include +-#include ++#include + #include + + void showUsage() +@@ -178,7 +177,7 @@ int main(int argc, char * argv[]) + + cv::Mat rgb; + rgb = camera->takeImage().imageRaw(); +- cv::namedWindow("Video", CV_WINDOW_AUTOSIZE); // create window ++ cv::namedWindow("Video", cv::WINDOW_AUTOSIZE); // create window + while(!rgb.empty()) + { + cv::imshow("Video", rgb); // show frame +diff --git a/tools/CameraRGBD/main.cpp b/tools/CameraRGBD/main.cpp +index 1d562d9..a1274f1 100644 +--- a/tools/CameraRGBD/main.cpp ++++ b/tools/CameraRGBD/main.cpp +@@ -35,12 +35,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UFile.h" + #include "rtabmap/utilite/UDirectory.h" + #include "rtabmap/utilite/UConversion.h" +-#include +-#include +-#include +-#if CV_MAJOR_VERSION >= 3 +-#include +-#endif ++#include ++#include ++#include + #include + #include + #include +@@ -399,7 +396,7 @@ int main(int argc, char * argv[]) + UASSERT(fourcc.size() == 4); + videoWriter.open( + stereoSavePath, +- CV_FOURCC(fourcc.at(0), fourcc.at(1), fourcc.at(2), fourcc.at(3)), ++ cv::VideoWriter::fourcc(fourcc.at(0), fourcc.at(1), fourcc.at(2), fourcc.at(3)), + rate, + targetSize, + data.imageRaw().channels() == 3); +@@ -480,7 +477,7 @@ int main(int argc, char * argv[]) + { + if(right.channels() == 3) + { +- cv::cvtColor(right, right, CV_BGR2GRAY); ++ cv::cvtColor(right, right, cv::COLOR_BGR2GRAY); + } + pcl::PointCloud::Ptr cloud = rtabmap::util3d::cloudFromStereoImages( + rgb, right, +@@ -507,14 +504,14 @@ int main(int argc, char * argv[]) + if(right.type() != left.type()) + { + cv::Mat tmp; +- cv::cvtColor(right, tmp, left.channels()==3?CV_GRAY2BGR:CV_BGR2GRAY); ++ cv::cvtColor(right, tmp, left.channels()==3?cv::COLOR_GRAY2BGR:cv::COLOR_BGR2GRAY); + right = tmp; + } + UASSERT(left.type() == right.type()); + + cv::Mat roiA(targetImage, cv::Rect( 0, 0, left.size().width, left.size().height )); + left.copyTo(roiA); +- cv::Mat roiB( targetImage, cvRect( left.size().width, 0, left.size().width, left.size().height ) ); ++ cv::Mat roiB( targetImage, cv::Rect( left.size().width, 0, left.size().width, left.size().height ) ); + right.copyTo(roiB); + + videoWriter.write(targetImage); +diff --git a/tools/EpipolarGeometry/main.cpp b/tools/EpipolarGeometry/main.cpp +index aa309fa..49cc610 100644 +--- a/tools/EpipolarGeometry/main.cpp ++++ b/tools/EpipolarGeometry/main.cpp +@@ -26,9 +26,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include +-#include +-#include +-#include ++#include ++#include + #include + #include + #include +@@ -36,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include + #include "rtabmap/core/Features2d.h" + #include "rtabmap/core/EpipolarGeometry.h" + #include "rtabmap/core/VWDictionary.h" +diff --git a/tools/ImagesJoiner/main.cpp b/tools/ImagesJoiner/main.cpp +index ad4d3dd..3cf5264 100644 +--- a/tools/ImagesJoiner/main.cpp ++++ b/tools/ImagesJoiner/main.cpp +@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include "rtabmap/utilite/UFile.h" + #include "rtabmap/utilite/UConversion.h" + #include +-#include ++#include + + void showUsage() + { +diff --git a/tools/StereoEval/main.cpp b/tools/StereoEval/main.cpp +index bd3313f..9c15e34 100644 +--- a/tools/StereoEval/main.cpp ++++ b/tools/StereoEval/main.cpp +@@ -37,7 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include + #include + #include + +@@ -222,7 +221,7 @@ int main(int argc, char * argv[]) + cv::Mat leftMono; + if(left.channels() == 3) + { +- cv::cvtColor(left, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(left, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -231,7 +230,7 @@ int main(int argc, char * argv[]) + cv::Mat rightMono; + if(right.channels() == 3) + { +- cv::cvtColor(right, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(right, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -266,7 +265,7 @@ int main(int argc, char * argv[]) + cv::cornerSubPix(leftMono, leftCorners, + cv::Size( subPixWinSize, subPixWinSize ), + cv::Size( -1, -1 ), +- cv::TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, subPixIterations, subPixEps ) ); ++ cv::TermCriteria( cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, subPixIterations, subPixEps ) ); + UDEBUG("cv::cornerSubPix() end"); + } + +diff --git a/tools/VocabularyComparison/main.cpp b/tools/VocabularyComparison/main.cpp +index 410439b..cc65f02 100644 +--- a/tools/VocabularyComparison/main.cpp ++++ b/tools/VocabularyComparison/main.cpp +@@ -27,10 +27,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + #include +-#include +-#include + #include +-#include ++#include + #include + #include + #include diff --git a/patch/ros-rolling-septentrio-gnss-driver.patch b/patch/ros-rolling-septentrio-gnss-driver.patch new file mode 100644 index 000000000..0da08ebc9 --- /dev/null +++ b/patch/ros-rolling-septentrio-gnss-driver.patch @@ -0,0 +1,34 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 66dec47..0ad6caa 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,8 +1,11 @@ + cmake_minimum_required(VERSION 3.10) + project(septentrio_gnss_driver) + +-## Compile as C++17 +-add_compile_options(-std=c++17) ++# rclcpp_components' class_loader now uses C++20 concepts (requires/concept/ ++# std::ranges) on rolling. This unconditional -std=c++17 override came after ++# ament's own -std=gnu++20 default on the compile line, so being last it won, ++# breaking any translation unit that pulls in class_loader headers. Let ++# ament's default C++ standard apply instead of forcing C++17. + + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to Release as none was specified.") +diff --git a/include/septentrio_gnss_driver/abstraction/typedefs.hpp b/include/septentrio_gnss_driver/abstraction/typedefs.hpp +index 69f7b2c..25ec2c7 100644 +--- a/include/septentrio_gnss_driver/abstraction/typedefs.hpp ++++ b/include/septentrio_gnss_driver/abstraction/typedefs.hpp +@@ -40,9 +40,11 @@ + // tf2 includes + #ifdef ROS2_VER_N520 + #include ++#include + #include + #else + #include ++#include + #include + #endif + #ifdef ROS2_VER_N250 diff --git a/patch/ros-rolling-sick-safetyscanners-base.patch b/patch/ros-rolling-sick-safetyscanners-base.patch new file mode 100644 index 000000000..0b04c6fff --- /dev/null +++ b/patch/ros-rolling-sick-safetyscanners-base.patch @@ -0,0 +1,334 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 59faf98..38f1a17 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -9,7 +9,7 @@ add_definitions(-std=c++11 -Wall -Werror) + + + ## Find system libraries +-find_package(Boost REQUIRED COMPONENTS system thread chrono) ++find_package(Boost REQUIRED COMPONENTS thread chrono) + + + ########### +diff --git a/include/sick_safetyscanners_base/SickSafetyscanners.h b/include/sick_safetyscanners_base/SickSafetyscanners.h +index 9dace76..70f564b 100644 +--- a/include/sick_safetyscanners_base/SickSafetyscanners.h ++++ b/include/sick_safetyscanners_base/SickSafetyscanners.h +@@ -65,7 +65,7 @@ + + namespace sick { + +-using io_service_ptr = std::shared_ptr; ++using io_service_ptr = std::shared_ptr; + + using namespace sick::datastructure; + +@@ -99,7 +99,7 @@ public: + SickSafetyscannersBase(sick::types::ip_address_t sensor_ip, + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, +- boost::asio::io_service& io_service); ++ boost::asio::io_context& io_service); + /*! + * \brief Constructor of the SickSafetyscannersBase class. + * +@@ -263,7 +263,7 @@ public: + private: + sick::types::ip_address_t m_sensor_ip; + CommSettings m_comm_settings; +- std::unique_ptr m_io_service_ptr; ++ std::unique_ptr m_io_service_ptr; + + /*! + * \brief Helper function to create command objects generically. +@@ -282,7 +282,7 @@ private: + } + + protected: +- boost::asio::io_service& m_io_service; ++ boost::asio::io_context& m_io_service; + sick::communication::UDPClient m_udp_client; + sick::cola2::Cola2Session m_session; + sick::data_processing::UDPPacketMerger m_packet_merger; +@@ -351,7 +351,7 @@ public: + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, + sick::types::ScanDataCb callback, +- boost::asio::io_service& io_service); ++ boost::asio::io_context& io_service); + + /*! + * \brief Destructor of the AsyncSickSafetyScanner object +@@ -382,9 +382,11 @@ private: + void processUDPPacket(const sick::datastructure::PacketBuffer& buffer); + + sick::types::ScanDataCb m_scan_data_cb; +- std::unique_ptr m_io_service_ptr; ++ std::unique_ptr m_io_service_ptr; + boost::thread m_service_thread; +- std::unique_ptr m_work; ++ // io_context::work was removed; executor_work_guard is the modern replacement ++ // for keeping io_context::run() from returning while idle. ++ std::unique_ptr> m_work; + }; + + /*! +@@ -403,7 +405,7 @@ public: + SyncSickSafetyScanner(sick::types::ip_address_t sensor_ip, + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, +- boost::asio::io_service& io_service) = delete; ++ boost::asio::io_context& io_service) = delete; + /*! + * \brief Indicates whether sensor data is available in the receiving buffers. + * +diff --git a/include/sick_safetyscanners_base/Types.h b/include/sick_safetyscanners_base/Types.h +index a31eb22..ffe418f 100644 +--- a/include/sick_safetyscanners_base/Types.h ++++ b/include/sick_safetyscanners_base/Types.h +@@ -38,6 +38,7 @@ + #include "sick_safetyscanners_base/datastructure/Data.h" + #include "sick_safetyscanners_base/datastructure/PacketBuffer.h" + #include ++#include + #include + #include + #include +diff --git a/include/sick_safetyscanners_base/communication/TCPClient.h b/include/sick_safetyscanners_base/communication/TCPClient.h +index db9cbb6..795398d 100644 +--- a/include/sick_safetyscanners_base/communication/TCPClient.h ++++ b/include/sick_safetyscanners_base/communication/TCPClient.h +@@ -36,6 +36,7 @@ + #define SICK_SAFETYSCANNERS_BASE_COMMUNICATION_SYNCTCPCLIENT_H + + #include ++#include + #include + #include + #include +@@ -104,12 +105,12 @@ public: + receive(sick::types::time_duration_t timeout = boost::posix_time::seconds(5)); + + private: +- boost::asio::io_service m_io_service; ++ boost::asio::io_context m_io_service; + sick::datastructure::PacketBuffer::ArrayBuffer m_recv_buffer; + boost::asio::ip::tcp::socket m_socket; + sick::types::ip_address_t m_server_ip; + sick::types::port_t m_server_port; +- boost::asio::deadline_timer m_deadline; ++ boost::asio::basic_deadline_timer m_deadline; + + /*! + * \brief A function to check internal deadline constraints on connect, receive and send +diff --git a/include/sick_safetyscanners_base/communication/UDPClient.h b/include/sick_safetyscanners_base/communication/UDPClient.h +index 02831a5..c77b34a 100644 +--- a/include/sick_safetyscanners_base/communication/UDPClient.h ++++ b/include/sick_safetyscanners_base/communication/UDPClient.h +@@ -40,6 +40,8 @@ + #include + + #include ++#include ++#include + + #include "sick_safetyscanners_base/Types.h" + #include "sick_safetyscanners_base/datastructure/PacketBuffer.h" +@@ -60,7 +62,7 @@ public: + * \param io_service Instance of the boost::asio io_service + * \param server_port The local port number on the receiver (this client's) side. + */ +- UDPClient(boost::asio::io_service& io_service, sick::types::port_t server_port); ++ UDPClient(boost::asio::io_context& io_service, sick::types::port_t server_port); + + /*! + * \brief Constructor of a UDPClient object +@@ -71,7 +73,7 @@ public: + * \param interface_ip The used host (client's) interface IP which is needed to join the + * multicast group. + */ +- UDPClient(boost::asio::io_service& io_service, ++ UDPClient(boost::asio::io_context& io_service, + sick::types::port_t server_port, + boost::asio::ip::address_v4 host_ip, + boost::asio::ip::address_v4 interface_ip); +@@ -139,12 +141,12 @@ public: + sick::datastructure::PacketBuffer receive(sick::types::time_duration_t timeout); + + private: +- boost::asio::io_service& m_io_service; ++ boost::asio::io_context& m_io_service; + boost::asio::ip::udp::endpoint m_remote_endpoint; + boost::asio::ip::udp::socket m_socket; + types::PacketHandler m_packet_handler; + datastructure::PacketBuffer::ArrayBuffer m_recv_buffer; +- boost::asio::deadline_timer m_deadline; ++ boost::asio::basic_deadline_timer m_deadline; + + /*! + * \brief A function to check internal deadline constraints on connect, receive and send +diff --git a/include/sick_safetyscanners_base/datastructure/CommSettings.h b/include/sick_safetyscanners_base/datastructure/CommSettings.h +index bbbe83b..9dda5d7 100644 +--- a/include/sick_safetyscanners_base/datastructure/CommSettings.h ++++ b/include/sick_safetyscanners_base/datastructure/CommSettings.h +@@ -67,7 +67,7 @@ struct CommSettings + bool enabled{true}; + + sick::types::port_t host_udp_port{0}; +- sick::types::ip_address_t host_ip{boost::asio::ip::address_v4::from_string("192.168.1.100")}; ++ sick::types::ip_address_t host_ip{boost::asio::ip::make_address_v4("192.168.1.100")}; + }; + + std::ostream& operator<<(std::ostream& os, const CommSettings& settings); +diff --git a/src/SickSafetyscanners.cpp b/src/SickSafetyscanners.cpp +index 0d1f9c1..c4d75d6 100644 +--- a/src/SickSafetyscanners.cpp ++++ b/src/SickSafetyscanners.cpp +@@ -46,7 +46,7 @@ SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ + CommSettings comm_settings) + : m_sensor_ip(sensor_ip) + , m_comm_settings(comm_settings) +- , m_io_service_ptr(sick::make_unique()) ++ , m_io_service_ptr(sick::make_unique()) + , m_io_service(*m_io_service_ptr) + , m_udp_client(m_io_service, comm_settings.host_udp_port) + , m_session(sick::make_unique(m_sensor_ip, sensor_tcp_port)) +@@ -61,7 +61,7 @@ SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ + boost::asio::ip::address_v4 interface_ip) + : m_sensor_ip(sensor_ip) + , m_comm_settings(comm_settings) +- , m_io_service_ptr(sick::make_unique()) ++ , m_io_service_ptr(sick::make_unique()) + , m_io_service(*m_io_service_ptr) + , m_udp_client(m_io_service, comm_settings.host_udp_port, comm_settings.host_ip, interface_ip) + , m_session(sick::make_unique(m_sensor_ip, sensor_tcp_port)) +@@ -73,7 +73,7 @@ SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ + SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ip, + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, +- boost::asio::io_service& io_service) ++ boost::asio::io_context& io_service) + : m_sensor_ip(sensor_ip) + , m_comm_settings(comm_settings) + , m_io_service_ptr(nullptr) +@@ -235,7 +235,7 @@ AsyncSickSafetyScanner::AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ + sick::types::ScanDataCb callback) + : SickSafetyscannersBase(sensor_ip, sensor_tcp_port, comm_settings) + , m_scan_data_cb(callback) +- , m_work(sick::make_unique(m_io_service)) ++ , m_work(sick::make_unique>(boost::asio::make_work_guard(m_io_service))) + { + m_service_thread = boost::thread([this] { + try +@@ -256,7 +256,7 @@ AsyncSickSafetyScanner::AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ + sick::types::ScanDataCb callback) + : SickSafetyscannersBase(sensor_ip, sensor_tcp_port, comm_settings, interface_ip) + , m_scan_data_cb(callback) +- , m_work(sick::make_unique(m_io_service)) ++ , m_work(sick::make_unique>(boost::asio::make_work_guard(m_io_service))) + { + m_service_thread = boost::thread([this] { + try +@@ -274,7 +274,7 @@ AsyncSickSafetyScanner::AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, + sick::types::ScanDataCb callback, +- boost::asio::io_service& io_service) ++ boost::asio::io_context& io_service) + : SickSafetyscannersBase(sensor_ip, sensor_tcp_port, comm_settings, io_service) + , m_scan_data_cb(callback) + , m_work() +diff --git a/src/cola2/ChangeCommSettingsCommand.cpp b/src/cola2/ChangeCommSettingsCommand.cpp +index 117b1e0..6d5a4d5 100644 +--- a/src/cola2/ChangeCommSettingsCommand.cpp ++++ b/src/cola2/ChangeCommSettingsCommand.cpp +@@ -105,7 +105,7 @@ void ChangeCommSettingsCommand::writeEInterfaceTypeToDataPtr( + void ChangeCommSettingsCommand::writeIPAddresstoDataPtr( + std::vector::iterator data_ptr) const + { +- read_write_helper::writeUint32LittleEndian(data_ptr + 8, m_settings.host_ip.to_ulong()); ++ read_write_helper::writeUint32LittleEndian(data_ptr + 8, m_settings.host_ip.to_uint()); + } + + void ChangeCommSettingsCommand::writePortToDataPtr(std::vector::iterator data_ptr) const +diff --git a/src/communication/TCPClient.cpp b/src/communication/TCPClient.cpp +index 272b6e8..5ef1725 100644 +--- a/src/communication/TCPClient.cpp ++++ b/src/communication/TCPClient.cpp +@@ -46,7 +46,7 @@ + namespace sick { + namespace communication { + +-using boost::asio::deadline_timer; ++using deadline_timer = boost::asio::basic_deadline_timer; + using boost::asio::ip::tcp; + using boost::lambda::_1; + using boost::lambda::_2; +diff --git a/src/communication/UDPClient.cpp b/src/communication/UDPClient.cpp +index b2037e1..b2008dd 100644 +--- a/src/communication/UDPClient.cpp ++++ b/src/communication/UDPClient.cpp +@@ -53,14 +53,14 @@ + namespace sick { + namespace communication { + +-using boost::asio::deadline_timer; ++using deadline_timer = boost::asio::basic_deadline_timer; + using boost::asio::ip::tcp; + using boost::lambda::_1; + using boost::lambda::_2; + using boost::lambda::bind; + using boost::lambda::var; + +-UDPClient::UDPClient(boost::asio::io_service& io_service, sick::types::port_t server_port) ++UDPClient::UDPClient(boost::asio::io_context& io_service, sick::types::port_t server_port) + : m_io_service(io_service) + , m_socket(io_service, boost::asio::ip::udp::endpoint{boost::asio::ip::udp::v4(), server_port}) + , m_packet_handler() +@@ -71,7 +71,7 @@ UDPClient::UDPClient(boost::asio::io_service& io_service, sick::types::port_t se + checkDeadline(); + } + +-UDPClient::UDPClient(boost::asio::io_service& io_service, ++UDPClient::UDPClient(boost::asio::io_context& io_service, + sick::types::port_t server_port, + boost::asio::ip::address_v4 host_ip, + boost::asio::ip::address_v4 interface_ip) +diff --git a/src/datastructure/ConfigData.cpp b/src/datastructure/ConfigData.cpp +index 0f42f5b..bd96ba4 100644 +--- a/src/datastructure/ConfigData.cpp ++++ b/src/datastructure/ConfigData.cpp +@@ -91,7 +91,7 @@ void ConfigData::setHostIp(const boost::asio::ip::address_v4& host_ip) + + void ConfigData::setHostIp(const std::string& host_ip) + { +- m_host_ip = boost::asio::ip::address_v4::from_string(host_ip); ++ m_host_ip = boost::asio::ip::make_address_v4(host_ip); + } + + uint16_t ConfigData::getHostUdpPort() const +diff --git a/package.xml b/package.xml +index 0000000..0000000 100644 +--- a/package.xml ++++ b/package.xml +@@ -13,7 +13,6 @@ + cmake + + libboost-chrono-dev +- libboost-system-dev + libboost-thread-dev + + +diff --git a/sick_safetyscanners_baseConfig.cmake b/sick_safetyscanners_baseConfig.cmake +index 0000000..0000000 100644 +--- a/sick_safetyscanners_baseConfig.cmake ++++ b/sick_safetyscanners_baseConfig.cmake +@@ -1,6 +1,6 @@ + include(CMakeFindDependencyMacro) + #find_dependency(Threads) + # Note that find_dependency does not support COMPONENTS or MODULE until 3.8.0 +-find_package(Boost COMPONENTS chrono system thread REQUIRED) ++find_package(Boost COMPONENTS chrono thread REQUIRED) + include("${CMAKE_CURRENT_LIST_DIR}/sick_safetyscanners_baseTargets.cmake") + diff --git a/patch/ros-rolling-sick-safetyscanners2-interfaces.patch b/patch/ros-rolling-sick-safetyscanners2-interfaces.patch new file mode 100644 index 000000000..18f1c5549 --- /dev/null +++ b/patch/ros-rolling-sick-safetyscanners2-interfaces.patch @@ -0,0 +1,42 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0000000..0000000 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -37,6 +37,7 @@ + "msg/RawMicroScanData.msg" + "msg/ScanPoint.msg" + "srv/FieldData.srv" ++ "srv/StatusOverview.srv" + DEPENDENCIES sensor_msgs + ) + +diff --git a/srv/StatusOverview.srv b/srv/StatusOverview.srv +new file mode 100644 +index 0000000..0000000 +--- /dev/null ++++ b/srv/StatusOverview.srv +@@ -0,0 +1,23 @@ ++--- ++ ++string version_c_version ++uint8 version_major_version_number ++uint8 version_minor_version_number ++uint8 version_release_number ++ ++uint8 device_state ++uint8 config_state ++uint8 application_state ++uint32 current_time_power_on_count ++ ++string current_time ++# for devices without real time clock, also provide the raw time information ++uint32 current_time_time ++uint16 current_time_date ++ ++uint32 error_info_code ++ ++string error_info_time ++# for devices without real time clock, also provide the raw time information ++uint32 error_info_time_time ++uint16 error_info_time_date +\ No newline at end of file diff --git a/patch/ros-rolling-sick-safetyscanners2.patch b/patch/ros-rolling-sick-safetyscanners2.patch new file mode 100644 index 000000000..6d32910e4 --- /dev/null +++ b/patch/ros-rolling-sick-safetyscanners2.patch @@ -0,0 +1,78 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0000000..0000000 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -36,6 +36,14 @@ + sick_safetyscanners2_interfaces + ) + ++# ament_target_dependencies() was removed from ament_cmake_target_dependencies; ++# link against each dependency's exported _TARGETS instead. ++macro(link_ament_dependencies target) ++ foreach(_ament_dep ${ARGN}) ++ target_link_libraries(${target} ${${_ament_dep}_TARGETS}) ++ endforeach() ++endmacro() ++ + add_executable(sick_safetyscanners2_node + src/sick_safetyscanners2_node.cpp + src/SickSafetyscanners.cpp +@@ -46,7 +54,7 @@ + sick_safetyscanners_base::sick_safetyscanners_base + ${Boost_LIBRARIES}) + +-ament_target_dependencies(sick_safetyscanners2_node ${dependencies}) ++link_ament_dependencies(sick_safetyscanners2_node ${dependencies}) + + target_include_directories(sick_safetyscanners2_node PUBLIC + $ +@@ -62,7 +70,7 @@ + sick_safetyscanners_base::sick_safetyscanners_base + ${Boost_LIBRARIES}) + +-ament_target_dependencies(sick_safetyscanners2_lifecycle_node ${dependencies}) ++link_ament_dependencies(sick_safetyscanners2_lifecycle_node ${dependencies}) + + target_include_directories(sick_safetyscanners2_lifecycle_node PUBLIC + $ +diff --git a/include/sick_safetyscanners2/SickSafetyscanners.hpp b/include/sick_safetyscanners2/SickSafetyscanners.hpp +index 0000000..0000000 100644 +--- a/include/sick_safetyscanners2/SickSafetyscanners.hpp ++++ b/include/sick_safetyscanners2/SickSafetyscanners.hpp +@@ -148,20 +148,20 @@ + std::string sensor_ip; + node.template get_parameter("sensor_ip", sensor_ip); + RCLCPP_INFO(getLogger(), "sensor_ip: %s", sensor_ip.c_str()); +- m_config.m_sensor_ip = boost::asio::ip::address_v4::from_string(sensor_ip); ++ m_config.m_sensor_ip = boost::asio::ip::make_address_v4(sensor_ip); + + std::string interface_ip; + node.template get_parameter("interface_ip", interface_ip); + RCLCPP_INFO(getLogger(), "interface_ip: %s", interface_ip.c_str()); + m_config.m_interface_ip = +- boost::asio::ip::address_v4::from_string(interface_ip); ++ boost::asio::ip::make_address_v4(interface_ip); + + std::string host_ip; + node.template get_parameter("host_ip", host_ip); + RCLCPP_INFO(getLogger(), "host_ip: %s", host_ip.c_str()); + // TODO check if valid IP? + m_config.m_communications_settings.host_ip = +- boost::asio::ip::address_v4::from_string(host_ip); ++ boost::asio::ip::make_address_v4(host_ip); + + int host_udp_port; + node.template get_parameter("host_udp_port", host_udp_port); +diff --git a/src/SickSafetyscanners.cpp b/src/SickSafetyscanners.cpp +index 0000000..0000000 100644 +--- a/src/SickSafetyscanners.cpp ++++ b/src/SickSafetyscanners.cpp +@@ -54,7 +54,7 @@ + m_config.m_frame_id = param.value_to_string(); + } else if (param.get_name() == "host_ip") { + m_config.m_communications_settings.host_ip = +- boost::asio::ip::address_v4::from_string(param.value_to_string()); ++ boost::asio::ip::make_address_v4(param.value_to_string()); + update_sensor_config = true; + } else if (param.get_name() == "host_udp_port") { + m_config.m_communications_settings.host_udp_port = param.as_int(); diff --git a/patch/ros-rolling-stereo-image-proc.patch b/patch/ros-rolling-stereo-image-proc.patch new file mode 100644 index 000000000..68201ce5c --- /dev/null +++ b/patch/ros-rolling-stereo-image-proc.patch @@ -0,0 +1,13 @@ +diff --git a/src/stereo_image_proc/disparity_node.cpp b/src/stereo_image_proc/disparity_node.cpp +index 958f43a..d82a240 100644 +--- a/src/stereo_image_proc/disparity_node.cpp ++++ b/src/stereo_image_proc/disparity_node.cpp +@@ -53,7 +53,7 @@ + #include + #include + +-#include ++#include + + namespace stereo_image_proc + { diff --git a/patch/ros-rolling-system-modes.patch b/patch/ros-rolling-system-modes.patch new file mode 100644 index 000000000..64d0a80dd --- /dev/null +++ b/patch/ros-rolling-system-modes.patch @@ -0,0 +1,25 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0000000..0000000 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -34,13 +34,13 @@ + target_include_directories(mode PUBLIC + $ + $) +-ament_target_dependencies(mode +- "rclcpp" +- "rcl_lifecycle" +- "rclcpp_lifecycle" +- "rosidl_typesupport_cpp" +- "lifecycle_msgs" +- "system_modes_msgs" ++target_link_libraries(mode ++ ${rclcpp_TARGETS} ++ ${rcl_lifecycle_TARGETS} ++ ${rclcpp_lifecycle_TARGETS} ++ ${rosidl_typesupport_cpp_TARGETS} ++ ${lifecycle_msgs_TARGETS} ++ ${system_modes_msgs_TARGETS} + ) + + # Causes the visibility macros to use dllexport rather than dllimport, diff --git a/patch/ros-rolling-theora-image-transport.patch b/patch/ros-rolling-theora-image-transport.patch new file mode 100644 index 000000000..d76fda704 --- /dev/null +++ b/patch/ros-rolling-theora-image-transport.patch @@ -0,0 +1,12 @@ +diff -ruN a/src/theora_subscriber.cpp b/src/theora_subscriber.cpp +--- a/src/theora_subscriber.cpp ++++ b/src/theora_subscriber.cpp +@@ -294,7 +294,7 @@ + + // Convert to BGR color + cv::Mat bgr, bgr_padded; +- cv::cvtColor(ycrcb, bgr_padded, CV_YCrCb2BGR); ++ cv::cvtColor(ycrcb, bgr_padded, cv::COLOR_YCrCb2BGR); + // Pull out original (non-padded) image region + bgr = bgr_padded(cv::Rect(header_info_.pic_x, header_info_.pic_y, + header_info_.pic_width, header_info_.pic_height)); diff --git a/patch/ros-rolling-turtle-tf2-cpp.patch b/patch/ros-rolling-turtle-tf2-cpp.patch new file mode 100644 index 000000000..d4795453e --- /dev/null +++ b/patch/ros-rolling-turtle-tf2-cpp.patch @@ -0,0 +1,63 @@ +diff --git a/src/dynamic_frame_tf2_broadcaster.cpp b/src/dynamic_frame_tf2_broadcaster.cpp +index de08ba7..7e5a7b7 100644 +--- a/src/dynamic_frame_tf2_broadcaster.cpp ++++ b/src/dynamic_frame_tf2_broadcaster.cpp +@@ -30,7 +30,7 @@ public: + DynamicFrameBroadcaster() + : Node("dynamic_frame_tf2_broadcaster") + { +- tf_broadcaster_ = std::make_shared(this); ++ tf_broadcaster_ = std::make_shared(*this); + timer_ = this->create_wall_timer( + 100ms, std::bind(&DynamicFrameBroadcaster::broadcast_timer_callback, this)); + } +diff --git a/src/fixed_frame_tf2_broadcaster.cpp b/src/fixed_frame_tf2_broadcaster.cpp +index 057134f..47347e8 100644 +--- a/src/fixed_frame_tf2_broadcaster.cpp ++++ b/src/fixed_frame_tf2_broadcaster.cpp +@@ -28,7 +28,7 @@ public: + FixedFrameBroadcaster() + : Node("fixed_frame_tf2_broadcaster") + { +- tf_broadcaster_ = std::make_shared(this); ++ tf_broadcaster_ = std::make_shared(*this); + timer_ = this->create_wall_timer( + 100ms, std::bind(&FixedFrameBroadcaster::broadcast_timer_callback, this)); + } +diff --git a/src/static_turtle_tf2_broadcaster.cpp b/src/static_turtle_tf2_broadcaster.cpp +index ddd3218..8f25849 100644 +--- a/src/static_turtle_tf2_broadcaster.cpp ++++ b/src/static_turtle_tf2_broadcaster.cpp +@@ -25,7 +25,7 @@ public: + explicit StaticFramePublisher(char * transformation[]) + : Node("static_turtle_tf2_broadcaster") + { +- tf_static_broadcaster_ = std::make_shared(this); ++ tf_static_broadcaster_ = std::make_shared(*this); + + // Publish static transforms once at startup + this->make_transforms(transformation); +diff --git a/src/turtle_tf2_message_filter.cpp b/src/turtle_tf2_message_filter.cpp +index c2d7085..f57ff6f 100644 +--- a/src/turtle_tf2_message_filter.cpp ++++ b/src/turtle_tf2_message_filter.cpp +@@ -45,17 +45,14 @@ public: + tf2_buffer_ = std::make_shared(this->get_clock()); + // Create the timer interface before call to waitForTransform, + // to avoid a tf2_ros::CreateTimerInterfaceException exception +- auto timer_interface = std::make_shared( +- this->get_node_base_interface(), +- this->get_node_timers_interface()); ++ auto timer_interface = std::make_shared(*this); + tf2_buffer_->setCreateTimerInterface(timer_interface); + tf2_listener_ = + std::make_shared(*tf2_buffer_); + + point_sub_.subscribe(this, "/turtle3/turtle_point_stamped", rclcpp::QoS(10)); + tf2_filter_ = std::make_shared>( +- point_sub_, *tf2_buffer_, target_frame_, 100, this->get_node_logging_interface(), +- this->get_node_clock_interface(), buffer_timeout); ++ point_sub_, *tf2_buffer_, target_frame_, 100, *this, buffer_timeout); + // Register a callback with tf2_ros::MessageFilter to be called when transforms are available + tf2_filter_->registerCallback(&PoseDrawer::msgCallback, this); + } diff --git a/patch/ros-rolling-ublox-dgnss-node.patch b/patch/ros-rolling-ublox-dgnss-node.patch new file mode 100644 index 000000000..c2fa33bfd --- /dev/null +++ b/patch/ros-rolling-ublox-dgnss-node.patch @@ -0,0 +1,64 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index da65c8f..380b187 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -53,9 +53,11 @@ target_compile_definitions(ublox_dgnss_components + PRIVATE "UBLOX_DGNSS_NODE_BUILDING_DLL" + ) + ++if(NOT APPLE) + target_link_options(ublox_dgnss_components PRIVATE + "LINKER:--allow-multiple-definition" + ) ++endif() + + target_link_libraries(ublox_dgnss_components PUBLIC + ${rtcm_msgs_TARGETS} +diff --git a/include/ublox_dgnss_node/ubx/ubx.hpp b/include/ublox_dgnss_node/ubx/ubx.hpp +index 6d9834e..a32b4bb 100644 +--- a/include/ublox_dgnss_node/ubx/ubx.hpp ++++ b/include/ublox_dgnss_node/ubx/ubx.hpp +@@ -112,7 +112,7 @@ using FramePoll = Frame; + using FramePolled = Frame; + using FrameValSet = Frame; + +-std::shared_ptr get_polled_frame( ++inline std::shared_ptr get_polled_frame( + std::shared_ptr usbc, + std::shared_ptr poll_frame) + { +diff --git a/include/ublox_dgnss_node/ubx/ubx_cfg_item.hpp b/include/ublox_dgnss_node/ubx/ubx_cfg_item.hpp +index 8983dbb..c5d3796 100644 +--- a/include/ublox_dgnss_node/ubx/ubx_cfg_item.hpp ++++ b/include/ublox_dgnss_node/ubx/ubx_cfg_item.hpp +@@ -24,7 +24,7 @@ + + namespace ubx::cfg + { +-size_t storage_size_bytes(u8_t storage_size_id) ++inline size_t storage_size_bytes(u8_t storage_size_id) + { + size_t size = 0; + switch (storage_size_id) { +diff --git a/include/ublox_dgnss_node/ubx/ubx_cfg_item_map.hpp b/include/ublox_dgnss_node/ubx/ubx_cfg_item_map.hpp +index 4340333..410a952 100644 +--- a/include/ublox_dgnss_node/ubx/ubx_cfg_item_map.hpp ++++ b/include/ublox_dgnss_node/ubx/ubx_cfg_item_map.hpp +@@ -446,7 +446,7 @@ enum CFG_ITFM_ANTSETTING_ENUM + }; + + +-ubx_cfg_item_map_t ubxKeyCfgItemMap = { ++inline ubx_cfg_item_map_t ubxKeyCfgItemMap = { + {CFG_INFMSG_UBX_USB.ubx_key_id, CFG_INFMSG_UBX_USB}, + {CFG_INFMSG_NMEA_USB.ubx_key_id, CFG_INFMSG_NMEA_USB}, + {CFG_UART1INPROT_UBX.ubx_key_id, CFG_UART1INPROT_UBX}, +@@ -632,7 +632,7 @@ ubx_cfg_item_map_t ubxKeyCfgItemMap = { + // {CFG_ITFM_ENABLE_AUX.ubx_key_id, CFG_ITFM_ENABLE_AUX}, + }; + +-bool operator<(const ubx_key_id_t & fk1, const ubx_key_id_t & fk2) ++inline bool operator<(const ubx_key_id_t & fk1, const ubx_key_id_t & fk2) + { + return fk1.all < fk2.all; + } diff --git a/patch/ros-rolling-udp-driver.patch b/patch/ros-rolling-udp-driver.patch new file mode 100644 index 000000000..b767e03cc --- /dev/null +++ b/patch/ros-rolling-udp-driver.patch @@ -0,0 +1,56 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b9ca55c..c88adac 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -37,13 +37,15 @@ ament_auto_add_library(${PROJECT_NAME} SHARED + src/udp_socket.cpp + src/udp_driver.cpp + ) +-ament_target_dependencies(${PROJECT_NAME} "ASIO") ++target_include_directories(${PROJECT_NAME} PUBLIC ${ASIO_INCLUDE_DIRS}) ++target_compile_definitions(${PROJECT_NAME} PUBLIC ${ASIO_DEFINITIONS}) + + ament_auto_add_library(${PROJECT_NAME}_nodes SHARED + src/udp_receiver_node.cpp + src/udp_sender_node.cpp + ) +-ament_target_dependencies(${PROJECT_NAME}_nodes "ASIO") ++target_include_directories(${PROJECT_NAME}_nodes PUBLIC ${ASIO_INCLUDE_DIRS}) ++target_compile_definitions(${PROJECT_NAME}_nodes PUBLIC ${ASIO_DEFINITIONS}) + target_link_libraries(${PROJECT_NAME}_nodes ${PROJECT_NAME}) + + rclcpp_components_register_node(${PROJECT_NAME}_nodes +@@ -61,7 +63,8 @@ ament_auto_add_executable(udp_bridge_node_exe + ) + + target_link_libraries(udp_bridge_node_exe ${PROJECT_NAME} ${PROJECT_NAME}_nodes) +-ament_target_dependencies(udp_bridge_node_exe ASIO) ++target_include_directories(udp_bridge_node_exe PUBLIC ${ASIO_INCLUDE_DIRS}) ++target_compile_definitions(udp_bridge_node_exe PUBLIC ${ASIO_DEFINITIONS}) + + if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) +diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp +index 619c7be..1b12400 100644 +--- a/src/udp_socket.cpp ++++ b/src/udp_socket.cpp +@@ -38,15 +38,15 @@ UdpSocket::UdpSocket( + const uint16_t host_port) + : m_ctx(ctx), + m_udp_socket(ctx.ios()), +- m_remote_endpoint(address::from_string(remote_ip), remote_port), +- m_host_endpoint(address::from_string(host_ip), host_port) ++ m_remote_endpoint(asio::ip::make_address(remote_ip), remote_port), ++ m_host_endpoint(asio::ip::make_address(host_ip), host_port) + { + m_remote_endpoint = remote_ip.empty() ? + udp::endpoint{udp::v4(), remote_port} : +- udp::endpoint{address::from_string(remote_ip), remote_port}; ++ udp::endpoint{asio::ip::make_address(remote_ip), remote_port}; + m_host_endpoint = host_ip.empty() ? + udp::endpoint{udp::v4(), host_port} : +- udp::endpoint{address::from_string(host_ip), host_port}; ++ udp::endpoint{asio::ip::make_address(host_ip), host_port}; + m_recv_buffer.resize(m_recv_buffer_size); + } + diff --git a/patch/ros-rolling-urg-c.patch b/patch/ros-rolling-urg-c.patch new file mode 100644 index 000000000..a032f0c7d --- /dev/null +++ b/patch/ros-rolling-urg-c.patch @@ -0,0 +1,3910 @@ +diff --git a/current/dox/connect_and_get.c b/current/dox/connect_and_get.c +index f11a6b3..934daed 100644 +--- a/current/dox/connect_and_get.c ++++ b/current/dox/connect_and_get.c +@@ -1,4 +1,4 @@ +-// VAڑł̃ZTƂ̐ڑƋf[^̎擾 ++// シリアル接続でのセンサとの接続と距離データの取得 + + #include "urg_sensor.h" + #include "urg_utils.h" +@@ -12,26 +12,26 @@ int main(void) + long *length_data; + int length_data_size; + +- // "COM1" ́AZTFĂfoCXɂKv ++ // "COM1" は、センサが認識されているデバイス名にする必要がある + const char connect_device[] = "COM1"; + const long connect_baudrate = 115200; + +- // ZTɑ΂ĐڑsB ++ // センサに対して接続を行う。 + ret = urg_open(&urg, URG_SERIAL, connect_device, connect_baudrate); +- // \todo check error code ++ // ¥todo check error code + +- // f[^M̂߂̗̈mۂ ++ // データ受信のための領域を確保する + length_data = (long *)malloc(sizeof(long) * urg_max_data_size(&urg)); +- // \todo check length_data is not NULL ++ // ¥todo check length_data is not NULL + +- // ZT狗f[^擾B ++ // センサから距離データを取得する。 + ret = urg_start_measurement(&urg, URG_DISTANCE, 1, 0); +- // \todo check error code ++ // ¥todo check error code + + length_data_size = urg_get_distance(&urg, length_data, NULL); +- // \todo process length_data array ++ // ¥todo process length_data array + +- // ZTƂ̐ڑ‚B ++ // センサとの接続を閉じる。 + urg_close(&urg); + + return 0; +diff --git a/current/dox/connect_ethernet.c b/current/dox/connect_ethernet.c +index 706fdc6..64c3910 100644 +--- a/current/dox/connect_ethernet.c ++++ b/current/dox/connect_ethernet.c +@@ -5,13 +5,13 @@ int main(void) + { + urg_t urg; + int ret; +-// C[T[lbgڑł̃ZTƂ̐ڑƋf[^̎擾 ++// イーサーネット接続でのセンサとの接続と距離データの取得 + + const char connect_address[] = "192.168.0.10"; + const long connect_port = 10940; + +-// ZTɑ΂ĐڑsB ++// センサに対して接続を行う。 + ret = urg_open(&urg, URG_ETHERNET, connect_address, connect_port); +-// \todo check error code ++// ¥todo check error code + return 0; + } +diff --git a/current/dox/convert_xy.c b/current/dox/convert_xy.c +index 7fc90da..4a8252c 100644 +--- a/current/dox/convert_xy.c ++++ b/current/dox/convert_xy.c +@@ -9,11 +9,11 @@ urg_t urg; + long *length_data = NULL; + int length_data_size; + int i; +-// f[^ X-Y Wnɕϊĕ\ ++// 距離データを X-Y 座標系に変換して表示する + + length_data_size = urg_get_distance(&urg, length_data, NULL); + for (i = 0; i < length_data_size; ++i) { +- // ̋f[^̃WApx߁AX, Y ̍WlvZ ++ // その距離データのラジアン角度を求め、X, Y の座標値を計算する + double radian; + long length; + long x; +@@ -21,12 +21,12 @@ for (i = 0; i < length_data_size; ++i) { + + radian = urg_index2rad(&urg, i); + length = length_data[i]; +- // \todo check length is valid ++ // ¥todo check length is valid + + x = (long)(length * cos(radian)); + y = (long)(length * sin(radian)); + printf("(%ld, %ld), ", x, y); + } +-printf("\n"); ++printf("¥n"); + return 0; + } +diff --git a/current/dox/get_scans.c b/current/dox/get_scans.c +index 4ce7c71..bed6a54 100644 +--- a/current/dox/get_scans.c ++++ b/current/dox/get_scans.c +@@ -6,22 +6,22 @@ int main(void) + urg_t urg; + int ret; + long *length_data = NULL; +-// scan_times ̃XLf[^擾 ++// scan_times 回のスキャンデータを取得 + +-// urg_start_measurement() ֐ŃXL񐔂w肵 +-// urg_get_distance() ֐Ŏw肵񐔂f[^MB ++// urg_start_measurement() 関数でスキャン回数を指定し ++// urg_get_distance() 関数で指定した回数だけデータを受信する。 + + const int scan_times = 123; + int length_data_size; + int i; + +-// ZT狗f[^擾B ++// センサから距離データを取得する。 + ret = urg_start_measurement(&urg, URG_DISTANCE, scan_times, 0); +-// \todo check error code ++// ¥todo check error code + + for (i = 0; i < scan_times; ++i) { + length_data_size = urg_get_distance(&urg, length_data, NULL); +- // \todo process length_data array ++ // ¥todo process length_data array + } + return 0; + } +diff --git a/current/dox/get_timestamp.c b/current/dox/get_timestamp.c +index 17039b5..5c6ff92 100644 +--- a/current/dox/get_timestamp.c ++++ b/current/dox/get_timestamp.c +@@ -6,25 +6,25 @@ int main(void) + urg_t urg; + long *length_data = NULL; + int ret; +-// ^CX^v̎擾 ++// タイムスタンプの取得 + +-// urg_get_distance() ֐ɕϐ^A^CX^v擾B ++// urg_get_distance() 関数に変数を与え、タイムスタンプを取得する。 + + const int scan_times = 123; + int length_data_size; + long timestamp; + int i; + +-// ZT狗f[^擾B ++// センサから距離データを取得する。 + ret = urg_start_measurement(&urg, URG_DISTANCE, scan_times, 0); +-// \todo check error code ++// ¥todo check error code + + for (i = 0; i < scan_times; ++i) { + length_data_size = urg_get_distance(&urg, length_data, ×tamp); +- // \todo process length_data array ++ // ¥todo process length_data array + +- // 擾^CX^vo͂ +- printf("%ld\n", timestamp); ++ // 取得したタイムスタンプを出力する ++ printf("%ld¥n", timestamp); + } + return 0; + } +diff --git a/current/dox/set_parameter.c b/current/dox/set_parameter.c +index 88e43cb..f3c9671 100644 +--- a/current/dox/set_parameter.c ++++ b/current/dox/set_parameter.c +@@ -12,26 +12,26 @@ int skip_step; + int scan_times; + int skip_scan; + int ret; +-// vp[^̐ݒ ++// 計測パラメータの設定 + +-// ZTɑ΂ĐڑsB +-// ڑsƁAvp[^̐ݒ͏ ++// センサに対して接続を行う。 ++// 接続を行うと、計測パラメータの設定は初期化される + ret = urg_open(&urg, URG_SERIAL, connect_device, connect_baudrate); +-// \todo check error code ++// ¥todo check error code + +-// v͈͂w肷 +-// ZTʕ 90 [deg] ͈͂̃f[^擾sAXebvԈsȂ ++// 計測範囲を指定する ++// センサ正面方向の 90 [deg] 範囲のデータ取得を行い、ステップ間引きを行わない例 + first_step = urg_rad2step(&urg, -45); + last_step = urg_rad2step(&urg, +45); + skip_step = 0; + ret = urg_set_scanning_parameter(&urg, first_step, last_step, skip_step); +-// \todo check error code ++// ¥todo check error code + +-// v񐔂ƌv̊Ԉw肵āAvJn +-// 123 ̌vwAXL̊ԈsȂ ++// 計測回数と計測の間引きを指定して、計測を開始する ++// 123 回の計測を指示し、スキャンの間引きを行わない例 + scan_times = 123; + skip_scan = 0; + ret = urg_start_measurement(&urg, URG_DISTANCE, scan_times, skip_scan); +-// \todo check error code ++// ¥todo check error code + return 0; + } +diff --git a/current/include/urg_c/urg_connection.h b/current/include/urg_c/urg_connection.h +index 865c6e9..59661f6 100644 +--- a/current/include/urg_c/urg_connection.h ++++ b/current/include/urg_c/urg_connection.h +@@ -2,10 +2,10 @@ + #define URG_CONNECTION_H + + /*! +- \file +- \brief ʐM̏ ++ ¥file ++ ¥brief 通信の処理 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_connection.h,v 1d233c7a2240 2011/02/19 03:08:45 Satofumi $ + */ +@@ -19,73 +19,73 @@ extern "C" { + + + /*! +- \brief 萔` ++ ¥brief 定数定義 + */ + enum { +- URG_CONNECTION_TIMEOUT = -1, //!< ^CAEgƂ̖߂l ++ URG_CONNECTION_TIMEOUT = -1, //!< タイムアウトが発生したときの戻り値 + }; + + + /*! +- \brief ʐM^Cv ++ ¥brief 通信タイプ + */ + typedef enum { +- URG_SERIAL, //!< VA, USB ڑ +- URG_ETHERNET, //!< C[T[lbgڑ ++ URG_SERIAL, //!< シリアル, USB 接続 ++ URG_ETHERNET, //!< イーサーネット接続 + } urg_connection_type_t; + + + /*! +- \brief ʐM\[X ++ ¥brief 通信リソース + */ + typedef struct + { +- urg_connection_type_t type; //!< ڑ^Cv +- urg_serial_t serial; //!< VAڑ +- urg_tcpclient_t tcpclient; //!< C[T[lbgڑ ++ urg_connection_type_t type; //!< 接続タイプ ++ urg_serial_t serial; //!< シリアル接続 ++ urg_tcpclient_t tcpclient; //!< イーサーネット接続 + } urg_connection_t; + + + /*! +- \brief ڑ ++ ¥brief 接続 + +- w肳ꂽfoCXɐڑB ++ 指定されたデバイスに接続する。 + +- \param[in,out] connection ʐM\[X +- \param[in] connection_type ڑ^Cv +- \param[in] device ڑ +- \param[in] baudrate_or_port {[[g / |[gԍ ++ ¥param[in,out] connection 通信リソース ++ ¥param[in] connection_type 接続タイプ ++ ¥param[in] device 接続名 ++ ¥param[in] baudrate_or_port ボーレート / ポート番号 + +- \retval 0 +- \retval <0 G[ ++ ¥retval 0 正常 ++ ¥retval <0 エラー + +- connection_type ɂ ++ connection_type には + +- - URG_SERIAL ... VAʐM +- - URG_ETHERNET .. C[T[lbgʐM ++ - URG_SERIAL ... シリアル通信 ++ - URG_ETHERNET .. イーサーネット通信 + +- w肷B ++ を指定する。 + +- device, baudrate_or_port ̎w connection_type ɂwłlقȂB +- Ⴆ΁AVAʐM̏ꍇ͈ȉ̂悤ɂȂB ++ device, baudrate_or_port の指定は connection_type により指定できる値が異なる。 ++ 例えば、シリアル通信の場合は以下のようになる。 + + Example +- \code ++ ¥code + connection_t connection; + if (! connection_open(&connection, URG_SERIAL, "COM1", 115200)) { + return 1; +- } \endcode ++ } ¥endcode + +- ܂AC[T[lbgʐM̏ꍇ͈ȉ̂悤ɂȂB ++ また、イーサーネット通信の場合は以下のようになる。 + + Example +- \code ++ ¥code + connection_t connection; + if (! connection_open(&connection, URG_ETHERNET, "192.168.0.10", 10940)) { + return 1; +- } \endcode ++ } ¥endcode + +- \see connection_close() ++ ¥see connection_close() + */ + extern int connection_open(urg_connection_t *connection, + urg_connection_type_t connection_type, +@@ -93,98 +93,98 @@ extern int connection_open(urg_connection_t *connection, + + + /*! +- \brief ؒf ++ ¥brief 切断 + +- foCXƂ̐ڑؒfB ++ デバイスとの接続を切断する。 + +- \param[in,out] connection ʐM\[X ++ ¥param[in,out] connection 通信リソース + +- \code +- connection_close(&connection); \endcode ++ ¥code ++ connection_close(&connection); ¥endcode + +- \see connection_open() ++ ¥see connection_open() + */ + extern void connection_close(urg_connection_t *connection); + + +-/*! {[[gݒ肷 */ ++/*! ボーレートを設定する */ + extern int connection_set_baudrate(urg_connection_t *connection, long baudrate); + + + /*! +- \brief M ++ ¥brief 送信 + +- f[^𑗐MB ++ データを送信する。 + +- \param[in,out] connection ʐM\[X +- \param[in] data Mf[^ +- \param[in] size MoCg ++ ¥param[in,out] connection 通信リソース ++ ¥param[in] data 送信データ ++ ¥param[in] size 送信バイト数 + +- \retval >=0 Mf[^ +- \retval <0 G[ ++ ¥retval >=0 送信データ数 ++ ¥retval <0 エラー + + Example +- \code +- n = connection_write(&connection, "QT\n", 3); \endcode ++ ¥code ++ n = connection_write(&connection, "QT¥n", 3); ¥endcode + +- \see connection_read(), connection_readline() ++ ¥see connection_read(), connection_readline() + */ + extern int connection_write(urg_connection_t *connection, + const char *data, int size); + + + /*! +- \brief M ++ ¥brief 受信 + +- f[^MB ++ データを受信する。 + +- \param[in,out] connection ʐM\[X +- \param[in] data Mf[^i[obt@ +- \param[in] max_size Mf[^i[łoCg +- \param[in] timeout ^CAEg [msec] ++ ¥param[in,out] connection 通信リソース ++ ¥param[in] data 受信データを格納するバッファ ++ ¥param[in] max_size 受信データを格納できるバイト数 ++ ¥param[in] timeout タイムアウト時間 [msec] + +- \retval >=0 Mf[^ +- \retval <0 G[ ++ ¥retval >=0 受信データ数 ++ ¥retval <0 エラー + +- timeout ɕ̒lw肵ꍇA^CAEg͔ȂB ++ timeout に負の値を指定した場合、タイムアウトは発生しない。 + +- 1 MȂƂ #URG_CONNECTION_TIMEOUT ԂB ++ 1 文字も受信しなかったときは #URG_CONNECTION_TIMEOUT を返す。 + + Example +- \code ++ ¥code + enum { + BUFFER_SIZE = 256, + TIMEOUT_MSEC = 1000, + }; + char buffer[BUFFER_SIZE]; +-n = connection_read(&connection, buffer, BUFFER_SIZE, TIMEOUT_MSEC); \endcode ++n = connection_read(&connection, buffer, BUFFER_SIZE, TIMEOUT_MSEC); ¥endcode + +- \see connection_write(), connection_readline() ++ ¥see connection_write(), connection_readline() + */ + extern int connection_read(urg_connection_t *connection, + char *data, int max_size, int timeout); + + + /*! +- \brief s܂ł̎M ++ ¥brief 改行文字までの受信 + +- s܂ł̃f[^MB ++ 改行文字までのデータを受信する。 + +- \param[in,out] connection ʐM\[X +- \param[in] data Mf[^i[obt@ +- \param[in] max_size Mf[^i[łoCg +- \param[in] timeout ^CAEg [msec] ++ ¥param[in,out] connection 通信リソース ++ ¥param[in] data 受信データを格納するバッファ ++ ¥param[in] max_size 受信データを格納できるバイト数 ++ ¥param[in] timeout タイムアウト時間 [msec] + +- \retval >=0 Mf[^ +- \retval <0 G[ ++ ¥retval >=0 受信データ数 ++ ¥retval <0 エラー + +- data ɂ́A'\\0' I[ꂽ max_size zȂoCgi[B ‚܂AMł镶̃oCǵAő max_size - 1 ƂȂB ++ data には、'¥¥0' 終端された文字列が max_size を越えないバイト数だけ格納される。 つまり、受信できる文字のバイト数は、最大で max_size - 1 となる。 + +- s '\\r' ܂ '\\n' ƂB ++ 改行文字は '¥¥r' または '¥¥n' とする。 + +- Mŏ̕s̏ꍇ́A0 ԂA1 MȂƂ #URG_CONNECTION_TIMEOUT ԂB ++ 受信した最初の文字が改行の場合は、0 を返し、1 文字も受信しなかったときは #URG_CONNECTION_TIMEOUT を返す。 + +- \see connection_write(), connection_read() ++ ¥see connection_write(), connection_read() + */ + extern int connection_readline(urg_connection_t *connection, + char *data, int max_size, int timeout); +diff --git a/current/include/urg_c/urg_debug.h b/current/include/urg_c/urg_debug.h +index 0b79b8e..984dc1d 100644 +--- a/current/include/urg_c/urg_debug.h ++++ b/current/include/urg_c/urg_debug.h +@@ -2,16 +2,16 @@ + #define URG_DEBUG_H + + /*! +- \file +- \brief URG debugging functions ++ ¥file ++ ¥brief URG debugging functions + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + +- \~japanese +- \attention gKv͂܂B ++ ¥‾japanese ++ ¥attention 使う必要はありません。 + +- \~english +- \attention Don't need to use these functions. ++ ¥‾english ++ ¥attention Don't need to use these functions. + + $Id$ + */ +@@ -23,15 +23,15 @@ extern "C" { + #include "urg_c/urg_sensor.h" + + +- /*! \~japanese ZTɃf[^𒼐ڑM */ ++ /*! ¥‾japanese センサにデータを直接送信する */ + extern int urg_raw_write(urg_t *urg, const char *data, int data_size); + + +- /*! \~japanese ZTf[^𒼐ڎM */ ++ /*! ¥‾japanese センサからデータを直接受信する */ + extern int urg_raw_read(urg_t *urg, char *data, int max_data_size, + int timeout); + +- /*! \~japanese ZTs܂ł̃f[^𒼐ڎM */ ++ /*! ¥‾japanese センサから改行までのデータを直接受信する */ + extern int urg_raw_readline(urg_t *urg,char *data, int max_data_size, + int timeout); + +diff --git a/current/include/urg_c/urg_detect_os.h b/current/include/urg_c/urg_detect_os.h +index ab5b6fb..a873788 100644 +--- a/current/include/urg_c/urg_detect_os.h ++++ b/current/include/urg_c/urg_detect_os.h +@@ -2,10 +2,10 @@ + #define URG_DETECT_OS_H + + /*! +- \file +- \brief OS ̌o ++ ¥file ++ ¥brief OS の検出 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_detect_os.h,v 0caa22c18f6b 2010/12/30 03:36:32 Satofumi $ + */ +@@ -21,7 +21,7 @@ + #define URG_LINUX_OS + + #else +-// ołȂƂAMac ɂĂ܂ ++// 検出できないときを、Mac 扱いにしてしまう + #define URG_MAC_OS + #endif + +diff --git a/current/include/urg_c/urg_errno.h b/current/include/urg_c/urg_errno.h +index 08cac7d..0c13eaa 100644 +--- a/current/include/urg_c/urg_errno.h ++++ b/current/include/urg_c/urg_errno.h +@@ -2,10 +2,10 @@ + #define URG_ERRNO_H + + /*! +- \file +- \brief URG CũG[` ++ ¥file ++ ¥brief URG ライブラリのエラー定義 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +diff --git a/current/include/urg_c/urg_ring_buffer.h b/current/include/urg_c/urg_ring_buffer.h +index dfe8d77..ee4d319 100644 +--- a/current/include/urg_c/urg_ring_buffer.h ++++ b/current/include/urg_c/urg_ring_buffer.h +@@ -2,80 +2,80 @@ + #define URG_RING_BUFFER_H + + /*! +- \file +- \brief Oobt@ ++ ¥file ++ ¥brief リングバッファ + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ + + +-//! Oobt@̊Ǘ ++//! リングバッファの管理情報 + typedef struct + { +- char *buffer; //!< obt@ւ̃|C^ +- int buffer_size; //!< obt@TCY +- int first; //!< obt@̐擪ʒu +- int last; //!< obt@̍ŏIʒu ++ char *buffer; //!< バッファへのポインタ ++ int buffer_size; //!< バッファサイズ ++ int first; //!< バッファの先頭位置 ++ int last; //!< バッファの最終位置 + } ring_buffer_t; + + + /*! +- \brief ++ ¥brief 初期化 + +- \param[in] ring Oobt@̍\ +- \param[in] buffer 蓖Ăobt@ +- \param[in] shift_length obt@TCY 2 ̏搔 ++ ¥param[in] ring リングバッファの構造体 ++ ¥param[in] buffer 割り当てるバッファ ++ ¥param[in] shift_length バッファサイズの 2 の乗数 + */ + extern void ring_initialize(ring_buffer_t *ring, + char *buffer, const int shift_length); + + + /*! +- \brief Oobt@̃NA ++ ¥brief リングバッファのクリア + +- \param[in] ring Oobt@̍\ ++ ¥param[in] ring リングバッファの構造体 + */ + extern void ring_clear(ring_buffer_t *ring); + + + /*! +- \brief i[f[^Ԃ ++ ¥brief 格納データ数を返す + +- \param[in] ring Oobt@̍\ ++ ¥param[in] ring リングバッファの構造体 + */ + extern int ring_size(const ring_buffer_t *ring); + + + /*! +- \brief ő̊i[f[^Ԃ ++ ¥brief 最大の格納データ数を返す + +- \param[in] ring Oobt@̍\ ++ ¥param[in] ring リングバッファの構造体 + */ + extern int ring_capacity(const ring_buffer_t *ring); + + + /*! +- \brief f[^̊i[ ++ ¥brief データの格納 + +- \param[in] ring Oobt@̍\ +- \param[in] data f[^ +- \param[in] size f[^TCY ++ ¥param[in] ring リングバッファの構造体 ++ ¥param[in] data データ ++ ¥param[in] size データサイズ + +- \return i[f[^ ++ ¥return 格納したデータ数 + */ + extern int ring_write(ring_buffer_t *ring, const char *data, int size); + + + /*! +- \brief f[^̎o ++ ¥brief データの取り出し + +- \param[in] ring Oobt@̍\ +- \param[out] buffer f[^ +- \param[in] size ő̃f[^TCY ++ ¥param[in] ring リングバッファの構造体 ++ ¥param[out] buffer データ ++ ¥param[in] size 最大のデータサイズ + +- \return of[^ ++ ¥return 取り出したデータ数 + */ + extern int ring_read(ring_buffer_t *ring, char *buffer, int size); + +diff --git a/current/include/urg_c/urg_sensor.h b/current/include/urg_c/urg_sensor.h +index 018d932..4c7d3e0 100644 +--- a/current/include/urg_c/urg_sensor.h ++++ b/current/include/urg_c/urg_sensor.h +@@ -2,20 +2,20 @@ + #define URG_SENSOR_H + + /*! +- \file +- \~japanese +- \brief URG ZT ++ ¥file ++ ¥‾japanese ++ ¥brief URG センサ制御 + +- URG p̊{IȊ֐񋟂܂B ++ URG 用の基本的な関数を提供します。 + + +- \~english +- \brief URG sensor ++ ¥‾english ++ ¥brief URG sensor + +- URG p̊{IȊ֐񋟂܂B ++ URG 用の基本的な関数を提供します。 + +- \~ +- \author Satofumi KAMIMURA ++ ¥‾ ++ ¥author Satofumi KAMIMURA + + $Id: urg_sensor.h,v 540bc11f70c8 2011/05/08 23:04:49 satofumi $ + */ +@@ -29,45 +29,45 @@ extern "C" { + + + /*! +- \~japanese +- \brief v^Cv ++ ¥‾japanese ++ ¥brief 計測タイプ + */ + typedef enum { +- URG_DISTANCE, /*!< \~japanese */ +- URG_DISTANCE_INTENSITY, /*!< \~japanese + x */ +- URG_MULTIECHO, /*!< \~japanese }`GR[̋ */ +- URG_MULTIECHO_INTENSITY, /*!< \~japanese }`GR[( + x) */ +- URG_STOP, /*!< \~japanese v̒~ */ +- URG_UNKNOWN, /*!< \~japanese s */ ++ URG_DISTANCE, /*!< ¥‾japanese 距離 */ ++ URG_DISTANCE_INTENSITY, /*!< ¥‾japanese 距離 + 強度 */ ++ URG_MULTIECHO, /*!< ¥‾japanese マルチエコーの距離 */ ++ URG_MULTIECHO_INTENSITY, /*!< ¥‾japanese マルチエコーの(距離 + 強度) */ ++ URG_STOP, /*!< ¥‾japanese 計測の停止 */ ++ URG_UNKNOWN, /*!< ¥‾japanese 不明 */ + } urg_measurement_type_t; + + /*! +- \~japanese +- \brief byte ŕ\邩̎w ++ ¥‾japanese ++ ¥brief 距離を何 byte で表現するかの指定 + */ + typedef enum { +- URG_COMMUNICATION_3_BYTE, /*!< \~japanese 3 byte ŕ\ */ +- URG_COMMUNICATION_2_BYTE, /*!< \~japanese 2 byte ŕ\ */ ++ URG_COMMUNICATION_3_BYTE, /*!< ¥‾japanese 距離を 3 byte で表現する */ ++ URG_COMMUNICATION_2_BYTE, /*!< ¥‾japanese 距離を 2 byte で表現する */ + } urg_range_data_byte_t; + + + enum { +- URG_SCAN_INFINITY = 0, /*!< \~japanese ̃f[^擾 */ +- URG_MAX_ECHO = 3, /*!< \~japanese }`GR[̍őGR[ */ ++ URG_SCAN_INFINITY = 0, /*!< ¥‾japanese 無限回のデータ取得 */ ++ URG_MAX_ECHO = 3, /*!< ¥‾japanese マルチエコーの最大エコー数 */ + }; + + +- /*! \~japanese G[nh \~english error handler */ ++ /*! ¥‾japanese エラーハンドラ ¥‾english error handler */ + typedef urg_measurement_type_t + (*urg_error_handler)(const char *status, void *urg); + + + /*! +- \~japanese +- \brief URG ZTǗ ++ ¥‾japanese ++ ¥brief URG センサ管理 + +- \~english +- \brief URG sensor ++ ¥‾english ++ ¥brief URG sensor + */ + typedef struct + { +@@ -106,29 +106,29 @@ extern "C" { + + + /*! +- \~japanese +- \brief ڑ ++ ¥‾japanese ++ ¥brief 接続 + +- w肵foCXɐڑAvł悤ɂB ++ 指定したデバイスに接続し、距離を計測できるようにする。 + +- \param[in,out] urg URG ZTǗ +- \param[in] connection_type ʐM^Cv +- \param[in] device_or_address ڑfoCX +- \param[in] baudrate_or_port ڑ{[[g [bps] / TCP/IP |[g ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[in] connection_type 通信タイプ ++ ¥param[in] device_or_address 接続デバイス名 ++ ¥param[in] baudrate_or_port 接続ボーレート [bps] / TCP/IP ポート + +- \retval 0 +- \retval <0 G[ ++ ¥retval 0 正常 ++ ¥retval <0 エラー + +- connection_type ɂ́Aȉ̍ڂwł܂B ++ connection_type には、以下の項目が指定できます。 + + - #URG_SERIAL +- - VAAUSB ڑ ++ - シリアル、USB 接続 + + - #URG_ETHERNET +- - C[T[lbgڑ ++ - イーサーネット接続 + + Example +- \code ++ ¥code + urg_t urg; + + if (urg_open(&urg, URG_SERIAL, "/dev/ttyACM0", 115200) < 0) { +@@ -137,12 +137,12 @@ extern "C" { + + ... + +- urg_close(&urg); \endcode ++ urg_close(&urg); ¥endcode + +- \attention URG C Cȗ̊֐ĂяoOɁÅ֐ĂяoKv܂B ++ ¥attention URG C ライブラリの他の関数を呼び出す前に、この関数を呼び出す必要があります。 + +- \~ +- \see urg_close() ++ ¥‾ ++ ¥see urg_close() + */ + extern int urg_open(urg_t *urg, urg_connection_type_t connection_type, + const char *device_or_address, +@@ -150,177 +150,177 @@ extern "C" { + + + /*! +- \~japanese +- \brief ؒf ++ ¥‾japanese ++ ¥brief 切断 + +- [UAURG Ƃ̐ڑؒf܂B ++ レーザを消灯し、URG との接続を切断します。 + +- \param[in,out] urg URG ZTǗ ++ ¥param[in,out] urg URG センサ管理 + +- \~ +- \see urg_open() ++ ¥‾ ++ ¥see urg_open() + */ + extern void urg_close(urg_t *urg); + + + /*! +- \brief ^CAEgԂ̐ݒ ++ ¥brief タイムアウト時間の設定 + +- \param[in,out] urg URG ZTǗ +- \param[in] msec ^CAEg鎞 [msec] ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[in] msec タイムアウトする時間 [msec] + +- \attention urg_open() Ăяo timeout ̐ݒl̓ftHglɏ邽߁Å֐ urg_open() ɌĂяoƁB ++ ¥attention urg_open() を呼び出すと timeout の設定値はデフォルト値に初期化されるため、この関数は urg_open() 後に呼び出すこと。 + */ + extern void urg_set_timeout_msec(urg_t *urg, int msec); + + +- /*! \~japanese ^CX^v[h̊Jn */ ++ /*! ¥‾japanese タイムスタンプモードの開始 */ + extern int urg_start_time_stamp_mode(urg_t *urg); + + + /*! +- \~japanese +- \brief ^CX^v̎擾 ++ ¥‾japanese ++ ¥brief タイムスタンプの取得 + +- \param[in,out] urg URG ZTǗ ++ ¥param[in,out] urg URG センサ管理 + +- \retval >=0 ^CX^v [msec] +- \retval <0 G[ ++ ¥retval >=0 タイムスタンプ [msec] ++ ¥retval <0 エラー + + Example +- \code ++ ¥code + urg_start_time_stamp_mode(&urg); + + before_ticks = get_pc_msec_function(); + time_stamp = urg_time_stamp(&urg); + after_ticks = get_pc_msec_function(); + +- // ^CX^vɂ‚Ă̌vZ ++ // タイムスタンプについての計算 + ... + +- urg_stop_time_stamp_mode(&urg); \endcode ++ urg_stop_time_stamp_mode(&urg); ¥endcode + +- ڂ \ref sync_time_stamp.c QƂĉB ++ 詳しくは ¥ref sync_time_stamp.c を参照して下さい。 + */ + extern long urg_time_stamp(urg_t *urg); + + +- /*! \~japanese ^CX^v[h̏I */ ++ /*! ¥‾japanese タイムスタンプモードの終了 */ + extern int urg_stop_time_stamp_mode(urg_t *urg); + + + /*! +- \~japanese +- \brief f[^̎擾Jn ++ ¥‾japanese ++ ¥brief 距離データの取得を開始 + +- f[^̎擾Jn܂Bۂ̃f[^ urg_get_distance(), urg_get_distance_intensity(), urg_get_multiecho(), urg_get_multiecho_intensity() Ŏ擾ł܂B ++ 距離データの取得を開始します。実際のデータは urg_get_distance(), urg_get_distance_intensity(), urg_get_multiecho(), urg_get_multiecho_intensity() で取得できます。 + +- \param[in,out] urg URG ZTǗ +- \param[in] type f[^E^Cv +- \param[in] scan_times f[^̎擾 +- \param[in] skip_scan f[^̎擾Ԋu ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[in] type データ・タイプ ++ ¥param[in] scan_times データの取得回数 ++ ¥param[in] skip_scan データの取得間隔 + +- \retval 0 +- \retval <0 G[ ++ ¥retval 0 正常 ++ ¥retval <0 エラー + +- type ɂ͎擾f[^̎ނw肵܂B ++ type には取得するデータの種類を指定します。 + +- - #URG_DISTANCE ... f[^ +- - #URG_DISTANCE_INTENSITY ... f[^Ƌxf[^ +- - #URG_MULTIECHO ... }`GR[ł̋f[^ +- - #URG_MULTIECHO_INTENSITY ... }`GR[ł(f[^Ƌxf[^) ++ - #URG_DISTANCE ... 距離データ ++ - #URG_DISTANCE_INTENSITY ... 距離データと強度データ ++ - #URG_MULTIECHO ... マルチエコー版の距離データ ++ - #URG_MULTIECHO_INTENSITY ... マルチエコー版の(距離データと強度データ) + +- scan_times ͉̃f[^擾邩 0 ȏ̐Ŏw肵܂BA0 ܂ #URG_SCAN_INFINITY w肵ꍇ́Ãf[^擾܂B\n +- Jnv𒆒fɂ urg_stop_measurement() g܂B ++ scan_times は何回のデータを取得するかを 0 以上の数で指定します。ただし、0 または #URG_SCAN_INFINITY を指定した場合は、無限回のデータを取得します。¥n ++ 開始した計測を中断するには urg_stop_measurement() を使います。 + +- skip_scan ̓~[̉]̂AP̃XLɉXLȂw肵܂Bskip_scan Ɏwł͈͂ [0, 9] łB ++ skip_scan はミラーの回転数のうち、1回のスキャン後に何回スキャンしないかを指定します。skip_scan に指定できる範囲は [0, 9] です。 + +- \image html skip_scan_image.png ɂP񂾂v邩 ++ ¥image html skip_scan_image.png 何回に1回だけ計測するか + +- Ƃ΁A~[̂P] 100 [msec] ̃ZT skip_scan 1 w肵ꍇAf[^̎擾Ԋu 200 [msec] ɂȂ܂B ++ たとえば、ミラーの1回転が 100 [msec] のセンサで skip_scan に 1 を指定した場合、データの取得間隔は 200 [msec] になります。 + + Example +- \code ++ ¥code + enum { CAPTURE_TIMES = 10 }; + urg_start_measurement(&urg, URG_DISTANCE, CAPTURE_TIMES, 0); + + for (i = 0; i < CAPTURE_TIMES; ++i) { + int n = urg_get_distance(&urg, data, &time_stamp); + +- // Mf[^̗p ++ // 受信したデータの利用 + ... +- } \endcode ++ } ¥endcode + +- \~ +- \see urg_get_distance(), urg_get_distance_intensity(), urg_get_multiecho(), urg_get_multiecho_intensity(), urg_stop_measurement() ++ ¥‾ ++ ¥see urg_get_distance(), urg_get_distance_intensity(), urg_get_multiecho(), urg_get_multiecho_intensity(), urg_stop_measurement() + */ + extern int urg_start_measurement(urg_t *urg, urg_measurement_type_t type, + int scan_times, int skip_scan); + + + /*! +- \~japanese +- \brief f[^̎擾 ++ ¥‾japanese ++ ¥brief 距離データの取得 + +- ZT狗f[^擾܂BO urg_start_measurement() #URG_DISTANCE wŌĂяoĂKv܂B ++ センサから距離データを取得します。事前に urg_start_measurement() を #URG_DISTANCE 指定で呼び出しておく必要があります。 + +- \param[in,out] urg URG ZTǗ +- \param[out] data f[^ [mm] +- \param[out] time_stamp ^CX^v [msec] ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[out] data 距離データ [mm] ++ ¥param[out] time_stamp タイムスタンプ [msec] + +- \retval >=0 Mf[^ +- \retval <0 G[ ++ ¥retval >=0 受信したデータ個数 ++ ¥retval <0 エラー + +- data ɂ́AZT擾f[^i[܂Bdata ̓f[^i[̃TCYmۂĂKv܂Bdata Ɋi[f[^ urg_max_data_size() Ŏ擾ł܂B ++ data には、センサから取得した距離データが格納されます。data はデータを格納するのサイズを確保しておく必要があります。data に格納されるデータ数は urg_max_data_size() で取得できます。 + +- time_stamp ɂ́AZT̃^CX^vi[܂Btime_stamp 擾Ȃꍇ NULL w肵ĉB ++ time_stamp には、センサ内部のタイムスタンプが格納されます。time_stamp を取得したくない場合 NULL を指定して下さい。 + + Example +- \code ++ ¥code + long *data = (long*)malloc(urg_max_data_size(&urg) * sizeof(data[0])); + + ... + +- // f[^̂ݎ擾 ++ // データのみ取得する + urg_start_measurement(&urg, URG_DISTANCE, 1, 0); + int n = urg_get_distance(&urg, data, NULL); + + ... + +- // f[^ƃ^CX^v擾 ++ // データとタイムスタンプを取得する + long time_stamp; + urg_start_measurement(&urg, URG_DISTANCE, 1, 0); +- n = urg_get_distance(&urg, data, &time_stamp); \endcode ++ n = urg_get_distance(&urg, data, &time_stamp); ¥endcode + +- \~ +- \see urg_start_measurement(), urg_max_data_size() ++ ¥‾ ++ ¥see urg_start_measurement(), urg_max_data_size() + */ + extern int urg_get_distance(urg_t *urg, long data[], long *time_stamp, unsigned long long *system_time_stamp); + + + /*! +- \~japanese +- \brief Ƌxf[^̎擾 ++ ¥‾japanese ++ ¥brief 距離と強度データの取得 + +- urg_get_distance() ɉAxf[^̎擾ł֐łBO urg_start_measurement() #URG_DISTANCE_INTENSITY wŌĂяoĂKv܂B ++ urg_get_distance() に加え、強度データの取得ができる関数です。事前に urg_start_measurement() を #URG_DISTANCE_INTENSITY 指定で呼び出しておく必要があります。 + +- \param[in,out] urg URG ZTǗ +- \param[out] data f[^ [mm] +- \param[out] intensity xf[^ +- \param[out] time_stamp ^CX^v [msec] ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[out] data 距離データ [mm] ++ ¥param[out] intensity 強度データ ++ ¥param[out] time_stamp タイムスタンプ [msec] + +- \retval >=0 Mf[^ +- \retval <0 G[ ++ ¥retval >=0 受信したデータ個数 ++ ¥retval <0 エラー + +- xf[^Ƃ́AvZɎgg`̔ˋxłAZT̃V[YɓقȂ܂B xf[^gƂŁÂ̔˗‹̑܂ȔZW𐄑ł܂B ++ 強度データとは、距離計算に使った波形の反射強度であり、センサのシリーズ毎に特性が異なります。 強度データを使うことで、物体の反射率や環境の大まかな濃淡を推測できます。 + +- data, time_stamp ɂ‚Ă urg_get_distance() ƓłB ++ data, time_stamp については urg_get_distance() と同じです。 + +- intensity ɂ́AZT擾xf[^i[܂Bintensity ̓f[^i[̃TCYmۂĂKv܂Bintensity Ɋi[f[^ urg_max_data_size() Ŏ擾ł܂B ++ intensity には、センサから取得した強度データが格納されます。intensity はデータを格納するのサイズを確保しておく必要があります。intensity に格納されるデータ数は urg_max_data_size() で取得できます。 + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + int data_size = urg_max_data_size(&urg); + long *data = malloc(data_size * sizeof(long)); + long *intensity = malloc(data_size * sizeof(unsigned short)); +@@ -328,10 +328,10 @@ extern "C" { + ... + + urg_start_measurement(&urg, URG_DISTANCE_INTENSITY, 1, 0); +- int n = urg_get_distance_intensity(&urg, data, intesnity, NULLL); \endcode ++ int n = urg_get_distance_intensity(&urg, data, intesnity, NULLL); ¥endcode + +- \~ +- \see urg_start_measurement(), urg_max_data_size() ++ ¥‾ ++ ¥see urg_start_measurement(), urg_max_data_size() + */ + extern int urg_get_distance_intensity(urg_t *urg, long data[], + unsigned short intensity[], +@@ -339,75 +339,75 @@ extern "C" { + + + /*! +- \~japanese +- \brief f[^̎擾 (}`GR[) ++ ¥‾japanese ++ ¥brief 距離データの取得 (マルチエコー版) + +- }`GR[ł̋f[^擾֐łBO urg_start_measurement() #URG_MULTIECHO wŌĂяoĂKv܂B ++ マルチエコー版の距離データ取得関数です。事前に urg_start_measurement() を #URG_MULTIECHO 指定で呼び出しておく必要があります。 + +- \param[in,out] urg URG ZTǗ +- \param[out] data_multi f[^ [mm] +- \param[out] time_stamp ^CX^v [msec] ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[out] data_multi 距離データ [mm] ++ ¥param[out] time_stamp タイムスタンプ [msec] + +- \retval >=0 Mf[^ +- \retval <0 G[ ++ ¥retval >=0 受信したデータ個数 ++ ¥retval <0 エラー + +- }`GR[Ƃ͕̋f[^łB }`GR[́AP‚̃[Uɂĕ̋f[^ꂽƂɓ܂B ++ マルチエコーとは複数の距離データです。 マルチエコーは、1つのレーザ発光において複数の距離データが得られたときに得られます。 + +- \image html multiecho_image.png }`GR[̃C[W} ++ ¥image html multiecho_image.png マルチエコーのイメージ図 + +- time_stamp ɂ‚Ă urg_get_distance() ƓłB ++ time_stamp については urg_get_distance() と同じです。 + +- data_multi ɂ́AZT擾f[^P‚ step ő #URG_MAX_ECHO (3 )i[܂B}`GR[݂Ȃڂ̃f[^l -1 i[Ă܂B ++ data_multi には、センサから取得した距離データが1つの step あたり最大で #URG_MAX_ECHO (3 つ)格納されます。マルチエコーが存在しない項目のデータ値は -1 が格納されています。 + +- \verbatim +- data_multi[0] ... step n ̋f[^ (1 ‚) +- data_multi[1] ... step n ̋f[^ (2 ‚) +- data_multi[2] ... step n ̋f[^ (3 ‚) +- data_multi[3] ... step (n + 1) f[^ (1 ‚) +- data_multi[4] ... step (n + 1) f[^ (2 ‚) +- data_multi[5] ... step (n + 1) f[^ (3 ‚) +- ... \endverbatim ++ ¥verbatim ++ data_multi[0] ... step n の距離データ (1 つめ) ++ data_multi[1] ... step n の距離データ (2 つめ) ++ data_multi[2] ... step n の距離データ (3 つめ) ++ data_multi[3] ... step (n + 1) の 距離データ (1 つめ) ++ data_multi[4] ... step (n + 1) の 距離データ (2 つめ) ++ data_multi[5] ... step (n + 1) の 距離データ (3 つめ) ++ ... ¥endverbatim + +- i[́Ae step ɂ urg_get_distance() ̂ƂƓ̃f[^ (3n + 0) ̈ʒuɊi[AȊÕf[^ (3n + 1), (3n + 2) ̈ʒuɍ~Ɋi[܂B\n +- ‚܂ data_multi[3n + 1] >= data_multi[3n + 2] ɂȂ邱Ƃ͕ۏ؂܂ data_multi[3n + 0] data_multi[3n + 1] ̊֌W͖`łB(data_multi[3n + 1] == data_multi[3n + 2] 藧‚̂̓f[^l -1 ̂ƂB) ++ 格納順は、各 step において urg_get_distance() のときと同じ距離のデータが (3n + 0) の位置に格納され、それ以外のデータが (3n + 1), (3n + 2) の位置に降順に格納されます。¥n ++ つまり data_multi[3n + 1] >= data_multi[3n + 2] になることは保証されますが data_multi[3n + 0] と data_multi[3n + 1] の関係は未定義です。(data_multi[3n + 1] == data_multi[3n + 2] が成り立つのはデータ値が -1 のとき。) + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + long *data_multi = malloc(3 * urg_max_data_size(&urg) * sizeof(long)); + + ... + + urg_start_measurement(&urg, URG_MULTIECHO, 1, 0); +- int n = urg_get_distance_intensity(&urg, data_multi, NULLL); \endcode ++ int n = urg_get_distance_intensity(&urg, data_multi, NULLL); ¥endcode + +- \~ +- \see urg_start_measurement(), urg_max_data_size() ++ ¥‾ ++ ¥see urg_start_measurement(), urg_max_data_size() + */ + extern int urg_get_multiecho(urg_t *urg, long data_multi[], long *time_stamp, unsigned long long *system_time_stamp); + + + /*! +- \~japanese +- \brief Ƌxf[^̎擾 (}`GR[) ++ ¥‾japanese ++ ¥brief 距離と強度データの取得 (マルチエコー版) + +- urg_get_multiecho() ɉAxf[^̎擾ł֐łBO urg_start_measurement() #URG_MULTIECHO_INTENSITY wŌĂяoĂKv܂B ++ urg_get_multiecho() に加え、強度データの取得できる関数です。事前に urg_start_measurement() を #URG_MULTIECHO_INTENSITY 指定で呼び出しておく必要があります。 + +- \param[in,out] urg URG ZTǗ +- \param[out] data_multi f[^ [mm] +- \param[out] intensity_multi xf[^ +- \param[out] time_stamp ^CX^v [msec] ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[out] data_multi 距離データ [mm] ++ ¥param[out] intensity_multi 強度データ ++ ¥param[out] time_stamp タイムスタンプ [msec] + +- \retval >=0 Mf[^ +- \retval <0 G[ ++ ¥retval >=0 受信したデータ個数 ++ ¥retval <0 エラー + +- data_multi, time_stamp ɂ‚Ă urg_get_multiecho() ƓłB ++ data_multi, time_stamp については urg_get_multiecho() と同じです。 + +- intensity_multi ̃f[^̕т data_multi ƑΉ̂ɂȂ܂Bintensity_multi Ɋi[f[^ urg_max_data_size() Ŏ擾ł܂B ++ intensity_multi のデータの並びは data_multi と対応したものになります。intensity_multi に格納されるデータ数は urg_max_data_size() で取得できます。 + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + int data_size = urg_max_data_size(&urg); + long *data_multi = malloc(3 * data_size * sizeof(long)); + long *intensity_multi = malloc(3 * data_size * sizeof(unsigned short)); +@@ -416,10 +416,10 @@ extern "C" { + + urg_start_measurement(&urg, URG_DISTANCE_INTENSITY, 1, 0); + int n = urg_get_multiecho_intensity(&urg, data_multi, +- intesnity_multi, NULLL); \endcode ++ intesnity_multi, NULLL); ¥endcode + +- \~ +- \see urg_start_measurement(), urg_max_data_size() ++ ¥‾ ++ ¥see urg_start_measurement(), urg_max_data_size() + */ + extern int urg_get_multiecho_intensity(urg_t *urg, long data_multi[], + unsigned short intensity_multi[], +@@ -427,259 +427,259 @@ extern "C" { + + + /*! +- \~japanese +- \brief v𒆒fA[U܂ ++ ¥‾japanese ++ ¥brief 計測を中断し、レーザを消灯させます + +- \ref urg_start_measurement() ̌v𒆒f܂B ++ ¥ref urg_start_measurement() の計測を中断します。 + +- \param[in,out] urg URG ZTǗ ++ ¥param[in,out] urg URG センサ管理 + +- \retval 0 +- \retval <0 G[ ++ ¥retval 0 正常 ++ ¥retval <0 エラー + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + urg_start_measurement(&urg, URG_DISTANCE, URG_SCAN_INFINITY, 0); + for (int i = 0; i < 10; ++i) { + urg_get_distance(&urg, data, NULL); + } +- urg_stop_measurement(&urg); \endcode ++ urg_stop_measurement(&urg); ¥endcode + +- \~ +- \see urg_start_measurement() ++ ¥‾ ++ ¥see urg_start_measurement() + */ + extern int urg_stop_measurement(urg_t *urg); + + + /*! +- \~japanese +- \brief v͈͂ݒ肵܂ ++ ¥‾japanese ++ ¥brief 計測範囲を設定します + +- ZTv͈͂ step lŎw肵܂Burg_get_distance() Ȃǂ̋f[^擾̊֐ŕԂf[^́AŎw肵͈͂Ő܂B ++ センサが計測する範囲を step 値で指定します。urg_get_distance() などの距離データ取得の関数で返されるデータ数は、ここで指定した範囲で制限されます。 + +- \param[in,out] urg URG ZTǗ +- \param[in] first_step v̊Jn step +- \param[in] last_step v̏I step +- \param[in] skip_step vf[^O[sO ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[in] first_step 計測の開始 step ++ ¥param[in] last_step 計測の終了 step ++ ¥param[in] skip_step 計測データをグルーピングする個数 + +- \retval 0 +- \retval <0 G[ ++ ¥retval 0 正常 ++ ¥retval <0 エラー + +- ZT step ́AZTʂ 0 ƂAZT㕔猩Ĕv܂̌̒lƂȂ鏇ɊU܂B ++ センサの step は、センサ正面を 0 とし、センサ上部から見て反時計まわりの向きが正の値となる順に割り振られます。 + +- \image html sensor_angle_image.png ZT step ̊֌W ++ ¥image html sensor_angle_image.png センサと step の関係 + +- step ̊ԊuƁAőlAŏl̓ZTˑłBstep l̍őlAŏl urg_step_min_max() Ŏ擾ł܂B\n ++ step の間隔と、最大値、最小値はセンサ依存です。step 値の最大値、最小値は urg_step_min_max() で取得できます。¥n + +- first_step, last_step Ńf[^̌v͈͂w肵܂Bv͈͂ [first_step, last_step] ƂȂ܂B ++ first_step, last_step でデータの計測範囲を指定します。計測範囲は [first_step, last_step] となります。 + +- skip_step ́Avf[^O[sOw肵܂Bwłl [0, 99] łB\n +- skip_step ́Aw肳ꂽ̃f[^ 1 ‚ɂ܂Ƃ߂邱ƂŁAZTMf[^ʂ炵A擾s֐̉߂ƂɎg܂BAf[^܂Ƃ߂邽߁Af[^̕\͌܂B ++ skip_step は、計測データをグルーピングする個数を指定します。指定できる値は [0, 99] です。¥n ++ skip_step は、指定された数のデータを 1 つにまとめることで、センサから受信するデータ量を減らし、距離取得を行う関数の応答性を高めるときに使います。ただし、データをまとめるため、得られるデータの分解能は減ります。 + +- ႦΈȉ̂悤ȋf[^ꍇ +- \verbatim ++ 例えば以下のような距離データが得られる場合に ++ ¥verbatim + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109 +- \endverbatim ++ ¥endverbatim + +- skip_step 2 w肷ƁAf[^ +- \verbatim +- \endverbatim ++ skip_step に 2 を指定すると、得られるデータは ++ ¥verbatim ++ ¥endverbatim + +- f[^́A܂Ƃ߂f[^̂AԏȒl̃f[^p܂B ++ データは、まとめるデータのうち、一番小さな値のデータが用いられます。 + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + urg_set_scanning_parameter(&urg, urg_deg2step(&urg, -45), + urg_deg2step(&urg, +45), 1); + urg_start_measurement(&urg, URG_DISTANCE, 0); + int n = urg_get_distance(&urg, data, NULL); + for (int i = 0; i < n; ++i) { +- printf("%d [mm], %d [deg]\n", data[i], urg_index2deg(&urg, i)); +- } \endcode ++ printf("%d [mm], %d [deg]¥n", data[i], urg_index2deg(&urg, i)); ++ } ¥endcode + +- \~ +- \see urg_step_min_max(), urg_rad2step(), urg_deg2step() ++ ¥‾ ++ ¥see urg_step_min_max(), urg_rad2step(), urg_deg2step() + */ + extern int urg_set_scanning_parameter(urg_t *urg, int first_step, + int last_step, int skip_step); + + + /*! +- \~japanese +- \brief ʐMf[^̃TCYύX ++ ¥‾japanese ++ ¥brief 通信データのサイズ変更 + +- f[^ZTM̍ۂ̃f[^TCYύX܂B ++ 距離データをセンサから受信の際のデータサイズを変更します。 + +- \param[in,out] urg URG ZTǗ +- \param[in] data_byte l\f[^̃oCg ++ ¥param[in,out] urg URG センサ管理 ++ ¥param[in] data_byte 距離値を表現するデータのバイト数 + +- \retval 0 +- \retval <0 G[ ++ ¥retval 0 成功 ++ ¥retval <0 エラー + +- data_byte ɂ ++ data_byte には + +- - URG_COMMUNICATION_3_BYTE ... 3 byte ŕ\ +- - URG_COMMUNICATION_2_BYTE ... 2 byte ŕ\ ++ - URG_COMMUNICATION_3_BYTE ... 距離を 3 byte で表現する ++ - URG_COMMUNICATION_2_BYTE ... 距離を 2 byte で表現する + +- wł܂B\n +- Ԃł͋ 3 byte ŕ\悤ɂȂĂ܂B̐ݒ 2 byte ɐݒ肷邱ƂŁAZTMf[^ 2/3 ɂȂ܂BA擾ł鋗̍ől 4095 ɂȂ邽߁AϑΏۂ 4 [m] ȓ͈̔͂ɑ݂ꍇ̂ݗpĉB ++ を指定できます。¥n ++ 初期状態では距離を 3 byte で表現するようになっています。この設定を 2 byte に設定することで、センサから受信するデータ数は 2/3 になります。ただし、取得できる距離の最大値が 4095 になるため、観測したい対象が 4 [m] 以内の範囲に存在する場合のみ利用して下さい。 + */ + extern int urg_set_communication_data_size(urg_t *urg, + urg_range_data_byte_t data_byte); + + +- /*! \~japanese [U𔭌 */ ++ /*! ¥‾japanese レーザを発光させる */ + extern int urg_laser_on(urg_t *urg); + + +- /*! \~japanese [U */ ++ /*! ¥‾japanese レーザを消灯する */ + extern int urg_laser_off(urg_t *urg); + + +- /*! \~japanese ZTċN */ ++ /*! ¥‾japanese センサを再起動する */ + extern int urg_reboot(urg_t *urg); + + + /*! +- \~japanese +- \brief ZTd͂̏ԂɑJڂ ++ ¥‾japanese ++ ¥brief センサを低消費電力の状態に遷移させる + +- d͂̃[hł́AXLỉ]~vf܂B ++ 低消費電力のモードでは、スキャナの回転が停止し計測も中断されます。 + +- - d͂̃[h +- - [UČvfB +- - XLỉ]~B ++ - 低消費電力のモード ++ - レーザが消灯して計測が中断される。 ++ - スキャナの回転が停止する。 + +- d͂̃[h甲邽߂ɂ \ref urg_wakeup() ֐ĂяoĉB ++ 低消費電力のモードから抜けるためには ¥ref urg_wakeup() 関数を呼び出して下さい。 + +- \see urg_wakeup() ++ ¥see urg_wakeup() + */ + extern void urg_sleep(urg_t *urg); + + + /*! +- \~japanese +- \brief ZTd͂̃[hʏ̏ԂɑJڂ ++ ¥‾japanese ++ ¥brief センサを低消費電力のモードから通常の状態に遷移させる + +- \see urg_sleep() ++ ¥see urg_sleep() + */ + extern void urg_wakeup(urg_t *urg); + + /*! +- \~japanese +- \brief ZTvłԂԂ ++ ¥‾japanese ++ ¥brief センサが計測できる状態かを返す + +- \retval 1 ZTvłԂɂ +- \retval 0 ZTvłԂɂȂ ++ ¥retval 1 センサが計測できる状態にある ++ ¥retval 0 センサが計測できる状態にない + +- NŃXLỉ]肵ĂȂꍇA炩̃G[ŌvłȂꍇÅ֐ 0 Ԃ܂B ++ 起動直後でスキャナの回転が安定していない場合や、何らかのエラーで計測できない場合、この関数は 0 を返します。 + */ + extern int urg_is_stable(urg_t *urg); + + + /*! +- \~japanese +- \brief ZT^𕶎ŕԂ ++ ¥‾japanese ++ ¥brief センサ型式を文字列で返す + +- ZŤ^𕶎ŕԂBԂ镶̓ZTˑƂȂB ++ センサの型式を文字列で返す。返される文字列はセンサ依存となる。 + +- \param[in] urg URG ZTǗ ++ ¥param[in] urg URG センサ管理 + +- \return ZT^̕ ++ ¥return センサ型式の文字列 + */ + extern const char *urg_sensor_product_type(urg_t *urg); + + + /*! +- \~japanese +- \brief ZT̃VA ID Ԃ ++ ¥‾japanese ++ ¥brief センサのシリアル ID 文字列を返す + +- ZT̃VA ID ԂBԂ镶̓ZTˑƂȂB ++ センサのシリアル ID 文字列を返す。返される文字列はセンサ依存となる。 + +- \param[in] urg URG ZTǗ ++ ¥param[in] urg URG センサ管理 + +- \return VA ID ++ ¥return シリアル ID 文字列 + */ + extern const char *urg_sensor_serial_id(urg_t *urg); + + /*! +- \brief returns the vendor name ++ ¥brief returns the vendor name + +- \param[in] URG ++ ¥param[in] URG + +- \return The vendor name ++ ¥return The vendor name + */ + extern const char *urg_sensor_vendor(urg_t *urg); + + + /*! +- \~japanese +- \brief ZT̃o[WԂ ++ ¥‾japanese ++ ¥brief センサのバージョン文字列を返す + +- ZT̃\tgEFAEo[WԂBԂ镶̓ZTˑƂȂB ++ センサのソフトウェア・バージョン文字列を返す。返される文字列はセンサ依存となる。 + +- \param[in] urg URG ZTǗ ++ ¥param[in] urg URG センサ管理 + +- \return o[W ++ ¥return バージョン文字列 + */ + extern const char *urg_sensor_firmware_version(urg_t *urg); + + extern const char *urg_sensor_firmware_date(urg_t *urg); + + /*! +- \brief returns the protocol version ++ ¥brief returns the protocol version + +- \param[in] URG ++ ¥param[in] URG + +- \return The current protocol version ++ ¥return The current protocol version + */ + extern const char *urg_sensor_protocol_version(urg_t *urg); + + /*! +- \~japanese +- \brief ZT̃Xe[^XԂ ++ ¥‾japanese ++ ¥brief センサのステータス文字列を返す + +- ZT̃Xe[^XԂBԂ镶̓ZTˑƂȂB ++ センサのステータス文字列を返す。返される文字列はセンサ依存となる。 + +- \param[in] urg URG ZTǗ +- \return Xe[^X ++ ¥param[in] urg URG センサ管理 ++ ¥return ステータス文字列 + */ + extern const char *urg_sensor_status(urg_t *urg); + + + /*! +- \~japanese +- \brief ZT̏ԂԂ ++ ¥‾japanese ++ ¥brief センサの状態を返す + +- ZT̃Xe[^XԂBԂ镶̓ZTˑƂȂB ++ センサのステータス文字列を返す。返される文字列はセンサ依存となる。 + +- \param[in] urg URG ZTǗ +- \return Ԃ ++ ¥param[in] urg URG センサ管理 ++ ¥return 状態を示す文字列 + +- \attention Ԃɂ‚Ă SCIP ̒ʐMdlQƂ̂ƁB ++ ¥attention 状態については SCIP の通信仕様書を参照のこと。 + */ + extern const char *urg_sensor_state(urg_t *urg); + + + /*! +- \~japanese +- \brief vp̃G[nho^ ++ ¥‾japanese ++ ¥brief 計測用のエラーハンドラを登録する + +- G[nh Gx, Mx ñR}h̉ "00" "99" ȊÔƂɌĂяoB ++ エラーハンドラは Gx, Mx 系のコマンドの応答が "00" か "99" 以外のときに呼び出される。 + */ + extern void urg_set_error_handler(urg_t *urg, urg_error_handler handler); + + + /*! +- \~japanese +- \brief SCIP ̃fR[hs ++ ¥‾japanese ++ ¥brief SCIP 文字列のデコードを行う + +- \param[in] data SCIP +- \param[in] data byte TCY ++ ¥param[in] data SCIP 文字列 ++ ¥param[in] data の byte サイズ + +- \retval fR[h̐l ++ ¥retval デコード後の数値 + */ + extern long urg_scip_decode(const char data[], int size); + +diff --git a/current/include/urg_c/urg_serial.h b/current/include/urg_c/urg_serial.h +index 3ac5ec7..417df86 100644 +--- a/current/include/urg_c/urg_serial.h ++++ b/current/include/urg_c/urg_serial.h +@@ -2,10 +2,10 @@ + #define URG_SERIAL_H + + /*! +- \file +- \brief VAʐM ++ ¥file ++ ¥brief シリアル通信 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_serial.h,v 1d233c7a2240 2011/02/19 03:08:45 Satofumi $ + */ +@@ -36,51 +36,51 @@ enum { + }; + + +-//! VAʐMp ++//! シリアル通信用 + typedef struct + { + #if defined(URG_WINDOWS_OS) +- HANDLE hCom; /*!< ڑ\[X */ +- int current_timeout; /*!< ^CAEg̐ݒ莞 [msec] */ ++ HANDLE hCom; /*!< 接続リソース */ ++ int current_timeout; /*!< タイムアウトの設定時間 [msec] */ + #else +- int fd; /*!< t@CfBXNv^*/ +- struct termios sio; /*!< ʐMݒ */ ++ int fd; /*!< ファイルディスクリプタ*/ ++ struct termios sio; /*!< 通信設定 */ + #endif + +- ring_buffer_t ring; /*!< Oobt@ */ +- char buffer[RING_BUFFER_SIZE]; /*!< obt@̈ */ +- char has_last_ch; /*!< ߂邩̃tO */ +- char last_ch; /*!< ߂P */ ++ ring_buffer_t ring; /*!< リングバッファ */ ++ char buffer[RING_BUFFER_SIZE]; /*!< バッファ領域 */ ++ char has_last_ch; /*!< 書き戻した文字があるかのフラグ */ ++ char last_ch; /*!< 書き戻した1文字 */ + } urg_serial_t; + + +-//! ڑJ ++//! 接続を開く + extern int serial_open(urg_serial_t *serial, const char *device, long baudrate); + + +-//! ڑ‚ ++//! 接続を閉じる + extern void serial_close(urg_serial_t *serial); + + +-//! {[[gݒ肷 ++//! ボーレートを設定する + extern int serial_set_baudrate(urg_serial_t *serial, long baudrate); + + +-//! f[^𑗐M ++//! データを送信する + extern int serial_write(urg_serial_t *serial, const char *data, int size); + + +-//! f[^M ++//! データを受信する + extern int serial_read(urg_serial_t *serial, + char *data, int max_size, int timeout); + + +-//! s܂ł̃f[^M ++//! 改行までのデータを受信する + extern int serial_readline(urg_serial_t *serial, + char *data, int max_size, int timeout); + + +-//! G[i[ĕԂ ++//! エラー文字列を格納して返す + extern int serial_error(urg_serial_t *serial, + char *error_message, int max_size); + +diff --git a/current/include/urg_c/urg_serial_utils.h b/current/include/urg_c/urg_serial_utils.h +index f1650c1..30afdf5 100644 +--- a/current/include/urg_c/urg_serial_utils.h ++++ b/current/include/urg_c/urg_serial_utils.h +@@ -2,29 +2,29 @@ + #define URG_SERIAL_UTILS_H + + /*! +- \file +- \brief VAp̕⏕֐ ++ ¥file ++ ¥brief シリアル用の補助関数 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ + + +-//! VA|[g ++//! シリアルポートを検索する + extern int urg_serial_find_port(void); + + +-//! VA|[gԂ ++//! 検索したシリアルポート名を返す + extern const char *urg_serial_port_name(int index); + + + /*! +- \brief |[g URG ǂ ++ ¥brief ポートが URG かどうか + +- \retval 1 URG ̃|[g +- \retval 0 s +- \retval <0 G[ ++ ¥retval 1 URG のポート ++ ¥retval 0 不明 ++ ¥retval <0 エラー + */ + extern int urg_serial_is_urg_port(int index); + +diff --git a/current/include/urg_c/urg_utils.h b/current/include/urg_c/urg_utils.h +index 8048421..2f02d0f 100644 +--- a/current/include/urg_c/urg_utils.h ++++ b/current/include/urg_c/urg_utils.h +@@ -2,15 +2,15 @@ + #define URG_UTILS_H + + /*! +- \file +- \~japanese +- \brief URG ZTp̕⏕֐ ++ ¥file ++ ¥‾japanese ++ ¥brief URG センサ用の補助関数 + +- \~english +- \brief URG sensor utility ++ ¥‾english ++ ¥brief URG sensor utility + +- \~ +- \author Satofumi KAMIMURA ++ ¥‾ ++ ¥author Satofumi KAMIMURA + + $Id: urg_utils.h,v 630ee326c5ce 2011/02/19 08:06:25 Satofumi $ + */ +@@ -23,37 +23,37 @@ extern "C" { + + + /*! +- \~japanese +- \brief URG ̃G[Ԃ ++ ¥‾japanese ++ ¥brief URG のエラーを示す文字列を返す + +- \param[in] urg URG ZTǗ ++ ¥param[in] urg URG センサ管理 + +- \retval URG ̃G[ ++ ¥retval URG のエラーを示す文字列 + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + if (!urg_open(&urg, "/dev/ttyACM0", 115200, URG_SERIAL)) { +- printf("urg_open: %s\n", urg_error(&urg)); ++ printf("urg_open: %s¥n", urg_error(&urg)); + return -1; +- } \endcode ++ } ¥endcode + */ + extern const char *urg_error(const urg_t *urg); + + + /*! +- \~japanese +- \brief ZTԂ̍őlAŏlԂ ++ ¥‾japanese ++ ¥brief センサが返す距離の最大値、最小値を返す + +- ZTԂ [ŏl, ől] ŕԂ܂B ++ センサが返す距離を [最小値, 最大値] で返します。 + +- \param[in] urg URG ZTǗ +- \param[out] min_distance ŏl [mm] +- \param[out] max_distance ől [mm] ++ ¥param[in] urg URG センサ管理 ++ ¥param[out] min_distance 最小値 [mm] ++ ¥param[out] max_distance 最大値 [mm] + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + long min_distance, max_distance; + urg_distance_min_max(&urg, &min_distance, &max_distance); + +@@ -63,126 +63,126 @@ extern "C" { + continue; + } + ... +- } \endcode ++ } ¥endcode + */ + extern void urg_distance_min_max(const urg_t *urg, + long *min_distance, long *max_distance); + + + /*! +- \~japanese +- \brief v step ̍őlAŏlԂ ++ ¥‾japanese ++ ¥brief 計測 step の最大値、最小値を返す + +- urg_set_scanning_parameter() Ŏwł͈͂ [ŏl, ől] ŕԂB ++ urg_set_scanning_parameter() で指定できる範囲を [最小値, 最大値] で返す。 + +- \param[in] urg URG ZTǗ +- \param[out] min_step ŏl +- \param[out] max_step ől ++ ¥param[in] urg URG センサ管理 ++ ¥param[out] min_step 最小値 ++ ¥param[out] max_step 最大値 + +- step ̓ZTʂ 0 łAZT㕔猩ꍇ̔v܂̕Av܂̕ step lƂȂB ++ step はセンサ正面が 0 であり、センサ上部から見た場合の反時計まわりの方向が正、時計まわりの方向が負の step 値となる。 + +- \image html sensor_step_image.png ZT step ̊֌W ++ ¥image html sensor_step_image.png センサと step の関係 + +- min_step, max_step ̒l̓ZTɂĈقȂB ++ min_step, max_step の値はセンサによって異なる。 + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + urg_step_min_max(&urg, &min_step, &max_step); + +- printf("range first: %d [deg]\n", urg_step2deg(&urg, min_step)); +- printf("range last : %d [deg]\n", urg_step2deg(&urg, max_step)); \endcode ++ printf("range first: %d [deg]¥n", urg_step2deg(&urg, min_step)); ++ printf("range last : %d [deg]¥n", urg_step2deg(&urg, max_step)); ¥endcode + +- \see urg_set_scanning_parameter(), urg_step2rad(), urg_step2deg() ++ ¥see urg_set_scanning_parameter(), urg_step2rad(), urg_step2deg() + */ + extern void urg_step_min_max(const urg_t *urg, int *min_step, int *max_step); + + +- /*! \~japanese PXLɂ鎞 [usec] Ԃ */ ++ /*! ¥‾japanese 1スキャンにかかる時間 [usec] を返す */ + extern long urg_scan_usec(const urg_t *urg); + + +- /*! \~japanese 擾f[^̍őlԂ */ ++ /*! ¥‾japanese 取得データ数の最大値を返す */ + extern int urg_max_data_size(const urg_t *urg); + + + /*! +- \~japanese +- \brief CfbNXƊpx(radian)̕ϊs ++ ¥‾japanese ++ ¥brief インデックスと角度(radian)の変換を行う + +- CfbNƂ urg_get_distance() Ȃǂ̋f[^擾֐Ԃf[^zɂ‚Ă̒lłB̊֐́AŌɍsf[^擾֐̃f[^zɂ‚ėLƂȂB ++ インデックとは urg_get_distance() などの距離データ取得関数が返したデータ配列についての値である。この関数は、最後に行った距離データ取得関数のデータ配列について有効となる。 + +- \param[in] urg URG ZTǗ +- \param[in] index CfbNX ++ ¥param[in] urg URG センサ管理 ++ ¥param[in] index インデックス + +- \return px [radian] ++ ¥return 角度 [radian] + +- index ́A擾vf[^ɂ‚Ă̒lł step pxƂ̊֌W͎擾ݒɂقȂB ++ index は、取得した計測データについての値であり step や角度との関係は取得設定により異なる。 + +- \image html sensor_index_image.png ZŤv͈͂ƃCfbNX̊֌W ++ ¥image html sensor_index_image.png センサの計測範囲とインデックスの関係 + +- \~ ++ ¥‾ + Example +- \code ++ ¥code + int n = urg_get_distance(&urg, data, NULL); + for (int i = 0; i < n; ++i) { + long distance = data[i]; + double radian = urg_index2rad(i); + double x = distance * cos(radian); + double y = distance * sin(radian); +- printf("%.1f, %.1f\n", x, y); +- } \endcode ++ printf("%.1f, %.1f¥n", x, y); ++ } ¥endcode + +- \see urg_index2deg(), urg_rad2index(), urg_deg2index() ++ ¥see urg_index2deg(), urg_rad2index(), urg_deg2index() + */ + extern double urg_index2rad(const urg_t *urg, int index); + + +- /*! \~japanese CfbNXƊpx(degree)̕ϊs */ ++ /*! ¥‾japanese インデックスと角度(degree)の変換を行う */ + extern double urg_index2deg(const urg_t *urg, int index); + + +- /*! \~japanese px(radian)ƃCfbNX̕ϊs */ ++ /*! ¥‾japanese 角度(radian)とインデックスの変換を行う */ + extern int urg_rad2index(const urg_t *urg, double radian); + + +- /*! \~japanese px(degree)ƃCfbNX̕ϊs */ ++ /*! ¥‾japanese 角度(degree)とインデックスの変換を行う */ + extern int urg_deg2index(const urg_t *urg, double degree); + + + /*! +- \~japanese +- \brief px(radian) step ̕ϊs ++ ¥‾japanese ++ ¥brief 角度(radian)と step の変換を行う + +- urg_step_min_max() Œ`Ă step ɂ‚āApx(radian) step ̕ϊsB ++ urg_step_min_max() で定義されている step について、角度(radian)と step の変換を行う。 + +- \param[in] urg URG ZTǗ +- \param[in] radian px [radian] ++ ¥param[in] urg URG センサ管理 ++ ¥param[in] radian 角度 [radian] + +- \return step ++ ¥return step + +- \image html sensor_angle_image.png ZT step ƊpxƂ̊֌W ++ ¥image html sensor_angle_image.png センサの step と角度との関係 + +- px step ֕ϊʂłȂꍇAʂ 0 ̕ɐ؂̂ĂꂽlƂȂB ++ 角度から step へ変換した結果が整数でない場合、結果は 0 の方向に切り捨てられた値となる。 + +- \~ +- \see urg_step_min_max(), urg_deg2step(), urg_step2rad(), urg_step2deg() ++ ¥‾ ++ ¥see urg_step_min_max(), urg_deg2step(), urg_step2rad(), urg_step2deg() + */ + extern int urg_rad2step(const urg_t *urg, double radian); + + +- /*! \~japanese px(degree) step ̕ϊs */ ++ /*! ¥‾japanese 角度(degree)と step の変換を行う */ + extern int urg_deg2step(const urg_t *urg, double degree); + + +- /*! \~japanese step px(radian)̕ϊs */ ++ /*! ¥‾japanese step と 角度(radian)の変換を行う */ + extern double urg_step2rad(const urg_t *urg, int step); + + +- /*! \~japanese step px(degree)̕ϊs */ ++ /*! ¥‾japanese step と 角度(degree)の変換を行う */ + extern double urg_step2deg(const urg_t *urg, int step); + +- /*! \~japanese step ƃCfbNX̕ϊs */ ++ /*! ¥‾japanese step とインデックスの変換を行う */ + extern int urg_step2index(const urg_t *urg, int step); + + #ifdef __cplusplus +diff --git a/current/samples/calculate_xy.c b/current/samples/calculate_xy.c +index 5cf21e5..230ad3d 100644 +--- a/current/samples/calculate_xy.c ++++ b/current/samples/calculate_xy.c +@@ -1,10 +1,10 @@ + /*! +- \~japanese +- \example calculate_xy.c X-Y Wnł̈ʒuvZ ++ ¥‾japanese ++ ¥example calculate_xy.c X-Y 座標系での位置を計算する + +- ZTO X ̕Ƃ݂ȂsWŁAf[^ʒuo͂B ++ センサ前方が X 軸の方向とみなした直行座標上で、距離データを位置を出力する。 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: calculate_xy.c,v 586c4fa697ef 2011/01/24 08:50:01 Satofumi $ + */ +@@ -38,16 +38,16 @@ int main(int argc, char *argv[]) + return 1; + } + +- // \~japanese f[^擾 ++ // ¥‾japanese データ取得 + urg_start_measurement(&urg, URG_DISTANCE, 1, 0); + n = urg_get_distance(&urg, data, &time_stamp, &system_time_stamp); + if (n < 0) { +- printf("urg_get_distance: %s\n", urg_error(&urg)); ++ printf("urg_get_distance: %s¥n", urg_error(&urg)); + urg_close(&urg); + return 1; + } + +- // \~japanese X-Y Wn̒lo ++ // ¥‾japanese X-Y 座標系の値を出力 + urg_distance_min_max(&urg, &min_distance, &max_distance); + for (i = 0; i < n; ++i) { + long distance = data[i]; +@@ -63,11 +63,11 @@ int main(int argc, char *argv[]) + x = (long)(distance * cos(radian)); + y = (long)(distance * sin(radian)); + +- printf("%ld, %ld\n", x, y); ++ printf("%ld, %ld¥n", x, y); + } +- printf("\n"); ++ printf("¥n"); + +- // \~japanese ؒf ++ // ¥‾japanese 切断 + free(data); + urg_close(&urg); + +diff --git a/current/samples/find_port.c b/current/samples/find_port.c +index 5039934..88e04f2 100644 +--- a/current/samples/find_port.c ++++ b/current/samples/find_port.c +@@ -1,8 +1,8 @@ + /*! +- \~japanese +- \example find_port.c |[g̒T ++ ¥‾japanese ++ ¥example find_port.c ポートの探索 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +@@ -17,7 +17,7 @@ int main(void) + int i; + + if (found_port_size == 0) { +- printf("could not found ports.\n"); ++ printf("could not found ports.¥n"); + return 1; + } + +@@ -26,7 +26,7 @@ int main(void) + if (urg_serial_is_urg_port(i)) { + printf(" [URG]"); + } +- printf("\n"); ++ printf("¥n"); + } + + return 0; +diff --git a/current/samples/get_distance.c b/current/samples/get_distance.c +index 98f2336..3002ece 100644 +--- a/current/samples/get_distance.c ++++ b/current/samples/get_distance.c +@@ -1,9 +1,9 @@ + /*! +- \~japanese +- \example get_distance.c f[^擾 ++ ¥‾japanese ++ ¥example get_distance.c 距離データを取得する + +- \~ +- \author Satofumi KAMIMURA ++ ¥‾ ++ ¥author Satofumi KAMIMURA + + $Id: get_distance.c,v 586c4fa697ef 2011/01/24 08:50:01 Satofumi $ + */ +@@ -22,9 +22,9 @@ static void print_data(urg_t *urg, long data[], int data_n, long time_stamp) + + (void)data_n; + +- // \~japanese Õf[^݂̂\ ++ // ¥‾japanese 前方のデータのみを表示 + front_index = urg_step2index(urg, 0); +- printf("%ld [mm], (%ld [msec])\n", data[front_index], time_stamp); ++ printf("%ld [mm], (%ld [msec])¥n", data[front_index], time_stamp); + + #else + (void)time_stamp; +@@ -33,7 +33,7 @@ static void print_data(urg_t *urg, long data[], int data_n, long time_stamp) + long min_distance; + long max_distance; + +- // \~japanese SẴf[^ X-Y ̈ʒu\ ++ // ¥‾japanese 全てのデータの X-Y の位置を表示 + urg_distance_min_max(urg, &min_distance, &max_distance); + for (i = 0; i < data_n; ++i) { + long l = data[i]; +@@ -49,7 +49,7 @@ static void print_data(urg_t *urg, long data[], int data_n, long time_stamp) + y = (long)(l * sin(radian)); + printf("(%ld, %ld), ", x, y); + } +- printf("\n"); ++ printf("¥n"); + #endif + } + +@@ -76,9 +76,9 @@ int main(int argc, char *argv[]) + return 1; + } + +- // \~japanese f[^擾 ++ // ¥‾japanese データ取得 + #if 0 +- // \~japanese f[^̎擾͈͂ύXꍇ ++ // ¥‾japanese データの取得範囲を変更する場合 + urg_set_scanning_parameter(&urg, + urg_deg2step(&urg, -90), + urg_deg2step(&urg, +90), 0); +@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) + for (i = 0; i < CAPTURE_TIMES; ++i) { + n = urg_get_distance(&urg, data, &time_stamp, &system_time_stamp); + if (n <= 0) { +- printf("urg_get_distance: %s\n", urg_error(&urg)); ++ printf("urg_get_distance: %s¥n", urg_error(&urg)); + free(data); + urg_close(&urg); + return 1; +@@ -96,7 +96,7 @@ int main(int argc, char *argv[]) + print_data(&urg, data, n, time_stamp); + } + +- // \~japanese ؒf ++ // ¥‾japanese 切断 + free(data); + urg_close(&urg); + +diff --git a/current/samples/get_distance_intensity.c b/current/samples/get_distance_intensity.c +index 0c5acc2..584c78e 100644 +--- a/current/samples/get_distance_intensity.c ++++ b/current/samples/get_distance_intensity.c +@@ -1,8 +1,8 @@ + /*! +- \~japanese +- \example get_distance_intensity.c Exf[^擾 ++ ¥‾japanese ++ ¥example get_distance_intensity.c 距離・強度データを取得する + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: get_distance_intensity.c,v 586c4fa697ef 2011/01/24 08:50:01 Satofumi $ + */ +@@ -22,9 +22,9 @@ static void print_data(urg_t *urg, long data[], unsigned short intensity[], + int front_index; + (void)data_n; + +- // \~japanese Õf[^݂̂\ ++ // ¥‾japanese 前方のデータのみを表示 + front_index = urg_step2index(urg, 0); +- printf("%ld [mm], %d [1], (%ld [msec])\n", ++ printf("%ld [mm], %d [1], (%ld [msec])¥n", + data[front_index], intensity[front_index], time_stamp); + + #else +@@ -32,10 +32,10 @@ static void print_data(urg_t *urg, long data[], unsigned short intensity[], + + int i; + +- // \~japanese SẴf[^\ +- printf("# n = %d, time_stamp = %ld\n", data_n, time_stamp); ++ // ¥‾japanese 全てのデータを表示 ++ printf("# n = %d, time_stamp = %ld¥n", data_n, time_stamp); + for (i = 0; i < data_n; ++i) { +- printf("%d, %ld, %d\n", i, data[i], intensity[i]); ++ printf("%d, %ld, %d¥n", i, data[i], intensity[i]); + } + #endif + } +@@ -61,7 +61,7 @@ int main(int argc, char *argv[]) + + // Distance Intensity reading only (?) on UXM-30LX + if (!strstr(urg_sensor_product_type(&urg),"UXM-30LX")) { +- fprintf(stderr,"Distance Intensity not supported on %s\n", ++ fprintf(stderr,"Distance Intensity not supported on %s¥n", + urg_sensor_product_type(&urg)); + return 1; + } +@@ -78,12 +78,12 @@ int main(int argc, char *argv[]) + return 1; + } + +- // \~japanese f[^擾 ++ // ¥‾japanese データ取得 + urg_start_measurement(&urg, URG_DISTANCE_INTENSITY, CAPTURE_TIMES, 0); + for (i = 0; i < CAPTURE_TIMES; ++i) { + n = urg_get_distance_intensity(&urg, data, intensity, &time_stamp, &system_time_stamp); + if (n <= 0) { +- printf("urg_get_distance_intensity: %s\n", urg_error(&urg)); ++ printf("urg_get_distance_intensity: %s¥n", urg_error(&urg)); + free(data); + urg_close(&urg); + return 1; +@@ -91,7 +91,7 @@ int main(int argc, char *argv[]) + print_data(&urg, data, intensity, n, time_stamp); + } + +- // \~japanese ؒf ++ // ¥‾japanese 切断 + free(intensity); + free(data); + urg_close(&urg); +diff --git a/current/samples/get_multiecho.c b/current/samples/get_multiecho.c +index 6e3816d..b9445f6 100644 +--- a/current/samples/get_multiecho.c ++++ b/current/samples/get_multiecho.c +@@ -1,8 +1,8 @@ + /*! +- \~japanese +- \example get_multiecho.c f[^(}`GR[)擾 ++ ¥‾japanese ++ ¥example get_multiecho.c 距離データ(マルチエコー)を取得する + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +@@ -32,21 +32,21 @@ static void print_data(urg_t *urg, long data[], int data_n, long time_stamp) + + (void)data_n; + +- // \~japanese Õf[^݂̂\ ++ // ¥‾japanese 前方のデータのみを表示 + front_index = urg_step2index(urg, 0); + print_echo_data(data, front_index); +- printf("%ld\n", time_stamp); ++ printf("%ld¥n", time_stamp); + + #else + (void)urg; + + int i; + +- // \~japanese SẴf[^\ +- printf("# n = %d, time_stamp = %ld\n", data_n, time_stamp); ++ // ¥‾japanese 全てのデータを表示 ++ printf("# n = %d, time_stamp = %ld¥n", data_n, time_stamp); + for (i = 0; i < data_n; ++i) { + print_echo_data(data, i); +- printf("\n"); ++ printf("¥n"); + } + #endif + } +@@ -74,12 +74,12 @@ int main(int argc, char *argv[]) + return 1; + } + +- // \~japanese f[^擾 ++ // ¥‾japanese データ取得 + urg_start_measurement(&urg, URG_MULTIECHO, CAPTURE_TIMES, 0); + for (i = 0; i < CAPTURE_TIMES; ++i) { + n = urg_get_multiecho(&urg, data, &time_stamp, &system_time_stamp); + if (n <= 0) { +- printf("urg_get_multiecho: %s\n", urg_error(&urg)); ++ printf("urg_get_multiecho: %s¥n", urg_error(&urg)); + free(data); + urg_close(&urg); + return 1; +@@ -87,7 +87,7 @@ int main(int argc, char *argv[]) + print_data(&urg, data, n, time_stamp); + } + +- // \~japanese ؒf ++ // ¥‾japanese 切断 + free(data); + urg_close(&urg); + +diff --git a/current/samples/get_multiecho_intensity.c b/current/samples/get_multiecho_intensity.c +index 1c1d79c..717250b 100644 +--- a/current/samples/get_multiecho_intensity.c ++++ b/current/samples/get_multiecho_intensity.c +@@ -1,8 +1,8 @@ + /*! +- \~japanese +- \example get_multiecho_intensity.c Exf[^(}`GR[)擾 ++ ¥‾japanese ++ ¥example get_multiecho_intensity.c 距離・強度データ(マルチエコー)を取得する + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +@@ -31,7 +31,7 @@ static void print_echo_data(long data[], unsigned short intensity[], + } + + +-// \~japanese Ax̃f[^\ ++// ¥‾japanese 距離、強度のデータを表示する + static void print_data(urg_t *urg, long data[], + unsigned short intensity[], int data_n, long time_stamp) + { +@@ -40,20 +40,20 @@ static void print_data(urg_t *urg, long data[], + + (void)data_n; + +- // \~japanese Õf[^݂̂\ ++ // ¥‾japanese 前方のデータのみを表示 + front_index = urg_step2index(urg, 0); + print_echo_data(data, intensity, front_index); +- printf("%ld\n", time_stamp); ++ printf("%ld¥n", time_stamp); + + #else + (void)urg; + int i; + +- // \~japanese SẴf[^\ +- printf("# n = %d, time_stamp = %ld\n", data_n, time_stamp); ++ // ¥‾japanese 全てのデータを表示 ++ printf("# n = %d, time_stamp = %ld¥n", data_n, time_stamp); + for (i = 0; i < data_n; ++i) { + print_echo_data(data, intensity, i); +- printf("\n"); ++ printf("¥n"); + } + #endif + } +@@ -87,12 +87,12 @@ int main(int argc, char *argv[]) + return 1; + } + +- // \~japanese f[^擾 ++ // ¥‾japanese データ取得 + urg_start_measurement(&urg, URG_MULTIECHO_INTENSITY, CAPTURE_TIMES, 0); + for (i = 0; i < CAPTURE_TIMES; ++i) { + n = urg_get_multiecho_intensity(&urg, data, intensity, &time_stamp, &system_time_stamp); + if (n <= 0) { +- printf("urg_get_multiecho_intensity: %s\n", urg_error(&urg)); ++ printf("urg_get_multiecho_intensity: %s¥n", urg_error(&urg)); + free(data); + free(intensity); + urg_close(&urg); +@@ -101,7 +101,7 @@ int main(int argc, char *argv[]) + print_data(&urg, data, intensity, n, time_stamp); + } + +- // \~japanese ؒf ++ // ¥‾japanese 切断 + free(data); + free(intensity); + urg_close(&urg); +diff --git a/current/samples/open_urg_sensor.c b/current/samples/open_urg_sensor.c +index 5a0a564..00ecb75 100644 +--- a/current/samples/open_urg_sensor.c ++++ b/current/samples/open_urg_sensor.c +@@ -1,9 +1,9 @@ + /*! +- \~japanese +- \brief URG Ƃ̐ڑ ++ ¥‾japanese ++ ¥brief URG との接続 + +- \~ +- \author Satofumi KAMIMURA ++ ¥‾ ++ ¥author Satofumi KAMIMURA + + $Id: open_urg_sensor.c,v d00944669fc8 2011/02/16 13:41:09 Satofumi $ + */ +@@ -31,7 +31,7 @@ int open_urg_sensor(urg_t *urg, int argc, char *argv[]) + const char *ip_address = "192.168.0.10"; + int i; + +- // \~japanese ڑ^Cv̐ؑւ ++ // ¥‾japanese 接続タイプの切替え + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-e")) { + connection_type = URG_ETHERNET; +@@ -40,9 +40,9 @@ int open_urg_sensor(urg_t *urg, int argc, char *argv[]) + } + } + +- // \~japanese ڑ ++ // ¥‾japanese 接続 + if (urg_open(urg, connection_type, device, baudrate_or_port) < 0) { +- printf("urg_open: %s, %ld: %s\n", ++ printf("urg_open: %s, %ld: %s¥n", + device, baudrate_or_port, urg_error(urg)); + return -1; + } +diff --git a/current/samples/open_urg_sensor.h b/current/samples/open_urg_sensor.h +index 9eb9b7a..42565e4 100644 +--- a/current/samples/open_urg_sensor.h ++++ b/current/samples/open_urg_sensor.h +@@ -2,11 +2,11 @@ + #define OPEN_URG_SENSOR_H + + /*! +- \~japanese +- \brief URG Ƃ̐ڑ ++ ¥‾japanese ++ ¥brief URG との接続 + +- \~ +- \author Satofumi KAMIMURA ++ ¥‾ ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +diff --git a/current/samples/sensor_parameter.c b/current/samples/sensor_parameter.c +index c379050..8cd5094 100644 +--- a/current/samples/sensor_parameter.c ++++ b/current/samples/sensor_parameter.c +@@ -1,8 +1,8 @@ + /*! +- \~japanese +- \example sensor_parameter.c ZT̏o ++ ¥‾japanese ++ ¥example sensor_parameter.c センサ情報の出力 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: sensor_parameter.c,v 0caa22c18f6b 2010/12/30 03:36:32 Satofumi $ + */ +@@ -25,20 +25,20 @@ int main(int argc, char *argv[]) + return 1; + } + +- printf("Sensor product type: %s\n", urg_sensor_product_type(&urg)); +- printf("Sensor firmware version: %s\n", urg_sensor_firmware_version(&urg)); +- printf("Sensor serial ID: %s\n", urg_sensor_serial_id(&urg)); +- printf("Sensor status: %s\n", urg_sensor_status(&urg)); +- printf("Sensor state: %s\n", urg_sensor_state(&urg)); ++ printf("Sensor product type: %s¥n", urg_sensor_product_type(&urg)); ++ printf("Sensor firmware version: %s¥n", urg_sensor_firmware_version(&urg)); ++ printf("Sensor serial ID: %s¥n", urg_sensor_serial_id(&urg)); ++ printf("Sensor status: %s¥n", urg_sensor_status(&urg)); ++ printf("Sensor state: %s¥n", urg_sensor_state(&urg)); + + urg_step_min_max(&urg, &min_step, &max_step); +- printf("step: [%d, %d]\n", min_step, max_step); ++ printf("step: [%d, %d]¥n", min_step, max_step); + + urg_distance_min_max(&urg, &min_distance, &max_distance); +- printf("distance: [%ld, %ld)\n", min_distance, max_distance); ++ printf("distance: [%ld, %ld)¥n", min_distance, max_distance); + +- printf("scan interval: %ld [usec]\n", urg_scan_usec(&urg)); +- printf("sensor data size: %d\n", urg_max_data_size(&urg)); ++ printf("scan interval: %ld [usec]¥n", urg_scan_usec(&urg)); ++ printf("sensor data size: %d¥n", urg_max_data_size(&urg)); + + urg_close(&urg); + +diff --git a/current/samples/sync_time_stamp.c b/current/samples/sync_time_stamp.c +index 196803d..0a32b1c 100644 +--- a/current/samples/sync_time_stamp.c ++++ b/current/samples/sync_time_stamp.c +@@ -1,8 +1,8 @@ + /*! +- \~japanese +- \example sync_time_stamp.c ZT PC ̃^CX^v𓯊 ++ ¥‾japanese ++ ¥example sync_time_stamp.c センサと PC のタイムスタンプを同期する + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: sync_time_stamp.c,v 799c195d046c 2011/01/14 05:10:38 hokuyo $ + */ +@@ -52,8 +52,8 @@ static int pc_msec_time(void) + + + /*! +- \~japanese +- \brief PC ̃^CX^vɕ␳邽߂̒lԂ ++ ¥‾japanese ++ ¥brief PC のタイムスタンプに補正するための値を返す + */ + static long print_time_stamp(urg_t *urg, long time_stamp_offset) + { +@@ -71,7 +71,7 @@ static long print_time_stamp(urg_t *urg, long time_stamp_offset) + delay = (after_pc_time_stamp - before_pc_time_stamp) / 2; + + if (sensor_time_stamp < 0) { +- printf("urg_time_stamp: %s\n", urg_error(urg)); ++ printf("urg_time_stamp: %s¥n", urg_error(urg)); + return -1; + } + sensor_time_stamp -= time_stamp_offset; +@@ -79,7 +79,7 @@ static long print_time_stamp(urg_t *urg, long time_stamp_offset) + pc_time_stamp = pc_msec_time(); + urg_stop_time_stamp_mode(urg); + +- printf("%ld,\t%ld\n", pc_time_stamp, sensor_time_stamp); ++ printf("%ld,¥t%ld¥n", pc_time_stamp, sensor_time_stamp); + + return sensor_time_stamp - (pc_time_stamp - delay); + } +@@ -99,12 +99,12 @@ int main(int argc, char *argv[]) + return 1; + } + +- printf("# pc,\tsensor\n"); ++ printf("# pc,¥tsensor¥n"); + +- // \~japanese URG ̃^CX^v PC ̃^CX^v\ ++ // ¥‾japanese URG のタイムスタンプと PC のタイムスタンプを表示 + time_stamp_offset = print_time_stamp(&urg, 0); + +- // \~japanese URG ̕␳̃^CX^v PC ^CX^v\ ++ // ¥‾japanese URG の補正後のタイムスタンプと PC タイムスタンプを表示 + for (i = 0; i < TIME_STAMP_PRINT_TIMES; ++i) { + print_time_stamp(&urg, time_stamp_offset); + } +diff --git a/current/src/urg_connection.c b/current/src/urg_connection.c +index c474459..46adf8d 100644 +--- a/current/src/urg_connection.c ++++ b/current/src/urg_connection.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief ʐM̏ ++ ¥file ++ ¥brief 通信の処理 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_connection.c,v 0caa22c18f6b 2010/12/30 03:36:32 Satofumi $ + */ +diff --git a/current/src/urg_debug.c b/current/src/urg_debug.c +index 1d55c3e..b670f59 100644 +--- a/current/src/urg_debug.c ++++ b/current/src/urg_debug.c +@@ -1,8 +1,8 @@ + /*! +- \~japanese +- \brief URG ZTp̕⏕֐ ++ ¥‾japanese ++ ¥brief URG センサ用の補助関数 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_utils.c,v da778fd816c2 2011/01/05 20:02:06 Satofumi $ + */ +diff --git a/current/src/urg_ring_buffer.c b/current/src/urg_ring_buffer.c +index cdbfb2c..72d29ec 100644 +--- a/current/src/urg_ring_buffer.c ++++ b/current/src/urg_ring_buffer.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief Oobt@ ++ ¥file ++ ¥brief リングバッファ + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +@@ -54,9 +54,9 @@ int ring_write(ring_buffer_t *ring, const char *data, int size) + int free_size = ring_capacity(ring) - ring_size(ring); + int push_size = (size > free_size) ? free_size : size; + +- // f[^zu ++ // データ配置 + if (ring->first <= ring->last) { +- // last buffer_size I[܂łɔzu ++ // last から buffer_size 終端までに配置 + int left_size = 0; + int to_end = ring->buffer_size - ring->last; + int move_size = (to_end > push_size) ? push_size : to_end; +@@ -67,12 +67,12 @@ int ring_write(ring_buffer_t *ring, const char *data, int size) + + left_size = push_size - move_size; + if (left_size > 0) { +- // 0 first ̑O܂łzu ++ // 0 から first の前までを配置 + byte_move(ring->buffer, &data[move_size], left_size); + ring->last = left_size; + } + } else { +- // last first ̑O܂Ŕzu ++ // last から first の前まで配置 + byte_move(&ring->buffer[ring->last], data, size); + ring->last += push_size; + } +@@ -82,7 +82,7 @@ int ring_write(ring_buffer_t *ring, const char *data, int size) + + int ring_read(ring_buffer_t *ring, char *buffer, int size) + { +- // f[^擾 ++ // データ取得 + int now_size = ring_size(ring); + int pop_size = (size > now_size) ? now_size : size; + +@@ -91,7 +91,7 @@ int ring_read(ring_buffer_t *ring, char *buffer, int size) + ring->first += pop_size; + + } else { +- // first buffer_size I[܂łzu ++ // first から buffer_size 終端までを配置 + int left_size = 0; + int to_end = ring->buffer_size - ring->first; + int move_size = (to_end > pop_size) ? pop_size : to_end; +@@ -102,7 +102,7 @@ int ring_read(ring_buffer_t *ring, char *buffer, int size) + + left_size = pop_size - move_size; + if (left_size > 0) { +- // 0 last ̑O܂łzu ++ // 0 から last の前までを配置 + byte_move(&buffer[move_size], ring->buffer, left_size); + + ring->first = left_size; +diff --git a/current/src/urg_sensor.c b/current/src/urg_sensor.c +index 801d366..f4fa3dd 100644 +--- a/current/src/urg_sensor.c ++++ b/current/src/urg_sensor.c +@@ -1,11 +1,11 @@ + /*! +- \brief URG ZT ++ ¥brief URG センサ制御 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_sensor.c,v 66816edea765 2011/05/03 06:53:52 satofumi $ + +- \todo Mx vɑ Mx R}h𑗐MƂɁAK؂ɓ삷悤ɂ ++ ¥todo Mx 計測中に他の Mx コマンドを送信したときに、適切に動作するようにする + */ + + #include "urg_c/urg_sensor.h" +@@ -29,7 +29,7 @@ enum { + EXPECTED_END = -1, + + RECEIVE_DATA_TIMEOUT, +- RECEIVE_DATA_COMPLETE, /*!< f[^𐳏ɎM */ ++ RECEIVE_DATA_COMPLETE, /*!< データを正常に受信 */ + + PP_RESPONSE_LINES = 10, + VV_RESPONSE_LINES = 7, +@@ -43,7 +43,7 @@ static const char NOT_CONNECTED_MESSAGE[] = "not connected."; + static const char RECEIVE_ERROR_MESSAGE[] = "receive error."; + + +-//! `FbNŤvZ ++//! チェックサムの計算 + static char scip_checksum(const char buffer[], int size) + { + unsigned char sum = 0x00; +@@ -53,7 +53,7 @@ static char scip_checksum(const char buffer[], int size) + sum += buffer[i]; + } + +- // vZ̈Ӗ SCIP dlQƂ̂ ++ // 計算の意味は SCIP 仕様書を参照のこと + return (sum & 0x3f) + 0x30; + } + +@@ -65,7 +65,7 @@ static int set_errno_and_return(urg_t *urg, int urg_errno) + } + + +-// M̍sԂ ++// 受信した応答の行数を返す + static int scip_response(urg_t *urg, const char* command, + const int expected_ret[], int timeout, + char *receive_buffer, int receive_buffer_max_size) +@@ -84,7 +84,7 @@ static int scip_response(urg_t *urg, const char* command, + } + + if (p) { +- *p = '\0'; ++ *p = '¥0'; + } + + do { +@@ -94,20 +94,20 @@ static int scip_response(urg_t *urg, const char* command, + + } else if (p && (line_number > 0) + && (n < (receive_buffer_max_size - filled_size))) { +- // GR[obN͊Sṽ`FbNs߁Ai[Ȃ ++ // エコーバックは完全一致のチェックを行うため、格納しない + memcpy(p, buffer, n); + p += n; +- *p++ = '\0'; ++ *p++ = '¥0'; + filled_size += n; + } + + if (line_number == 0) { +- // GR[obN񂪁Av邩mF ++ // エコーバック文字列が、一致するかを確認する + if (strncmp(buffer, command, write_size - 1)) { + return set_errno_and_return(urg, URG_INVALID_RESPONSE); + } + } else if (n > 0) { +- // GR[obNȊO̍s̃`FbNT] ++ // エコーバック以外の行のチェックサムを評価する + char checksum = buffer[n - 1]; + if ((checksum != scip_checksum(buffer, n - 1)) && + (checksum != scip_checksum(buffer, n - 2))) { +@@ -115,10 +115,10 @@ static int scip_response(urg_t *urg, const char* command, + } + } + +- // Xe[^X]āA߂l肷 ++ // ステータス応答を評価して、戻り値を決定する + if (line_number == 1) { + if (n == 1) { +- // SCIP 1.1 ̏ꍇ́A퉞Ƃ݂Ȃ ++ // SCIP 1.1 応答の場合は、正常応答とみなす + ret = 0; + + } else if (n != 3) { +@@ -167,7 +167,7 @@ static void ignore_receive_data_with_qt(urg_t *urg, int timeout) + return; + } + +- connection_write(&urg->connection, "QT\n", 3); ++ connection_write(&urg->connection, "QT¥n", 3); + urg->is_sending = URG_TRUE; + urg->is_laser_on = URG_FALSE; + ignore_receive_data(urg, timeout); +@@ -183,15 +183,15 @@ static int change_sensor_baudrate(urg_t *urg, + int ret; + + if (current_baudrate == next_baudrate) { +- // ݂̃{[[gƐݒ肷{[[gꏏȂ΁A߂ ++ // 現在のボーレートと設定するボーレートが一緒ならば、戻る + return set_errno_and_return(urg, URG_NO_ERROR); + } + +- // "SS" R}hŃ{[[gύX +- snprintf(buffer, SS_COMMAND_SIZE, "SS%06ld\n", next_baudrate); ++ // "SS" コマンドでボーレートを変更する ++ snprintf(buffer, SS_COMMAND_SIZE, "SS%06ld¥n", next_baudrate); + ret = scip_response(urg, buffer, ss_expected, urg->timeout, NULL, 0); + +- // 0F ̂Ƃ Ethernet p̃ZTƂ݂ȂA퉞Ԃ ++ // 0F 応答のときは Ethernet 用のセンサとみなし、正常応答を返す + if (ret == -15) { + return set_errno_and_return(urg, URG_NO_ERROR); + } +@@ -199,24 +199,24 @@ static int change_sensor_baudrate(urg_t *urg, + return set_errno_and_return(urg, URG_INVALID_PARAMETER); + } + +- // 퉞Ȃ΁AzXg̃{[[gύX ++ // 正常応答ならば、ホスト側のボーレートを変更する + ret = connection_set_baudrate(&urg->connection, next_baudrate); + +- // ZT̐ݒ蔽f҂‚߂ɏҋ@ ++ // センサ側の設定反映を待つために少しだけ待機する + ignore_receive_data(urg, MAX_TIMEOUT); + + return set_errno_and_return(urg, ret); + } + + +-// {[[gύXȂڑ ++// ボーレートを変更しながら接続する + static int connect_urg_device(urg_t *urg, long baudrate) + { + long try_baudrate[] = { 19200, 38400, 115200 }; + int try_times = sizeof(try_baudrate) / sizeof(try_baudrate[0]); + int i; + +- // wꂽ{[[gڑ ++ // 指示されたボーレートから接続する + for (i = 0; i < try_times; ++i) { + if (try_baudrate[i] == baudrate) { + try_baudrate[i] = try_baudrate[0]; +@@ -233,55 +233,55 @@ static int connect_urg_device(urg_t *urg, long baudrate) + + connection_set_baudrate(&urg->connection, try_baudrate[i]); + +- // QT 𑗐MAԂ邩Ń{[[gvĂ邩mF +- ret = scip_response(urg, "QT\n", qt_expected, MAX_TIMEOUT, ++ // QT を送信し、応答が返されるかでボーレートが一致しているかを確認する ++ ret = scip_response(urg, "QT¥n", qt_expected, MAX_TIMEOUT, + receive_buffer, RECEIVE_BUFFER_SIZE); + if (ret > 0) { + if (!strcmp(receive_buffer, "E")) { + int scip20_expected[] = { 0, EXPECTED_END }; + +- // QT ̍Ō̉sǂݔ΂ ++ // QT 応答の最後の改行を読み飛ばす + ignore_receive_data(urg, MAX_TIMEOUT); + +- // "E" Ԃꂽꍇ́ASCIP 1.1 Ƃ݂Ȃ "SCIP2.0" 𑗐M +- ret = scip_response(urg, "SCIP2.0\n", scip20_expected, ++ // "E" が返された場合は、SCIP 1.1 とみなし "SCIP2.0" を送信する ++ ret = scip_response(urg, "SCIP2.0¥n", scip20_expected, + MAX_TIMEOUT, NULL, 0); + +- // SCIP2.0 ̍Ō̉sǂݔ΂ ++ // SCIP2.0 応答の最後の改行を読み飛ばす + ignore_receive_data(urg, MAX_TIMEOUT); + +- // {[[gύXĖ߂ ++ // ボーレートを変更して戻る + return change_sensor_baudrate(urg, try_baudrate[i], baudrate); + + } else if (!strcmp(receive_buffer, "0Ee")) { + int tm2_expected[] = { 0, EXPECTED_END }; + +- // "0Ee" Ԃꂽꍇ́ATM [hƂ݂Ȃ "TM2" 𑗐M +- scip_response(urg, "TM2\n", tm2_expected, ++ // "0Ee" が返された場合は、TM モードとみなし "TM2" を送信する ++ scip_response(urg, "TM2¥n", tm2_expected, + MAX_TIMEOUT, NULL, 0); + +- // {[[gύXĖ߂ ++ // ボーレートを変更して戻る + return change_sensor_baudrate(urg, try_baudrate[i], baudrate); + } + } + + if (ret <= 0) { + if (ret == URG_INVALID_RESPONSE) { +- // ُȃGR[obN̂Ƃ́Af[^MƂ݂Ȃ +- // f[^ǂݔ΂ ++ // 異常なエコーバックのときは、距離データ受信中とみなして ++ // データを読み飛ばす + ignore_receive_data_with_qt(urg, MAX_TIMEOUT); + +- // {[[gύXĖ߂ ++ // ボーレートを変更して戻る + return change_sensor_baudrate(urg, try_baudrate[i], baudrate); + + } else { +- // ȂƂ́A{[[gύXāAēxڑs ++ // 応答がないときは、ボーレートを変更して、再度接続を行う + ignore_receive_data_with_qt(urg, MAX_TIMEOUT); + continue; + } + } else if (!strcmp("00P", receive_buffer)) { + +- // ZTƃzXg̃{[[gύXĖ߂ ++ // センサとホストのボーレートを変更して戻る + return change_sensor_baudrate(urg, try_baudrate[i], baudrate); + } + } +@@ -290,7 +290,7 @@ static int connect_urg_device(urg_t *urg, long baudrate) + } + + +-// PP R}h̉ urg_t Ɋi[ ++// PP コマンドの応答を urg_t に格納する + static int receive_parameter(urg_t *urg) + { + enum { RECEIVE_BUFFER_SIZE = BUFFER_SIZE * 9, }; +@@ -300,7 +300,7 @@ static int receive_parameter(urg_t *urg) + char *p; + int i; + +- int ret = scip_response(urg, "PP\n", pp_expected, MAX_TIMEOUT, ++ int ret = scip_response(urg, "PP¥n", pp_expected, MAX_TIMEOUT, + receive_buffer, RECEIVE_BUFFER_SIZE); + if (ret < 0) { + return ret; +@@ -338,7 +338,7 @@ static int receive_parameter(urg_t *urg) + + } else if (!strncmp(p, "SCAN:", 5)) { + int rpm = strtol(p + 5, NULL, 10); +- // ^CAEgԂ́Av 16 {x̒lɂ ++ // タイムアウト時間は、計測周期の 16 倍程度の値にする + urg->scan_usec = 1000 * 1000 * 60 / rpm; + urg->timeout = urg->scan_usec >> (10 - 4); + received_bits |= 0x0040; +@@ -346,7 +346,7 @@ static int receive_parameter(urg_t *urg) + p += strlen(p) + 1; + } + +- // SẴp[^MmF ++ // 全てのパラメータを受信したか確認 + if (received_bits != 0x007f) { + return set_errno_and_return(urg, URG_RECEIVE_ERROR); + } +@@ -360,7 +360,7 @@ static int receive_parameter(urg_t *urg) + } + + +-//! SCIP ̃fR[h ++//! SCIP 文字列のデコード + long urg_scip_decode(const char data[], int size) + { + const char* p = data; +@@ -369,7 +369,7 @@ long urg_scip_decode(const char data[], int size) + + while (p < last_p) { + value <<= 6; +- value &= ~0x3f; ++ value &= ‾0x3f; + value |= *p++ - 0x30; + } + return value; +@@ -381,7 +381,7 @@ static int parse_parameter(const char *parameter, int size) + char buffer[5]; + + memcpy(buffer, parameter, size); +- buffer[size] = '\0'; ++ buffer[size] = '¥0'; + + return strtol(buffer, NULL, 10); + } +@@ -413,7 +413,7 @@ static urg_measurement_type_t parse_distance_parameter(urg_t *urg, + return URG_UNKNOWN; + } + +- // p[^̊i[ ++ // パラメータの格納 + urg->received_first_index = parse_parameter(&echoback[2], 4); + urg->received_last_index = parse_parameter(&echoback[6], 4); + urg->received_skip_step = parse_parameter(&echoback[10], 2); +@@ -479,7 +479,7 @@ static int receive_length_data(urg_t *urg, long length[], + urg->timeout); + + if (n > 0) { +- // `FbNT̕] ++ // チェックサムの評価 + if (buffer[line_filled + n - 1] != + scip_checksum(&buffer[line_filled], n - 1)) { + ignore_receive_data_with_qt(urg, urg->timeout); +@@ -496,10 +496,10 @@ static int receive_length_data(urg_t *urg, long length[], + int index; + + if (*p == '&') { +- // 擪 '&' Ƃ́A}`GR[̃f[^Ƃ݂Ȃ ++ // 先頭文字が '&' だったときは、マルチエコーのデータとみなす + + if ((last_p - (p + 1)) < data_size) { +- // '&' āAdata_size f[^Δ ++ // '&' を除いて、data_size 分データが無ければ抜ける + break; + } + +@@ -509,7 +509,7 @@ static int receive_length_data(urg_t *urg, long length[], + --line_filled; + + } else { +- // ̃f[^ ++ // 次のデータ + multiecho_index = 0; + } + +@@ -517,14 +517,14 @@ static int receive_length_data(urg_t *urg, long length[], + + if (step_filled > + (urg->received_last_index - urg->received_first_index)) { +- // f[^߂ꍇ́Ac̃f[^𖳎Ė߂ ++ // データが多過ぎる場合は、残りのデータを無視して戻る + ignore_receive_data_with_qt(urg, urg->timeout); + return set_errno_and_return(urg, URG_RECEIVE_ERROR); + } + + + if (is_multiecho && (multiecho_index == 0)) { +- // }`GR[̃f[^i[_~[f[^Ŗ߂ ++ // マルチエコーのデータ格納先をダミーデータで埋める + int i; + if (length) { + for (i = 1; i < multiecho_max_size; ++i) { +@@ -538,13 +538,13 @@ static int receive_length_data(urg_t *urg, long length[], + } + } + +- // f[^̊i[ ++ // 距離データの格納 + if (length) { + length[index] = urg_scip_decode(p, 3); + } + p += 3; + +- // xf[^̊i[ ++ // 強度データの格納 + if (is_intensity) { + if (intensity) { + intensity[index] = (unsigned short)urg_scip_decode(p, 3); +@@ -556,7 +556,7 @@ static int receive_length_data(urg_t *urg, long length[], + line_filled -= data_size; + } + +- // ɏ镶ޔ ++ // 次に処理する文字を退避 + memmove(buffer, p, line_filled); + } while (n > 0); + +@@ -564,7 +564,7 @@ static int receive_length_data(urg_t *urg, long length[], + } + + +-//! f[^̎擾 ++//! 距離データの取得 + static int receive_data(urg_t *urg, long data[], unsigned short intensity[], + long *time_stamp, unsigned long long *system_time_stamp) + { +@@ -575,16 +575,16 @@ static int receive_data(urg_t *urg, long data[], unsigned short intensity[], + int extended_timeout = urg->timeout + + 2 * (urg->scan_usec * (urg->scanning_skip_scan) / 1000); + +- // GR[obN̎擾 ++ // エコーバックの取得 + n = connection_readline(&urg->connection, + buffer, BUFFER_SIZE, extended_timeout); + if (n <= 0) { + return set_errno_and_return(urg, URG_NO_RESPONSE); + } +- // GR[obN̉ ++ // エコーバックの解析 + type = parse_distance_echoback(urg, buffer); + +- // ̎擾 ++ // 応答の取得 + n = connection_readline(&urg->connection, + buffer, BUFFER_SIZE, urg->timeout); + if (n != 3) { +@@ -593,13 +593,13 @@ static int receive_data(urg_t *urg, long data[], unsigned short intensity[], + } + + if (buffer[n - 1] != scip_checksum(buffer, n - 1)) { +- // `FbNT̕] ++ // チェックサムの評価 + ignore_receive_data_with_qt(urg, urg->timeout); + return set_errno_and_return(urg, URG_CHECKSUM_ERROR); + } + + if (type == URG_STOP) { +- // QT ̏ꍇɂ́AŌ̉sǂݎ̂āA퉞Ƃď ++ // QT 応答の場合には、最後の改行を読み捨て、正常応答として処理する + n = connection_readline(&urg->connection, + buffer, BUFFER_SIZE, urg->timeout); + if (n == 0) { +@@ -611,8 +611,8 @@ static int receive_data(urg_t *urg, long data[], unsigned short intensity[], + + if (urg->specified_scan_times != 1) { + if (!strncmp(buffer, "00", 2)) { +- // "00" ̏ꍇ́AGR[obNƂ݂ȂA +- // Ō̋sǂݎ̂āÃf[^Ԃ ++ // "00" 応答の場合は、エコーバック応答とみなし、 ++ // 最後の空行を読み捨て、次からのデータを返す + n = connection_readline(&urg->connection, + buffer, BUFFER_SIZE, urg->timeout); + +@@ -632,14 +632,14 @@ static int receive_data(urg_t *urg, long data[], unsigned short intensity[], + } + + if (type == URG_UNKNOWN) { +- // Gx, Hx ̂Ƃ 00P ԂꂽƂf[^ +- // Mx, Nx ̂Ƃ 99b ԂꂽƂf[^ ++ // Gx, Hx のときは 00P が返されたときがデータ ++ // Mx, Nx のときは 99b が返されたときがデータ + ignore_receive_data_with_qt(urg, urg->timeout); + return set_errno_and_return(urg, URG_INVALID_RESPONSE); + } + } + +- // ^CX^v̎擾 ++ // タイムスタンプの取得 + n = connection_readline(&urg->connection, + buffer, BUFFER_SIZE, urg->timeout); + if (n > 0) { +@@ -651,7 +651,7 @@ static int receive_data(urg_t *urg, long data[], unsigned short intensity[], + } + } + +- // f[^̎擾 ++ // データの取得 + switch (type) { + case URG_DISTANCE: + case URG_MULTIECHO: +@@ -669,11 +669,11 @@ static int receive_data(urg_t *urg, long data[], unsigned short intensity[], + break; + } + +- // specified_scan_times == 1 ̂Ƃ Gx nR}hg邽 +- // f[^𖾎Iɒ~ȂĂ悢 ++ // specified_scan_times == 1 のときは Gx 系コマンドが使われるため ++ // データを明示的に停止しなくてよい + if ((urg->specified_scan_times > 1) && (urg->scanning_remain_times > 0)) { + if (--urg->scanning_remain_times <= 0) { +- // f[^̒~݂̂s ++ // データの停止のみを行う + urg_stop_measurement(urg); + } + } +@@ -694,7 +694,7 @@ int urg_open(urg_t *urg, urg_connection_type_t connection_type, + urg->scanning_skip_scan = 0; + urg->error_handler = NULL; + +- // foCXւ̐ڑ ++ // デバイスへの接続 + ret = connection_open(&urg->connection, connection_type, + device_or_address, baudrate_or_port); + +@@ -715,9 +715,9 @@ int urg_open(urg_t *urg, urg_connection_type_t connection_type, + return urg->last_errno; + } + +- // w肵{[[g URG ƒʐMł悤ɒ ++ // 指定したボーレートで URG と通信できるように調整 + if (connection_type == URG_ETHERNET) { +- // Ethernet ̂Ƃ͉̒ʐMxw肵Ă ++ // Ethernet のときは仮の通信速度を指定しておく + baudrate = 115200; + } + +@@ -726,14 +726,14 @@ int urg_open(urg_t *urg, urg_connection_type_t connection_type, + } + urg->is_sending = URG_FALSE; + +- // ϐ̏ ++ // 変数の初期化 + urg->last_errno = URG_NO_ERROR; + urg->range_data_byte = URG_COMMUNICATION_3_BYTE; + urg->specified_scan_times = 0; + urg->scanning_remain_times = 0; + urg->is_laser_on = URG_FALSE; + +- // p[^擾 ++ // パラメータ情報を取得 + ret = receive_parameter(urg); + if (ret == URG_NO_ERROR) { + urg->is_active = URG_TRUE; +@@ -767,8 +767,8 @@ int urg_start_time_stamp_mode(urg_t *urg) + return set_errno_and_return(urg, URG_NOT_CONNECTED); + } + +- // TM0 𔭍s +- n = scip_response(urg, "TM0\n", expected, urg->timeout, NULL, 0); ++ // TM0 を発行する ++ n = scip_response(urg, "TM0¥n", expected, urg->timeout, NULL, 0); + if (n <= 0) { + return set_errno_and_return(urg, URG_INVALID_RESPONSE); + } else { +@@ -788,15 +788,15 @@ long urg_time_stamp(urg_t *urg) + return set_errno_and_return(urg, URG_NOT_CONNECTED); + } + +- ret = scip_response(urg, "TM1\n", expected, ++ ret = scip_response(urg, "TM1¥n", expected, + urg->timeout, buffer, BUFFER_SIZE); + if (ret < 0) { + return ret; + } + +- // buffer ^CX^v擾AfR[hĕԂ ++ // buffer からタイムスタンプを取得し、デコードして返す + if (strcmp(buffer, "00P")) { +- // ŏ̉ "00P" łȂΖ߂ ++ // 最初の応答が "00P" でなければ戻る + return set_errno_and_return(urg, URG_RECEIVE_ERROR); + } + p = buffer + 4; +@@ -819,8 +819,8 @@ int urg_stop_time_stamp_mode(urg_t *urg) + return set_errno_and_return(urg, URG_NOT_CONNECTED); + } + +- // TM2 𔭍s +- n = scip_response(urg, "TM2\n", expected, urg->timeout, NULL, 0); ++ // TM2 を発行する ++ n = scip_response(urg, "TM2¥n", expected, urg->timeout, NULL, 0); + if (n <= 0) { + return set_errno_and_return(urg, URG_INVALID_RESPONSE); + } else { +@@ -842,21 +842,21 @@ static int send_distance_command(urg_t *urg, int scan_times, int skip_scan, + urg->scanning_remain_times = urg->specified_scan_times; + urg->scanning_skip_scan = (skip_scan < 0) ? 0 : skip_scan; + if (scan_times >= 100) { +- // v񐔂 99 zꍇ́ÃXLs ++ // 計測回数が 99 を越える場合は、無限回のスキャンを行う + urg->specified_scan_times = 0; + } + + if (urg->scanning_remain_times == 1) { +- // [Uw ++ // レーザ発光を指示 + urg_laser_on(urg); + +- write_size = snprintf(buffer, BUFFER_SIZE, "%c%c%04d%04d%02d\n", ++ write_size = snprintf(buffer, BUFFER_SIZE, "%c%c%04d%04d%02d¥n", + single_scan_ch, scan_type_ch, + urg->scanning_first_step + front_index, + urg->scanning_last_step + front_index, + urg->scanning_skip_step); + } else { +- write_size = snprintf(buffer, BUFFER_SIZE, "%c%c%04d%04d%02d%01d%02d\n", ++ write_size = snprintf(buffer, BUFFER_SIZE, "%c%c%04d%04d%02d%01d%02d¥n", + continuous_scan_ch, scan_type_ch, + urg->scanning_first_step + front_index, + urg->scanning_last_step + front_index, +@@ -889,12 +889,12 @@ int urg_start_measurement(urg_t *urg, urg_measurement_type_t type, + return set_errno_and_return(urg, URG_INVALID_PARAMETER); + } + +- // !!! Mx n, Nx ňv̂Ƃ́AQT 𔭍sĂ +- // !!! vJnR}h𑗐M悤ɂ +- // !!! AMD v MD 𔭍s悤ɁAR}h̏ꍇ +- // !!! Mx n, Nx ňv͏㏑邱Ƃł悤ɂ ++ // !!! Mx 系, Nx 系の計測中のときは、QT を発行してから ++ // !!! 計測開始コマンドを送信するようにする ++ // !!! ただし、MD 計測中に MD を発行するように、同じコマンドの場合は ++ // !!! Mx 系, Nx 系の計測は上書きすることができるようにする + +- // w肳ꂽ^CṽpPbg𐶐AM ++ // 指定されたタイプのパケットを生成し、送信する + switch (type) { + case URG_DISTANCE: + range_byte_ch = +@@ -986,17 +986,17 @@ int urg_stop_measurement(urg_t *urg) + return set_errno_and_return(urg, URG_NOT_CONNECTED); + } + +- // QT 𔭍s +- n = connection_write(&urg->connection, "QT\n", 3); ++ // QT を発行する ++ n = connection_write(&urg->connection, "QT¥n", 3); + if (n != 3) { + return set_errno_and_return(urg, URG_SEND_ERROR); + } + + for (i = 0; i < MAX_READ_TIMES; ++i) { +- // QT ̉Ԃ܂ŁAf[^ǂݎ̂Ă ++ // QT の応答が返されるまで、距離データを読み捨てる + ret = receive_data(urg, NULL, NULL, NULL, NULL); + if (ret == URG_NO_ERROR) { +- // 퉞 ++ // 正常応答 + urg->is_laser_on = URG_FALSE; + urg->is_sending = URG_FALSE; + return set_errno_and_return(urg, URG_NO_ERROR); +@@ -1009,7 +1009,7 @@ int urg_stop_measurement(urg_t *urg) + int urg_set_scanning_parameter(urg_t *urg, int first_step, int last_step, + int skip_step) + { +- // ݒ͈̔͊Ow肵Ƃ́AG[Ԃ ++ // 設定の範囲外を指定したときは、エラーを返す + if (((skip_step < 0) || (skip_step >= 100)) || + (first_step > last_step) || + (first_step < -urg->front_data_index) || +@@ -1053,12 +1053,12 @@ int urg_laser_on(urg_t *urg) + } + + if (urg->is_laser_on != URG_FALSE) { +- // Ƀ[UĂƂ́AR}h𑗐MȂ悤ɂ ++ // 既にレーザが発光しているときは、コマンドを送信しないようにする + urg->last_errno = 0; + return urg->last_errno; + } + +- ret = scip_response(urg, "BM\n", expected, urg->timeout, NULL, 0); ++ ret = scip_response(urg, "BM¥n", expected, urg->timeout, NULL, 0); + if (ret >= 0) { + urg->is_laser_on = URG_TRUE; + ret = 0; +@@ -1083,9 +1083,9 @@ int urg_reboot(urg_t *urg) + return set_errno_and_return(urg, URG_NOT_CONNECTED); + } + +- // Qڂ RB MAڑؒf ++ // 2回目の RB 送信後、接続を切断する + for (i = 0; i < 2; ++i) { +- ret = scip_response(urg, "RB\n", expected, urg->timeout, NULL, 0); ++ ret = scip_response(urg, "RB¥n", expected, urg->timeout, NULL, 0); + if (ret < 0) { + return set_errno_and_return(urg, URG_INVALID_RESPONSE); + } +@@ -1108,7 +1108,7 @@ void urg_sleep(urg_t *urg) + return; + } + +- scip_response(urg, "%SL\n", sl_expected, MAX_TIMEOUT, ++ scip_response(urg, "%SL¥n", sl_expected, MAX_TIMEOUT, + receive_buffer, RECEIVE_BUFFER_SIZE); + } + +@@ -1142,7 +1142,7 @@ static char *copy_token(char *dest, char *receive_buffer, + + char *last_p = strchr(p + start_str_len, end_ch[j]); + if (last_p) { +- *last_p = '\0'; ++ *last_p = '¥0'; + memcpy(dest, p + start_str_len, + last_p - (p + start_str_len) + 1); + return dest; +@@ -1187,7 +1187,7 @@ const char *urg_sensor_product_type(urg_t *urg) + char *p; + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "VV\n", VV_RESPONSE_LINES); ++ "VV¥n", VV_RESPONSE_LINES); + if (ret) { + return ret; + } +@@ -1208,7 +1208,7 @@ const char *urg_sensor_serial_id(urg_t *urg) + char *p; + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "VV\n", VV_RESPONSE_LINES); ++ "VV¥n", VV_RESPONSE_LINES); + if (ret) { + return ret; + } +@@ -1231,7 +1231,7 @@ const char *urg_sensor_vendor(urg_t *urg){ + } + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "VV\n", VV_RESPONSE_LINES); ++ "VV¥n", VV_RESPONSE_LINES); + if (ret) { + return ret; + } +@@ -1255,7 +1255,7 @@ const char *urg_sensor_firmware_version(urg_t *urg) + } + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "VV\n", VV_RESPONSE_LINES); ++ "VV¥n", VV_RESPONSE_LINES); + if (ret) { + return ret; + } +@@ -1284,7 +1284,7 @@ const char *urg_sensor_firmware_date(urg_t *urg) + strcat(firmware_version, "("); + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "VV\n", VV_RESPONSE_LINES); ++ "VV¥n", VV_RESPONSE_LINES); + if (ret) { + return ret; + } +@@ -1311,7 +1311,7 @@ const char *urg_sensor_protocol_version(urg_t *urg) + } + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "VV\n", VV_RESPONSE_LINES); ++ "VV¥n", VV_RESPONSE_LINES); + if (ret) { + return ret; + } +@@ -1336,7 +1336,7 @@ const char *urg_sensor_status(urg_t *urg) + } + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "II\n", II_RESPONSE_LINES); ++ "II¥n", II_RESPONSE_LINES); + if (ret) { + return ret; + } +@@ -1361,7 +1361,7 @@ const char *urg_sensor_state(urg_t *urg) + } + + ret = receive_command_response(urg, receive_buffer, RECEIVE_BUFFER_SIZE, +- "II\n", II_RESPONSE_LINES); ++ "II¥n", II_RESPONSE_LINES); + if (ret) { + return ret; + } +diff --git a/current/src/urg_serial.c b/current/src/urg_serial.c +index 68a24c3..7d7158d 100644 +--- a/current/src/urg_serial.c ++++ b/current/src/urg_serial.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief VAʐM ++ ¥file ++ ¥brief シリアル通信 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_serial.c,v 0caa22c18f6b 2010/12/30 03:36:32 Satofumi $ + */ +@@ -23,10 +23,10 @@ enum { + #endif + + +-// sǂ̔ ++// 改行かどうかの判定 + static int is_linefeed(const char ch) + { +- return ((ch == '\r') || (ch == '\n')) ? 1 : 0; ++ return ((ch == '¥r') || (ch == '¥n')) ? 1 : 0; + } + + +@@ -39,7 +39,7 @@ static void serial_ungetc(urg_serial_t *serial, char ch) + + int serial_readline(urg_serial_t *serial, char *data, int max_size, int timeout) + { +- /* P“ǂݏoĕ] */ ++ /* 1文字ずつ読み出して評価する */ + int filled = 0; + int is_timeout = 0; + +@@ -58,12 +58,12 @@ int serial_readline(urg_serial_t *serial, char *data, int max_size, int timeout) + --filled; + serial_ungetc(serial, data[filled]); + } +- data[filled] = '\0'; ++ data[filled] = '¥0'; + + if ((filled == 0) && is_timeout) { + return -1; + } else { +- //fprintf(stderr, "%s\n", data); ++ //fprintf(stderr, "%s¥n", data); + return filled; + } + } +diff --git a/current/src/urg_serial_linux.c b/current/src/urg_serial_linux.c +index ff8e75d..d928a6c 100644 +--- a/current/src/urg_serial_linux.c ++++ b/current/src/urg_serial_linux.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief VAʐM ++ ¥file ++ ¥brief シリアル通信 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +@@ -43,36 +43,36 @@ int serial_open(urg_serial_t *serial, const char *device, long baudrate) + serial_initialize(serial); + + #ifndef URG_MAC_OS +- enum { O_EXLOCK = 0x0 }; /* Linux ł͎gȂ̂Ń_~[쐬Ă */ ++ enum { O_EXLOCK = 0x0 }; /* Linux では使えないのでダミーを作成しておく */ + #endif + serial->fd = open(device, O_RDWR | O_EXLOCK | O_NONBLOCK | O_NOCTTY); + if (serial->fd < 0) { +- /* ڑɎs */ ++ /* 接続に失敗 */ + //strerror_r(errno, serial->error_string, ERROR_MESSAGE_SIZE); + return -1; + } + + flags = fcntl(serial->fd, F_GETFL, 0); +- fcntl(serial->fd, F_SETFL, flags & ~O_NONBLOCK); ++ fcntl(serial->fd, F_SETFL, flags & ‾O_NONBLOCK); + +- /* VAʐM̏ */ ++ /* シリアル通信の初期化 */ + tcgetattr(serial->fd, &serial->sio); + serial->sio.c_iflag = 0; + serial->sio.c_oflag = 0; +- serial->sio.c_cflag &= ~(CSIZE | PARENB | CSTOPB); ++ serial->sio.c_cflag &= ‾(CSIZE | PARENB | CSTOPB); + serial->sio.c_cflag |= CS8 | CREAD | CLOCAL; +- serial->sio.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN); ++ serial->sio.c_lflag &= ‾(ICANON | ECHO | ISIG | IEXTEN); + + serial->sio.c_cc[VMIN] = 0; + serial->sio.c_cc[VTIME] = 0; + +- /* {[[g̕ύX */ ++ /* ボーレートの変更 */ + ret = serial_set_baudrate(serial, baudrate); + if (ret < 0) { + return ret; + } + +- /* VA\̂̏ */ ++ /* シリアル制御構造体の初期化 */ + serial->has_last_ch = False; + + return 0; +@@ -121,7 +121,7 @@ int serial_set_baudrate(urg_serial_t *serial, long baudrate) + return -1; + } + +- /* {[[gύX */ ++ /* ボーレート変更 */ + cfsetospeed(&serial->sio, baudrate_value); + cfsetispeed(&serial->sio, baudrate_value); + tcsetattr(serial->fd, TCSADRAIN, &serial->sio); +@@ -145,7 +145,7 @@ static int wait_receive(urg_serial_t* serial, int timeout) + fd_set rfds; + struct timeval tv; + +- // ^CAEgݒ ++ // タイムアウト設定 + FD_ZERO(&rfds); + FD_SET(serial->fd, &rfds); + +@@ -154,7 +154,7 @@ static int wait_receive(urg_serial_t* serial, int timeout) + + if (select(serial->fd + 1, &rfds, NULL, NULL, + (timeout < 0) ? NULL : &tv) <= 0) { +- /* ^CAEg */ ++ /* タイムアウト発生 */ + return 0; + } + return 1; +@@ -181,7 +181,7 @@ static int internal_receive(char data[], int data_size_max, + require_n = data_size_max - filled; + read_n = read(serial->fd, &data[filled], require_n); + if (read_n <= 0) { +- /* ǂݏoG[B݂܂ł̎MeŖ߂ */ ++ /* 読み出しエラー。現在までの受信内容で戻る */ + break; + } + filled += read_n; +@@ -200,7 +200,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + return 0; + } + +- /* ߂P΁Ao */ ++ /* 書き戻した1文字があれば、書き出す */ + if (serial->has_last_ch != False) { + data[0] = serial->last_ch; + serial->has_last_ch = False; +@@ -217,7 +217,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + buffer_size = ring_size(&serial->ring); + read_n = max_size - filled; + if (buffer_size < read_n) { +- // Oobt@̃f[^őȂ΁Af[^ǂݑ ++ // リングバッファ内のデータで足りなければ、データを読み足す + char buffer[RING_BUFFER_SIZE]; + int n = internal_receive(buffer, + ring_capacity(&serial->ring) - buffer_size, +@@ -228,7 +228,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + } + } + +- // Oobt@̃f[^Ԃ ++ // リングバッファ内のデータを返す + if (read_n > buffer_size) { + read_n = buffer_size; + } +@@ -237,7 +237,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + filled += read_n; + } + +- // f[^^CAEgtœǂݏo ++ // データをタイムアウト付きで読み出す + filled += internal_receive(&data[filled], max_size - filled, + serial, timeout); + return filled; +diff --git a/current/src/urg_serial_utils.c b/current/src/urg_serial_utils.c +index 42c534a..73fe946 100644 +--- a/current/src/urg_serial_utils.c ++++ b/current/src/urg_serial_utils.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief VAp̕⏕֐ ++ ¥file ++ ¥brief シリアル用の補助関数 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +diff --git a/current/src/urg_serial_utils_linux.c b/current/src/urg_serial_utils_linux.c +index 509c069..2e48531 100644 +--- a/current/src/urg_serial_utils_linux.c ++++ b/current/src/urg_serial_utils_linux.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief VAp̕⏕֐ ++ ¥file ++ ¥brief シリアル用の補助関数 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_serial_utils_linux.c,v 0caa22c18f6b 2010/12/30 03:36:32 Satofumi $ + */ +@@ -84,8 +84,8 @@ const char *urg_serial_port_name(int index) + + int urg_serial_is_urg_port(int index) + { +- // Linux ̏ꍇA|[g URG ǂ͒fłȂ +- // !!! ]͂΁Admesg Ȃǂ̏o͂画肷悤ɂĂ悢 ++ // Linux の場合、ポートが URG かどうかは断定できない ++ // !!! 余力があれば、dmesg などの出力から判定するようにしてもよい + (void)index; + return 0; + } +diff --git a/current/src/urg_serial_utils_windows.c b/current/src/urg_serial_utils_windows.c +index fa68e9b..fe10a20 100644 +--- a/current/src/urg_serial_utils_windows.c ++++ b/current/src/urg_serial_utils_windows.c +@@ -1,13 +1,13 @@ + /*! +- \file +- \brief VAp̕⏕֐ ++ ¥file ++ ¥brief シリアル用の補助関数 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_serial_utils_windows.c,v faa71b0113fd 2011/01/17 12:00:22 Satofumi $ + +- \todo ϐ '_' ؂̌`ɕύX +- \todo C90 œ삷悤ɒBA"//" Rg͎g ++ ¥todo 変数名を '_' 区切りの形式に変更する ++ ¥todo C90 相当で動作するように調整する。ただし、"//" コメントは使う + */ + + #include "urg_c/urg_serial_utils.h" +@@ -74,7 +74,7 @@ static void sort_ports(void) + + int urg_serial_find_port(void) + { +- // foCX}l[Ẅꗗ COM foCXT ++ // デバイスマネージャの一覧から COM デバイスを探す + + //4D36E978-E325-11CE-BFC1-08002BE10318 + GUID GUID_DEVINTERFACE_COM_DEVICE = { +@@ -108,24 +108,24 @@ int urg_serial_find_port(void) + int n; + int j; + +- // th[l[擾 COM ԍo ++ // フレンドリーネームを取得して COM 番号を取り出す + SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_FRIENDLYNAME, + &dwRegType, (BYTE*)buffer, BufferSize, + &dwSize); + n = (int)strlen(buffer); + if (n < ComNameLengthMax) { +- // COM Z߂ꍇAȂ +- // 肪ꍇ́AC ++ // COM 名が短過ぎた場合、処理しない ++ // 問題がある場合は、修正する + continue; + } + +- // (COMx) ̍Ō̊ʂ̈ʒu '\0' ++ // (COMx) の最後の括弧の位置に '¥0' を代入する + p = strrchr(buffer, ')'); + if (p) { +- *p = '\0'; ++ *p = '¥0'; + } + +- // COM Ɣԍ܂ł̕𔲂o ++ // COM と番号までの文字列を抜き出す + p = strstr(&buffer[n - ComNameLengthMax], "COM"); + if (! p) { + continue; +@@ -133,7 +133,7 @@ int urg_serial_find_port(void) + + snprintf(found_ports[found_ports_size], DEVICE_NAME_SIZE, "%s", p); + +- // foCX擾AURG |[g̔ɗp ++ // デバイス名を取得し、URG ポートかの判定に用いる + SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_DEVICEDESC, + &dwRegType, (BYTE*)buffer, BufferSize, + &dwSize); +@@ -150,7 +150,7 @@ int urg_serial_find_port(void) + } + SetupDiDestroyDeviceInfoList(hdi); + +- // is_urg_port ̗vf擪ɗ悤Ƀ\[g ++ // is_urg_port の要素が先頭に来るようにソートする + sort_ports(); + + return found_ports_size; +diff --git a/current/src/urg_serial_windows.c b/current/src/urg_serial_windows.c +index c10a279..6a42b7c 100644 +--- a/current/src/urg_serial_windows.c ++++ b/current/src/urg_serial_windows.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief VAʐM ++ ¥file ++ ¥brief シリアル通信 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id$ + */ +@@ -39,34 +39,34 @@ static void set_timeout(urg_serial_t *serial, int timeout) + + int serial_open(urg_serial_t *serial, const char *device, long baudrate) + { +- // COM10 ȍ~ւ̑Ήp ++ // COM10 以降への対応用 + enum { NameLength = 11 }; + char adjusted_device[NameLength]; + + serial_initialize(serial); + +- /* COM |[gJ */ +- _snprintf(adjusted_device, NameLength, "\\\\.\\%s", device); ++ /* COM ポートを開く */ ++ _snprintf(adjusted_device, NameLength, "¥¥¥¥.¥¥%s", device); + serial->hCom = CreateFileA(adjusted_device, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (serial->hCom == INVALID_HANDLE_VALUE) { + // !!! store error_message buffer +- //printf("open failed: %s\n", device); ++ //printf("open failed: %s¥n", device); + return -1; + } + +- /* ʐMTCY̍XV */ ++ /* 通信サイズの更新 */ + SetupComm(serial->hCom, 4096 * 8, 4096); + +- /* {[[g̕ύX */ ++ /* ボーレートの変更 */ + serial_set_baudrate(serial, baudrate); + +- /* VA\̂̏ */ ++ /* シリアル制御構造体の初期化 */ + serial->has_last_ch = False; + +- /* ^CAEg̐ݒ */ ++ /* タイムアウトの設定 */ + serial->current_timeout = 0; + set_timeout(serial, serial->current_timeout); + +@@ -174,7 +174,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + return 0; + } + +- /* ߂P΁Ao */ ++ /* 書き戻した1文字があれば、書き出す */ + if (serial->has_last_ch) { + data[0] = serial->last_ch; + serial->has_last_ch = False; +@@ -191,7 +191,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + buffer_size = ring_size(&serial->ring); + read_n = max_size - filled; + if (buffer_size < read_n) { +- // Oobt@̃f[^őȂ΁Af[^ǂݑ ++ // リングバッファ内のデータで足りなければ、データを読み足す + char buffer[RING_BUFFER_SIZE]; + int n = internal_receive(buffer, + ring_capacity(&serial->ring) - buffer_size, +@@ -200,7 +200,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + } + buffer_size = ring_size(&serial->ring); + +- // Oobt@̃f[^Ԃ ++ // リングバッファ内のデータを返す + if (read_n > buffer_size) { + read_n = buffer_size; + } +@@ -209,7 +209,7 @@ int serial_read(urg_serial_t *serial, char *data, int max_size, int timeout) + filled += read_n; + } + +- // f[^^CAEgtœǂݏo ++ // データをタイムアウト付きで読み出す + filled += internal_receive(&data[filled], + max_size - filled, serial, timeout); + return filled; +diff --git a/current/src/urg_tcpclient.c b/current/src/urg_tcpclient.c +index 3abc934..24b592a 100644 +--- a/current/src/urg_tcpclient.c ++++ b/current/src/urg_tcpclient.c +@@ -1,8 +1,8 @@ + /*! +- \file +- \brief TCP/IP read/write functions ++ ¥file ++ ¥brief TCP/IP read/write functions + +- \author Katsumi Kimoto ++ ¥author Katsumi Kimoto + + $Id: urg_tcpclient.c,v d746d6f9127d 2011/05/08 23:10:44 satofumi $ + */ +@@ -118,7 +118,7 @@ int tcpclient_open(urg_tcpclient_t* cli, const char* ip_str, int port_num) + } + + #if defined(URG_WINDOWS_OS) +- //mubNɕύX ++ //ノンブロックに変更 + flag = 1; + ioctlsocket(cli->sock_desc, FIONBIO, &flag); + +@@ -136,16 +136,16 @@ int tcpclient_open(urg_tcpclient_t* cli, const char* ip_str, int port_num) + + ret = select((int)cli->sock_desc + 1, &rmask, &wmask, NULL, &tv); + if (ret == 0) { +- // ^CAEg ++ // タイムアウト + tcpclient_close(cli); + return -2; + } + } +- //ubN[hɂ ++ //ブロックモードにする + set_block_mode(cli); + + #else +- //mubNɕύX ++ //ノンブロックに変更 + flag = fcntl(cli->sock_desc, F_GETFL, 0); + fcntl(cli->sock_desc, F_SETFL, flag | O_NONBLOCK); + +@@ -156,27 +156,27 @@ int tcpclient_open(urg_tcpclient_t* cli, const char* ip_str, int port_num) + return -1; + } + +- // EINPROGRESS:RlNVv͎n܂A܂ĂȂ ++ // EINPROGRESS:コネクション要求は始まったが、まだ完了していない + FD_ZERO(&rmask); + FD_SET(cli->sock_desc, &rmask); + wmask = rmask; + + ret = select(cli->sock_desc + 1, &rmask, &wmask, NULL, &tv); + if (ret <= 0) { +- // ^CAEg ++ // タイムアウト処理 + tcpclient_close(cli); + return -2; + } + + if (getsockopt(cli->sock_desc, SOL_SOCKET, SO_ERROR, (int*)&sock_optval, + (socklen_t*)&sock_optval_size) != 0) { +- // ڑɎs ++ // 接続に失敗 + tcpclient_close(cli); + return -3; + } + + if (sock_optval != 0) { +- // ڑɎs ++ // 接続に失敗 + tcpclient_close(cli); + return -4; + } +@@ -306,7 +306,7 @@ int tcpclient_readline(urg_tcpclient_t* cli, + if (n <= 0) { + break; // error + } +- if (ch == '\n' || ch == '\r') { ++ if (ch == '¥n' || ch == '¥r') { + break; // success + } + userbuf[i] = ch; +@@ -315,9 +315,9 @@ int tcpclient_readline(urg_tcpclient_t* cli, + if (i >= buf_size) { // No CR or LF found. + --i; + cli->pushed_back = userbuf[buf_size - 1] & 0xff; +- userbuf[buf_size - 1] = '\0'; ++ userbuf[buf_size - 1] = '¥0'; + } +- userbuf[i] = '\0'; ++ userbuf[i] = '¥0'; + + if (i == 0 && n <= 0) { // error + return -1; +diff --git a/current/src/urg_utils.c b/current/src/urg_utils.c +index 2a272d1..ea9108c 100644 +--- a/current/src/urg_utils.c ++++ b/current/src/urg_utils.c +@@ -1,7 +1,7 @@ + /*! +- \brief URG ZTp̕⏕֐ ++ ¥brief URG センサ用の補助関数 + +- \author Satofumi KAMIMURA ++ ¥author Satofumi KAMIMURA + + $Id: urg_utils.c,v da778fd816c2 2011/01/05 20:02:06 Satofumi $ + */ +@@ -81,7 +81,7 @@ void urg_distance_min_max(const urg_t *urg, + + *min_distance = urg->min_distance; + +- // urg_set_communication_data_size() 𔽉fԂ ++ // urg_set_communication_data_size() を反映した距離を返す + *max_distance = + (urg->range_data_byte == URG_COMMUNICATION_2_BYTE) ? + max(urg->max_distance, 4095) : urg->max_distance; diff --git a/patch/ros-rolling-urg-node.patch b/patch/ros-rolling-urg-node.patch new file mode 100644 index 000000000..07b9d018c --- /dev/null +++ b/patch/ros-rolling-urg-node.patch @@ -0,0 +1,13 @@ +diff --git a/src/urg_c_wrapper.cpp b/src/urg_c_wrapper.cpp +index 10d2ed3..6d7499d 100644 +--- a/src/urg_c_wrapper.cpp ++++ b/src/urg_c_wrapper.cpp +@@ -33,6 +33,8 @@ + + #include + ++#include ++ + #include + #include + #include diff --git a/patch/ros-rolling-vision-msgs-rviz-plugins.patch b/patch/ros-rolling-vision-msgs-rviz-plugins.patch new file mode 100644 index 000000000..b14e4bf03 --- /dev/null +++ b/patch/ros-rolling-vision-msgs-rviz-plugins.patch @@ -0,0 +1,175 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d1ac767..c7c2a5f 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -16,7 +16,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + endif() + + # find dependencies +-find_package(Qt5 REQUIRED COMPONENTS Widgets Core) ++find_package(Qt6 REQUIRED COMPONENTS Widgets Core) + find_package(yaml_cpp_vendor REQUIRED) + + find_package(ament_cmake REQUIRED) +@@ -45,7 +45,7 @@ set(vision_msgs_rviz_plugins_headers_to_moc + ) + + foreach(header "${vision_msgs_rviz_plugins_headers_to_moc}") +- qt5_wrap_cpp(vision_msgs_rviz_plugins_moc_files "${header}") ++ qt6_wrap_cpp(vision_msgs_rviz_plugins_moc_files "${header}") + endforeach() + + +@@ -67,13 +67,15 @@ add_library(${PROJECT_NAME} SHARED + target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ +- ${Qt5Widgets_INCLUDE_DIRS} + ) + + target_link_libraries(${PROJECT_NAME} PUBLIC + rviz_ogre_vendor::OgreMain + rviz_ogre_vendor::OgreOverlay + rviz_common::rviz_common ++ rviz_default_plugins::rviz_default_plugins ++ Qt6::Core ++ Qt6::Widgets + ) + + +diff --git a/include/vision_msgs_rviz_plugins/bounding_box_3d.hpp b/include/vision_msgs_rviz_plugins/bounding_box_3d.hpp +index ef60eea..27cc3fb 100644 +--- a/include/vision_msgs_rviz_plugins/bounding_box_3d.hpp ++++ b/include/vision_msgs_rviz_plugins/bounding_box_3d.hpp +@@ -16,6 +16,7 @@ + #define VISION_MSGS_RVIZ_PLUGINS__BOUNDING_BOX_3D_HPP_ + + #include ++#include + #include + #include + #include +@@ -52,7 +53,7 @@ public: + BOUNDING_BOX_3D_DISPLAY_HPP_PUBLIC + void load(const rviz_common::Config & config) override; + BOUNDING_BOX_3D_DISPLAY_HPP_PUBLIC +- void update(float wall_dt, float ros_dt) override; ++ void update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) override; + BOUNDING_BOX_3D_DISPLAY_HPP_PUBLIC + void reset() override; + +diff --git a/include/vision_msgs_rviz_plugins/bounding_box_3d_array.hpp b/include/vision_msgs_rviz_plugins/bounding_box_3d_array.hpp +index cd2b84c..5c5ffd0 100644 +--- a/include/vision_msgs_rviz_plugins/bounding_box_3d_array.hpp ++++ b/include/vision_msgs_rviz_plugins/bounding_box_3d_array.hpp +@@ -16,6 +16,7 @@ + #define VISION_MSGS_RVIZ_PLUGINS__BOUNDING_BOX_3D_ARRAY_HPP_ + + #include ++#include + #include + #include + #include +@@ -54,7 +55,7 @@ public: + BOUNDING_BOX_3D_ARRAY_DISPLAY_HPP_PUBLIC + void load(const rviz_common::Config & config) override; + BOUNDING_BOX_3D_ARRAY_DISPLAY_HPP_PUBLIC +- void update(float wall_dt, float ros_dt) override; ++ void update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) override; + BOUNDING_BOX_3D_ARRAY_DISPLAY_HPP_PUBLIC + void reset() override; + +diff --git a/include/vision_msgs_rviz_plugins/detection_3d.hpp b/include/vision_msgs_rviz_plugins/detection_3d.hpp +index bc6ad9b..0975e09 100644 +--- a/include/vision_msgs_rviz_plugins/detection_3d.hpp ++++ b/include/vision_msgs_rviz_plugins/detection_3d.hpp +@@ -16,6 +16,7 @@ + #define VISION_MSGS_RVIZ_PLUGINS__DETECTION_3D_HPP_ + + #include ++#include + #include + #include + #include +@@ -53,7 +54,7 @@ public: + DETECTION_3D_DISPLAY_HPP_PUBLIC + void load(const rviz_common::Config & config) override; + DETECTION_3D_DISPLAY_HPP_PUBLIC +- void update(float wall_dt, float ros_dt) override; ++ void update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) override; + DETECTION_3D_DISPLAY_HPP_PUBLIC + void reset() override; + +diff --git a/include/vision_msgs_rviz_plugins/detection_3d_array.hpp b/include/vision_msgs_rviz_plugins/detection_3d_array.hpp +index d2b2b50..9ba0e8e 100644 +--- a/include/vision_msgs_rviz_plugins/detection_3d_array.hpp ++++ b/include/vision_msgs_rviz_plugins/detection_3d_array.hpp +@@ -16,6 +16,7 @@ + #define VISION_MSGS_RVIZ_PLUGINS__DETECTION_3D_ARRAY_HPP_ + + #include ++#include + #include + #include + #include +@@ -57,7 +58,7 @@ public: + DETECTION_3D_ARRAY_DISPLAY_HPP_PUBLIC + void load(const rviz_common::Config & config) override; + DETECTION_3D_ARRAY_DISPLAY_HPP_PUBLIC +- void update(float wall_dt, float ros_dt) override; ++ void update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) override; + DETECTION_3D_ARRAY_DISPLAY_HPP_PUBLIC + void reset() override; + +diff --git a/src/bounding_box_3d.cpp b/src/bounding_box_3d.cpp +index daf52a5..286bcec 100644 +--- a/src/bounding_box_3d.cpp ++++ b/src/bounding_box_3d.cpp +@@ -77,7 +77,7 @@ void BoundingBox3DDisplay::processMessage( + } + } + +-void BoundingBox3DDisplay::update(float wall_dt, float ros_dt) ++void BoundingBox3DDisplay::update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) + { + m_marker_common->update(wall_dt, ros_dt); + } +diff --git a/src/bounding_box_3d_array.cpp b/src/bounding_box_3d_array.cpp +index f03ea64..7920cbd 100644 +--- a/src/bounding_box_3d_array.cpp ++++ b/src/bounding_box_3d_array.cpp +@@ -77,7 +77,7 @@ void BoundingBox3DArrayDisplay::processMessage( + } + } + +-void BoundingBox3DArrayDisplay::update(float wall_dt, float ros_dt) ++void BoundingBox3DArrayDisplay::update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) + { + m_marker_common->update(wall_dt, ros_dt); + } +diff --git a/src/detection_3d.cpp b/src/detection_3d.cpp +index 69a6016..03d8ebb 100644 +--- a/src/detection_3d.cpp ++++ b/src/detection_3d.cpp +@@ -81,7 +81,7 @@ void Detection3DDisplay::processMessage( + } + } + +-void Detection3DDisplay::update(float wall_dt, float ros_dt) ++void Detection3DDisplay::update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) + { + m_marker_common->update(wall_dt, ros_dt); + } +diff --git a/src/detection_3d_array.cpp b/src/detection_3d_array.cpp +index b4c1cc5..7bdb041 100644 +--- a/src/detection_3d_array.cpp ++++ b/src/detection_3d_array.cpp +@@ -81,7 +81,7 @@ void Detection3DArrayDisplay::processMessage( + } + } + +-void Detection3DArrayDisplay::update(float wall_dt, float ros_dt) ++void Detection3DArrayDisplay::update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds ros_dt) + { + m_marker_common->update(wall_dt, ros_dt); + } diff --git a/patch/ros-rolling-web-video-server.patch b/patch/ros-rolling-web-video-server.patch new file mode 100644 index 000000000..0bfc28e26 --- /dev/null +++ b/patch/ros-rolling-web-video-server.patch @@ -0,0 +1,26 @@ +diff --git a/src/streamers/image_transport_streamer.cpp b/src/streamers/image_transport_streamer.cpp +index 5369276..b706528 100644 +--- a/src/streamers/image_transport_streamer.cpp ++++ b/src/streamers/image_transport_streamer.cpp +@@ -118,7 +118,7 @@ void ImageTransportStreamerBase::start() + return; + } + +- const image_transport::TransportHints hints(node.get(), default_transport_); ++ const image_transport::TransportHints hints(*node, default_transport_); + auto tnat = node->get_topic_names_and_types(); + inactive_ = true; + for (auto topic_and_types : tnat) { +@@ -148,9 +148,10 @@ void ImageTransportStreamerBase::start() + + // Create subscriber + image_sub_ = image_transport::create_subscription( +- node.get(), topic_, ++ *node, topic_, + std::bind(&ImageTransportStreamerBase::image_callback, this, std::placeholders::_1), +- default_transport_, qos_profile.value()); ++ default_transport_, ++ rclcpp::QoS(rclcpp::QoSInitialization(qos_profile.value().history, 1), qos_profile.value())); + } + + #pragma GCC diagnostic pop diff --git a/patch/ros-rolling-webots-ros2-control.patch b/patch/ros-rolling-webots-ros2-control.patch new file mode 100644 index 000000000..06f6149ec --- /dev/null +++ b/patch/ros-rolling-webots-ros2-control.patch @@ -0,0 +1,48 @@ +diff --git a/include/webots_ros2_control/Ros2ControlSystem.hpp b/include/webots_ros2_control/Ros2ControlSystem.hpp +index 1a938e2..917049f 100644 +--- a/include/webots_ros2_control/Ros2ControlSystem.hpp ++++ b/include/webots_ros2_control/Ros2ControlSystem.hpp +@@ -52,11 +52,12 @@ namespace webots_ros2_control { + Ros2ControlSystem(); + void init(webots_ros2_driver::WebotsNode *node, const hardware_interface::HardwareInfo &info) override; + +- rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_init( +- const hardware_interface::HardwareInfo &info) override; + #if HARDWARE_INTERFACE_VERSION_MAJOR > 5 || (HARDWARE_INTERFACE_VERSION_MAJOR == 5 && HARDWARE_INTERFACE_VERSION_MINOR >= 3) + rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_init( + const hardware_interface::HardwareComponentInterfaceParams ¶ms) override; ++#else ++ rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_init( ++ const hardware_interface::HardwareInfo &info) override; + #endif + rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_activate( + const rclcpp_lifecycle::State & /*previous_state*/) override; +diff --git a/src/Ros2ControlSystem.cpp b/src/Ros2ControlSystem.cpp +index df6c8c1..ba4b742 100644 +--- a/src/Ros2ControlSystem.cpp ++++ b/src/Ros2ControlSystem.cpp +@@ -90,18 +90,19 @@ namespace webots_ros2_control { + } + } + ++#if HARDWARE_INTERFACE_VERSION_MAJOR > 5 || (HARDWARE_INTERFACE_VERSION_MAJOR == 5 && HARDWARE_INTERFACE_VERSION_MINOR >= 3) + rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn Ros2ControlSystem::on_init( +- const hardware_interface::HardwareInfo &info) { +- if (hardware_interface::SystemInterface::on_init(info) != ++ const hardware_interface::HardwareComponentInterfaceParams ¶ms) { ++ if (hardware_interface::SystemInterface::on_init(params) != + rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS) { + return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR; + } + return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS; + } +-#if HARDWARE_INTERFACE_VERSION_MAJOR > 5 || (HARDWARE_INTERFACE_VERSION_MAJOR == 5 && HARDWARE_INTERFACE_VERSION_MINOR >= 3) ++#else + rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn Ros2ControlSystem::on_init( +- const hardware_interface::HardwareComponentInterfaceParams ¶ms) { +- if (hardware_interface::SystemInterface::on_init(params) != ++ const hardware_interface::HardwareInfo &info) { ++ if (hardware_interface::SystemInterface::on_init(info) != + rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS) { + return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR; + } diff --git a/patch/ros-rolling-webots-ros2-driver.patch b/patch/ros-rolling-webots-ros2-driver.patch new file mode 100644 index 000000000..8d0f7ed9e --- /dev/null +++ b/patch/ros-rolling-webots-ros2-driver.patch @@ -0,0 +1,30 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 1f913c1..52dbf3e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -32,17 +32,14 @@ find_package(tinyxml2_vendor REQUIRED) + find_package(TinyXML2 REQUIRED) + find_package(yaml-cpp REQUIRED) + +-if($ENV{ROS_DISTRO} MATCHES "humble") +- find_package(Python 3.10 EXACT REQUIRED COMPONENTS Development) +-elseif($ENV{ROS_DISTRO} MATCHES "iron") +- find_package(Python 3.10 EXACT REQUIRED COMPONENTS Development) +-elseif($ENV{ROS_DISTRO} MATCHES "jazzy") +- find_package(Python 3.12 EXACT REQUIRED COMPONENTS Development) +-elseif($ENV{ROS_DISTRO} MATCHES "kilted") +- find_package(Python 3.12 EXACT REQUIRED COMPONENTS Development) +-elseif($ENV{ROS_DISTRO} MATCHES "rolling") +- find_package(Python 3.12 EXACT REQUIRED COMPONENTS Development) +-endif() ++# Upstream hardcodes an EXACT Python version per ROS_DISTRO matching whatever ++# Python Ubuntu ships for that distro's release. conda-forge's Python version ++# moves independently (currently 3.14 for rolling, not the 3.12 upstream ++# expects), so the EXACT match fails to find conda's Python and CMake falls ++# back to the system Python headers instead, which lack the Debian ++# multiarch pyconfig.h. Just find whatever Python 3 is active in the build ++# environment instead of hardcoding a version tied to Ubuntu's release. ++find_package(Python 3 REQUIRED COMPONENTS Development) + + add_custom_target(compile-lib-controller ALL + COMMAND ${CMAKE_COMMAND} -E env "WEBOTS_HOME=${CMAKE_CURRENT_SOURCE_DIR}/webots" make release -f Makefile > /dev/null 2>&1 diff --git a/pixi.lock b/pixi.lock index 0b6ba83ec..c4e2f72b4 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1,29 +1,29 @@ version: 7 platforms: -- name: osx-64 - virtual-packages: - - __unix=0=0 - - __osx=13.0 - - __archspec=0=x86_64 -- name: osx-arm64 - virtual-packages: - - __unix=0=0 - - __osx=13.0 - - __archspec=0=m1 -- name: p1 +- name: linux-64-glibc-2-17 subdir: linux-64 virtual-packages: - __glibc=2.17 - __unix=0=0 - __linux=4.18 - __archspec=0=x86_64 -- name: p2 +- name: linux-aarch64-glibc-2-17 subdir: linux-aarch64 virtual-packages: - __glibc=2.17 - __unix=0=0 - __linux=4.18 - __archspec=0=aarch64 +- name: osx-64 + virtual-packages: + - __unix=0=0 + - __osx=13.0 + - __archspec=0=x86_64 +- name: osx-arm64 + virtual-packages: + - __unix=0=0 + - __osx=13.0 + - __archspec=0=m1 - name: win-64 virtual-packages: - __win=10.0 @@ -35,126 +35,7 @@ environments: indexes: - https://pypi.org/simple packages: - osx-64: - - conda: https://repo.prefix.dev/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://repo.prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://repo.prefix.dev/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda - - conda: https://repo.prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/cmake-3.31.8-h29fc008_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libcxx-22.1.4-h19cb2f5_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libev-4.33-h10d778d_2.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libsqlite-3.53.0-h8f8c405_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/python-3.14.4-h7c6738f_100_cp314.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/rattler-build-0.57.2-h4728fb8_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/rattler-index-0.27.21-hbc4d974_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda - - conda: https://repo.prefix.dev/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda - - pypi: git+https://github.com/RoboStack/vinca.git?rev=34316c7f195b359fb9cd4bfd2ae8fd83cb559dff#34316c7f195b359fb9cd4bfd2ae8fd83cb559dff - - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/32/d0fbc4383a6a213d315c39dda9107f81654d9941c43d6c687e61995ec388/rosdistro-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/35/79/5e2cffa1c77432f11cd93a5351f30732c997a239d3a3090856a72d6d8ba7/ruamel.yaml-0.17.40-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/95/88ed47cb7da88569a78b7d6fb9420298df7e99997810c844a924d96d3c08/empy-3.3.4.tar.gz - - pypi: https://files.pythonhosted.org/packages/50/19/1ee204b047ef84ce3dc9f77a5f935076211832f50bc7a4c918275193f807/rospkg-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/53/b2/acc33950394b3becb2b664741a0c0889c7ef9f9ffbfa8d47eddb53a50abd/idna-3.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/99/1b/50316bd6f95c50686b35799abebb6168d90ee18b7c03e3065f587f010f7c/catkin_pkg-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl - osx-arm64: - - conda: https://repo.prefix.dev/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://repo.prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://repo.prefix.dev/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda - - conda: https://repo.prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/cmake-3.31.8-h54ad630_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libcxx-22.1.4-h55c6f16_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libsqlite-3.53.0-h1b79a29_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/python-3.14.4-h4c637c5_100_cp314.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/rattler-build-0.57.2-h6fdd925_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/rattler-index-0.27.21-hcb0414c_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - - conda: https://repo.prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: git+https://github.com/RoboStack/vinca.git?rev=34316c7f195b359fb9cd4bfd2ae8fd83cb559dff#34316c7f195b359fb9cd4bfd2ae8fd83cb559dff - - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/32/d0fbc4383a6a213d315c39dda9107f81654d9941c43d6c687e61995ec388/rosdistro-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/79/5e2cffa1c77432f11cd93a5351f30732c997a239d3a3090856a72d6d8ba7/ruamel.yaml-0.17.40-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/95/88ed47cb7da88569a78b7d6fb9420298df7e99997810c844a924d96d3c08/empy-3.3.4.tar.gz - - pypi: https://files.pythonhosted.org/packages/50/19/1ee204b047ef84ce3dc9f77a5f935076211832f50bc7a4c918275193f807/rospkg-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/53/b2/acc33950394b3becb2b664741a0c0889c7ef9f9ffbfa8d47eddb53a50abd/idna-3.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/99/1b/50316bd6f95c50686b35799abebb6168d90ee18b7c03e3065f587f010f7c/catkin_pkg-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl - p1: + linux-64-glibc-2-17: - conda: https://repo.prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - conda: https://repo.prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - conda: https://repo.prefix.dev/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda @@ -195,11 +76,12 @@ environments: - conda: https://repo.prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://repo.prefix.dev/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda - conda: https://repo.prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - pypi: git+https://github.com/RoboStack/vinca.git?rev=34316c7f195b359fb9cd4bfd2ae8fd83cb559dff#34316c7f195b359fb9cd4bfd2ae8fd83cb559dff + - pypi: git+https://github.com/Tobias-Fischer/vinca.git?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/32/d0fbc4383a6a213d315c39dda9107f81654d9941c43d6c687e61995ec388/rosdistro-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/35/79/5e2cffa1c77432f11cd93a5351f30732c997a239d3a3090856a72d6d8ba7/ruamel.yaml-0.17.40-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/95/88ed47cb7da88569a78b7d6fb9420298df7e99997810c844a924d96d3c08/empy-3.3.4.tar.gz @@ -222,7 +104,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl - p2: + linux-aarch64-glibc-2-17: - conda: https://repo.prefix.dev/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda - conda: https://repo.prefix.dev/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda - conda: https://repo.prefix.dev/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda @@ -262,7 +144,7 @@ environments: - conda: https://repo.prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://repo.prefix.dev/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda - conda: https://repo.prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - pypi: git+https://github.com/RoboStack/vinca.git?rev=34316c7f195b359fb9cd4bfd2ae8fd83cb559dff#34316c7f195b359fb9cd4bfd2ae8fd83cb559dff + - pypi: git+https://github.com/Tobias-Fischer/vinca.git?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl @@ -281,6 +163,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl - pypi: https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl @@ -289,6 +172,127 @@ environments: - pypi: https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + osx-64: + - conda: https://repo.prefix.dev/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://repo.prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://repo.prefix.dev/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda + - conda: https://repo.prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/cmake-3.31.8-h29fc008_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libcxx-22.1.4-h19cb2f5_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libsqlite-3.53.0-h8f8c405_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/python-3.14.4-h7c6738f_100_cp314.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/rattler-build-0.57.2-h4728fb8_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/rattler-index-0.27.21-hbc4d974_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + - conda: https://repo.prefix.dev/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + - pypi: git+https://github.com/Tobias-Fischer/vinca.git?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 + - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/32/d0fbc4383a6a213d315c39dda9107f81654d9941c43d6c687e61995ec388/rosdistro-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/35/79/5e2cffa1c77432f11cd93a5351f30732c997a239d3a3090856a72d6d8ba7/ruamel.yaml-0.17.40-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/95/88ed47cb7da88569a78b7d6fb9420298df7e99997810c844a924d96d3c08/empy-3.3.4.tar.gz + - pypi: https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/50/19/1ee204b047ef84ce3dc9f77a5f935076211832f50bc7a4c918275193f807/rospkg-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/53/b2/acc33950394b3becb2b664741a0c0889c7ef9f9ffbfa8d47eddb53a50abd/idna-3.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/99/1b/50316bd6f95c50686b35799abebb6168d90ee18b7c03e3065f587f010f7c/catkin_pkg-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + osx-arm64: + - conda: https://repo.prefix.dev/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://repo.prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://repo.prefix.dev/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda + - conda: https://repo.prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/cmake-3.31.8-h54ad630_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libcxx-22.1.4-h55c6f16_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libsqlite-3.53.0-h1b79a29_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/python-3.14.4-h4c637c5_100_cp314.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/rattler-build-0.57.2-h6fdd925_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/rattler-index-0.27.21-hcb0414c_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://repo.prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: git+https://github.com/Tobias-Fischer/vinca.git?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 + - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/32/d0fbc4383a6a213d315c39dda9107f81654d9941c43d6c687e61995ec388/rosdistro-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/79/5e2cffa1c77432f11cd93a5351f30732c997a239d3a3090856a72d6d8ba7/ruamel.yaml-0.17.40-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/95/88ed47cb7da88569a78b7d6fb9420298df7e99997810c844a924d96d3c08/empy-3.3.4.tar.gz + - pypi: https://files.pythonhosted.org/packages/50/19/1ee204b047ef84ce3dc9f77a5f935076211832f50bc7a4c918275193f807/rospkg-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/53/b2/acc33950394b3becb2b664741a0c0889c7ef9f9ffbfa8d47eddb53a50abd/idna-3.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/99/1b/50316bd6f95c50686b35799abebb6168d90ee18b7c03e3065f587f010f7c/catkin_pkg-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl win-64: - conda: https://repo.prefix.dev/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda - conda: https://repo.prefix.dev/conda-forge/noarch/m2-msys2-runtime-3.6.1.4-hc364b38_6.conda @@ -321,7 +325,7 @@ environments: - conda: https://repo.prefix.dev/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - conda: https://repo.prefix.dev/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://repo.prefix.dev/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: git+https://github.com/RoboStack/vinca.git?rev=34316c7f195b359fb9cd4bfd2ae8fd83cb559dff#34316c7f195b359fb9cd4bfd2ae8fd83cb559dff + - pypi: git+https://github.com/Tobias-Fischer/vinca.git?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl @@ -330,6 +334,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/35/79/5e2cffa1c77432f11cd93a5351f30732c997a239d3a3090856a72d6d8ba7/ruamel.yaml-0.17.40-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/3b/95/88ed47cb7da88569a78b7d6fb9420298df7e99997810c844a924d96d3c08/empy-3.3.4.tar.gz - pypi: https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/50/19/1ee204b047ef84ce3dc9f77a5f935076211832f50bc7a4c918275193f807/rospkg-1.6.1-py3-none-any.whl @@ -2294,19 +2299,21 @@ packages: purls: [] size: 388453 timestamp: 1764777142545 -- pypi: git+https://github.com/RoboStack/vinca.git?rev=34316c7f195b359fb9cd4bfd2ae8fd83cb559dff#34316c7f195b359fb9cd4bfd2ae8fd83cb559dff +- pypi: git+https://github.com/Tobias-Fischer/vinca.git?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 name: vinca version: 0.2.0 requires_dist: - catkin-pkg>=0.4.16 + - ruamel-yaml>=0.16.6,<0.18.0 + - rosdistro>=0.8.0 - empy>=3.3.4,<4.0.0 - - jinja2>=3.0.0 - - license-expression>=30.0.0 - - networkx>=2.5 - requests>=2.24.0 + - networkx>=2.5 - rich>=10 - - rosdistro>=0.8.0 - - ruamel-yaml>=0.16.6,<0.18.0 + - jinja2>=3.0.0 + - license-expression>=30.0.0 + - packaging>=23.0 + - zstandard>=0.19.0 requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl name: docutils @@ -2347,6 +2354,14 @@ packages: version: 3.0.3 sha256: bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: zstandard + version: 0.25.0 + sha256: e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0 + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl name: markupsafe version: 3.0.3 @@ -2373,10 +2388,26 @@ packages: - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' - backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd' requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl + name: zstandard + version: 0.25.0 + sha256: c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2 + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/3b/95/88ed47cb7da88569a78b7d6fb9420298df7e99997810c844a924d96d3c08/empy-3.3.4.tar.gz name: empy version: 3.3.4 sha256: 73ac49785b601479df4ea18a7c79bc1304a8a7c34c02b9472cf1206ae88f01b3 +- pypi: https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl + name: zstandard + version: 0.25.0 + sha256: e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3 + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: markupsafe version: 3.0.3 @@ -2438,6 +2469,14 @@ packages: version: 6.0.3 sha256: c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl + name: zstandard + version: 0.25.0 + sha256: 05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl name: pyyaml version: 6.0.3 @@ -2560,6 +2599,14 @@ packages: - pytest-mpl ; extra == 'test-extras' - pytest-randomly ; extra == 'test-extras' requires_python: '>=3.11,!=3.14.1' +- pypi: https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl + name: zstandard + version: 0.25.0 + sha256: 223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439 + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl name: license-expression version: 30.4.4 diff --git a/pixi.toml b/pixi.toml index c84d6b61a..0d16f491c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -29,7 +29,13 @@ git = "*" [pypi-dependencies] # This is typically the latest commit on main branch -vinca = { git = "https://github.com/RoboStack/vinca.git", rev = "34316c7f195b359fb9cd4bfd2ae8fd83cb559dff" } +# TEMPORARY: pinned to RoboStack/vinca@1f1dca5 (last commit before the +# rosdistro-cache-snapshot feature landed -- our already-generated +# rosdistro_snapshot.yaml wasn't produced with that machinery and broke +# against it) with the raw.githubusercontent.com tag-URL ambiguity fix +# (RoboStack/vinca#156) cherry-picked on top. Revert to RoboStack/vinca.git +# once #156 merges and the snapshot format is reconciled. +vinca = { git = "https://github.com/Tobias-Fischer/vinca.git", rev = "9e44663eaf17a1a7ae698e3140ff095a78e849e7" } # Uncomment this line to work with a local vinca for faster iteration, but remember to comment it back # (and regenerate the pixi.lock) once you push the modified commit to the repo # vinca = { path = "../vinca", editable = true } @@ -37,14 +43,15 @@ vinca = { git = "https://github.com/RoboStack/vinca.git", rev = "34316c7f195b359 [tasks] generate-recipes = { cmd = "vinca -m", depends-on = ["remove-recipes"] } generate-gha-workflows = { cmd = "vinca-gha --trigger-branch dummy_build_branch_as_it_is_unused -d ./recipes", depends-on = ["generate-recipes"] } -check-patches = { cmd = "python check_patches_clean_apply.py", depends-on = ["generate-recipes"] } +check-orphaned-patches = { cmd = "python check_orphaned_platform_patches.py", description = "Detect patch/ files vinca's add_package_name_variants() will never wire into any recipe because a same-package patch exists under a different name-prefix variant (see script docstring)." } +check-patches = { cmd = "python check_patches_clean_apply.py", depends-on = ["generate-recipes", "check-orphaned-patches"] } create_snapshot = { cmd = "vinca-snapshot -d rolling -o rosdistro_snapshot.yaml" } upload = "rattler-build upload prefix -c robostack-rolling --generate-attestation" -build_continue_on_failure = { cmd = "rattler-build build --recipe-dir ./recipes -m ./conda_build_config.yaml -c robostack-rolling -c https://repo.prefix.dev/conda-forge --continue-on-failure --skip-existing", depends-on = ["generate-recipes"] } +build_continue_on_failure = { cmd = "rattler-build build --recipe-dir ./recipes -m ./conda_build_config.yaml -c https://repo.prefix.dev/robostack-rolling -c https://repo.prefix.dev/conda-forge --continue-on-failure --skip-existing --channel-priority disabled", depends-on = ["generate-recipes"] } sort = "sh -lc 'vinca-sort-vinca-lists $@ vinca.yaml && vinca-sort-yaml-keys $@ pkg_additional_info.yaml robostack.yaml rosdistro_additional_recipes.yaml' --" [tasks.build] -cmd = "rattler-build build --recipe-dir ./recipes -m ./conda_build_config.yaml -c https://prefix.dev/robostack-rolling -c https://prefix.dev/conda-forge --skip-existing" +cmd = "rattler-build build --recipe-dir ./recipes -m ./conda_build_config.yaml -c https://prefix.dev/robostack-rolling -c https://prefix.dev/conda-forge --skip-existing --channel-priority disabled" depends-on = ["generate-recipes"] description = "Build all packages, from the ./recipes dir. This will skip already existing packages, so it can be used to build only a subset of packages by first removing the recipes of the packages you want to rebuild (see `pixi remove-recipes`)." @@ -53,6 +60,6 @@ cmd = "rm -rf recipes_only_patch; rm -rf recipes; mkdir recipes" description = "Remove all generated recipes, before regenerating them." [tasks.build-one] -cmd = "cp ./patch/{{ PACKAGE }}.*patch ./recipes/{{ PACKAGE }}/patch/; rattler-build build --recipe ./recipes/{{ PACKAGE }}/recipe.yaml -m ./conda_build_config.yaml -c https://prefix.dev/robostack-rolling -c https://prefix.dev/conda-forge" +cmd = "cp ./patch/{{ PACKAGE }}.*patch ./recipes/{{ PACKAGE }}/patch/; rattler-build build --recipe ./recipes/{{ PACKAGE }}/recipe.yaml -m ./conda_build_config.yaml -c https://prefix.dev/robostack-rolling -c https://prefix.dev/conda-forge --channel-priority disabled" args = [{ arg = "PACKAGE", default = "ros-rolling-ros-workspace" }] description = "Build a single package, from the ./recipes dir. Add the `ros-rolling-` prefix to the package name, e.g. `pixi build-one --package ros-rolling-ros-workspace`" diff --git a/pkg_additional_info.yaml b/pkg_additional_info.yaml index 88bec6795..78584686f 100644 --- a/pkg_additional_info.yaml +++ b/pkg_additional_info.yaml @@ -110,6 +110,8 @@ libcamera: override_version: '0.5.2' libcurl_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" +libg2o: + additional_cmake_args: "-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON" liblz4_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" librealsense2: @@ -227,11 +229,6 @@ visp: generate_dummy_package_with_run_deps: dep_name: visp max_pin: 'x.x' - # the version on ros is outdated w.r.t. to the conda-forge one - override_version: '3.6.0' + override_version: '3.7.0' zenoh_cpp_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK -DUSE_SYSTEM_ZENOH=ON" -ros2cli: - build_number: 26 -rosidl_cli: - build_number: 26 diff --git a/robostack.yaml b/robostack.yaml index cee7dd0c0..6ed16d164 100644 --- a/robostack.yaml +++ b/robostack.yaml @@ -33,6 +33,8 @@ binutils: win64: [] bison: robostack: [bison] +black: + robostack: [black] boost: robostack: [libboost-devel, libboost-python-devel] bullet: @@ -113,6 +115,8 @@ flex: robostack: [flex] fmt: robostack: [fmt] +fri_client_sdk: + robostack: [lbr-fri-client-sdk] g++-static: robostack: [] gawk: @@ -177,6 +181,11 @@ ignition-gazebo6: robostack: [libignition-gazebo6] ignition-gui5: robostack: [libignition-gui5] +ignition-gui6: + robostack: + linux: [libignition-gui6, libgl-devel] + osx: [libignition-gui6] + win64: [libignition-gui6] ignition-math6: robostack: [libignition-math6] ignition-msgs5: @@ -185,6 +194,8 @@ ignition-msgs7: robostack: [libignition-msgs7] ignition-msgs8: robostack: [libignition-msgs8] +ignition-plugin: + robostack: [libignition-plugin1] ignition-rendering5: robostack: [libignition-rendering5] ignition-transport10: @@ -201,6 +212,8 @@ jupyter-notebook: robostack: [notebook] kitchen: robostack: [kitchen] +konsole: + robostack: [konsole] lcov: robostack: [lcov] leveldb: @@ -209,10 +222,16 @@ libabsl-dev: robostack: [libabseil] libblas-dev: robostack: [libblas, libcblas] +libblosc-dev: + robostack: [blosc] libboost: robostack: [libboost] libboost-chrono-dev: robostack: [libboost-devel] +libboost-coroutine: + robostack: [libboost] +libboost-coroutine-dev: + robostack: [libboost-devel] libboost-date-time: robostack: [libboost] libboost-date-time-dev: @@ -266,6 +285,8 @@ libclang-dev: robostack: [libclang] libconsole-bridge-dev: robostack: [console_bridge] +libcpp-httplib-dev: + robostack: [cpp-httplib] libcunit-dev: robostack: [cunit] libcurl: @@ -273,7 +294,10 @@ libcurl: libcurl-dev: robostack: [libcurl] libdc1394-dev: - robostack: [libdc1394] + robostack: + linux: [libdc1394] + osx: [libdc1394] + win64: [] libdraco-dev: robostack: [draco] libdw-dev: @@ -283,6 +307,8 @@ libdw-dev: win64: [] libexpected-dev: robostack: [cpp-expected] +libfcl: + robostack: [fcl] libfcl-dev: robostack: [fcl] libffi-dev: @@ -331,6 +357,11 @@ libgpgme-dev: linux: [gpgme] osx: [gpgme] win64: [] +libgpiod-dev: + robostack: + linux: [libgpiod] + osx: [] + win64: [] libgps: robostack: [gpsd] libgsl: @@ -411,8 +442,12 @@ libopencv-imgproc-dev: linux: [py-opencv, libopencv, libopengl-devel, libgl-devel] osx: [py-opencv, libopencv] win64: [py-opencv, libopencv] +libopenexr-dev: + robostack: [openexr] libopenni-dev: robostack: [] +libopenvdb-dev: + robostack: [openvdb] liborocos-kdl: robostack: [orocos-kdl] liborocos-kdl-dev: @@ -426,6 +461,18 @@ libpcl-all-dev: linux: [pcl, libboost-devel, vtk-base, libopengl-devel, libgl-devel, eigen-abi-devel] osx: [pcl, libboost-devel, vtk-base, eigen-abi-devel] win64: [pcl, libboost-devel, vtk-base, eigen-abi-devel] +libpcl-common: + robostack: [pcl] +libpcl-features: + robostack: [pcl] +libpcl-filters: + robostack: [pcl] +libpcl-io: + robostack: [pcl] +libpcl-segmentation: + robostack: [pcl] +libpcl-surface: + robostack: [pcl] libpng-dev: robostack: [libpng] libpoco-dev: @@ -660,6 +707,8 @@ lz4: robostack: [lz4] maven: robostack: [maven] +meson: + robostack: [meson] mongodb: robostack: [mongodb] mosquitto: @@ -827,6 +876,8 @@ python3: robostack: [python] python3-argcomplete: robostack: [argcomplete] +python3-attrs: + robostack: [attrs] python3-autobahn: robostack: [autobahn] python3-bson: @@ -909,6 +960,8 @@ python3-grpcio: robostack: [grpcio] python3-h5py: robostack: [h5py] +python3-httpx: + robostack: [httpx] python3-ifcfg: robostack: [ifcfg] python3-imageio: @@ -964,6 +1017,8 @@ python3-pip: robostack: [pip] python3-pkg-resources: robostack: [] +python3-platformdirs: + robostack: [platformdirs] python3-prompt-toolkit: robostack: [prompt-toolkit] python3-protobuf: @@ -1026,6 +1081,8 @@ python3-ruff: robostack: [ruff] python3-scipy: robostack: [scipy] +python3-semver: + robostack: [semver] python3-serial: robostack: [pyserial] python3-setproctitle: @@ -1048,14 +1105,30 @@ python3-termcolor: robostack: [termcolor] python3-texttable: robostack: [texttable] +python3-textual: + robostack: [textual] python3-tk: robostack: [tk] +python3-toml: + robostack: [toml] +python3-torchvision: + robostack: [torchvision] +python3-torchvision-pip: + robostack: [torchvision] python3-tornado: robostack: [tornado] +python3-tqdm: + robostack: [tqdm] +python3-transforms3d: + robostack: [transforms3d] python3-twisted: robostack: [twisted] python3-typeguard: robostack: [typeguard] +python3-ujson: + robostack: [ujson] +python3-ultralytics-pip: + robostack: [ultralytics] python3-unidiff: robostack: [unidiff] python3-usb: @@ -1064,16 +1137,28 @@ python3-utm: robostack: [utm] python3-uvicorn: robostack: [uvicorn] +python3-uvloop: + robostack: + linux: [uvloop] + osx: [uvloop] + win64: [] python3-vcstool: robostack: [vcs2l] python3-venv: robostack: [virtualenv, pip, pip-tools, setuptools] python3-websocket: robostack: [websocket-client] +python3-websockets: + robostack: [websockets] python3-yaml: robostack: [pyyaml] python3-zmq: robostack: [pyzmq] +qml-module-qtquick-extras: + robostack: + linux: [qt6-main, libopengl-devel, libgl-devel] + osx: [qt6-main] + win64: [qt6-main] qt-base-dev: robostack: linux: [qt6-main, libopengl-devel, libgl-devel] @@ -1109,6 +1194,8 @@ rsync: robostack: [rsync] rti-connext-dds-5.3.1: robostack: [] +rti-connext-dds-6.0.1: + robostack: [] ruby: robostack: [ruby] sbcl: @@ -1128,6 +1215,8 @@ sdl-image: robostack: [sdl_image] sdl2: robostack: [sdl2] +simde: + robostack: [simde] smartmontools: robostack: [smartmontools] socat: diff --git a/vinca.yaml b/vinca.yaml index 022061440..8c96e667e 100644 --- a/vinca.yaml +++ b/vinca.yaml @@ -7,12 +7,13 @@ conda_index: - robostack.yaml - packages-ignore.yaml -# Reminder for next full rebuild, the next build number should be 27 -build_number: 25 +# Reminder for next full rebuild, the next build number should be 28 +build_number: 27 mutex_package: name: "ros2-distro-mutex" version: "0.20.0" + build_number: 27 upper_bound: "x.x" run_constraints: - libboost 1.90.* @@ -20,12 +21,15 @@ mutex_package: - pcl 1.15.1.* - gazebo 11.* - libprotobuf 7.35.1.* - - vtk 9.6.2.* + - vtk 9.7.0.* packages_skip_by_deps: - rplidar_ros - rviz_visual_tools + # not yet released for rolling; rtabmap builds fine without it (disables the optional dependent feature) + - libpointmatcher + - if: not linux then: - pendulum_control @@ -33,6 +37,16 @@ packages_skip_by_deps: - tlsf - tlsf_cpp + # mujoco_vendor has no prebuilt MuJoCo binary for macOS, so mujoco_3d_lidar (which calls real MuJoCo API functions) can't build there. + - if: osx + then: + - mujoco_3d_lidar + + # mujoco_ros2_control_plugins needs EGL, which doesn't exist on Windows (or macOS, see the mujoco_vendor gap above) -- a genuine platform gap. + - if: osx or win + then: + - mujoco_ros2_control_plugins + packages_remove_from_deps: - if: not linux @@ -145,6 +159,7 @@ packages_select_by_deps: - rosidl_buffer_backend - rosidl_buffer_backend_registry - rosidl_buffer_py + - rtabmap - rviz_visual_tools - sbg_driver - simulation @@ -161,81 +176,278 @@ packages_select_by_deps: # - web-video-server - persist-parameter-server - - twist_stamper # Requested in https://github.com/RoboStack/ros-rolling/issues/12 - urdf_tutorial - # These packages are only built on Linux as they depend on Linux-specific API - - if: linux - then: - - libcamera - - nobleo_socketcan_bridge # Depends on socketcan - - ros2_socketcan # Depends on socketcan - - rosgraph_monitor - - usb_cam # Depends on v4l - - # These packages are currently only build on Linux, - # as trying to build them in the past on macos or Windows resulted in errors + # Packages only built on Linux: hardware-specific deps (libcamera/v4l/socketcan), or previously failed on macOS/Windows. - if: linux then: - apriltag_ros # Depends on camera_ros - camera_ros # Depends on libcamera that is only available on linux + - libcamera - livox_ros_driver2 - mavros # libmavconn currently fails to build on macOS and windows + - nobleo_socketcan_bridge # Depends on socketcan - py_binding_tools + - ros2_socketcan # Depends on socketcan + - rviz_satellite + - sdl2_vendor + - septentrio_gnss_driver + - serial_driver + - sick_safetyscanners2 + - sick_safetyscanners2_interfaces + - simulation_interfaces + - slider_publisher + - swri_console # Until sync of: https://github.com/ros/rosdistro/pull/49750 - swri_serial_util # Serial communication only implemented for linux + - usb_cam # Depends on v4l - v4l2_camera # Depends on v4l that is only available on linux - # These packages are currently not build on Windows, but they be with some work + # These packages are currently not built on Windows, but they may be with some work - if: not win then: + - ament_cmake + - ament_cmake_vendor_package + - apex_test_tools + - apriltag - apriltag_detector_mit - apriltag_detector_umich - apriltag_draw - apriltag_tools + - automatika_embodied_agents + - automatika_ros_sugar - autoware_core - autoware_core_control # depends on autoware_motion_utils - autoware_core_localization # depends on autoware_ekf_localizer - autoware_ekf_localizer # Windows error: error C2338: static_assert failed: 'First argument to logging macros must be an rclcpp::Logger' + - autoware_internal_localization_msgs - autoware_lanlet2_utils # Windows errors: C3546 (no parameter packs to expand), C2678 (no operator '|' for transform_view) - autoware_motion_utils # Windows error: error C2765: 'function': an explicit specialization of a function template cannot have any default arguments - autoware_osqp_interface - autoware_pose_initializer # depends on autoware_motion_utils - autoware_qp_interface - autoware_trajectory # depends on autoware_motion_utils + - bno055 + - cartographer_ros + - cascade_lifecycle_msgs + - color_util + - control_msgs + - control_toolbox + - demo_nodes_cpp + - demo_nodes_py + - diff_drive_controller - dual-laser-merger + - event_camera_codecs + - event_camera_renderer - ffmpeg_image_transport # TODO on windows: fix iconv link issue - foxglove_compressed_video_transport + - geodesy + - geographic_info + - geometry_tutorials + - graph_msgs - grid_map # rviz linking problems on Windows, see https://github.com/RoboStack/ros-jazzy/pull/79#issuecomment-2993499990 - - laser-segmentation - - libg2o - - mocap4r2_control - - mocap4r2_control_msgs - - mocap4r2_dummy_driver - - mocap4r2_marker_publisher - - mocap4r2_marker_viz - - mocap4r2_marker_viz_srvs - - mocap4r2_robot_gt - - mocap4r2_robot_gt_msgs - - moveit-hybrid-planning # Windows error: error C3861: '__builtin_unreachable': identifier not found - - moveit-py - - moveit-ros-occupancy-map-monitor - - moveit-ros-perception - - moveit-runtime - - odom_to_tf_ros2 - - ouster_ros # TODO on windows: cannot open pcl_io.lib - - pinocchio - - plotjuggler-ros - - pointcloud-to-laserscan - - rplidar_ros + - imu_tools + - imu_transformer + - io_context + - joint_state_publisher + - joy + - ament_flake8 + - ament_lint + - ament_lint_common + - ament_pep257 + - ament_pycodestyle + - autoware_adapi_v1_msgs + - autoware_adapi_version_msgs + - autoware_auto_msgs + - autoware_internal_debug_msgs + - autoware_internal_metric_msgs + - autoware_internal_perception_msgs + - autoware_internal_planning_msgs + - autoware_lanelet2_extension + - autoware_lanelet2_extension_python + - autoware_lint_common + - autoware_msgs + - autoware_utils_debug + - autoware_utils_diagnostics + - autoware_utils_geometry + - autoware_utils_logging + - autoware_utils_math + - autoware_utils_pcl + - autoware_utils_rclcpp + - autoware_utils_system + - autoware_utils_tf + - autoware_utils_uuid + - autoware_utils_visualization + - builtin_interfaces + - irobot_create_msgs + - joy_teleop + - key_teleop + - mavros_msgs + - mouse_teleop + - mujoco_ros2_control_msgs + - mujoco_vendor + - osrf_testing_tools_cpp + - pick_ik + - picknik_ament_copyright + - point_cloud_transport_py + - rclc + - rclcpp + - rclpy + - rclpy_cascade_lifecycle + - rcpputils + - rcutils + - rmw + - rosidl_generator_dds_idl + - rosidl_runtime_c + - rosidl_runtime_cpp + - rosidl_typesupport_introspection_c + - rosidl_typesupport_introspection_cpp + - rqt_robot_monitor + - rqt_runtime_monitor + - rtest + - rviz_2d_overlay_msgs + - teleop_tools + - ntrip_client + - tracetools + - tracetools_launch + - tracetools_trace + - turtlebot3_gazebo + - urdf_launch + - yaml_cpp_vendor + - rqt_moveit + - rqt_robot_dashboard + - rqt_robot_steering + - rslidar_sdk + - rtcm_msgs + - rviz2 + - if: not win + then: - rqt_mocap4r2_control - rqt_tf_tree - - rslidar_sdk - - rviz_satellite - - serial_driver - - swri_console # Until sync of: https://github.com/ros/rosdistro/pull/49750 + + # Allied Vision only ships prebuilt Vimba SDK binaries for Linux (x86_64/arm), not macOS -- no source-level fix is possible. + - if: linux + then: + - avt_vimba_camera + - joy_linux + - kinematics_interface + - kinematics_interface_kdl + - laser-segmentation + - libg2o + - librealsense2 + - marker_msgs + - mavlink + - mavros_extras + - microstrain_inertial_description + - microstrain_inertial_driver + - microstrain_inertial_examples + - microstrain_inertial_msgs + - microstrain_inertial_rqt + - mocap4r2_control + - mocap4r2_control_msgs + - mocap4r2_dummy_driver + - mocap4r2_marker_publisher + - mocap4r2_marker_viz + - mocap4r2_marker_viz_srvs + - mocap4r2_robot_gt + - mocap4r2_robot_gt_msgs + - motion_capture_tracking + - moveit-hybrid-planning # Windows error: error C3861: '__builtin_unreachable': identifier not found + - moveit-py + - moveit-ros-occupancy-map-monitor + - moveit-ros-perception + - moveit-runtime + - moveit_resources + - moveit_task_constructor_demo + - nmea_msgs + - odom_to_tf_ros2 + - pal_statistics + - pilz_industrial_motion_planner + - pinocchio + - plotjuggler + - plotjuggler-ros + - plotjuggler_msgs + - pointcloud-to-laserscan + - polygon_utils + - py_trees_js + - py_trees_ros_tutorials + - radar_msgs + - random_numbers + - rclc_lifecycle + - rclc_parameter + - rclcpp_cascade_lifecycle + - realsense2_camera + - realsense2_description + - realtime_tools + - rmf_demos + - rmw_stats_shim + - robotiq_controllers + - robotiq_description + - ros2_control_cmake + - ros_core + - ros_gz_interfaces + - rosbag2_performance_benchmarking + - rosbag2_storage_mcap + - rosgraph_monitor_msgs + - rosidl_generator_dds_idl + - rplidar_ros + - rqt + - rqt_controller_manager + - rqt_gui + + # mujoco_ros2_control hard-depends on mujoco_ros2_control_plugins, skipped on osx/win above (no prebuilt binary / EGL requirement), so it can't build there either. + - if: linux + then: + - mujoco_ros2_control + - mujoco_ros2_control_demos + + # jazzy already builds these on osx; rolling had them needlessly linux-only. Keep this comment here -- vinca-sort-vinca-lists pools then-items across adjacent if-blocks not separated by a comment. + - if: not win + then: + - ouster_ros # conda-forge's Windows PCL package doesn't expose pcl_io.lib by the plain name ouster_ros's CMake links against (LNK1181) + - rclc_examples # MSVC C2055 on rcl_timer_t in callback signatures; root cause unresolved, already excluded on humble too + - rosgraph_monitor + - rviz_2d_overlay_plugins + - sick_safetyscanners_base + - spacenav + - system_modes + - system_modes_msgs + - teleop_tools + - tf_transformations + - topic_tools + - trac_ik + - turtle_tf2_cpp + - turtle_tf2_py + - turtlebot3_gazebo + - turtlebot3_simulations + - ublox_dgnss + - ublox_dgnss_node + - ublox_ubx_interfaces + - udp_driver + - ur_calibration + - ur_robot_driver + - urg_node - velodyne + - vision_msgs + - vision_msgs_rviz_plugins + - visp + - web_video_server + - yasmin + - yasmin_cli + - yasmin_demos + - yasmin_editor + - yasmin_factory + - yasmin_msgs + - yasmin_pcl + - yasmin_plugins_manager + - yasmin_ros + - zed_msgs # jazzy builds this on osx; was needlessly linux-only here + + # webots_ros2 is linux-only (excluding aarch64); keep this comment here -- vinca-sort-vinca-lists pools then-items across adjacent if-blocks not separated by a comment. + - if: linux and not aarch64 + then: + - webots_ros2 patch_dir: patch rosdistro_snapshot: rosdistro_snapshot.yaml diff --git a/vinca_pinning.yaml b/vinca_pinning.yaml new file mode 100644 index 000000000..30ecdc8fb --- /dev/null +++ b/vinca_pinning.yaml @@ -0,0 +1,59 @@ +conda_forge_pinning_version: 2026.09.01.16.28.00 +migrations: + - giflib6 + - go_macos + - gstreamer128 + - hdf52 + - libboost190 + - pybind11_abi11 + - urdfdom6 + - vtk970 +pinning_overrides: + # Build commands provide their channels with `-c`, so omit the inherited + # conda-forge-pinning channel_sources value from the rendered configuration. + channel_sources: null + channel_targets: null + # glibc floor raised from 2.17 (CentOS 7) to 2.28: conda-forge packages such as + # gazebo/openal-soft already require it. macOS deployment target raised to 14.0. + # c_stdlib_version shares a zip_keys group with the compiler versions, so the whole + # group has to be overridden; the compiler entries mirror the conda-forge base file + # and must be refreshed when `vinca-pinning-update` moves to a newer compiler. + c_stdlib_version: + - 2.28 # [linux and not riscv64] + - 2.39 # [linux and riscv64] + - 2.28 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - 14.0 # [osx] + c_compiler_version: + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + cxx_compiler_version: + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + fortran_compiler_version: + - 15 # [unix] + - 5 # [win64] + - 22 # [win and arm64] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + cuda_compiler_version: + - None + - 12.9 # [((linux and (x86_64 or aarch64)) or win64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + libzenohc: + - 1.9.0 + libzenohcxx: + - 1.9.0 + # conda-forge published sip 6.16.1 on 2026-09-08, which broke ABI targeting for + # packages like qt_gui_cpp_sip that build against PyQt-sip's fixed ABI v12 + # (hit this on humble/jazzy first; rolling also builds qt_gui_cpp via + # pyqt6/sip so it's equally exposed). Pin back to the last known-good line + # until upstream fixes it. + sip: + - 6.15 + python: + - 3.14.* *_cp314 + is_python_min: + - false + python_impl: + - cpython +