Commit f84797ea authored by Andreas Rauschert's avatar Andreas Rauschert
Browse files

Merge master into buildfix_define_function_in_header_inline

Conflicting files:
MantleAPI/include/MantleAPI/Execution/i_environment.h
MantleAPI/include/MantleAPI/Map/i_lane_location_query_service.h
MantleAPI/include/MantleAPI/Map/map_details.h
MantleAPI/include/MantleAPI/Traffic/control_strategy.h
MantleAPI/include/MantleAPI/Traffic/entity_helper.h
MantleAPI/include/MantleAPI/Traffic/entity_properties.h
MantleAPI/include/MantleAPI/Traffic/i_entity.h
MantleAPI/include/MantleAPI/Traffic/i_entity_repository.h
MantleAPI/test/MantleAPI/Test/test_utils.h
MantleAPI/test/interface_test.cpp
parents 778590f9 6e78b450
---
BasedOnStyle: Google
AccessModifierOffset: -2
AllowShortFunctionsOnASingleLine: Inline
BinPackArguments: false
BinPackParameters: false
BreakBeforeBraces: Allman
ColumnLimit: 0
line_width: 120
tab_size: 2
max_subgroups_hwrap: 2
max_pargs_hwrap: 6
separate_ctrl_name_with_space: false
separate_fn_name_with_space: false
dangle_parens: true
dangle_align: prefix
min_prefix_chars: 4
max_prefix_chars: 10
max_lines_hwrap: 2
line_ending: unix
command_case: canonical
keyword_case: upper
additional_commands:
configure_package_config_file:
flags:
- NO_SET_AND_CHECK_MACRO
- NO_CHECK_REQUIRED_COMPONENTS_MACRO
kwargs:
INSTALL_DESTINATION: "*"
PATH_VARS: "*"
INSTALL_PREFIX: "*"
find_dependency:
flags:
- CONFIG
- QUIET
- REQUIRED
kwargs:
COMPONENTS: "*"
gtest_discover_tests:
flags:
- NO_PRETTY_TYPES
- NO_PRETTY_VALUES
kwargs:
EXTRA_ARGS: "*"
WORKING_DIRECTORY: "*"
TEST_PREFIX: "*"
TEST_SUFFIX: "*"
PROPERTIES: "*"
TEST_LIST: "*"
DISCOVERY_TIMEOUT: "*"
setup_target_for_coverage_gcovr_html:
kwargs:
BASE_DIRECTORY: "*"
EXCLUDE: "*"
EXECUTABLE: "*"
EXECUTABLE_ARGS: "*"
DEPENDENCIES: "*"
always_wrap: ["add_library", "find_package", "find_dependency", "target_include_directories"]
enable_sort: true
autosort: false
hashruler_min_length: 10
per_command: {}
layout_passes: {}
bullet_char: "*"
enum_char: .
enable_markup: true
first_comment_is_literal: true
literal_comment_pattern: null
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
canonicalize_hashrulers: true
emit_byteorder_mark: false
input_encoding: utf-8
output_encoding: utf-8
......@@ -8,7 +8,7 @@
# SPDX-License-Identifier: EPL-2.0
################################################################################
cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR)
# Add the custom CMake modules to CMake's module path
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
......@@ -17,7 +17,8 @@ project(
ScenarioAPI
VERSION 0.1.0
DESCRIPTION "Scenario API, an abstraction layer for environmental simulators"
LANGUAGES CXX)
LANGUAGES CXX
)
# Project setup only if this is the main project
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
......@@ -30,8 +31,7 @@ endif()
add_subdirectory(MantleAPI)
# Should we build documentation for the project?
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_DOCUMENTATION)
OR ScenarioAPI_BUILD_DOCUMENTATION)
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_DOCUMENTATION) OR ScenarioAPI_BUILD_DOCUMENTATION)
add_subdirectory(doc)
endif()
......
......@@ -8,15 +8,22 @@
# SPDX-License-Identifier: EPL-2.0
################################################################################
find_package(units CONFIG REQUIRED)
find_package(
units CONFIG REQUIRED
)
file(
GLOB_RECURSE HEADERS
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
CONFIGURE_DEPENDS "*.h")
CONFIGURE_DEPENDS "*.h"
)
add_library(ScenarioAPI INTERFACE)
add_library(ScenarioAPI::ScenarioAPI ALIAS ScenarioAPI)
add_library(
ScenarioAPI INTERFACE
)
add_library(
ScenarioAPI::ScenarioAPI ALIAS ScenarioAPI
)
target_link_libraries(ScenarioAPI INTERFACE units)
......@@ -24,21 +31,24 @@ include(GNUInstallDirs)
set(INSTALL_CONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/ScenarioAPI")
target_include_directories(
ScenarioAPI INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
ScenarioAPI
INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_features(ScenarioAPI INTERFACE cxx_std_17)
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/ScenarioAPIConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/ScenarioAPIConfig.cmake"
"${PROJECT_SOURCE_DIR}/cmake/ScenarioAPIConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/ScenarioAPIConfig.cmake"
INSTALL_DESTINATION ${INSTALL_CONFIG_DIR}
PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
PATH_VARS CMAKE_INSTALL_INCLUDEDIR
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/ScenarioAPIConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
COMPATIBILITY SameMajorVersion
)
install(DIRECTORY MantleAPI TYPE INCLUDE)
install(TARGETS ScenarioAPI EXPORT ScenarioAPITargets)
......@@ -46,10 +56,12 @@ install(TARGETS ScenarioAPI EXPORT ScenarioAPITargets)
install(
EXPORT ScenarioAPITargets
DESTINATION ${INSTALL_CONFIG_DIR}
NAMESPACE ScenarioAPI::)
NAMESPACE ScenarioAPI::
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/ScenarioAPIConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/ScenarioAPIConfigVersion.cmake"
DESTINATION ${INSTALL_CONFIG_DIR}
COMPONENT dev)
COMPONENT dev
)
......@@ -17,20 +17,23 @@
#include <MantleAPI/Common/dimension.h>
#include <MantleAPI/Common/vector.h>
#include <units.h>
namespace mantle_api
{
/// Bounding box is defined in local entity coordinate system.
/// The origin of the entity coordinate system is defined in relation to the geometric center.
/// The origin of the entity coordinate system is defined in relation to the
/// geometric center.
struct BoundingBox
{
Vec3d geometric_center{0.0, 0.0, 0.0};
Dimension3d dimension{0.0, 0.0, 0.0};
Vec3<units::length::meter_t> geometric_center{};
Dimension3 dimension{};
};
inline bool operator==(const BoundingBox& lhs, const BoundingBox& rhs) noexcept
{
return lhs.geometric_center == rhs.geometric_center && lhs.dimension == rhs.dimension;
return lhs.geometric_center == rhs.geometric_center &&
lhs.dimension == rhs.dimension;
}
} // namespace mantle_api
......
......@@ -16,29 +16,25 @@
#define MANTLEAPI_COMMON_DIMENSION_H
#include <MantleAPI/Common/floating_point_helper.h>
#include <MantleAPI/Common/vector.h>
#include <units.h>
namespace mantle_api
{
template <typename T>
struct Dimension3
{
T length{};
T width{};
T height{};
units::length::meter_t length{0};
units::length::meter_t width{0};
units::length::meter_t height{0};
};
using Dimension3d = Dimension3<double>;
inline bool operator==(const Dimension3d& lhs, const Dimension3d& rhs) noexcept
inline bool operator==(const Dimension3& lhs, const Dimension3& rhs) noexcept
{
return IsEqual(lhs.length, rhs.length) && IsEqual(lhs.width, rhs.width) && IsEqual(lhs.height, rhs.height);
return IsEqual(lhs.length, rhs.length) && IsEqual(lhs.width, rhs.width) && IsEqual(lhs.height, rhs.height);
}
inline bool operator!=(const Dimension3d& lhs, const Dimension3d& rhs) noexcept
inline bool operator!=(const Dimension3& lhs, const Dimension3& rhs) noexcept
{
return !(lhs == rhs);
return !(lhs == rhs);
}
} // namespace mantle_api
......
......@@ -15,12 +15,32 @@
#ifndef MANTLEAPI_COMMON_FLOATING_POINT_HELPER_H
#define MANTLEAPI_COMMON_FLOATING_POINT_HELPER_H
#include <units.h>
#include <cmath>
#include <limits>
#include <type_traits>
namespace mantle_api
{
/// @brief Compares two floating point numbers for equality.
///
/// **Attention** No approximation of the correct precision for the actual value is done!
///
/// This function uses a default precision of `std::numeric_limts<T>::epsilon()`, which means that without providing the
/// precision yourself, it is only suited for
/// * bit-wise equal numbers
/// * numbers around 1 or smaller
///
/// @tparam T Floating point type, ensured by SFINAE
/// @param lhs Left-hand operand
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if both numbers are equal within the given precision.
inline bool IsEqual(double lhs, double rhs, double precision = std::numeric_limits<double>::epsilon())
{
return std::abs(lhs - rhs) < precision;
}
/// @brief Compares two floating point numbers for equality.
///
......@@ -36,10 +56,10 @@ namespace mantle_api
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if both numbers are equal within the given precision.
template <typename T, typename std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
bool IsEqual(T lhs, T rhs, T precision = std::numeric_limits<T>::epsilon())
template <typename T, class = typename std::enable_if_t<units::traits::is_unit_t<T>::value>>
bool IsEqual(T lhs, T rhs, double precision = std::numeric_limits<double>::epsilon())
{
return std::abs(lhs - rhs) < precision;
return units::unit_cast<double>(units::math::abs(lhs - rhs)) < precision;
}
/// @brief Compares two floating point numbers for equality.
......@@ -56,14 +76,14 @@ bool IsEqual(T lhs, T rhs, T precision = std::numeric_limits<T>::epsilon())
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if lhs is greater than rhs or both numbers are equal within the given precision.
template <typename T, typename std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
bool GreaterOrEqual(T lhs, T rhs, T precision = std::numeric_limits<T>::epsilon())
template <typename T, class = typename std::enable_if_t<units::traits::is_unit_t<T>::value>>
bool GreaterOrEqual(T lhs, T rhs, double precision = std::numeric_limits<double>::epsilon())
{
if (lhs > rhs)
{
return true;
}
return IsEqual(lhs, rhs, precision);
if (lhs > rhs)
{
return true;
}
return IsEqual(lhs, rhs, precision);
}
/// @brief Compares two floating point numbers for equality.
......@@ -80,15 +100,16 @@ bool GreaterOrEqual(T lhs, T rhs, T precision = std::numeric_limits<T>::epsilon(
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if lhs is less than rhs or both numbers are equal within the given precision.
template <typename T, typename std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
bool LessOrEqual(T lhs, T rhs, T precision = std::numeric_limits<T>::epsilon())
template <typename T, class = typename std::enable_if_t<units::traits::is_unit_t<T>::value>>
bool LessOrEqual(T lhs, T rhs, double precision = std::numeric_limits<double>::epsilon())
{
if (lhs < rhs)
{
return true;
}
return IsEqual(lhs, rhs, precision);
if (lhs < rhs)
{
return true;
}
return IsEqual(lhs, rhs, precision);
}
} // namespace mantle_api
#endif // MANTLEAPI_COMMON_FLOATING_POINT_HELPER_H
......@@ -26,16 +26,16 @@ constexpr UniqueId InvalidId{std::numeric_limits<UniqueId>::max()};
/// Common interface for all classes that can be referenced by an ID or name.
class IIdentifiable
{
public:
virtual ~IIdentifiable() = default;
/// The unique id is provided and maintained by the scenario simulator.
virtual UniqueId GetUniqueId() const = 0;
/// Scenario specific name of an object.
///
/// The scenario description is responsible for keeping the name unique.
virtual void SetName(const std::string& name) = 0;
virtual const std::string& GetName() const = 0;
public:
virtual ~IIdentifiable() = default;
/// The unique id is provided and maintained by the scenario simulator.
virtual UniqueId GetUniqueId() const = 0;
/// Scenario specific name of an object.
///
/// The scenario description is responsible for keeping the name unique.
virtual void SetName(const std::string& name) = 0;
virtual const std::string& GetName() const = 0;
};
} // namespace mantle_api
......
......@@ -16,41 +16,60 @@
#define MANTLEAPI_COMMON_ORIENTATION_H
#include <MantleAPI/Common/floating_point_helper.h>
#include <units.h>
namespace mantle_api
namespace units
{
UNIT_ADD(angular_acceleration,
radians_per_second_squared,
radians_per_second_squared,
rad_per_s_sq,
compound_unit<angle::radians, inverse<squared<time::seconds>>>)
template <typename T>
struct Orientation3
namespace category
{
Orientation3() = default;
Orientation3(T yaw, T pitch, T roll) : yaw{yaw}, pitch{pitch}, roll{roll} {}
typedef base_unit<detail::meter_ratio<0>, std::ratio<0>, std::ratio<-2>, std::ratio<1>> angular_acceleration_unit;
}
T yaw{};
T pitch{};
T roll{};
};
UNIT_ADD_CATEGORY_TRAIT(angular_acceleration)
using Orientation3d = Orientation3<double>;
} // namespace units
inline bool operator==(const Orientation3d& lhs, const Orientation3d& rhs) noexcept
namespace mantle_api
{
template <typename T,
class = typename std::enable_if_t<units::traits::is_angle_unit<T>::value ||
units::traits::is_angular_velocity_unit<T>::value ||
units::traits::is_angular_acceleration_unit<T>::value>>
struct Orientation3
{
return IsEqual(lhs.yaw, rhs.yaw) && IsEqual(lhs.pitch, rhs.pitch) && IsEqual(lhs.roll, rhs.roll);
T yaw{};
T pitch{};
T roll{};
};
template <typename T>
inline bool operator==(const Orientation3<T>& lhs, const Orientation3<T>& rhs) noexcept
{
return IsEqual(lhs.yaw, rhs.yaw) && IsEqual(lhs.pitch, rhs.pitch) && IsEqual(lhs.roll, rhs.roll);
}
inline bool operator!=(const Orientation3d& lhs, const Orientation3d& rhs) noexcept
template <typename T>
inline bool operator!=(const Orientation3<T>& lhs, const Orientation3<T>& rhs) noexcept
{
return !(lhs == rhs);
return !(lhs == rhs);
}
inline Orientation3d operator+(const Orientation3d& lhs, const Orientation3d& rhs) noexcept
template <typename T>
inline Orientation3<T> operator+(const Orientation3<T>& lhs, const Orientation3<T>& rhs) noexcept
{
return Orientation3d{lhs.yaw + rhs.yaw, lhs.pitch + rhs.pitch, lhs.roll + rhs.roll};
return Orientation3<T>{lhs.yaw + rhs.yaw, lhs.pitch + rhs.pitch, lhs.roll + rhs.roll};
}
inline Orientation3d operator-(const Orientation3d& lhs, const Orientation3d& rhs) noexcept
template <typename T>
inline Orientation3<T> operator-(const Orientation3<T>& lhs, const Orientation3<T>& rhs) noexcept
{
return Orientation3d{lhs.yaw - rhs.yaw, lhs.pitch - rhs.pitch, lhs.roll - rhs.roll};
return Orientation3<T>{lhs.yaw - rhs.yaw, lhs.pitch - rhs.pitch, lhs.roll - rhs.roll};
}
} // namespace mantle_api
......
/*******************************************************************************
* Copyright (c) 2021, 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 https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
//-----------------------------------------------------------------------------
/** @file poly_line.h */
//-----------------------------------------------------------------------------
#ifndef MANTLEAPI_COMMON_POLY_LINE_H
#define MANTLEAPI_COMMON_POLY_LINE_H
#include <MantleAPI/Common/pose.h>
#include <MantleAPI/Common/time_utils.h>
#include <optional>
#include <vector>
namespace mantle_api
{
struct PolyLinePoint
{
Pose pose{};
std::optional<Time> time{};
bool operator==(const PolyLinePoint& other) const
{
return other.time == time && other.pose == pose;
}
friend std::ostream& operator<<(std::ostream& os, const PolyLinePoint& polyLinePoint);
};
inline std::ostream& operator<<(std::ostream& os, const PolyLinePoint& polyLinePoint)
{
os << polyLinePoint.pose;
if (polyLinePoint.time.has_value())
{
os << ", time in ms " << polyLinePoint.time.value();
}
return os;
}
using PolyLine = std::vector<PolyLinePoint>;
} // namespace mantle_api
#endif // MANTLEAPI_COMMON_POLY_LINE_H
\ No newline at end of file
......@@ -17,15 +17,39 @@
#include <MantleAPI/Common/orientation.h>
#include <MantleAPI/Common/vector.h>
#include <units.h>
#include <iostream>
namespace mantle_api
{
struct Pose
{
Vec3d position{};
Orientation3d orientation{};
Vec3<units::length::meter_t> position{};
Orientation3<units::angle::radian_t> orientation{};
bool operator==(const Pose& other) const
{
return other.position == position && other.orientation == orientation;
}
friend inline std::ostream& operator<<(std::ostream& os, const Pose& pose);
};
std::ostream& operator<<(std::ostream& os, const Pose& pose)
{
os << "position ("
<< pose.position.x
<< ", " << pose.position.y
<< ", " << pose.position.z
<< "), orientation (" << pose.orientation.yaw
<< ", " << pose.orientation.pitch
<< ", " << pose.orientation.roll
<< ")";
return os;
}
} // namespace mantle_api
#endif // MANTLEAPI_COMMON_POSE_H
......@@ -17,6 +17,7 @@
#include <MantleAPI/Common/floating_point_helper.h>
#include <MantleAPI/Common/vector.h>
#include <units.h>
#include <cmath>
#include <cstdint>
......@@ -26,43 +27,43 @@ namespace mantle_api
{
struct ReferencedObject
{
std::int32_t road{0};
std::int32_t lane{0};
std::int32_t road{0};
std::int32_t lane{0};
};
struct OpenDrivePosition
{
ReferencedObject referenced_object{};
ReferencedObject referenced_object{};
/// @brief Offset in s direction, unit: [m]
double s_offset{0.0};
/// @brief Offset in t direction, unit: [m]
double t_offset{0.0};
/// @brief Offset in s direction, unit: [m]
units::length::meter_t s_offset{0.0};
/// @brief Offset in t direction, unit: [m]
units::length::meter_t t_offset{0.0};
};
struct LatLonPosition
{
/// @brief GPS latitude, unit: [rad]
double latitude{0.0};
/// @brief GPS longitude, unit: [rad]
double longitude{0.0};
/// @brief GPS latitude, unit: [rad]
units::angle::radian_t latitude{0.0};
/// @brief GPS longitude, unit: [rad]
units::angle::radian_t longitude{0.0};
};
using Position = std::variant<OpenDrivePosition, LatLonPosition, Vec3d>;
using Position = std::variant<OpenDrivePosition, LatLonPosition, Vec3<units::length::meter_t>>;
/// @brief Equality comparison for OpenDrivePosition.
///
/// **Attention** Floating-point comparision may require tweaks in precision.
inline bool operator==(const OpenDrivePosition& lhs, const OpenDrivePosition& rhs) noexcept
{
return lhs.referenced_object.road == rhs.referenced_object.road &&
lhs.referenced_object.lane == rhs.referenced_object.lane && IsEqual(lhs.s_offset, rhs.s_offset) &&
IsEqual(lhs.t_offset, rhs.t_offset);
return lhs.referenced_object.road == rhs.referenced_object.road &&
lhs.referenced_object.lane == rhs.referenced_object.lane && IsEqual(lhs.s_offset, rhs.