diff --git a/README.md b/README.md index 0484affebcb0b7c09ccdf42fe131ca6e6ec77128..a475cafcd4bd695d891b8115bd9329cab540bccf 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ The following Actions and Conditions of [ASAM OpenSCENARIO XML](https://publicat | ByEntityCondition | [SpeedCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/SpeedCondition.html) | âœ”ï¸ Without direction | | ByEntityCondition | [TimeHeadwayCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/TimeHeadwayCondition.html) | Supports only `DistanceType::kEuclidean` and `CoordinateSystem::kEntity` or `CoordinateSystem::kLane` | | ByEntityCondition | [TimeToCollisionCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/TimeToCollisionCondition.html) | In clarification: [Issue #7](https://gitlab.eclipse.org/eclipse/openopass/openscenario1_engine/-/issues/7) | +| ByEntityCondition | [TraveledDistanceCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/TraveledDistanceCondition.html) | âœ”ï¸ Complete | | ByValueCondition | [SimulationTimeCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/SimulationTimeCondition.html) | âœ”ï¸ Complete | | ByValueCondition | [UserDefinedValueCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/UserDefinedValueCondition.html) | âœ”ï¸ Complete | diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index c6a104d68d0171920d14197ed8111aa89f9bfe33..2e937ef779581ffd71c7eb0d2398719dcb566dcc 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -70,10 +70,10 @@ target_include_directories( $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include> ) -target_link_libraries(${PROJECT_NAME} PUBLIC openscenario_api::shared - antlr4_runtime::shared - Yase::agnostic_behavior_tree - units::units +target_link_libraries(${PROJECT_NAME} PUBLIC openscenario_api::shared + antlr4_runtime::shared + Yase::agnostic_behavior_tree + units::units MantleAPI::MantleAPI PRIVATE Stochastics::Stochastics) @@ -195,6 +195,7 @@ target_sources( ${CMAKE_CURRENT_LIST_DIR}/tests/Storyboard/ByEntityCondition/SpeedConditionTest.cpp ${CMAKE_CURRENT_LIST_DIR}/tests/Storyboard/ByEntityCondition/TimeHeadwayConditionTest.cpp ${CMAKE_CURRENT_LIST_DIR}/tests/Storyboard/ByEntityCondition/TimeToCollisionConditionTest.cpp + ${CMAKE_CURRENT_LIST_DIR}/tests/Storyboard/ByEntityCondition/TraveledDistanceConditionTest.cpp ${CMAKE_CURRENT_LIST_DIR}/tests/Storyboard/ByValueCondition/SimulationTimeConditionTest.cpp ${CMAKE_CURRENT_LIST_DIR}/tests/Storyboard/ByValueCondition/UserDefinedValueConditionTest.cpp ${CMAKE_CURRENT_LIST_DIR}/tests/Storyboard/GenericAction/AcquirePositionActionTest.cpp diff --git a/engine/cmake/generated_files.cmake b/engine/cmake/generated_files.cmake index 20fd7859982501b6eb18d48fa9707cde883e8ace..a1d1a4030c1e87582072b5c494c56f3bba8ef6da 100644 --- a/engine/cmake/generated_files.cmake +++ b/engine/cmake/generated_files.cmake @@ -111,7 +111,6 @@ list(APPEND ${PROJECT_NAME}_SOURCES gen/Storyboard/ByEntityCondition/RelativeAngleCondition_impl.cpp gen/Storyboard/ByEntityCondition/RelativeClearanceCondition_impl.cpp gen/Storyboard/ByEntityCondition/StandStillCondition_impl.cpp - gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp gen/Storyboard/ByValueCondition/ParameterCondition_impl.cpp gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.cpp gen/Storyboard/ByValueCondition/TimeOfDayCondition_impl.cpp @@ -207,6 +206,7 @@ list(APPEND ${PROJECT_NAME}_SOURCES src/Storyboard/ByEntityCondition/SpeedCondition_impl.cpp src/Storyboard/ByEntityCondition/TimeHeadwayCondition_impl.cpp src/Storyboard/ByEntityCondition/TimeToCollisionCondition_impl.cpp + src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp src/Storyboard/ByValueCondition/SimulationTimeCondition_impl.cpp src/Storyboard/ByValueCondition/UserDefinedValueCondition_impl.cpp src/Storyboard/GenericAction/AcquirePositionAction_impl.cpp @@ -378,7 +378,6 @@ list(APPEND ${PROJECT_NAME}_HEADERS gen/Storyboard/ByEntityCondition/TimeHeadwayCondition_impl.h gen/Storyboard/ByEntityCondition/TimeToCollisionCondition.h gen/Storyboard/ByEntityCondition/TraveledDistanceCondition.h - gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h gen/Storyboard/ByValueCondition/ParameterCondition.h gen/Storyboard/ByValueCondition/ParameterCondition_impl.h gen/Storyboard/ByValueCondition/SimulationTimeCondition.h @@ -571,6 +570,7 @@ list(APPEND ${PROJECT_NAME}_HEADERS src/Node/TrafficSignalPhaseNode.h src/Node/TriggerableCompositeNode.h src/Storyboard/ByEntityCondition/TimeToCollisionCondition_impl.h + src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h src/Storyboard/ByValueCondition/UserDefinedValueCondition_impl.h src/Storyboard/GenericAction/ActivateControllerAction.h src/Storyboard/GenericAction/ActivateControllerAction_base.h diff --git a/engine/gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp b/engine/src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp similarity index 53% rename from engine/gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp rename to engine/src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp index f06cb272a03d5c0461b9ce1c96cec4d70487f415..11e1a10b1615575dcf64ac895702726b318a3837 100644 --- a/engine/gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp +++ b/engine/src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.cpp @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2021-2024 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 @@ -10,18 +11,29 @@ #include "Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h" +#include "Utils/EntityUtils.h" #include "Utils/Logger.h" namespace OpenScenarioEngine::v1_3 { -bool TraveledDistanceCondition::IsSatisfied() const +bool TraveledDistanceCondition::IsSatisfied() { - // Note: - // - Access to values parse to mantle/ose datatypes: this->values.xxx - // - Access to mantle interfaces: this->mantle.xxx - Logger::Error("Method TraveledDistanceCondition::IsSatisfied() not implemented yet (returning \"true\" by default)"); - return true; + const auto& entity = EntityUtils::GetEntityByName(mantle.environment, values.triggeringEntity); + + auto current_position = entity.GetPosition(); + + if (!last_position_.has_value()) + { + last_position_ = current_position; + } + + const auto distance_delta = (current_position - last_position_.value()).Length(); + + traveled_distance_ += distance_delta; + last_position_ = current_position; + + return traveled_distance_.value() >= values.value; } } // namespace OpenScenarioEngine::v1_3 diff --git a/engine/gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h b/engine/src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h similarity index 78% rename from engine/gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h rename to engine/src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h index b1c2f5451984e3bbf1f948d1b0df41796867faa8..90179ad163565c0571e141ea13df494a374741f6 100644 --- a/engine/gen/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h +++ b/engine/src/Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2021-2024 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 @@ -10,7 +11,9 @@ #pragma once +#include <MantleAPI/Common/vector.h> #include <MantleAPI/Execution/i_environment.h> +#include <units.h> #include "Utils/EntityBroker.h" @@ -34,11 +37,14 @@ public: : values{std::move(values)}, mantle{std::move(interfaces)} {}; - bool IsSatisfied() const; + bool IsSatisfied(); private: Values values; Interfaces mantle; + + units::length::meter_t traveled_distance_{}; + std::optional<mantle_api::Vec3<units::length::meter_t>> last_position_; }; -} // namespace OpenScenarioEngine::v1_3 \ No newline at end of file +} // namespace OpenScenarioEngine::v1_3 diff --git a/engine/tests/Storyboard/ByEntityCondition/TraveledDistanceConditionTest.cpp b/engine/tests/Storyboard/ByEntityCondition/TraveledDistanceConditionTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..07417f459115d64f525f2eff18ed7ecd47ce2ac1 --- /dev/null +++ b/engine/tests/Storyboard/ByEntityCondition/TraveledDistanceConditionTest.cpp @@ -0,0 +1,84 @@ +/******************************************************************************** + * 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 + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ + +#include <MantleAPI/Test/test_utils.h> +#include <gtest/gtest.h> + +#include "Storyboard/ByEntityCondition/TraveledDistanceCondition_impl.h" +#include "TestUtils/TestLogger.h" + +using namespace mantle_api; +using namespace units::literals; +using testing::Eq; +using testing::Return; +using TestPosition = mantle_api::Vec3<units::length::meter_t>; + +class TraveledDistanceConditionTestFixture : public ::testing::Test +{ +protected: + void SetUp() override + { + mock_environment_ = std::make_shared<MockEnvironment>(); + auto &entity_ref = mock_environment_->GetEntityRepository().Get(condition_values_.triggeringEntity)->get(); + entity_under_test_ = dynamic_cast<MockVehicle *>(&entity_ref); + } + + std::shared_ptr<MockEnvironment> mock_environment_; + MockVehicle *entity_under_test_; + OpenScenarioEngine::v1_3::TraveledDistanceCondition::Values condition_values_{.triggeringEntity = "vehicle1", + .value = 5.0}; +}; + +TEST_F(TraveledDistanceConditionTestFixture, GivenConditionWithMockedEntities_WhenCheckingCondition_ThenDoesNotThrow) +{ + OpenScenarioEngine::v1_3::TraveledDistanceCondition traveled_distance_condition(condition_values_, + {mock_environment_}); + + EXPECT_NO_THROW([[maybe_unused]] auto _ = traveled_distance_condition.IsSatisfied()); +} + +TEST_F(TraveledDistanceConditionTestFixture, GivenConditionWithNoMovement_WhenCheckingCondition_ThenReturnsFalse) +{ + OpenScenarioEngine::v1_3::TraveledDistanceCondition traveled_distance_condition(condition_values_, + {mock_environment_}); + + EXPECT_CALL(*entity_under_test_, GetPosition()) + .WillOnce(Return(TestPosition{0_m, 0_m, 0_m})); + + EXPECT_FALSE(traveled_distance_condition.IsSatisfied()); +} + +TEST_F(TraveledDistanceConditionTestFixture, GivenConditionWithSatisfcatoryTraveledDistance_WhenCheckingCondition_ThenReturnsTrue) +{ + OpenScenarioEngine::v1_3::TraveledDistanceCondition traveled_distance_condition(condition_values_, + {mock_environment_}); + + EXPECT_CALL(*entity_under_test_, GetPosition()) + .WillOnce(Return(TestPosition{1_m, 1_m, 1_m})) + .WillOnce(Return(TestPosition{4_m, 5_m, 1_m})); + + EXPECT_THAT(traveled_distance_condition.IsSatisfied(), Eq(false)); + // Condition is satisfied after the second call. + EXPECT_THAT(traveled_distance_condition.IsSatisfied(), Eq(true)); +} + +TEST_F(TraveledDistanceConditionTestFixture, GivenConditionWithUnsatisfcatoryTraveledDistance_WhenCheckingCondition_ThenReturnsFalse) +{ + OpenScenarioEngine::v1_3::TraveledDistanceCondition traveled_distance_condition(condition_values_, + {mock_environment_}); + + EXPECT_CALL(*entity_under_test_, GetPosition()) + .WillOnce(Return(TestPosition{1_m, 1_m, 1_m})) + .WillOnce(Return(TestPosition{4_m, 4_m, 1_m})); + + EXPECT_THAT(traveled_distance_condition.IsSatisfied(), Eq(false)); + // Condition is still not satisfied after the second call. + EXPECT_THAT(traveled_distance_condition.IsSatisfied(), Eq(false)); +}