From 770d59c4a27f4cf3b3f27a223b94c96e59783b39 Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Mon, 19 Oct 2026 09:18:33 +1000 Subject: [PATCH 1/6] Add beluga_amcl and beluga_ros (Linux) [skip ci] Ports RoboStack/ros-jazzy#298 and #267. Beluga 2.1.1 is released for humble and jazzy, and conda-forge's sophus works (Eigen 5), so no additional recipes or dummy package are needed. The beluga patch includes instead of an Eigen-internal header (rejected by Eigen 5) and defaults BUILD_TESTING to OFF (its tests hit a GCC 15 constexpr std::optional error). macOS: libc++ lacks std::execution::sequenced_policy. Co-authored-by: Griffin Tabor <14334346+gftabor@users.noreply.github.com> Co-authored-by: Tim Clephas <5036851+Timple@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 --- shared/patch/ros2-beluga.patch | 26 ++++++++++++++++++++++++++ shared/vinca.yaml | 2 ++ 2 files changed, 28 insertions(+) create mode 100644 shared/patch/ros2-beluga.patch diff --git a/shared/patch/ros2-beluga.patch b/shared/patch/ros2-beluga.patch new file mode 100644 index 000000000..95a2971f2 --- /dev/null +++ b/shared/patch/ros2-beluga.patch @@ -0,0 +1,26 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 5c08a64..b94a7f1 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -94,7 +94,7 @@ target_sources(clang_tidy_findable PRIVATE src/clang_tidy_findable.cpp) + target_link_libraries(clang_tidy_findable PRIVATE ${PROJECT_NAME} + beluga_compile_options) + +-option(BUILD_TESTING "Build the testing tree." ON) ++option(BUILD_TESTING "Build the testing tree." OFF) + if(BUILD_TESTING) + message(STATUS "Build testing enabled.") + enable_testing() +diff --git a/include/beluga/policies/on_motion.hpp b/include/beluga/policies/on_motion.hpp +index 9d7ad43..eb7a21f 100644 +--- a/include/beluga/policies/on_motion.hpp ++++ b/include/beluga/policies/on_motion.hpp +@@ -15,7 +15,7 @@ + #ifndef BELUGA_POLICIES_ON_MOTION_HPP + #define BELUGA_POLICIES_ON_MOTION_HPP + +-#include ++#include + #include + #include + #include diff --git a/shared/vinca.yaml b/shared/vinca.yaml index c93bc0853..958eb328a 100644 --- a/shared/vinca.yaml +++ b/shared/vinca.yaml @@ -395,6 +395,8 @@ packages_select_by_deps: - apex_containers - apriltag_ros # These packages are currently only build on Linux,; as trying to build them in the past on macos or Windows resulted in errors - avt_vimba_camera # ships some Linux .so in the repo, so it only supports linux + - beluga_amcl # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 + - beluga_ros # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 - camera_ros # Depends on libcamera that is only available on linux; Depends on libcamera, only available on linux - can_dbc_parser - easynav From c6455dfa8710c860bda826019e39afbdaf08b617 Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Mon, 19 Oct 2026 11:42:07 +1000 Subject: [PATCH 2/6] beluga: no std::optional in the on_motion policy [skip ci] GCC 15 fails to instantiate std::optional (union storage "initializations for multiple members"), which beluga_amcl's NDT 3D node hits through the on_motion policy, not only the tests. Store the latest pose as a flag plus the pose instead; same behaviour. Co-Authored-By: Claude Opus 5.5 --- shared/patch/ros2-beluga.patch | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/shared/patch/ros2-beluga.patch b/shared/patch/ros2-beluga.patch index 95a2971f2..450ae6c7f 100644 --- a/shared/patch/ros2-beluga.patch +++ b/shared/patch/ros2-beluga.patch @@ -12,7 +12,7 @@ index 5c08a64..b94a7f1 100644 message(STATUS "Build testing enabled.") enable_testing() diff --git a/include/beluga/policies/on_motion.hpp b/include/beluga/policies/on_motion.hpp -index 9d7ad43..eb7a21f 100644 +index 9d7ad43..5cb6d95 100644 --- a/include/beluga/policies/on_motion.hpp +++ b/include/beluga/policies/on_motion.hpp @@ -15,7 +15,7 @@ @@ -24,3 +24,30 @@ index 9d7ad43..eb7a21f 100644 #include #include #include +@@ -119,12 +119,13 @@ struct on_motion_policy : public on_motion_policy_base { + + /// Return true if motion has been detected. + constexpr bool operator()(const Pose& pose) { +- if (!latest_pose_) { ++ if (!has_latest_pose_) { + latest_pose_ = pose; ++ has_latest_pose_ = true; + return true; + } + +- const bool moved = (*this)(*latest_pose_, pose); ++ const bool moved = (*this)(latest_pose_, pose); + if (moved) { + latest_pose_ = pose; + } +@@ -133,7 +134,9 @@ struct on_motion_policy : public on_motion_policy_base { + } + + private: +- std::optional latest_pose_; ///< The latest pose for motion comparison. ++ // a flag instead of std::optional: GCC 15 fails to instantiate std::optional ++ bool has_latest_pose_{false}; ///< Whether latest_pose_ holds a pose. ++ Pose latest_pose_{}; ///< The latest pose for motion comparison. + }; + + /// Implementation detail for the on_motion_fn object. From fb80c4d4a5180a876a821291ecc9ef83dfa59c72 Mon Sep 17 00:00:00 2001 From: Griffin Tabor Date: Wed, 21 Oct 2026 10:10:25 -0400 Subject: [PATCH 3/6] Beluga to windows as well --- shared/patch/ros2-beluga-amcl.win.patch | 12 ++++++++++++ shared/patch/ros2-beluga-ros.win.patch | 18 ++++++++++++++++++ shared/patch/ros2-beluga.patch | 13 +++++++++++++ shared/vinca.yaml | 7 +++++-- 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 shared/patch/ros2-beluga-amcl.win.patch create mode 100644 shared/patch/ros2-beluga-ros.win.patch diff --git a/shared/patch/ros2-beluga-amcl.win.patch b/shared/patch/ros2-beluga-amcl.win.patch new file mode 100644 index 000000000..abb9a980b --- /dev/null +++ b/shared/patch/ros2-beluga-amcl.win.patch @@ -0,0 +1,12 @@ +diff --git a/beluga_amcl/CMakeLists.txt b/beluga_amcl/CMakeLists.txt +index 85d042e..dafb64f 100644 +--- a/beluga_amcl/CMakeLists.txt ++++ b/beluga_amcl/CMakeLists.txt +@@ -71,6 +71,7 @@ if(NOT PARANOID) + endif() + endforeach() + endif() ++set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + + add_library(beluga_amcl_ros2_common SHARED) + target_sources(beluga_amcl_ros2_common PRIVATE src/ros2_common.cpp) \ No newline at end of file diff --git a/shared/patch/ros2-beluga-ros.win.patch b/shared/patch/ros2-beluga-ros.win.patch new file mode 100644 index 000000000..f8afab613 --- /dev/null +++ b/shared/patch/ros2-beluga-ros.win.patch @@ -0,0 +1,18 @@ +diff --git a/beluga_ros/CMakeLists.txt b/beluga_ros/CMakeLists.txt +index 212972e..8395c83 100644 +--- a/beluga_ros/CMakeLists.txt ++++ b/beluga_ros/CMakeLists.txt +@@ -73,7 +73,12 @@ if(NOT PARANOID) + endforeach() + endif() + +-add_library(beluga_ros) ++if(WIN32) ++ add_library(beluga_ros STATIC) ++else() ++ add_library(beluga_ros) ++endif() ++ + target_sources(beluga_ros PRIVATE src/amcl.cpp src/ndt_ellipsoid.cpp) + target_include_directories( + beluga_ros PUBLIC $ \ No newline at end of file diff --git a/shared/patch/ros2-beluga.patch b/shared/patch/ros2-beluga.patch index 450ae6c7f..779429568 100644 --- a/shared/patch/ros2-beluga.patch +++ b/shared/patch/ros2-beluga.patch @@ -51,3 +51,16 @@ index 9d7ad43..5cb6d95 100644 }; /// Implementation detail for the on_motion_fn object. +diff --git a/include/beluga/sensor/ndt_sensor_model.hpp b/include/beluga/sensor/ndt_sensor_model.hpp +index 21d4d6f..35aff49 100644 +--- a/include/beluga/sensor/ndt_sensor_model.hpp ++++ b/include/beluga/sensor/ndt_sensor_model.hpp +@@ -271,7 +271,7 @@ NDTMapRepresentationT load_from_hdf5(const std::filesystem::path& path_to_hdf5_f + throw std::invalid_argument(ss.str()); + } + +- const H5::H5File file(path_to_hdf5_file, H5F_ACC_RDONLY); ++ const H5::H5File file(path_to_hdf5_file.string(), H5F_ACC_RDONLY); + const H5::DataSet means_dataset = file.openDataSet("means"); + const H5::DataSet covariances_dataset = file.openDataSet("covariances"); + const H5::DataSet resolution_dataset = file.openDataSet("resolution"); \ No newline at end of file diff --git a/shared/vinca.yaml b/shared/vinca.yaml index 958eb328a..d244c5823 100644 --- a/shared/vinca.yaml +++ b/shared/vinca.yaml @@ -395,8 +395,6 @@ packages_select_by_deps: - apex_containers - apriltag_ros # These packages are currently only build on Linux,; as trying to build them in the past on macos or Windows resulted in errors - avt_vimba_camera # ships some Linux .so in the repo, so it only supports linux - - beluga_amcl # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 - - beluga_ros # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 - camera_ros # Depends on libcamera that is only available on linux; Depends on libcamera, only available on linux - can_dbc_parser - easynav @@ -513,6 +511,11 @@ packages_select_by_deps: - v4l2_camera - yaets + - if: not osx + then: + - beluga_amcl # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 + - beluga_ros # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 + - if: linux and not aarch64 then: - franka_ros2 # Franka robots support; see PR #338 for macOS/Windows errors From f9b8cd5ee57638a14fc4ceb57b7480179003f42c Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Sat, 24 Oct 2026 21:16:08 +1000 Subject: [PATCH 4/6] beluga on macOS too: libc++ patches; selected on every platform macOS's libc++ builds beluga with three changes, kept in .osx.patch files: - the execution policies need -fexperimental-library (an interface option of beluga, so beluga_amcl and beluga_ros get it); - spatial_hash checked is_same_v, false on macOS (unsigned long vs unsigned long long): compare sizeof; - libc++'s execution policies can't be copied, which beluga's action closures, Amcl and beluga_ros / beluga_amcl's policy variants did: they keep pointers to the standard policies (std::execution::seq, par) instead. Built locally on osx-arm64 (jazzy): beluga, beluga_amcl, beluga_ros. With #123 (Windows), beluga is built everywhere. Co-Authored-By: Claude Opus 5.5 --- shared/patch/ros2-beluga-amcl.osx.patch | 69 +++++++++ shared/patch/ros2-beluga-ros.osx.patch | 39 +++++ shared/patch/ros2-beluga.osx.patch | 195 ++++++++++++++++++++++++ shared/vinca.yaml | 7 +- 4 files changed, 305 insertions(+), 5 deletions(-) create mode 100644 shared/patch/ros2-beluga-amcl.osx.patch create mode 100644 shared/patch/ros2-beluga-ros.osx.patch create mode 100644 shared/patch/ros2-beluga.osx.patch diff --git a/shared/patch/ros2-beluga-amcl.osx.patch b/shared/patch/ros2-beluga-amcl.osx.patch new file mode 100644 index 000000000..b4f62b672 --- /dev/null +++ b/shared/patch/ros2-beluga-amcl.osx.patch @@ -0,0 +1,69 @@ +diff --git a/include/beluga_amcl/ndt_amcl_node.hpp b/include/beluga_amcl/ndt_amcl_node.hpp +index d309a2c..744e75b 100644 +--- a/include/beluga_amcl/ndt_amcl_node.hpp ++++ b/include/beluga_amcl/ndt_amcl_node.hpp +@@ -98,7 +98,7 @@ using MotionModelVariant = + std::variant; + + /// Supported execution policies. +-using ExecutionPolicyVariant = std::variant; ++using ExecutionPolicyVariant = std::variant; + + /// 2D NDT AMCL as a ROS 2 composable lifecycle node. + class NdtAmclNode : public BaseAMCLNode { +diff --git a/include/beluga_amcl/ros2_common.hpp b/include/beluga_amcl/ros2_common.hpp +index d749d83..01f2186 100644 +--- a/include/beluga_amcl/ros2_common.hpp ++++ b/include/beluga_amcl/ros2_common.hpp +@@ -52,7 +52,7 @@ constexpr std::string_view kNav2DifferentialModelName = "nav2_amcl::Differential + /// String identifier for a omnidirectional model name. + constexpr std::string_view kNav2OmnidirectionalModelName = "nav2_amcl::OmniMotionModel"; + /// Supported execution policies. +-using ExecutionPolicyVariant = std::variant; ++using ExecutionPolicyVariant = std::variant; + + /// Base AMCL lifecycle node, with some basic common functionalities, such as transform tree utilities, common + /// publishers, subscribers, lifecycle related callbacks and configuration points, enabling extension by inheritance. +diff --git a/src/ndt_amcl_node.cpp b/src/ndt_amcl_node.cpp +index bead7e7..f577d10 100644 +--- a/src/ndt_amcl_node.cpp ++++ b/src/ndt_amcl_node.cpp +@@ -259,7 +259,7 @@ auto NdtAmclNode::make_particle_filter() const -> std::unique_ptr(std::move(amcl)); +diff --git a/src/ndt_amcl_node_3d.cpp b/src/ndt_amcl_node_3d.cpp +index c14efec..a2ef77c 100644 +--- a/src/ndt_amcl_node_3d.cpp ++++ b/src/ndt_amcl_node_3d.cpp +@@ -314,7 +314,7 @@ auto NdtAmclNode3D::make_particle_filter() const -> std::unique_ptr(std::move(amcl)); +diff --git a/src/ros2_common.cpp b/src/ros2_common.cpp +index 0a0cd20..fa4d181 100644 +--- a/src/ros2_common.cpp ++++ b/src/ros2_common.cpp +@@ -559,10 +559,10 @@ void BaseAMCLNode::autostart_callback() { + auto BaseAMCLNode::get_execution_policy() const -> ExecutionPolicyVariant { + const auto name = get_parameter("execution_policy").as_string(); + if (name == "seq") { +- return std::execution::seq; ++ return &std::execution::seq; + } + if (name == "par") { +- return std::execution::par; ++ return &std::execution::par; + } + throw std::invalid_argument("Execution policy must be seq or par."); + } diff --git a/shared/patch/ros2-beluga-ros.osx.patch b/shared/patch/ros2-beluga-ros.osx.patch new file mode 100644 index 000000000..9ef813be4 --- /dev/null +++ b/shared/patch/ros2-beluga-ros.osx.patch @@ -0,0 +1,39 @@ +diff --git a/include/beluga_ros/amcl.hpp b/include/beluga_ros/amcl.hpp +index 46c612c..872b9fb 100644 +--- a/include/beluga_ros/amcl.hpp ++++ b/include/beluga_ros/amcl.hpp +@@ -117,7 +117,7 @@ class Amcl { + beluga::BeamSensorModel>; + + /// Execution policy variant type for runtime selection support. +- using execution_policy_variant = std::variant; ++ using execution_policy_variant = std::variant; + + /// Constructor. + /** +diff --git a/src/amcl.cpp b/src/amcl.cpp +index c38360e..b2eee7f 100644 +--- a/src/amcl.cpp ++++ b/src/amcl.cpp +@@ -30,7 +30,7 @@ Amcl::Amcl( + motion_model_variant motion_model, + sensor_model_variant sensor_model, + const AmclParams& params = AmclParams(), +- execution_policy_variant execution_policy = std::execution::seq) ++ execution_policy_variant execution_policy = &std::execution::seq) + : params_{params}, + map_distribution_{map}, + motion_model_{std::move(motion_model)}, +@@ -95,9 +95,9 @@ auto Amcl::update( + std::visit( + [&, this](auto& policy, auto& motion_model, auto& sensor_model) { + particles_ |= +- beluga::actions::propagate(policy, motion_model(control_action_window_ << base_pose_in_odom)) | // +- beluga::actions::reweight(policy, sensor_model(std::move(measurement))) | // +- beluga::actions::normalize(policy); ++ beluga::actions::propagate(*policy, motion_model(control_action_window_ << base_pose_in_odom)) | // ++ beluga::actions::reweight(*policy, sensor_model(std::move(measurement))) | // ++ beluga::actions::normalize(*policy); + }, + execution_policy_, motion_model_, sensor_model_); + diff --git a/shared/patch/ros2-beluga.osx.patch b/shared/patch/ros2-beluga.osx.patch new file mode 100644 index 000000000..fbba71b6a --- /dev/null +++ b/shared/patch/ros2-beluga.osx.patch @@ -0,0 +1,195 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b94a7f1..cacf183 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -72,6 +72,9 @@ target_include_directories( + "$") + target_link_libraries(${PROJECT_NAME} INTERFACE ${_deps}) + target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) ++# libc++ only has the execution policies with -fexperimental-library ++target_compile_options(${PROJECT_NAME} INTERFACE $<$:-fexperimental-library>) ++target_link_options(${PROJECT_NAME} INTERFACE $<$:-fexperimental-library>) + target_compile_definitions(${PROJECT_NAME} INTERFACE EIGEN_NO_DEBUG + SOPHUS_USE_BASIC_LOGGING) + +diff --git a/include/beluga/actions/normalize.hpp b/include/beluga/actions/normalize.hpp +index 14c54a5..81f33ca 100644 +--- a/include/beluga/actions/normalize.hpp ++++ b/include/beluga/actions/normalize.hpp +@@ -42,13 +42,13 @@ struct normalize_closure { + public: + static_assert(std::is_execution_policy_v); + +- constexpr normalize_closure() noexcept : policy_{std::execution::seq} {} ++ constexpr normalize_closure() noexcept : policy_{&std::execution::seq} {} + +- constexpr explicit normalize_closure(ExecutionPolicy policy) : policy_{std::move(policy)} {} ++ constexpr explicit normalize_closure(const ExecutionPolicy& policy) : policy_{&policy} {} + +- constexpr explicit normalize_closure(double factor) noexcept : policy_{std::execution::seq}, factor_{factor} {} ++ constexpr explicit normalize_closure(double factor) noexcept : policy_{&std::execution::seq}, factor_{factor} {} + +- constexpr normalize_closure(ExecutionPolicy policy, double factor) : policy_{std::move(policy)}, factor_{factor} {} ++ constexpr normalize_closure(const ExecutionPolicy& policy, double factor) : policy_{&policy}, factor_{factor} {} + + template + constexpr auto operator()(Range& range) const -> Range& { +@@ -75,7 +75,7 @@ struct normalize_closure { + } + + std::transform( +- policy_, // ++ *policy_, // + weights.begin(), // + weights.end(), // + weights.begin(), // +@@ -85,7 +85,7 @@ struct normalize_closure { + } + + private: +- ExecutionPolicy policy_{}; ++ const ExecutionPolicy* policy_; + std::optional factor_; + }; + +diff --git a/include/beluga/actions/overlay.hpp b/include/beluga/actions/overlay.hpp +index 5bc20c8..e9469d8 100644 +--- a/include/beluga/actions/overlay.hpp ++++ b/include/beluga/actions/overlay.hpp +@@ -38,10 +38,10 @@ struct overlay_closure { + static_assert(ranges::range); + + constexpr overlay_closure(MaskRange mask_range, MaskValue mask_value) +- : policy_{std::execution::seq}, mask_range_{std::move(mask_range)}, mask_value_{std::move(mask_value)} {} ++ : policy_{&std::execution::seq}, mask_range_{std::move(mask_range)}, mask_value_{std::move(mask_value)} {} + +- constexpr explicit overlay_closure(ExecutionPolicy policy, MaskRange mask_range, MaskValue mask_value) +- : policy_{std::move(policy)}, mask_range_{std::move(mask_range)}, mask_value_{std::move(mask_value)} {} ++ constexpr explicit overlay_closure(const ExecutionPolicy& policy, MaskRange mask_range, MaskValue mask_value) ++ : policy_{&policy}, mask_range_{std::move(mask_range)}, mask_value_{std::move(mask_value)} {} + + template + constexpr auto operator()(Range& range) const -> Range& { +@@ -50,7 +50,7 @@ struct overlay_closure { + const auto converted_mask_value = static_cast>(mask_value_); + + std::transform( +- policy_, // ++ *policy_, // + std::begin(common_range), // + std::end(common_range), // + std::begin(mask_range_), // +@@ -63,7 +63,7 @@ struct overlay_closure { + } + + private: +- ExecutionPolicy policy_{}; ++ const ExecutionPolicy* policy_; + MaskRange mask_range_{}; + MaskValue mask_value_{}; + }; +diff --git a/include/beluga/actions/propagate.hpp b/include/beluga/actions/propagate.hpp +index 7009447..fddf76a 100644 +--- a/include/beluga/actions/propagate.hpp ++++ b/include/beluga/actions/propagate.hpp +@@ -85,8 +85,9 @@ struct propagate_base_fn { + class ExecutionPolicy, + std::enable_if_t, int> = 0, + std::enable_if_t, int> = 0> +- constexpr auto operator()(Range&& range, StateSamplingFunction fn, ExecutionPolicy policy) const -> Range& { +- return (*this)(std::move(policy), std::forward(range), std::move(fn)); ++ constexpr auto operator()(Range&& range, StateSamplingFunction fn, const ExecutionPolicy* policy) ++ const -> Range& { ++ return (*this)(*policy, std::forward(range), std::move(fn)); + } + + /// Overload that returns a view closure to compose with other views. +@@ -94,8 +95,8 @@ struct propagate_base_fn { + class ExecutionPolicy, // + class StateSamplingFunction, // + std::enable_if_t, int> = 0> +- constexpr auto operator()(ExecutionPolicy policy, StateSamplingFunction fn) const { +- return ranges::make_action_closure(ranges::bind_back(propagate_base_fn{}, std::move(fn), std::move(policy))); ++ constexpr auto operator()(const ExecutionPolicy& policy, StateSamplingFunction fn) const { ++ return ranges::make_action_closure(ranges::bind_back(propagate_base_fn{}, std::move(fn), &policy)); + } + }; + +diff --git a/include/beluga/actions/reweight.hpp b/include/beluga/actions/reweight.hpp +index 6bda73b..3428d0a 100644 +--- a/include/beluga/actions/reweight.hpp ++++ b/include/beluga/actions/reweight.hpp +@@ -136,8 +136,15 @@ struct reweight_fn { + class Input, + std::enable_if_t>, int> = 0, + std::enable_if_t>, int> = 0> +- constexpr auto operator()(ExecutionPolicy policy, Input input) const { +- return ranges::make_action_closure(ranges::bind_back(reweight_fn{}, std::move(input), std::move(policy))); ++ constexpr auto operator()(const ExecutionPolicy& policy, Input input) const { ++ return ranges::make_action_closure(ranges::bind_back(reweight_fn{}, std::move(input), &policy)); ++ } ++ ++ /// Overload for the policy a view closure keeps by reference. ++ template , int> = 0> ++ constexpr auto operator()(Range&& range, Input&& input, const ExecutionPolicy* policy) const ++ -> auto& { ++ return (*this)(*policy, range, std::forward(input)); + } + + /// Overload that returns a view closure to compose with other views using the default execution policy. +diff --git a/include/beluga/algorithm/amcl_core.hpp b/include/beluga/algorithm/amcl_core.hpp +index 63f6ac1..6cba805 100644 +--- a/include/beluga/algorithm/amcl_core.hpp ++++ b/include/beluga/algorithm/amcl_core.hpp +@@ -108,11 +108,11 @@ class Amcl { + RandomStateGenerator random_state_generator, + spatial_hasher_type spatial_hasher, + const AmclParams& params = AmclParams{}, +- ExecutionPolicy execution_policy = std::execution::seq) ++ const ExecutionPolicy& execution_policy = std::execution::seq) + : params_{params}, + motion_model_{std::move(motion_model)}, + sensor_model_{std::move(sensor_model)}, +- execution_policy_{std::move(execution_policy)}, ++ execution_policy_{&execution_policy}, + spatial_hasher_{std::move(spatial_hasher)}, + random_probability_estimator_{params_.alpha_slow, params_.alpha_fast}, + update_policy_{beluga::policies::on_motion(params_.update_min_d, params_.update_min_a)}, +@@ -172,9 +172,9 @@ class Amcl { + } + + particles_ |= beluga::actions::propagate( +- execution_policy_, motion_model_(control_action_window_ << std::move(control_action))) | // +- beluga::actions::reweight(execution_policy_, sensor_model_(std::move(measurement))) | // +- beluga::actions::normalize(execution_policy_); ++ *execution_policy_, motion_model_(control_action_window_ << std::move(control_action))) | // ++ beluga::actions::reweight(*execution_policy_, sensor_model_(std::move(measurement))) | // ++ beluga::actions::normalize(*execution_policy_); + + const double random_state_probability = random_probability_estimator_(particles_); + +@@ -218,7 +218,7 @@ class Amcl { + + MotionModel motion_model_; + SensorModel sensor_model_; +- ExecutionPolicy execution_policy_; ++ const ExecutionPolicy* execution_policy_; + + spatial_hasher_type spatial_hasher_; + beluga::ThrunRecoveryProbabilityEstimator random_probability_estimator_; +diff --git a/include/beluga/algorithm/spatial_hash.hpp b/include/beluga/algorithm/spatial_hash.hpp +index 9c6c6ba..a3d0a8a 100644 +--- a/include/beluga/algorithm/spatial_hash.hpp ++++ b/include/beluga/algorithm/spatial_hash.hpp +@@ -44,9 +44,9 @@ namespace detail { + template + constexpr std::size_t floor_and_fibo_hash(double value) { + constexpr auto kFib = []() { +- if constexpr (std::is_same_v) { ++ if constexpr (sizeof(std::size_t) == sizeof(std::uint64_t)) { + return 11400714819323198485LLU; // golden ratio for 64 bits +- } else if constexpr (std::is_same_v) { ++ } else if constexpr (sizeof(std::size_t) == sizeof(std::uint32_t)) { + return 2654435769U; // golden ratio for 32 bits + } else { + // Write false in a sufficiently complex way so as to confuse the compiler. diff --git a/shared/vinca.yaml b/shared/vinca.yaml index d244c5823..abb5edd4d 100644 --- a/shared/vinca.yaml +++ b/shared/vinca.yaml @@ -98,6 +98,8 @@ packages_select_by_deps: - battery_state_broadcaster - behaviortree_cpp - behaviortree_cpp_v3 + - beluga_amcl # requested in https://github.com/RoboStack/ros-jazzy/pull/298; macOS: ros2-beluga*.osx.patch (libc++) + - beluga_ros # requested in https://github.com/RoboStack/ros-jazzy/pull/298 - better_launch - bno055 # flynneva - bond_core @@ -511,11 +513,6 @@ packages_select_by_deps: - v4l2_camera - yaets - - if: not osx - then: - - beluga_amcl # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 - - beluga_ros # macOS: libc++ lacks std::execution::sequenced_policy; requested in https://github.com/RoboStack/ros-jazzy/pull/298 - - if: linux and not aarch64 then: - franka_ros2 # Franka robots support; see PR #338 for macOS/Windows errors From 9f0e834887f3bba534f0e876537d06e2e2a2b51b Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Sun, 25 Oct 2026 08:56:04 +1000 Subject: [PATCH 5/6] beluga_ros: shared library on Windows (export all symbols) instead of static Rebuild beluga_ros and beluga_amcl in this PR's cache (ci.yaml evict_cache). Co-Authored-By: Claude Opus 5.5 --- distros/humble/ci.yaml | 4 +++- distros/jazzy/ci.yaml | 4 +++- shared/patch/ros2-beluga-ros.win.patch | 12 +++--------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/distros/humble/ci.yaml b/distros/humble/ci.yaml index 63d3a18eb..849cb4264 100644 --- a/distros/humble/ci.yaml +++ b/distros/humble/ci.yaml @@ -23,4 +23,6 @@ full_rebuild: false # # Remember that dependents are not rebuilt automatically: evict them as well if # they must pick up the change. -evict_cache: [] +evict_cache: + - beluga_ros + - beluga_amcl diff --git a/distros/jazzy/ci.yaml b/distros/jazzy/ci.yaml index 63d3a18eb..849cb4264 100644 --- a/distros/jazzy/ci.yaml +++ b/distros/jazzy/ci.yaml @@ -23,4 +23,6 @@ full_rebuild: false # # Remember that dependents are not rebuilt automatically: evict them as well if # they must pick up the change. -evict_cache: [] +evict_cache: + - beluga_ros + - beluga_amcl diff --git a/shared/patch/ros2-beluga-ros.win.patch b/shared/patch/ros2-beluga-ros.win.patch index f8afab613..cb36c9627 100644 --- a/shared/patch/ros2-beluga-ros.win.patch +++ b/shared/patch/ros2-beluga-ros.win.patch @@ -2,17 +2,11 @@ diff --git a/beluga_ros/CMakeLists.txt b/beluga_ros/CMakeLists.txt index 212972e..8395c83 100644 --- a/beluga_ros/CMakeLists.txt +++ b/beluga_ros/CMakeLists.txt -@@ -73,7 +73,12 @@ if(NOT PARANOID) +@@ -73,6 +73,7 @@ if(NOT PARANOID) endforeach() endif() --add_library(beluga_ros) -+if(WIN32) -+ add_library(beluga_ros STATIC) -+else() -+ add_library(beluga_ros) -+endif() -+ ++set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + add_library(beluga_ros) target_sources(beluga_ros PRIVATE src/amcl.cpp src/ndt_ellipsoid.cpp) target_include_directories( - beluga_ros PUBLIC $ \ No newline at end of file From 11107154d0d51713c14e131ce3ee93ed7b9c4803 Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Sun, 25 Oct 2026 15:32:47 +1000 Subject: [PATCH 6/6] ci.yaml: reset the beluga evictions (rebuilt) Co-Authored-By: Claude Opus 5.5 --- distros/humble/ci.yaml | 4 +--- distros/jazzy/ci.yaml | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/distros/humble/ci.yaml b/distros/humble/ci.yaml index 849cb4264..63d3a18eb 100644 --- a/distros/humble/ci.yaml +++ b/distros/humble/ci.yaml @@ -23,6 +23,4 @@ full_rebuild: false # # Remember that dependents are not rebuilt automatically: evict them as well if # they must pick up the change. -evict_cache: - - beluga_ros - - beluga_amcl +evict_cache: [] diff --git a/distros/jazzy/ci.yaml b/distros/jazzy/ci.yaml index 849cb4264..63d3a18eb 100644 --- a/distros/jazzy/ci.yaml +++ b/distros/jazzy/ci.yaml @@ -23,6 +23,4 @@ full_rebuild: false # # Remember that dependents are not rebuilt automatically: evict them as well if # they must pick up the change. -evict_cache: - - beluga_ros - - beluga_amcl +evict_cache: []