diff --git a/README.md b/README.md index 3061b72d72cb22a6f2ff5ef3c310927107a57fe3..d511aa968bd560ccc1be53376aea9d6884a7b052 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ The following Actions and Conditions of [ASAM OpenSCENARIO XML](https://publicat | ByEntityCondition | [RelativeDistanceCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/RelativeDistanceCondition.html) | Supports only `RelativeDistanceType::kLongitudinal && CoordinateSystem::kEntity` | | ByEntityCondition | [RelativeSpeedCondition](https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/RelativeSpeedCondition.html) | âœ”ï¸ Complete | | 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 | [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` or `CoordinateSystem::kRoad(freespace=false)` | | 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 | @@ -269,7 +269,7 @@ For more information on how to define these properties, refer to the documentati | [CPM](https://github.com/cpm-cmake/CPM.cmake) | 03705fc | 0.36.0 | MIT License | | [googletest](https://github.com/google/googletest) | f8d7d77 | 1.14.0 | BSD-3-Clause License | | [JSON for Modern C++](https://github.com/nlohmann/json) | db78ac1 | 3.9.1 | MIT License | -| [MantleAPI](https://gitlab.eclipse.org/eclipse/openpass/mantle-api) | fa2c771a | 17.0.0 | EPL 2.0 | +| [MantleAPI](https://gitlab.eclipse.org/eclipse/openpass/mantle-api) | 7d2ed281 | 18.0.0 | EPL 2.0 | | [openpass/stochastics-library](https://gitlab.eclipse.org/eclipse/openpass/stochastics-library) | 6c9dde71 | 0.11.0 | EPL 2.0 | | [OpenSCENARIO API](https://github.com/RA-Consulting-GmbH/openscenario.api.test/) | 5980e88 | 1.4.0 | Apache 2.0 | | [Units](https://github.com/nholthaus/units) | e27eed9 | 2.3.4 | MIT License | diff --git a/engine/src/Storyboard/ByEntityCondition/TimeHeadwayCondition_impl.cpp b/engine/src/Storyboard/ByEntityCondition/TimeHeadwayCondition_impl.cpp index 24b9bfbfa458083e09d4d58129941dc5ae27d513..d2f70a55c1a434acb8d6843b000224f787a1b63c 100644 --- a/engine/src/Storyboard/ByEntityCondition/TimeHeadwayCondition_impl.cpp +++ b/engine/src/Storyboard/ByEntityCondition/TimeHeadwayCondition_impl.cpp @@ -1,6 +1,6 @@ /******************************************************************************** * Copyright (c) 2021-2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2023 Ansys, Inc. + * Copyright (c) 2023-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 @@ -25,9 +25,11 @@ bool TimeHeadwayCondition::IsSatisfied() const return false; } - if (!(values.coordinateSystem == CoordinateSystem::kEntity || values.coordinateSystem == CoordinateSystem::kLane)) + if ((values.coordinateSystem != CoordinateSystem::kEntity && + values.coordinateSystem != CoordinateSystem::kLane && + values.coordinateSystem != CoordinateSystem::kRoad)) { - Logger::Error(R"(TimeHeadwayCondition: The given CoordinateSystem is not supported. Only "entity" and "lane" coordinate systems are supported for now. Returning false.)"); + Logger::Error(R"(TimeHeadwayCondition: The given CoordinateSystem is not supported. Only "entity", "lane" and "road" coordinate systems are supported for now. Returning false.)"); return false; } @@ -74,6 +76,24 @@ bool TimeHeadwayCondition::IsSatisfied() const units::math::abs(ref_entity_corners_along_lane.back().x)); } } + else if (values.coordinateSystem == CoordinateSystem::kRoad) + { + if (values.freespace) + { + Logger::Error(R"(TimeHeadwayCondition: The "road" coordinate system does not support freespace for now. Returning false.)"); + return false; + } + const auto longitudinal_lane_distance = + mantle.environment->GetQueryService().GetLongitudinalRoadDistanceBetweenPositions(trigger_entity->GetPosition(), + ref_entity->GetPosition()); + if (!longitudinal_lane_distance.has_value()) + { + throw std::runtime_error( + "TimeHeadwayCondition: CoordinateSystem is set to \"ROAD\", but can not get the longitudinal distance " + "of the reference and the triggering entities along the Road Refenrence line. Please adjust scenario."); + } + distance = longitudinal_lane_distance.value(); + } else { // should never happen, as pre-conditions are already checked in the beginning diff --git a/engine/tests/Storyboard/ByEntityCondition/TimeHeadwayConditionTest.cpp b/engine/tests/Storyboard/ByEntityCondition/TimeHeadwayConditionTest.cpp index 9eac6d977d2e66e3dc6f5b7c8dbfa5438781171a..1ff79ff2e4ca5d27951cd03a34ac0f3af4edfed7 100644 --- a/engine/tests/Storyboard/ByEntityCondition/TimeHeadwayConditionTest.cpp +++ b/engine/tests/Storyboard/ByEntityCondition/TimeHeadwayConditionTest.cpp @@ -1,6 +1,6 @@ /******************************************************************************** * Copyright (c) 2021-2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2023 Ansys, Inc. + * Copyright (c) 2023-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 @@ -86,16 +86,34 @@ TEST_F(TimeHeadwayConditionTestFixture, } TEST_F(TimeHeadwayConditionTestFixture, - GivenConditionWithUnsupportedCoordinateSystemRoad_WhenEvaluate_ThenReturnsFalse) + GivenConditionWithCoordinateSystemRoadAndFreespaceTrue_WhenEvaluate_ThenReturnsFalse) { condition_values_.coordinateSystem = OpenScenarioEngine::v1_3::CoordinateSystem::kRoad; + condition_values_.freespace = true; auto time_headway_condition = OpenScenarioEngine::v1_3::TimeHeadwayCondition(condition_values_, {fake_environment_}); EXPECT_FALSE(time_headway_condition.IsSatisfied()); EXPECT_THAT(LOGGER->LastLogLevel(), mantle_api::LogLevel::kError); - EXPECT_THAT(LOGGER->LastLogMessage(), HasSubstr("CoordinateSystem is not supported")); + EXPECT_THAT(LOGGER->LastLogMessage(), HasSubstr("does not support freespace")); +} + +TEST_F(TimeHeadwayConditionTestFixture, + GivenConditionWithCoordinateSystemRoadButCanNotCalculateDistance_WhenEvaluate_ThenThrowRuntimeError) +{ + condition_values_.coordinateSystem = OpenScenarioEngine::v1_3::CoordinateSystem::kRoad; + + auto& mocked_query_service = dynamic_cast<const mantle_api::MockLaneLocationQueryService&>(fake_environment_->GetQueryService()); + + EXPECT_CALL(mocked_query_service, GetLongitudinalRoadDistanceBetweenPositions(_, _)) + .Times(1) + .WillRepeatedly(Return(std::nullopt)); + + auto time_headway_condition = OpenScenarioEngine::v1_3::TimeHeadwayCondition(condition_values_, + {fake_environment_}); + + EXPECT_THROW(time_headway_condition.IsSatisfied(), std::runtime_error); } TEST_F(TimeHeadwayConditionTestFixture, @@ -286,3 +304,24 @@ TEST_P(TimeHeadwayConditionTestForCoordinateSystemWithFreespaceFalse, EXPECT_EQ(time_headway_condition.IsSatisfied(), expected_satisfied_status_); } + +TEST_P(TimeHeadwayConditionTestForCoordinateSystemWithFreespaceFalse, + GivenCoordinateSystemIsRoadWithTestInputsAndFreespaceFalse_WhenEvaluate_ThenExpectCorrectSatisfiedStatus) +{ + auto rule = OpenScenarioEngine::v1_3::Rule(NET_ASAM_OPENSCENARIO::v1_3::Rule::RuleEnum::EQUAL_TO, condition_value_); + condition_values_.rule = rule; + condition_values_.coordinateSystem = OpenScenarioEngine::v1_3::CoordinateSystem::kRoad; + + auto& mocked_query_service = dynamic_cast<const mantle_api::MockLaneLocationQueryService&>(fake_environment_->GetQueryService()); + auto& mocked_entity = dynamic_cast<mantle_api::MockVehicle&>(*fake_environment_->GetEntityRepository().Get("")); + + EXPECT_CALL(mocked_entity, GetVelocity()).WillOnce(Return(triggering_entity_velocity_)); + + EXPECT_CALL(mocked_query_service, GetLongitudinalRoadDistanceBetweenPositions(_, _)) + .WillOnce(Return(relative_distance_)); + + auto time_headway_condition = OpenScenarioEngine::v1_3::TimeHeadwayCondition(condition_values_, + {fake_environment_}); + + EXPECT_EQ(time_headway_condition.IsSatisfied(), expected_satisfied_status_); +} diff --git a/engine/third_party/mantle_api/mantle_api.bzl b/engine/third_party/mantle_api/mantle_api.bzl index ad52ffe6dd865db3d77464166aa2722f667f9e94..270c21bcea3c10d28b6ced1aa7caa5e88854fb22 100644 --- a/engine/third_party/mantle_api/mantle_api.bzl +++ b/engine/third_party/mantle_api/mantle_api.bzl @@ -1,14 +1,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") -_TAG = "v17.0.0" +_TAG = "v18.0.0" def mantle_api(): maybe( http_archive, name = "mantle_api", url = "https://gitlab.eclipse.org/eclipse/openpass/mantle-api/-/archive/{tag}/mantle-api-{tag}.tar.gz".format(tag = _TAG), - sha256 = "b13786605d9a1e459dc4c65ab0ce4c3c40ddfd859266f1d876622fa578ffc5f9", + sha256 = "4c413e3bd035531f232c5b54aeaa329b82c9e80926f44cd6364d6892034e87d5", strip_prefix = "mantle-api-{tag}".format(tag = _TAG), type = "tar.gz", ) diff --git a/utils/ci/conan/conanfile.txt b/utils/ci/conan/conanfile.txt index 2942ecce528a108ef80651a5863adba9c972d3bd..4f986fd063a6514d025192216362d5b6728db469 100644 --- a/utils/ci/conan/conanfile.txt +++ b/utils/ci/conan/conanfile.txt @@ -1,5 +1,5 @@ [requires] -mantleapi/v17.0.0@openscenarioengine/testing +mantleapi/v18.0.0@openscenarioengine/testing nlohmann_json/v3.9.1@openscenarioengine/testing openscenario_api/v1.4.0@openscenarioengine/testing stochastics/0.11.0@openscenarioengine/testing diff --git a/utils/ci/conan/recipe/mantleapi/all/conandata.yml b/utils/ci/conan/recipe/mantleapi/all/conandata.yml index 81269171254a1107bfd21634d3494ed9618d7a30..81018803ef8b87d8af9aa9086d3395b067ac0c16 100644 --- a/utils/ci/conan/recipe/mantleapi/all/conandata.yml +++ b/utils/ci/conan/recipe/mantleapi/all/conandata.yml @@ -65,5 +65,9 @@ sources: url: https://gitlab.eclipse.org/eclipse/openpass/mantle-api.git sha256: "fa2c771a62d8f7f0a5dca119f3b310439f06f825" + "18.0.0": + url: https://gitlab.eclipse.org/eclipse/openpass/mantle-api.git + sha256: "7d2ed281116d59d7270d4b8e01811e64a7dc665c" + "default": url: https://gitlab.eclipse.org/eclipse/openpass/mantle-api.git