Parse 'crosswalks' on openDRIVE

This commit is contained in:
bernatx 2019-11-15 10:40:11 +01:00 committed by Marc Garcia Puig
parent 632738b3c3
commit e6fc38a980
15 changed files with 491 additions and 240 deletions

View File

@ -97,5 +97,9 @@ namespace client {
return _map.GetGeoReference();
}
std::vector<geom::Location> Map::GetAllCrosswalkZones() const{
return _map.GetAllCrosswalkZones();
}
} // namespace client
} // namespace carla

View File

@ -65,6 +65,8 @@ namespace client {
const geom::GeoLocation &GetGeoReference() const;
std::vector<geom::Location> GetAllCrosswalkZones() const;
private:
const rpc::MapInfo _description;

View File

@ -42,7 +42,7 @@ namespace opendrive {
parser::ProfilesParser::Parse(xml, map_builder);
parser::TrafficGroupParser::Parse(xml, map_builder);
parser::SignalParser::Parse(xml, map_builder);
// parser::ObjectParser::Parse(xml, map_builder);
parser::ObjectParser::Parse(xml, map_builder);
return map_builder.Build();
}

View File

@ -7,6 +7,8 @@
#include "carla/opendrive/parser/ObjectParser.h"
#include "carla/road/MapBuilder.h"
#include "carla/road/element/RoadObjectCrosswalk.h"
#include "carla/road/Road.h"
#include <pugixml/pugixml.hpp>
@ -14,246 +16,56 @@ namespace carla {
namespace opendrive {
namespace parser {
using RoadID = std::string;
using ObjectID = std::string;
using DependencyID = std::string;
using SignalReferenceID = std::string;
template <typename T>
static void AddValidity(
pugi::xml_node parent_node,
const std::string &node_name,
const ObjectID &objectID,
T &&function) {
for (pugi::xml_node validity_node = parent_node.child(node_name.c_str());
validity_node;
validity_node = validity_node.next_sibling("validity")) {
const int from_lane = validity_node.attribute("fromLane").as_int();
const int to_lane = validity_node.attribute("toLane").as_int();
log_debug("Added validity to signal ", objectID, ":", from_lane, to_lane);
function(objectID, from_lane, to_lane);
}
}
void ObjectParser::Parse(
const pugi::xml_document & /*xml*/,
carla::road::MapBuilder & /* map_builder */) {
throw_exception(std::runtime_error("ObjectParser not ready"));
// Extracting the OpenDRIVE
// pugi::xml_node opendrive_node = xml.child("OpenDRIVE");
// for (pugi::xml_node road_node = opendrive_node.child("road");
// road_node;
// road_node = road_node.next_sibling("road")) {
// const RoadID road_id = static_cast<RoadID>(road_node.attribute("id").value());
// const pugi::xml_node objects_node = road_node.child("objects");
// for (pugi::xml_node object_node = objects_node.child("object");
// object_node;
// object_node = object_node.next_sibling("object")) {
// const std::string type = object_node.attribute("type").value();
// const std::string name = object_node.attribute("name").value();
// const ObjectID object_id = object_node.attribute("id").value();
// const double s_position = object_node.attribute("s").as_double();
// const double t_position = object_node.attribute("t").as_double();
// const double z_offset = object_node.attribute("zOffset").as_double();
// const double valid_length = object_node.attribute("validLength").as_double();
// const std::string orientation = object_node.attribute("orientation").value();
// const double lenght = object_node.attribute("lenght").as_double();
// const double width = object_node.attribute("width").as_double();
// const double radius = object_node.attribute("radius").as_double();
// const double height = object_node.attribute("height").as_double();
// const double hdg = object_node.attribute("hdg").as_double();
// const double pitch = object_node.attribute("pitch").as_double();
// const double roll = object_node.attribute("roll").as_double();
// /*map_builder.AddObjectInRoad(road_id, type, name, object_id,
// s_position, t_position, z_offset, valid_length,
// orientation, lenght, width, radius, height, hdg, pitch, roll);*/
// log_debug("AddObjectInRoad",
// road_id,
// type,
// name,
// object_id,
// s_position,
// t_position,
// z_offset,
// valid_length,
// orientation,
// lenght,
// width,
// radius,
// height,
// hdg,
// pitch,
// roll);
// for (pugi::xml_node repeat_node = object_node.child("repeat");
// repeat_node;
// repeat_node = repeat_node.next_sibling("repeat")) {
// const double s_position_rep = repeat_node.attribute("s").as_double();
// const double lenght_rep = repeat_node.attribute("lenght").as_double();
// const double distance_rep = repeat_node.attribute("distance").as_double();
// const double t_start_rep = repeat_node.attribute("tStart").as_double();
// const double t_end_rep = repeat_node.attribute("tEnd").as_double();
// const double width_start_rep = repeat_node.attribute("widthStart").as_double();
// const double width_end_rep = repeat_node.attribute("widthEnd").as_double();
// const double height_start_rep = repeat_node.attribute("heightStart").as_double();
// const double z_offset_start_rep = repeat_node.attribute("zOffsetStart").as_double();
// const double z_offset_end_rep = repeat_node.attribute("zOffsetEnd").as_double();
// /*map_builder.AddRepeatRecordInObject(object_id, s_position_rep,
// lenght_rep, t_start_rep,
// t_start_rep, t_end_rep, width_start_rep, width_end_rep,
// height_start_rep, z_offset_start_rep,
// z_offset_end_rep);
// */
// log_debug("AddRepeatRecordInObject", object_id, s_position_rep, lenght_rep, distance_rep,
// t_start_rep, t_end_rep, width_start_rep, width_end_rep, height_start_rep, z_offset_start_rep,
// z_offset_end_rep);
const pugi::xml_document &xml,
carla::road::MapBuilder &map_builder) {
std::vector<road::element::CrosswalkPoint> points;
for (pugi::xml_node node_road : xml.child("OpenDRIVE").children("road")) {
// }
// pugi::xml_node outline_node = object_node.child("outline");
// for (pugi::xml_node corner_road_node = outline_node.child("cornerRoad");
// corner_road_node;
// corner_road_node = corner_road_node.next_sibling("cornerRoad")) {
// const double s_position_corner_road = corner_road_node.attribute("s").as_double();
// const double t_position_corner_road = corner_road_node.attribute("t").as_double();
// const double dz_position_corner_road = corner_road_node.attribute("dz").as_double();
// const double height_position_corner_road = corner_road_node.attribute("height").as_double();
// /*
// map_builder.AddCornerRoadToObject(object_id,
// s_position_corner_road, t_position_corner_road,
// dz_position_corner_road, height_position_corner_road);
// */
// log_debug("AddCornerRoadToObject", object_id, s_position_corner_road, t_position_corner_road,
// dz_position_corner_road, height_position_corner_road);
// }
// for (pugi::xml_node corner_local_node = outline_node.child("cornerLocal");
// corner_local_node;
// corner_local_node = corner_local_node.next_sibling("cornerLocal")) {
// const double u_coordinate_corner_local = corner_local_node.attribute("u").as_double();
// const double v_coordinate_corner_local = corner_local_node.attribute("v").as_double();
// const double z_coordinate_corner_local = corner_local_node.attribute("z").as_double();
// const double height_corner_local = corner_local_node.attribute("height").as_double();
// /*
// map_builder.AddCornerLocalToObject(object_id,
// u_coordinate_corner_local, v_coordinate_corner_local,
// z_coordinate_corner_local, height_corner_local);
// */
// log_debug("AddCornerLocalToObject", object_id, u_coordinate_corner_local, v_coordinate_corner_local,
// z_coordinate_corner_local, height_corner_local);
// }
// pugi::xml_node material_node = object_node.child("material");
// if (material_node != nullptr) {
// const std::string surface_material = material_node.attribute("surface").value();
// const double friction_material = material_node.attribute("friction").as_double();
// const double roughness_material = material_node.attribute("roughness").as_double();
// /*
// map_builder.AddMaterialToObject(object_id, surface_material,
// friction_material, roughness_material);
// */
// log_debug("AddMaterialToObject", object_id, surface_material, friction_material,
// roughness_material);
// }
// parse all objects
pugi::xml_node node_objects = node_road.child("objects");
if (node_objects) {
// /* AddValidity(object_node, "validity", object_id,
// ([&map_builder](const ObjectID &object_id, const int16_t from_lane,
// const int16_t to_lane)
// { map_builder.AddValidityToObject(object_id, from_lane,
// to_lane);})); */
for (pugi::xml_node node_object : node_objects.children("object")) {
// type Crosswalk
std::string type = node_object.attribute("type").as_string();
if (type == "crosswalk") {
// pugi::xml_node parking_space_node = object_node.child("parkingSpace");
// if (parking_space_node != nullptr) {
// const std::string access_parking = parking_space_node.attribute("access").value();
// const std::string restrictions_parking = parking_space_node.attribute("restrictions").value();
// /*
// map_builder.AddParkingSpaceToObject(object_id, access_parking,
// restrictions_parking);
// */
// log_debug("AddParkingSpaceToObject", object_id, access_parking, restrictions_parking);
// }
// for (pugi::xml_node marking_node = parking_space_node.child("marking");
// marking_node;
// marking_node = marking_node.next_sibling("marking")) {
// const std::string side_marking = marking_node.attribute("side").value();
// const std::string type_marking = marking_node.attribute("type").value();
// const double width_marking = marking_node.attribute("width").as_double();
// const std::string color_marking = marking_node.attribute("color").value();
// /*
// Problem, there is no "Parking ID" or anything similar... how do we
// link them?
// map_builder.AddMarkingToParkingSpace(side_marking, type_marking,
// width_marking, color_marking);
// */
// log_debug("AddMarkingToParkingSpace", side_marking, type_marking,
// width_marking, color_marking);
// }
// for (pugi::xml_node obj_reference_node = object_node.child("objectReference");
// obj_reference_node;
// obj_reference_node = obj_reference_node.next_sibling("objectReference")) {
// const double s_position_obj_ref = obj_reference_node.attribute("s").as_double();
// const double t_position_obj_ref = obj_reference_node.attribute("t").as_double();
// const ObjectID id_obj_ref = obj_reference_node.attribute("id").value();
// const double z_offset_obj_ref = obj_reference_node.attribute("zOffset").as_double();
// const double valid_lenght_obj_ref = obj_reference_node.attribute("validLenght").as_double();
// const std::string orientation_obj_ref = obj_reference_node.attribute("orientation").value();
// /*
// map_builder.AddObjectReferenceToObject(object_id,
// s_position_obj_ref, t_position_obj_ref,
// id_obj_ref, z_offset_obj_ref, valid_lenght_obj_ref,
// orientation_obj_ref);
// */
// log_debug("AddObjectReferenceToObject", object_id, s_position_obj_ref, t_position_obj_ref,
// id_obj_ref, z_offset_obj_ref, valid_lenght_obj_ref, orientation_obj_ref);
// /* AddValidity(obj_reference_node, "validity", id_obj_ref,
// ([&map_builder](const ObjectID &id_obj_ref, const int16_t
// from_lane, const int16_t to_lane)
// { map_builder.AddValidityToObjectRef(id_obj_ref, from_lane,
// to_lane);})); */
// }
// read all points
pugi::xml_node node_outline = node_object.child("outline");
if (node_outline) {
points.clear();
for (pugi::xml_node node_corner : node_outline.children("cornerLocal")) {
points.emplace_back(node_corner.attribute("u").as_double(),
node_corner.attribute("v").as_double(),
node_corner.attribute("z").as_double());
}
}
// get road id
road::RoadId road_id = node_road.attribute("id").as_uint();
road::Road *road = map_builder.GetRoad(road_id);
// create the object
map_builder.AddRoadObjectCrosswalk(road,
node_object.attribute("name").as_string(),
node_object.attribute("s").as_double(),
node_object.attribute("t").as_double(),
node_object.attribute("zOffset").as_double(),
node_object.attribute("hdg").as_double(),
node_object.attribute("pitch").as_double(),
node_object.attribute("roll").as_double(),
node_object.attribute("orientation").as_string(),
node_object.attribute("width").as_double(),
node_object.attribute("length").as_double(),
points);
// }
// for (pugi::xml_node tunnel_node = objects_node.child("tunnel");
// tunnel_node;
// tunnel_node = tunnel_node.next_sibling("tunnel")) {
// const double s_position_tunnel = tunnel_node.attribute("s").as_double();
// const double lenght_tunnel = tunnel_node.attribute("lenght").as_double();
// const std::string name_tunnel = tunnel_node.attribute("name").value();
// const ObjectID id_tunnel = tunnel_node.attribute("id").value();
// const std::string type_tunnel = tunnel_node.attribute("type").value();
// const double lightning_tunnel = tunnel_node.attribute("lightning").as_double();
// const double daylight_tunnel = tunnel_node.attribute("daylight").as_double();
// /*
// map_builder.AddTunnel(s_position_tunnel, lenght_tunnel, name_tunnel,
// id_tunnel,
// type_tunnel, lightning_tunnel, daylight_tunnel);
// */
// log_debug("AddTunnel", s_position_tunnel, lenght_tunnel, name_tunnel, id_tunnel,
// type_tunnel, lightning_tunnel, daylight_tunnel);
// /* AddValidity(tunnel_node, "validity", id_tunnel,
// ([&map_builder](const ObjectID &id_tunnel, const int16_t from_lane,
// const int16_t to_lane)
// { map_builder.AddValidityToTunnel(id_tunnel, from_lane,
// to_lane);})); */
// }
// for (pugi::xml_node bridge_node = objects_node.child("bridge");
// bridge_node;
// bridge_node = bridge_node.next_sibling("bridge")) {
// const double s_position_bridge = bridge_node.attribute("s").as_double();
// const double lenght_bridge = bridge_node.attribute("lenght").as_double();
// const std::string name_bridge = bridge_node.attribute("name").value();
// const ObjectID id_bridge = bridge_node.attribute("id").value();
// const std::string type_bridge = bridge_node.attribute("type").value();
// /*
// map_builder.AddBridge(s_position_bridge, lenght_bridge, name_bridge,
// id_bridge,
// type_bridge);
// */
// log_debug("AddTunnel", s_position_bridge, lenght_bridge, name_bridge, id_bridge,
// type_bridge);
// /*AddValidity(bridge_node, "validity", id_bridge,
// ([&map_builder](const ObjectID &id_bridge, const int16_t from_lane,
// const int16_t to_lane)
// { map_builder.AddValidityToBridge(id_bridge, from_lane,
// to_lane);}));*/
// }
// }
}
}
}
}
}
} // namespace parser
} // namespace opendrive

View File

@ -12,6 +12,7 @@
#include "carla/road/element/RoadInfoLaneWidth.h"
#include "carla/road/element/RoadInfoMarkRecord.h"
#include "carla/road/element/RoadInfoLaneOffset.h"
#include "carla/road/element/RoadObjectCrosswalk.h"
#include "carla/geom/Math.h"
#include <stdexcept>
@ -107,6 +108,10 @@ namespace road {
const T container,
const double s,
const LaneId lane_id) {
// lane_id can't be 0
RELEASE_ASSERT(lane_id != 0);
const bool negative_lane_id = lane_id < 0;
double dist = 0.0;
double tangent = 0.0;
@ -240,9 +245,6 @@ namespace road {
}
geom::Transform Map::ComputeTransform(Waypoint waypoint) const {
// lane_id can't be 0
RELEASE_ASSERT(waypoint.lane_id != 0);
const auto &road = _data.GetRoad(waypoint.road_id);
// must s be smaller (or eq) than road lenght and bigger (or eq) than 0?
@ -259,6 +261,7 @@ namespace road {
float lane_width = 0.0f;
float lane_tangent = 0.0f;
if (waypoint.lane_id < 0) {
// right lane
const auto side_lanes = MakeListView(
@ -267,7 +270,7 @@ namespace road {
ComputeTotalLaneWidth(side_lanes, waypoint.s, waypoint.lane_id);
lane_width = static_cast<float>(computed_width.first);
lane_tangent = static_cast<float>(computed_width.second);
} else {
} else if (waypoint.lane_id > 0) {
// left lane
const auto side_lanes = MakeListView(lanes.lower_bound(1), lanes.end());
const auto computed_width =
@ -363,6 +366,61 @@ namespace road {
return LaneCrossingCalculator::Calculate(*this, origin, destination);
}
std::vector<geom::Location> Map::GetAllCrosswalkZones() const {
std::vector<geom::Location> result;
for (const auto &pair : _data.GetRoads()) {
const auto &road = pair.second;
std::vector<const RoadObjectCrosswalk *> crosswalks = road.GetObjects<RoadObjectCrosswalk>();
if (crosswalks.size() > 0) {
for (auto crosswalk : crosswalks) {
// waypoint only at start position
std::vector<geom::Location> points;
Waypoint waypoint;
geom::Transform base;
for (const auto &section : road.GetLaneSectionsAt(crosswalk->GetS())) {
// get the section with the center lane
for (const auto &lane : section.GetLanes()) {
// is the center line
if (lane.first == 0) {
// get the center point
waypoint.road_id = pair.first;
waypoint.section_id = section.GetId();
waypoint.lane_id = 0;
waypoint.s = crosswalk->GetS();
base = ComputeTransform(waypoint);
}
}
}
// move perpendicular ('t')
geom::Transform pivot = base;
pivot.rotation.yaw -= geom::Math::ToDegrees<float>(static_cast<float>(crosswalk->GetHeading()));
pivot.rotation.yaw -= 90; // move perpendicular to 's' for the lateral offset
geom::Vector3D v(static_cast<float>(crosswalk->GetT()), 0.0f, 0.0f);
pivot.TransformPoint(v);
// restore pivot position and orientation
pivot = base;
pivot.location = v;
pivot.rotation.yaw -= geom::Math::ToDegrees<float>(static_cast<float>(crosswalk->GetHeading()));
// calculate all the corners
for (auto corner : crosswalk->GetPoints()) {
geom::Vector3D v2(static_cast<float>(corner.u), static_cast<float>(corner.v), static_cast<float>(corner.z));
// set the width larger to contact with the sidewalk (in case they have gutter area)
if (corner.u < 0)
v2.x -= 1.0f;
else
v2.x += 1.0f;
pivot.TransformPoint(v2);
result.push_back(v2);
}
}
}
}
return result;
}
// ===========================================================================
// -- Map: Waypoint generation -----------------------------------------------
// ===========================================================================

View File

@ -75,6 +75,8 @@ namespace road {
const geom::Location &origin,
const geom::Location &destination) const;
std::vector<geom::Location> GetAllCrosswalkZones() const;
/// ========================================================================
/// -- Waypoint generation -------------------------------------------------
/// ========================================================================

View File

@ -20,6 +20,8 @@
#include "carla/road/element/RoadInfoMarkTypeLine.h"
#include "carla/road/element/RoadInfoSpeed.h"
#include "carla/road/element/RoadInfoVisitor.h"
#include "carla/road/element/RoadObjectCrosswalk.h"
#include "carla/road/element/RoadObjectVisitor.h"
#include "carla/road/InformationSet.h"
#include "carla/road/general/Validity.h"
#include "carla/road/signal/Signal.h"
@ -43,6 +45,11 @@ namespace road {
info.first->_info = InformationSet(std::move(info.second));
}
for (auto &&info : _temp_road_object_container) {
DEBUG_ASSERT(info.first != nullptr);
info.first->_objects = ObjectSet(std::move(info.second));
}
for (auto &&info : _temp_lane_info_container) {
DEBUG_ASSERT(info.first != nullptr);
info.first->_info = InformationSet(std::move(info.second));
@ -50,6 +57,7 @@ namespace road {
// remove temporal already used information
_temp_road_info_container.clear();
_temp_road_object_container.clear();
_temp_lane_info_container.clear();
// _map_data is a memeber of MapBuilder so you must especify if
@ -71,6 +79,24 @@ namespace road {
_temp_road_info_container[road].emplace_back(std::move(elevation));
}
void MapBuilder::AddRoadObjectCrosswalk(
Road *road,
const std::string name,
const double s,
const double t,
const double zOffset,
const double hdg,
const double pitch,
const double roll,
const std::string orientation,
const double width,
const double length,
const std::vector<road::element::CrosswalkPoint> points) {
DEBUG_ASSERT(road != nullptr);
auto cross = std::make_unique<RoadObjectCrosswalk>(s, name, t, zOffset, hdg, pitch, roll, std::move(orientation), width, length, std::move(points));
_temp_road_object_container[road].emplace_back(std::move(cross));
}
// called from lane parser
void MapBuilder::CreateLaneAccess(
Lane *lane,

View File

@ -7,6 +7,7 @@
#pragma once
#include "carla/road/Map.h"
#include "carla/road/element/RoadObjectCrosswalk.h"
#include <boost/optional.hpp>
@ -108,6 +109,20 @@ namespace road {
const double c,
const double d);
void AddRoadObjectCrosswalk(
Road *road,
const std::string name,
const double s,
const double t,
const double zOffset,
const double hdg,
const double pitch,
const double roll,
const std::string orientation,
const double width,
const double length,
const std::vector<road::element::CrosswalkPoint> points);
// void AddRoadLateralSuperElevation(
// Road* road,
// const double s,
@ -354,6 +369,9 @@ namespace road {
std::unordered_map<Road *, std::vector<std::unique_ptr<element::RoadInfo>>>
_temp_road_info_container;
std::unordered_map<Road *, std::vector<std::unique_ptr<element::RoadObject>>>
_temp_road_object_container;
std::unordered_map<Lane *, std::vector<std::unique_ptr<element::RoadInfo>>>
_temp_lane_info_container;

View File

@ -0,0 +1,53 @@
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/NonCopyable.h"
#include "carla/road/RoadElementSet.h"
#include "carla/road/element/RoadObject.h"
#include "carla/road/element/RoadObjectIterator.h"
#include <vector>
#include <memory>
namespace carla {
namespace road {
class ObjectSet : private MovableNonCopyable {
public:
ObjectSet() = default;
ObjectSet(std::vector<std::unique_ptr<element::RoadObject>> &&vec)
: _road_set(std::move(vec)) {}
/// Return all objects given a type from the start of the road
template <typename T>
std::vector<const T *> GetObjects() const {
std::vector<const T *> vec;
auto it = element::MakeRoadObjectIterator<T>(_road_set.GetAll());
for (; !it.IsAtEnd(); ++it) {
vec.emplace_back(&*it);
}
return vec;
}
/// Returns single object given a type and a distance (s) from
/// the start of the road
template <typename T>
const T *GetObject(const double s) const {
auto it = element::MakeRoadObjectIterator<T>(_road_set.GetReverseSubset(s));
return it.IsAtEnd() ? nullptr : &*it;
}
private:
RoadElementSet<std::unique_ptr<element::RoadObject>> _road_set;
};
} // road
} // carla

View File

@ -10,6 +10,7 @@
#include "carla/ListView.h"
#include "carla/NonCopyable.h"
#include "carla/road/InformationSet.h"
#include "carla/road/ObjectSet.h"
#include "carla/road/Junction.h"
#include "carla/road/LaneSection.h"
#include "carla/road/LaneSectionMap.h"
@ -17,6 +18,7 @@
#include "carla/road/RoadTypes.h"
#include "carla/road/element/Geometry.h"
#include "carla/road/element/RoadInfo.h"
#include "carla/road/element/RoadObject.h"
#include "carla/road/signal/Signal.h"
#include "carla/road/signal/SignalReference.h"
@ -113,6 +115,16 @@ namespace road {
return _info.GetInfo<T>(s);
}
template <typename T>
const T *GetObject(const double s) const {
return _objects.GetObject<T>(s);
}
template <typename T>
std::vector<const T *> GetObjects() const {
return _objects.GetObjects<T>();
}
auto GetLaneSections() const {
return MakeListView(
iterator::make_map_values_const_iterator(_lane_sections.begin()),
@ -198,6 +210,9 @@ namespace road {
std::unordered_map<SignId, signal::Signal> _signals;
std::unordered_map<SignRefId, signal::SignalReference> _sign_ref;
ObjectSet _objects;
};
} // road

View File

@ -0,0 +1,43 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/road/element/RoadObjectVisitor.h"
#include "carla/NonCopyable.h"
#include <map>
#include <string>
#include <vector>
namespace carla {
namespace road {
namespace element {
class RoadObject : private NonCopyable {
public:
virtual ~RoadObject() = default;
virtual void AcceptVisitor(RoadObjectVisitor &) = 0;
/// Distance from road's start location.
double GetDistance() const {
return _s;
}
protected:
RoadObject(double distance = 0.0) : _s(distance) {}
private:
double _s;
};
} // namespace element
} // namespace road
} // namespace carla

View File

@ -0,0 +1,79 @@
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/road/element/RoadObject.h"
namespace carla {
namespace road {
namespace element {
struct CrosswalkPoint {
double u { 0.0 };
double v { 0.0 };
double z { 0.0 };
CrosswalkPoint(double _u, double _v, double _z) : u(_u), v(_v), z(_z) {};
};
class RoadObjectCrosswalk final : public RoadObject {
public:
RoadObjectCrosswalk(
const double s,
const std::string name,
const double t,
const double zOffset,
const double hdg,
const double pitch,
const double roll,
const std::string orientation,
const double width,
const double length,
const std::vector<CrosswalkPoint> points)
: RoadObject(s),
_name(name),
_t(t),
_zOffset(zOffset),
_hdg(hdg),
_pitch(pitch),
_roll(roll),
_orientation(orientation),
_width(width),
_length(length),
_points(points) {}
void AcceptVisitor(RoadObjectVisitor &v) final {
v.Visit(*this);
}
double GetS() const { return GetDistance(); };
double GetT() const { return _t; };
double GetWidth() const { return _width; };
double GetLength() const { return _length; };
double GetHeading() const { return _hdg; };
double GetPitch() const { return _pitch; };
double GetRoll() const { return _roll; };
double GetZOffset() const { return _zOffset; };
std::string GetOrientation() const { return _orientation; };
const std::vector<CrosswalkPoint> &GetPoints() const { return _points; };
private:
std::string _name;
double _t;
double _zOffset;
double _hdg;
double _pitch;
double _roll;
std::string _orientation;
double _width;
double _length;
std::vector<CrosswalkPoint> _points;
};
} // namespace element
} // namespace road
} // namespace carla

View File

@ -0,0 +1,105 @@
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/Debug.h"
#include "carla/road/element/RoadObjectVisitor.h"
#include <iterator>
#include <memory>
namespace carla {
namespace road {
namespace element {
template <typename T, typename IT>
class RoadObjectIterator : private RoadObjectVisitor {
public:
static_assert(std::is_same<std::unique_ptr<RoadObject>, typename IT::value_type>::value, "Not compatible.");
using value_type = T;
using difference_type = typename IT::difference_type;
using pointer = T *;
using reference = T &;
RoadObjectIterator(IT begin, IT end)
: _it(begin),
_end(end) {
_success = false;
for (; !IsAtEnd(); ++_it) {
DEBUG_ASSERT((*_it) != nullptr);
(*_it)->AcceptVisitor(*this);
if (_success) {
break;
}
}
}
RoadObjectIterator &operator++() {
_success = false;
while (!_success) {
++_it;
if (IsAtEnd()) {
break;
}
DEBUG_ASSERT((*_it) != nullptr);
(*_it)->AcceptVisitor(*this);
}
return *this;
}
reference operator*() const {
DEBUG_ASSERT((*_it) != nullptr);
return static_cast<T &>(**_it);
}
pointer operator->() const {
DEBUG_ASSERT((*_it) != nullptr);
return static_cast<T *>(_it->get());
}
bool operator!=(const RoadObjectIterator &rhs) const {
return _it != rhs._it;
}
bool operator==(const RoadObjectIterator &rhs) const {
return !((*this) != rhs);
}
bool IsAtEnd() const {
return _it == _end;
}
private:
void Visit(T &) {
_success = true;
}
IT _it;
IT _end;
bool _success;
};
template <typename T, typename Container>
static auto MakeRoadObjectIterator(const Container &c) {
auto begin = std::begin(c);
auto end = std::end(c);
return RoadObjectIterator<T, decltype(begin)>(begin, end);
}
template <typename T, typename IT>
static auto MakeRoadObjectIterator(IT begin, IT end) {
return RoadObjectIterator<T, decltype(begin)>(begin, end);
}
} // namespace element
} // namespace road
} // namespace carla

View File

@ -0,0 +1,33 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
namespace carla {
namespace road {
namespace element {
class RoadObject;
class RoadObjectCrosswalk;
class RoadObjectVisitor {
public:
RoadObjectVisitor() = default;
virtual ~RoadObjectVisitor() = default;
RoadObjectVisitor(const RoadObjectVisitor &) = default;
RoadObjectVisitor(RoadObjectVisitor &&) = default;
RoadObjectVisitor &operator=(const RoadObjectVisitor &) = default;
RoadObjectVisitor &operator=(RoadObjectVisitor &&) = default;
virtual void Visit(RoadObjectCrosswalk &) {}
};
} // namespace element
} // namespace road
} // namespace carla

View File

@ -135,6 +135,7 @@ void export_map() {
.def("transform_to_geolocation", &ToGeolocation, (arg("location")))
.def("to_opendrive", CALL_RETURNING_COPY(cc::Map, GetOpenDrive))
.def("save_to_disk", &SaveOpenDriveToDisk, (arg("path")=""))
.def("get_crosswalks", CALL_RETURNING_LIST(cc::Map, GetAllCrosswalkZones))
.def(self_ns::str(self_ns::self))
;