33 const std::string 
BASE_PATH = LIBCARLA_TEST_CONTENT_FOLDER 
"/OpenDrive/";
    41     auto elevation_profile_nodes = road_node.children(
"elevationProfile");
    43     for (
pugi::xml_node elevation_profile_node : elevation_profile_nodes) {
    44       auto total_elevations = 0;
    45       auto elevation_nodes = elevation_profile_node.children(
"elevation");
    46       auto total_elevation_parser = std::distance(elevation_nodes.begin(), elevation_nodes.end());
    49         float s = elevation_node.attribute(
"s").as_float();
    50         const auto elevation = map->GetMap().GetRoad(road_id).GetInfo<
RoadInfoElevation>(s);
    51         if (elevation != 
nullptr)
    54       ASSERT_EQ(total_elevations, total_elevation_parser);
    67       auto geometries_parser = plan_view_nodes.children(
"geometry");
    68       auto total_geometries_parser = std::distance(geometries_parser.begin(), geometries_parser.end());
    69       auto total_geometries = 0;
    71         float s = geometry_node.attribute(
"s").as_float();
    73         if (geometry != 
nullptr)
    76       ASSERT_EQ(total_geometries, total_geometries_parser);
    85   constexpr 
auto error = 1e-5;
    86   auto total_road_mark = 0;
    87   auto total_road_mark_parser = 0;
    90     auto road_mark_nodes = lane_node.children(
"roadMark");
    91     total_road_mark_parser += std::distance(road_mark_nodes.begin(), road_mark_nodes.end());
    93     const int lane_id = lane_node.attribute(
"id").as_int();
    95     lane = lane_section.
GetLane(lane_id);
    96     EXPECT_NE(lane, 
nullptr);
   100       const auto s_offset = road_mark_node.attribute(
"sOffset").as_double();
   101       const auto type = road_mark_node.attribute(
"type").as_string();
   102       const auto material = road_mark_node.attribute(
"material").as_string();
   103       const auto color = road_mark_node.attribute(
"color").as_string();
   105       if (road_mark != 
nullptr) {
   106         EXPECT_NEAR(lane->
GetDistance() + s_offset, road_mark->GetDistance(), error);
   107         EXPECT_EQ(type, road_mark->GetType());
   108         EXPECT_EQ(material, road_mark->GetMaterial());
   109         EXPECT_EQ(color, road_mark->GetColor());
   114   return std::make_pair(total_road_mark, total_road_mark_parser);
   121   auto roads_parser = open_drive_node.
children(
"road");
   122   auto total_roads_parser = std::distance(roads_parser.begin(), roads_parser.end());
   123   auto total_roads = map->GetMap().GetRoads().size();
   124   ASSERT_EQ(total_roads, total_roads_parser);
   127     RoadId road_id = road_node.attribute(
"id").as_uint();
   132       auto lane_sections_parser = lanes_node.children(
"laneSection");
   133       auto total_lane_sections_parser = std::distance(lane_sections_parser.begin(), lane_sections_parser.end());
   134       auto total_lane_sections = map->GetMap().GetRoad(road_id).GetLaneSections().size();
   135       ASSERT_EQ(total_lane_sections, total_lane_sections_parser);
   140         const double s = lane_section_node.attribute(
"s").as_double();
   141         auto lane_section = map->GetMap().GetRoad(road_id).GetLaneSectionsAt(s);
   142         size_t total_lanes = 0u;
   143         for (
auto it = lane_section.begin(); it != lane_section.end(); ++it) {
   144           total_lanes = it->GetLanes().size();
   146         auto left_nodes = lane_section_node.child(
"left").children(
"lane");
   147         auto center_nodes = lane_section_node.child(
"center").children(
"lane");
   148         auto right_nodes = lane_section_node.child(
"right").children(
"lane");
   149         auto total_lanes_parser = std::distance(left_nodes.begin(), left_nodes.end());
   150         total_lanes_parser += std::distance(right_nodes.begin(), right_nodes.end());
   151         total_lanes_parser += std::distance(center_nodes.begin(), center_nodes.end());
   153         ASSERT_EQ(total_lanes, total_lanes_parser);
   156         auto total_road_mark = 0;
   157         auto total_road_mark_parser = 0;
   158         for (
auto it = lane_section.begin(); it != lane_section.end(); ++it) {
   162           total_road_mark = total_left.first + total_center.first + total_right.first;
   163           total_road_mark_parser = total_left.first + total_center.first + total_right.first;
   165         ASSERT_EQ(total_road_mark, total_road_mark_parser);
   176   auto& junctions = map->GetMap().GetJunctions();
   177   auto total_junctions_parser = std::distance(open_drive_node.
children(
"junction").begin(), open_drive_node.
children(
"junction").end());
   179   ASSERT_EQ(junctions.size(), total_junctions_parser);
   183     auto total_connections_parser = std::distance(junction_node.children(
"connection").begin(), junction_node.children(
"connection").end());
   186     auto& junction = junctions.find(junction_id)->second;
   188     auto& connections = junction.GetConnections();
   190     ASSERT_EQ(connections.size(), total_connections_parser);
   193       auto total_lane_links_parser = std::distance(connection_node.children(
"laneLink").begin(), connection_node.children(
"laneLink").end());
   195       ConId connection_id = connection_node.attribute(
"id").as_uint();
   196       auto& connection = connections.find(connection_id)->second;
   198     auto& lane_links = connection.lane_links;
   200     ASSERT_EQ(lane_links.size(), total_lane_links_parser);
   209   for (
auto &road : map->GetMap().GetRoads()) {
   210     for (
auto §ion : road.second.GetLaneSections()) {
   211       for (
auto &lane : section.GetLanes()) {
   213         for (
auto link : lane.second.GetNextLanes()) {
   214           ASSERT_TRUE(link != 
nullptr);
   217         for (
auto link : lane.second.GetPreviousLanes()) {
   218           ASSERT_TRUE(link != 
nullptr);
   246     ASSERT_TRUE(map.has_value());
   248     const std::string full_path = 
BASE_PATH + file;
   262     ASSERT_TRUE(map.has_value());
   264     const std::string full_path = 
BASE_PATH + file;
   274 TEST(road, parse_road_elevation) {
   277     ASSERT_TRUE(map.has_value());
   279     const std::string full_path = 
BASE_PATH + file;
   292     ASSERT_TRUE(map.has_value());
   294     const std::string full_path = 
BASE_PATH + file;
   304 TEST(road, iterate_waypoints) {
   307   std::vector<std::future<void>> results;
   310     results.push_back(pool.
Post([file]() {
   311       carla::StopWatch stop_watch;
   312       auto m = OpenDriveParser::Load(util::OpenDrive::Load(file));
   313       ASSERT_TRUE(m.has_value());
   315       const auto topology = map.GenerateTopology();
   316       ASSERT_FALSE(topology.empty());
   318       auto waypoints = map.GenerateWaypoints(0.5);
   319       ASSERT_FALSE(waypoints.empty());
   320       Random::Shuffle(waypoints);
   321       const auto number_of_waypoints_to_explore =
   322           std::min<size_t>(2000u, waypoints.size());
   323       for (auto i = 0u; i < number_of_waypoints_to_explore; ++i) {
   324         auto wp = waypoints[i];
   325         map.ComputeTransform(wp);
   327           ASSERT_NE(wp, waypoints[0u]);
   329         for (auto &&successor : map.GetSuccessors(wp)) {
   331               successor.road_id != wp.road_id ||
   332               successor.section_id != wp.section_id ||
   333               successor.lane_id != wp.lane_id ||
   334               successor.s != wp.s);
   337         for (auto j = 0u; j < 200u; ++j) {
   338           auto next_wps = map.GetNext(origin, Random::Uniform(0.0001, 150.0));
   339           if (next_wps.empty()) {
   342           const auto number_of_next_wps_to_explore =
   343               std::min<size_t>(10u, next_wps.size());
   344           Random::Shuffle(next_wps);
   345           for (auto k = 0u; k < number_of_next_wps_to_explore; ++k) {
   346             auto next = next_wps[k];
   349                 next.road_id != wp.road_id ||
   350                 next.section_id != wp.section_id ||
   351                 next.lane_id != wp.lane_id ||
   353             auto right = map.GetRight(next);
   354             if (right.has_value()) {
   355               ASSERT_EQ(right->road_id, next.road_id);
   356               ASSERT_EQ(right->section_id, next.section_id);
   357               ASSERT_NE(right->lane_id, next.lane_id);
   358               ASSERT_EQ(right->s, next.s);
   360             auto left = map.GetLeft(next);
   361             if (left.has_value()) {
   362               ASSERT_EQ(left->road_id, next.road_id);
   363               ASSERT_EQ(left->section_id, next.section_id);
   364               ASSERT_NE(left->lane_id, next.lane_id);
   365               ASSERT_EQ(left->s, next.s);
   368           origin = next_wps[0u];
   371       ASSERT_GT(count, 0u);
   372       float seconds = 1e-3f * stop_watch.GetElapsedTime();
   376   for (
auto &result : results) {
   384   std::vector<std::future<void>> results;
   387     results.push_back(pool.
Post([file]() {
   388       carla::StopWatch stop_watch;
   389       auto m = OpenDriveParser::Load(util::OpenDrive::Load(file));
   390       ASSERT_TRUE(m.has_value());
   392       for (auto i = 0u; i < 10
'000u; ++i) {   393         const auto location = Random::Location(-500.0f, 500.0f);   394         auto owp = map.GetClosestWaypointOnRoad(location);   395         ASSERT_TRUE(owp.has_value());   397         for (auto &next : map.GetNext(wp, 0.5)) {   399               next.road_id != wp.road_id ||   400               next.section_id != wp.section_id ||   401               next.lane_id != wp.lane_id ||   404         auto left = map.GetLeft(wp);   405         if (left.has_value()) {   406           ASSERT_EQ(left->road_id, wp.road_id);   407           ASSERT_EQ(left->section_id, wp.section_id);   408           ASSERT_NE(left->lane_id, wp.lane_id);   409           ASSERT_EQ(left->s, wp.s);   411         auto right = map.GetRight(wp);   412         if (right.has_value()) {   413           ASSERT_EQ(right->road_id, wp.road_id);   414           ASSERT_EQ(right->section_id, wp.section_id);   415           ASSERT_NE(right->lane_id, wp.lane_id);   416           ASSERT_EQ(right->s, wp.s);   419       float seconds = 1e-3f * stop_watch.GetElapsedTime();   420       carla::logging::log(file, "done in", seconds, "seconds.");   423   for (auto &result : results) { 
static void test_road_links(boost::optional< Map > &map)
 
static std::string Load(const std::string &filename)
 
unsigned int as_uint(unsigned int def=0) const
 
static void log(Args &&... args)
 
static std::vector< std::string > GetAvailableFiles()
 
xml_parse_result load_file(const char *path, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
 
Each lane within a road cross section can be provided with several road markentries. 
 
std::future< ResultT > Post(FunctorT &&functor)
Post a task to the pool. 
 
double GetDistance() const
 
xml_attribute attribute(const char_t *name) const
 
static void test_roads(const pugi::xml_document &xml, boost::optional< Map > &map)
 
static auto get_total_road_marks(pugi::xml_object_range< pugi::xml_named_node_iterator > &lane_nodes, LaneSection &lane_section)
 
static EpisodeProxyPointerType::Shared Load(EpisodeProxyPointerType::Strong ptr)
 
const std::string BASE_PATH
 
int as_int(int def=0) const
 
xml_node child(const char_t *name) const
 
static void test_junctions(const pugi::xml_document &xml, boost::optional< Map > &map)
 
static void test_road_elevation(const pugi::xml_document &xml, boost::optional< Map > &map)
 
A thread pool based on Boost.Asio's io context. 
 
const T * GetInfo(const double s) const
 
void AsyncRun(size_t worker_threads)
Launch threads to run tasks asynchronously. 
 
Lane * GetLane(const LaneId id)
 
static void test_geometry(const pugi::xml_document &xml, boost::optional< Map > &map)
 
xml_object_range< xml_node_iterator > children() const