diff --git a/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.cpp b/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.cpp index e2d130186bb2e9db5b67debbe996500587687a0a..ce93f519814b5fb4c26927774bb19579c2a51109 100644 --- a/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.cpp +++ b/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.cpp @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2021-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * Copyright (c) 2025, Ansys, Inc. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -11,9 +11,14 @@ #include "Conversion/OscToMantle/ConvertScenarioTransitionDynamics.h" +#include <ApiClassInterfacesV1_3.h> +#include <EnumerationsV1_3.h> +#include <MantleAPI/Traffic/control_strategy.h> #include <MantleAPI/Traffic/entity_helper.h> +#include <memory> #include <optional> +#include <stdexcept> #include "Conversion/OscToMantle/ConvertScenarioShape.h" @@ -61,13 +66,23 @@ mantle_api::Dimension ConvertToMantleApi(const NET_ASAM_OPENSCENARIO::v1_3::Dyna TransitionDynamics ConvertScenarioTransitionDynamics( const std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::ITransitionDynamics>& transitionDynamics) { - return { - {/*.dimension = */ detail::ConvertToMantleApi(transitionDynamics->GetDynamicsDimension()), - /*.shape = */ ConvertScenarioShape(transitionDynamics->GetDynamicsShape()), - /*.value = */ transitionDynamics->GetValue()}, + const auto kShape = ConvertScenarioShape(transitionDynamics->GetDynamicsShape()); + const auto kValue = transitionDynamics->GetValue(); + + if (kShape != mantle_api::Shape::kStep && kValue <= 0.0) + { + throw std::invalid_argument( + "ConvertScenarioTransitionDynamics: 'value' must be greater than zero " + "if 'dynamicsShape' is not 'step'. Please adjust the scenario."); + } + + const std::optional<FollowingMode> kFollowingMode = transitionDynamics->IsSetFollowingMode() - ? std::make_optional(detail::ConvertToOse(transitionDynamics->GetFollowingMode())) - : std::nullopt}; + ? std::make_optional<FollowingMode>(detail::ConvertToOse(transitionDynamics->GetFollowingMode())) + : std::nullopt; + + const auto kDimension = detail::ConvertToMantleApi(transitionDynamics->GetDynamicsDimension()); + return {{kDimension, kShape, kValue}, kFollowingMode}; } -} // namespace OpenScenarioEngine::v1_3 \ No newline at end of file +} // namespace OpenScenarioEngine::v1_3 diff --git a/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.h b/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.h index 68f949ffc880cca254b4c4694e77b14a22742328..5f4d354cc1afa6983f5037779ba1087da5432577 100644 --- a/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.h +++ b/engine/src/Conversion/OscToMantle/ConvertScenarioTransitionDynamics.h @@ -11,12 +11,11 @@ #pragma once +#include <ApiClassInterfacesV1_3.h> #include <MantleAPI/Traffic/control_strategy.h> -#include <openScenarioLib/generated/v1_3/api/ApiClassInterfacesV1_3.h> #include <memory> #include <optional> -#include <string> namespace OpenScenarioEngine::v1_3 { @@ -35,4 +34,4 @@ struct TransitionDynamics TransitionDynamics ConvertScenarioTransitionDynamics( const std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::ITransitionDynamics>& transitionDynamics); -} // namespace OpenScenarioEngine::v1_3 \ No newline at end of file +} // namespace OpenScenarioEngine::v1_3 diff --git a/engine/tests/Conversion/OscToMantle/ConvertScenarioTransitionDynamicsTest.cpp b/engine/tests/Conversion/OscToMantle/ConvertScenarioTransitionDynamicsTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c9247a758392c894a641dc5468b2818923e2149 --- /dev/null +++ b/engine/tests/Conversion/OscToMantle/ConvertScenarioTransitionDynamicsTest.cpp @@ -0,0 +1,68 @@ +/******************************************************************************** + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ + +#include <ApiClassImplV1_3.h> +#include <EnumerationsV1_3.h> +#include <gtest/gtest.h> + +#include <memory> +#include <stdexcept> + +#include "Conversion/OscToMantle/ConvertScenarioTransitionDynamics.h" + +class TransitionDynamicsTestFixture : public testing::Test +{ +protected: + static std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::TransitionDynamicsImpl> CreateTransitionDynamics( + const NET_ASAM_OPENSCENARIO::v1_3::DynamicsDimension& dimension, + const NET_ASAM_OPENSCENARIO::v1_3::DynamicsShape& shape, + const double& value) + { + std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::TransitionDynamicsImpl> transistion_dynamics{ + std::make_shared<NET_ASAM_OPENSCENARIO::v1_3::TransitionDynamicsImpl>()}; + + transistion_dynamics->SetDynamicsDimension(dimension); + transistion_dynamics->SetDynamicsShape(shape); + transistion_dynamics->SetValue(value); + + return transistion_dynamics; + } + + const NET_ASAM_OPENSCENARIO::v1_3::DynamicsDimension kDimensionTime{ + NET_ASAM_OPENSCENARIO::v1_3::DynamicsDimension::TIME}; + const NET_ASAM_OPENSCENARIO::v1_3::DynamicsShape kShapeLinear{NET_ASAM_OPENSCENARIO::v1_3::DynamicsShape::LINEAR}; +}; + +class TransitionDynamicsTestFixtureP : public TransitionDynamicsTestFixture, public testing::WithParamInterface<double> +{ +}; + +INSTANTIATE_TEST_SUITE_P(TransitionDynamicsTestFixture, TransitionDynamicsTestFixtureP, testing::Values(0.0, -1.0)); + +TEST_P(TransitionDynamicsTestFixtureP, GivenShapeWithInvalidInput_WhenConvert_ThenThrowExecption) +{ + const double kInvalidValue{GetParam()}; + + std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::TransitionDynamicsImpl> transistion_dynamics{ + CreateTransitionDynamics(kDimensionTime, kShapeLinear, kInvalidValue)}; + + EXPECT_THROW(OpenScenarioEngine::v1_3::ConvertScenarioTransitionDynamics(transistion_dynamics), + std::invalid_argument); +} + +TEST_F(TransitionDynamicsTestFixture, GivenShapeWithValidInput_WhenConvert_ThenNoExecption) +{ + const double kValidValue{1.0}; + + std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::TransitionDynamicsImpl> transistion_dynamics{ + CreateTransitionDynamics(kDimensionTime, kShapeLinear, kValidValue)}; + + EXPECT_NO_THROW(OpenScenarioEngine::v1_3::ConvertScenarioTransitionDynamics(transistion_dynamics)); +} diff --git a/engine/tests/builders/ActionBuilder.cpp b/engine/tests/builders/ActionBuilder.cpp index a6165270bed937e8fcbfc6579ac475dd6227e4bb..3862a42ab8439233b93d5e71535d7716161d2b98 100644 --- a/engine/tests/builders/ActionBuilder.cpp +++ b/engine/tests/builders/ActionBuilder.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021-2024, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2025, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * Copyright (c) 2022-2025 Ansys, Inc. * * This program and the accompanying materials are made @@ -257,6 +257,9 @@ std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::IRelativeTargetSpeedWriter> FakeRel FakeTransitionDynamicsBuilder::FakeTransitionDynamicsBuilder() : transition_dynamics_(std::make_shared<NET_ASAM_OPENSCENARIO::v1_3::TransitionDynamicsImpl>()) { + transition_dynamics_->SetDynamicsShape(NET_ASAM_OPENSCENARIO::v1_3::DynamicsShape::STEP); + transition_dynamics_->SetDynamicsDimension(NET_ASAM_OPENSCENARIO::v1_3::DynamicsDimension::TIME); + transition_dynamics_->SetValue(0.0); } FakeTransitionDynamicsBuilder::FakeTransitionDynamicsBuilder(