diff --git a/beluga/include/beluga/localization.hpp b/beluga/include/beluga/localization.hpp index ae6ac2000..277b21b87 100644 --- a/beluga/include/beluga/localization.hpp +++ b/beluga/include/beluga/localization.hpp @@ -44,6 +44,19 @@ namespace beluga { * - \ref localization.hpp */ +/// Composes multiple interfaces into a single interface type. +/** + * \tparam Interfaces Interfaces to combine. + */ +template +struct compose_interfaces : public Interfaces... { + /// Virtual destructor. + /** + * Makes it so at least one of the interfaces provides a virtual destructor. + */ + ~compose_interfaces() override = default; +}; + /// A null mixin interface. Meant to be the default value for an optional customization point. class NullMixinInterface { public: @@ -70,7 +83,7 @@ class NullMixin : public Mixin { * \tparam CustomExtensionMixinInterface An optional mixin interface for the user to customize the filter. */ template -using LaserLocalizationInterface2d = beluga::mixin::compose_interfaces< +using LaserLocalizationInterface2d = beluga::compose_interfaces< BaseParticleFilterInterface, StorageInterface, EstimationInterface2d, @@ -78,22 +91,52 @@ using LaserLocalizationInterface2d = beluga::mixin::compose_interfaces< LaserSensorModelInterface2d, CustomExtensionMixinInterface>; +/// \cond + +/// Wrapper to convert a motion model class into a mixin. +template +struct MotionMixin : public Mixin, public Model { + using update_type = typename Model::update_type; + + template + constexpr explicit MotionMixin(Model model, Args&&... args) + : Model(std::move(model)), Mixin(static_cast(args)...) {} + + void update_motion(const update_type& pose) { Model::update_motion(pose); } +}; + +/// Wrapper to convert a sensor model class into a mixin. +template +struct SensorMixin : public Mixin, public Model { + using measurement_type = typename Model::measurement_type; + using map_type = typename Model::map_type; + + template + constexpr explicit SensorMixin(Model model, Args&&... args) + : Model(std::move(model)), Mixin(static_cast(args)...) {} + + void update_sensor(measurement_type&& measurement) { Model::update_sensor(std::move(measurement)); } + void update_map(map_type&& map) { Model::update_map(std::move(map)); } +}; + +/// \endcond + /// An implementation of Monte Carlo Localization. /** * An instance of this class template implements beluga::LaserLocalizationInterface2d * and \ref LocalizationPage. * - * \tparam MotionDescriptor A descriptor of a mixin that implements \ref MotionModelPage. - * \tparam SensorDescriptor A descriptor of a mixin that implements \ref SensorModelPage. + * \tparam MotionModel A class that implements \ref MotionModelPage. + * \tparam SensorModel A class that implements \ref SensorModelPage. * \tparam Map Environment representation type consistent with the sensor descriptor. - * \tparam CustomExtensionMixinInterface An optional mixin interface for the user to customize the filter. + * \tparam Interface An optional mixin interface for the user to customize the filter. * \tparam CustomExtensionMixin An optional mixin type for the user to customize the filter. */ template < - class MotionDescriptor, - class SensorDescriptor, + class MotionModel, + class SensorModel, class Map, - class CustomExtensionMixinInterface = NullMixinInterface, + class Interface = NullMixinInterface, template class CustomExtensionMixin = NullMixin> using MonteCarloLocalization2d = ciabatta::mixin< BootstrapParticleFilter, @@ -102,27 +145,27 @@ using MonteCarloLocalization2d = ciabatta::mixin< RandomStateGenerator, NaiveSampler, FixedLimiter, - MotionDescriptor::template mixin, - SensorDescriptor::template mixin, + ciabatta::curry::template mixin, + ciabatta::curry::template mixin, CustomExtensionMixin, - ciabatta::provides>::template mixin>; + ciabatta::provides::template mixin>; /// An implementation of Adaptive Monte Carlo Localization. /** * An instance of this class template implements beluga::LaserLocalizationInterface2d * and \ref LocalizationPage. * - * \tparam MotionDescriptor A descriptor of a mixin that implements \ref MotionModelPage. - * \tparam SensorDescriptor A descriptor of a mixin that implements \ref SensorModelPage. + * \tparam MotionModel A class that implements \ref MotionModelPage. + * \tparam SensorModel A class that implements \ref SensorModelPage. * \tparam Map Environment representation type consistent with the sensor descriptor. - * \tparam CustomExtensionMixinInterface An optional mixin interface for the user to customize the filter. + * \tparam Interface An optional mixin interface for the user to customize the filter. * \tparam CustomExtensionMixin An optional mixin type for the user to customize the filter. */ template < - class MotionDescriptor, - class SensorDescriptor, + class MotionModel, + class SensorModel, class Map, - class CustomExtensionMixinInterface = NullMixinInterface, + class Interface = NullMixinInterface, template class CustomExtensionMixin = NullMixin> using AdaptiveMonteCarloLocalization2d = ciabatta::mixin< BootstrapParticleFilter, @@ -131,10 +174,10 @@ using AdaptiveMonteCarloLocalization2d = ciabatta::mixin< RandomStateGenerator, AdaptiveSampler, ciabatta::curry::mixin, - MotionDescriptor::template mixin, - SensorDescriptor::template mixin, + ciabatta::curry::template mixin, + ciabatta::curry::template mixin, CustomExtensionMixin, - ciabatta::provides>::template mixin>; + ciabatta::provides::template mixin>; } // namespace beluga diff --git a/beluga/include/beluga/mixin.hpp b/beluga/include/beluga/mixin.hpp index 8cf2d144e..b4f6fc544 100644 --- a/beluga/include/beluga/mixin.hpp +++ b/beluga/include/beluga/mixin.hpp @@ -15,13 +15,9 @@ #ifndef BELUGA_MIXIN_HPP #define BELUGA_MIXIN_HPP -#include - -#include #include #include #include -#include #include /** @@ -29,76 +25,4 @@ * \brief Implementation of mixin utilities and extensions. */ -namespace beluga::mixin { - -/// Composes multiple interfaces into a single interface type. -/** - * \tparam Interfaces Interfaces to combine. - */ -template -struct compose_interfaces : public Interfaces... { - /// Virtual destructor. - /** - * Makes it so at least one of the interfaces provides a virtual destructor. - */ - ~compose_interfaces() override = default; -}; - -/// Helper method to get descriptor parameters or forward the value. -/** - * \tparam T The type of the input value. - * \param value A value to get the params from, or to forward. - * \return The params with the same value category of the input value or - * the input value forwarded. - */ -template -constexpr auto&& params_or_forward(T&& value) noexcept { - if constexpr (is_descriptor_v && has_params_v) { - return forward_like(value.params); - } else { - return std::forward(value); - } -} - -/// Constructs a mixin and wraps it into a `std::unique_ptr` to a given interface. -/** - * This method can be used to create different mixin alternatives based on - * the input arguments. The input arguments can be parameters of the mixin constructor - * or descriptor variants holding parameters of the mixin constructor. - * - * This function will use the descriptor information to instantiate the correct - * mixin type and construct it with the given parameters. - * - * Descriptors can also contain no parameters, in which case the type information - * will be used to deduce the mixin type and there is no need to forward parameter - * values to the constructor. - * - * All the possible mixin alternatives from the input variants must implement `Interface`, - * and the `Interface` type must be specified since this function must return the - * same type for all possible combinations of variants. - * - * Examples: - * \snippet test/beluga/test_mixin.cpp Using make_mixin - * - * \tparam Interface The interface type used to create the std::unique_ptr. - * \tparam Base A base mixin template taking descriptors. - * \tparam Args The input argument or descriptor types from which to instantiate the mixin. - * \param args The input arguments or descriptor instances from which to construct the mixin. - * \return A `std::unique_ptr` of an instance of type `Interface`. - */ -template class Base, class... Args> -auto make_mixin(Args&&... args) { - return visit_everything( - [](auto&&... args) { - using InnerArgs = list; // avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86859 - using Concrete = mixin_from_descriptors_t>; - return std::apply( - [](auto&&... args) -> std::unique_ptr { return std::make_unique(args...); }, - make_tuple_with(params_or_forward(args)...)); - }, - args...); -} - -} // namespace beluga::mixin - #endif diff --git a/beluga/include/beluga/mixin/descriptor.hpp b/beluga/include/beluga/mixin/descriptor.hpp deleted file mode 100644 index b88410160..000000000 --- a/beluga/include/beluga/mixin/descriptor.hpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2023 Ekumen, Inc. -// -// 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 BELUGA_MIXIN_DESCRIPTOR_HPP -#define BELUGA_MIXIN_DESCRIPTOR_HPP - -#include - -#include - -/** - * \file - * \brief Implementation of descriptors and their traits. - */ - -namespace beluga::mixin { - -/// Primary template for a mixin descriptor. -/** - * \tparam Mixin A mixin template class. - * \tparam Params A variadic list of parameter types. - */ -template