16#include <rclcpp/rclcpp.hpp>
18#include <lanelet2_core/Attribute.h>
19#include <lanelet2_core/utility/Units.h>
20#include <boost/algorithm/string.hpp>
49 lanelet::Participants::VehicleBus,
50 lanelet::Participants::VehicleCar,
51 lanelet::Participants::VehicleCarElectric,
52 lanelet::Participants::VehicleCarCombustion,
53 lanelet::Participants::VehicleTruck,
54 lanelet::Participants::VehicleMotorcycle,
55 lanelet::Participants::VehicleTaxi,
56 lanelet::Participants::VehicleEmergency,
57 lanelet::Participants::Pedestrian,
58 lanelet::Participants::Bicycle,
59 lanelet::Participants::Train };
68 std::vector<lanelet::traffic_rules::TrafficRulesUPtr> german_traffic_rules_set;
78 lanelet::traffic_rules::TrafficRulesUPtr traffic_rules =
79 lanelet::traffic_rules::TrafficRulesFactory::create(lanelet::Locations::Germany,
participant_types[
i]);
80 german_traffic_rules_set.emplace_back(std::move(traffic_rules));
82 catch (
const lanelet::InvalidInputError& e)
85 RCLCPP_INFO_STREAM ( rclcpp::get_logger(
"MapConformer"),
"Ignoring participant: " <<
participant_types[
i] <<
", which there is no generic rule for...");
89 return german_traffic_rules_set;
108template <
typename Map,
typename Key,
typename Value>
111 auto elem = map.find(key);
112 if (elem == map.end())
134bool startswith(
const std::string& str,
const std::string& substr)
136 return str.compare(0, substr.size(), substr) == 0;
157 using LaneChangeMap = std::map<std::pair<std::string, std::string>,
LaneChangeType>;
158 const static LaneChangeMap VehicleChangeType{
159 { { AttributeValueString::LineThin, AttributeValueString::Dashed }, LaneChangeType::Both },
160 { { AttributeValueString::LineThick, AttributeValueString::Dashed }, LaneChangeType::Both },
161 { { AttributeValueString::LineThin, AttributeValueString::DashedSolid }, LaneChangeType::ToRight },
162 { { AttributeValueString::LineThick, AttributeValueString::DashedSolid }, LaneChangeType::ToRight },
163 { { AttributeValueString::LineThin, AttributeValueString::SolidDashed }, LaneChangeType::ToLeft },
164 { { AttributeValueString::LineThick, AttributeValueString::SolidDashed }, LaneChangeType::ToLeft }
166 const static LaneChangeMap PedestrianChangeType{ { { AttributeValueString::Curbstone, AttributeValueString::Low },
167 LaneChangeType::Both } };
169 if (
startswith(participant, Participants::Vehicle))
171 return getMapOrDefault(VehicleChangeType, std::make_pair(type, subtype), LaneChangeType::None);
173 if (participant == Participants::Pedestrian)
175 return getMapOrDefault(PedestrianChangeType, std::make_pair(type, subtype), LaneChangeType::None);
177 if (participant == Participants::Bicycle)
179 auto asVehicle =
getMapOrDefault(VehicleChangeType, std::make_pair(type, subtype), LaneChangeType::None);
180 if (asVehicle != LaneChangeType::None)
184 return getMapOrDefault(PedestrianChangeType, std::make_pair(type, subtype), LaneChangeType::None);
186 return LaneChangeType::None;
200 if (bound.inverted())
204 case LaneChangeType::ToRight:
205 return std::shared_ptr<PassingControlLine>(
new PassingControlLine(
206 PassingControlLine::buildData(lanelet::utils::getId(), { bound.invert() }, {}, { participant })));
207 case LaneChangeType::ToLeft:
208 return std::shared_ptr<PassingControlLine>(
new PassingControlLine(
209 PassingControlLine::buildData(lanelet::utils::getId(), { bound.invert() }, { participant }, {})));
210 case LaneChangeType::Both:
211 return std::shared_ptr<PassingControlLine>(
new PassingControlLine(PassingControlLine::buildData(
212 lanelet::utils::getId(), { bound.invert() }, { participant }, { participant })));
214 return std::shared_ptr<PassingControlLine>(
215 new PassingControlLine(PassingControlLine::buildData(lanelet::utils::getId(), { bound.invert() }, {}, {})));
222 case LaneChangeType::ToRight:
223 return std::shared_ptr<PassingControlLine>(
new PassingControlLine(
224 PassingControlLine::buildData(lanelet::utils::getId(), { bound }, { participant }, {})));
225 case LaneChangeType::ToLeft:
226 return std::shared_ptr<PassingControlLine>(
new PassingControlLine(
227 PassingControlLine::buildData(lanelet::utils::getId(), { bound }, {}, { participant })));
228 case LaneChangeType::Both:
229 return std::shared_ptr<PassingControlLine>(
new PassingControlLine(
230 PassingControlLine::buildData(lanelet::utils::getId(), { bound }, { participant }, { participant })));
232 return std::shared_ptr<PassingControlLine>(
233 new PassingControlLine(PassingControlLine::buildData(lanelet::utils::getId(), { bound }, {}, {})));
246 const std::vector<lanelet::traffic_rules::TrafficRulesUPtr>& default_traffic_rules)
248 auto access_rules =
lanelet.regulatoryElementsAs<RegionAccessRule>();
250 if (access_rules.size() == 0)
254 std::vector<std::string> allowed_participants;
256 for (
const auto& rules : default_traffic_rules)
260 allowed_participants.emplace_back(rules->participant());
264 std::shared_ptr<RegionAccessRule> rar(
new RegionAccessRule(
265 RegionAccessRule::buildData(lanelet::utils::getId(), {
lanelet }, {}, allowed_participants)));
266 lanelet.addRegulatoryElement(rar);
279 const std::vector<lanelet::traffic_rules::TrafficRulesUPtr>& default_traffic_rules)
281 auto access_rules = area.regulatoryElementsAs<RegionAccessRule>();
283 if (access_rules.size() == 0)
287 std::vector<std::string> allowed_participants;
289 for (
const auto& rules : default_traffic_rules)
291 if (rules->canPass(area))
293 allowed_participants.emplace_back(rules->participant());
297 std::shared_ptr<RegionAccessRule> rar(
298 new RegionAccessRule(RegionAccessRule::buildData(lanelet::utils::getId(), {}, { area }, allowed_participants)));
299 area.addRegulatoryElement(rar);
314 std::string participant(lanelet::Participants::Vehicle);
316 LineString3d left_bound =
lanelet.leftBound();
317 LineString3d right_bound =
lanelet.rightBound();
321 left_bound.attribute(AttributeName::Subtype).value(), participant);
323 right_bound.attribute(AttributeName::Subtype).value(), participant);
325 auto local_control_lines =
lanelet.regulatoryElementsAs<PassingControlLine>();
327 bool foundLeft =
false;
328 bool foundRight =
false;
332 for (
auto reg_elem : map->regulatoryElementLayer)
334 if (reg_elem->attribute(AttributeName::Subtype).value() != PassingControlLine::RuleName)
339 auto pcl = std::static_pointer_cast<PassingControlLine>(reg_elem);
340 for (
auto sub_line :
pcl->controlLine())
342 bool shouldAdd =
false;
344 if (left_bound.id() == sub_line.id() && !foundLeft)
347 shouldAdd = !lanelet::utils::contains(local_control_lines,
pcl);
349 else if (right_bound.id() == sub_line.id() && !foundRight)
352 shouldAdd = !lanelet::utils::contains(local_control_lines,
pcl);
368 PassingControlLinePtr pcl_left =
buildControlLine(left_bound, left_type, participant);
369 lanelet.addRegulatoryElement(pcl_left);
374 PassingControlLinePtr pcl_right =
buildControlLine(right_bound, right_type, participant);
375 lanelet.addRegulatoryElement(pcl_right);
390 std::string participant(lanelet::Participants::Vehicle);
392 LineStrings3d outerBounds = area.outerBound();
394 auto local_control_lines = area.regulatoryElementsAs<PassingControlLine>();
396 std::vector<size_t> found_indices;
400 for (
auto reg_elem : map->regulatoryElementLayer)
402 if (reg_elem->attribute(AttributeName::Subtype).value() == PassingControlLine::RuleName)
404 auto pcl = std::static_pointer_cast<PassingControlLine>(reg_elem);
405 for (
auto sub_line :
pcl->controlLine())
408 for (
auto sub_bound : outerBounds)
410 if (sub_bound.id() == sub_line.id())
412 found_indices.push_back(
i);
414 bool alreadyAdded = lanelet::utils::contains(local_control_lines,
pcl);
417 area.addRegulatoryElement(
pcl);
427 for (
auto sub_bound : outerBounds)
429 if (lanelet::utils::contains(found_indices,
i))
435 sub_bound.attribute(AttributeName::Subtype).value(), participant);
436 PassingControlLinePtr control_line =
buildControlLine(sub_bound, change_type, participant);
437 area.addRegulatoryElement(control_line);
438 map->add(control_line);
453 const std::vector<lanelet::traffic_rules::TrafficRulesUPtr>& default_traffic_rules)
455 auto direction_of_travel =
lanelet.regulatoryElementsAs<DirectionOfTravel>();
457 if (direction_of_travel.size() == 0)
461 std::vector<std::string> allowed_participants;
463 for (
const auto& rules : default_traffic_rules)
467 allowed_participants.emplace_back(rules->participant());
471 if (allowed_participants.size() > 0)
473 std::shared_ptr<DirectionOfTravel> rar(
new DirectionOfTravel(DirectionOfTravel::buildData(
474 lanelet::utils::getId(), {
lanelet }, DirectionOfTravel::BiDirectional, allowed_participants)));
475 lanelet.addRegulatoryElement(rar);
482 const std::vector<lanelet::traffic_rules::TrafficRulesUPtr>& default_traffic_rules )
484 lanelet::Velocity max_speed;
485 auto speed_limit =
lanelet.regulatoryElementsAs<DigitalSpeedLimit>();
486 if(config_limit < 80_mph && config_limit > 0_mph)
488 max_speed = config_limit;
496 std::vector<std::string> allowed_participants;
500 if (speed_limit.empty())
503 for(
const auto& rules : default_traffic_rules)
507 allowed_participants.emplace_back(rules->participant());
510 if (!allowed_participants.empty())
513 auto rar = std::make_shared<DigitalSpeedLimit>(DigitalSpeedLimit::buildData(lanelet::utils::getId(), max_speed, {
lanelet},
514 {}, allowed_participants));
516 lanelet.addRegulatoryElement(rar);
523 for(
const auto& rules : default_traffic_rules)
527 allowed_participants.emplace_back(rules->participant());
530 if(speed_limit.back().get()->speed_limit_ > max_speed)
533 RCLCPP_DEBUG_STREAM( rclcpp::get_logger(
"lanelet::MapConformer"),
"Invalid speed limit value. Value reset to maximum speed limit.");
534 auto rar = std::make_shared<DigitalSpeedLimit>(DigitalSpeedLimit::buildData(lanelet::utils::getId(), max_speed, {
lanelet},
535 {}, allowed_participants));
536 lanelet.removeRegulatoryElement(speed_limit.back());
537 lanelet.addRegulatoryElement(rar);
539 RCLCPP_INFO_STREAM( rclcpp::get_logger(
"lanelet::MapConformer"),
"Number of Regulatory Elements: "<< map->regulatoryElementLayer.size());
556 for (
auto lanelet : map->laneletLayer)
566 for (
auto area : map->areaLayer)