15 #ifndef TRAFFIC_SIMULATOR__TRAFFIC_LIGHTS__TRAFFIC_LIGHT_HPP_
16 #define TRAFFIC_SIMULATOR__TRAFFIC_LIGHTS__TRAFFIC_LIGHT_HPP_
18 #include <simulation_api_schema.pb.h>
20 #include <color_names/color_names.hpp>
22 #include <geometry_msgs/msg/point.hpp>
32 #include <traffic_simulator_msgs/msg/traffic_light_array_v1.hpp>
34 #include <type_traits>
35 #include <unordered_map>
53 static_assert(
static_cast<std::uint8_t
>(
green ) == 0b0000'0000);
54 static_assert(
static_cast<std::uint8_t
>(
yellow) == 0b0000'0001);
55 static_assert(
static_cast<std::uint8_t
>(
red ) == 0b0000'0010);
56 static_assert(
static_cast<std::uint8_t
>(
white ) == 0b0000'0011);
63 static inline const std::unordered_map<std::string, Value>
table{
64 std::make_pair(
"amber",
yellow),
65 std::make_pair(
"green",
green),
66 std::make_pair(
"red",
red),
67 std::make_pair(
"white",
white),
68 std::make_pair(
"yellow",
yellow),
71 std::make_pair(
"Green",
green),
72 std::make_pair(
"Red",
red),
73 std::make_pair(
"Yellow",
yellow),
78 constexpr
auto is(
const Color given)
const {
return value == given; }
80 constexpr
operator Value() const noexcept {
return value; }
84 friend auto operator<<(std::ostream & os,
const Color & color) -> std::ostream &;
97 static_assert(
static_cast<std::uint8_t
>(
solid_on ) == 0b0000'0000);
98 static_assert(
static_cast<std::uint8_t
>(
solid_off) == 0b0000'0001);
99 static_assert(
static_cast<std::uint8_t
>(
flashing ) == 0b0000'0010);
100 static_assert(
static_cast<std::uint8_t
>(
unknown ) == 0b0000'0011);
107 static inline const std::unordered_map<std::string, Value>
table{
108 std::make_pair(
"solidOn",
solid_on),
110 std::make_pair(
"flashing",
flashing),
111 std::make_pair(
"unknown",
unknown),
128 friend auto operator<<(std::ostream & os,
const Status & status) -> std::ostream &;
140 static_assert(
static_cast<std::uint8_t
>(Category::circle) == 0b0000'0000);
141 static_assert(
static_cast<std::uint8_t
>(Category::cross ) == 0b0000'0001);
142 static_assert(
static_cast<std::uint8_t
>(Category::arrow ) == 0b0000'0010);
147 circle =
static_cast<std::uint8_t
>(Category::circle),
148 cross =
static_cast<std::uint8_t
>(Category::cross ),
149 left = (0b0000'1000 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
150 down = (0b0000'0100 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
151 up = (0b0000'0010 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
152 right = (0b0000'0001 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
153 lower_left = (0b0000'1100 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
154 upper_left = (0b0000'1010 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
155 lower_right = (0b0000'0101 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
156 upper_right = (0b0000'0011 << 8) |
static_cast<std::uint8_t
>(Category::arrow ),
161 static_assert(
static_cast<std::uint16_t
>(
circle ) == 0b0000'0000'0000'0000);
162 static_assert(
static_cast<std::uint16_t
>(
cross ) == 0b0000'0000'0000'0001);
163 static_assert(
static_cast<std::uint16_t
>(
left ) == 0b0000'1000'0000'0010);
164 static_assert(
static_cast<std::uint16_t
>(
down ) == 0b0000'0100'0000'0010);
165 static_assert(
static_cast<std::uint16_t
>(
up ) == 0b0000'0010'0000'0010);
166 static_assert(
static_cast<std::uint16_t
>(
right ) == 0b0000'0001'0000'0010);
167 static_assert(
static_cast<std::uint16_t
>(
lower_left ) == 0b0000'1100'0000'0010);
168 static_assert(
static_cast<std::uint16_t
>(
upper_left ) == 0b0000'1010'0000'0010);
169 static_assert(
static_cast<std::uint16_t
>(
lower_right) == 0b0000'0101'0000'0010);
170 static_assert(
static_cast<std::uint16_t
>(
upper_right) == 0b0000'0011'0000'0010);
177 static inline const std::unordered_map<std::string, Shape::Value>
table{
197 return static_cast<Category>(
static_cast<std::uint16_t
>(
value) & 0b1111'1111);
208 friend auto operator<<(std::ostream & os,
const Shape & shape) -> std::ostream &;
213 using Value = std::tuple<Color, Status, Shape>;
222 :
Bulb(std::forward_as_tuple(color, status, shape))
230 constexpr
auto is(
const Color color)
const {
return std::get<Color>(
value).is(color); }
232 constexpr
auto is(
const Status status)
const {
return std::get<Status>(
value).is(status); }
234 constexpr
auto is(
const Shape shape)
const {
return std::get<Shape>(
value).is(shape); }
238 return std::get<Shape>(
value).is(category);
244 (
static_cast<Hash>(std::get<Status>(
value).value) << 16) |
245 static_cast<Hash>(std::get<Shape>(
value).value);
250 return lhs.hash() < rhs.hash();
253 friend auto operator<<(std::ostream & os,
const Bulb & bulb) -> std::ostream &;
257 const auto color = [
this]() {
258 auto color_message = simulation_api_schema::TrafficLight_Color_UNKNOWN_COLOR;
259 switch (std::get<Color>(
value).value) {
261 color_message = simulation_api_schema::TrafficLight_Color_GREEN;
264 color_message = simulation_api_schema::TrafficLight_Color_AMBER;
267 color_message = simulation_api_schema::TrafficLight_Color_RED;
270 color_message = simulation_api_schema::TrafficLight_Color_WHITE;
273 return color_message;
276 const auto status = [
this]() {
277 auto status_message = simulation_api_schema::TrafficLight_Status_UNKNOWN_STATUS;
278 switch (std::get<Status>(
value).value) {
280 status_message = simulation_api_schema::TrafficLight_Status_SOLID_ON;
283 status_message = simulation_api_schema::TrafficLight_Status_SOLID_OFF;
286 status_message = simulation_api_schema::TrafficLight_Status_FLASHING;
289 status_message = simulation_api_schema::TrafficLight_Status_UNKNOWN_STATUS;
292 return status_message;
295 const auto shape = [
this]() {
296 auto shape_message = simulation_api_schema::TrafficLight_Shape_UNKNOWN_SHAPE;
297 switch (std::get<Shape>(
value).value) {
299 shape_message = simulation_api_schema::TrafficLight_Shape_CIRCLE;
302 shape_message = simulation_api_schema::TrafficLight_Shape_CROSS;
305 shape_message = simulation_api_schema::TrafficLight_Shape_LEFT_ARROW;
308 shape_message = simulation_api_schema::TrafficLight_Shape_DOWN_ARROW;
311 shape_message = simulation_api_schema::TrafficLight_Shape_UP_ARROW;
314 shape_message = simulation_api_schema::TrafficLight_Shape_RIGHT_ARROW;
317 shape_message = simulation_api_schema::TrafficLight_Shape_DOWN_LEFT_ARROW;
320 shape_message = simulation_api_schema::TrafficLight_Shape_DOWN_RIGHT_ARROW;
323 shape_message = simulation_api_schema::TrafficLight_Shape_UP_LEFT_ARROW;
326 shape_message = simulation_api_schema::TrafficLight_Shape_UP_RIGHT_ARROW;
329 return shape_message;
333 traffic_light_bulb_proto.set_status(status());
334 traffic_light_bulb_proto.set_shape(shape());
335 traffic_light_bulb_proto.set_color(color());
337 traffic_light_bulb_proto.set_confidence(1.0);
339 return traffic_light_bulb_proto;
342 explicit operator traffic_simulator_msgs::msg::TrafficLightBulbV1()
const
344 const auto color = [
this] {
345 auto color_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::UNKNOWN;
348 color_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::GREEN;
351 color_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::AMBER;
354 color_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::RED;
357 color_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::WHITE;
360 return color_message;
363 const auto status = [
this] {
364 auto status_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::UNKNOWN;
367 status_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::SOLID_ON;
370 status_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::SOLID_OFF;
373 status_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::FLASHING;
376 status_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::UNKNOWN;
379 return status_message;
382 const auto shape = [
this] {
383 auto shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::UNKNOWN;
386 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::CIRCLE;
389 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::CROSS;
392 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::LEFT_ARROW;
395 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::DOWN_ARROW;
398 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::UP_ARROW;
401 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::RIGHT_ARROW;
404 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::DOWN_LEFT_ARROW;
407 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::DOWN_RIGHT_ARROW;
410 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::UP_LEFT_ARROW;
413 shape_message = traffic_simulator_msgs::msg::TrafficLightBulbV1::UP_RIGHT_ARROW;
416 return shape_message;
419 traffic_simulator_msgs::msg::TrafficLightBulbV1 msg;
421 msg.status = status();
424 msg.confidence = 1.0;
441 const std::map<Bulb::Hash, std::optional<geometry_msgs::msg::Point>>
positions;
454 template <
typename Markers,
typename Now>
457 auto optional_position = [
this](
auto && bulb) {
459 return positions.at(bulb.hash() & 0b1111'0000'1111'1111);
460 }
catch (
const std::out_of_range &) {
461 return std::optional<geometry_msgs::msg::Point>(std::nullopt);
465 for (
const auto & bulb :
bulbs) {
467 visualization_msgs::msg::Marker marker;
468 marker.header.stamp = now;
469 marker.header.frame_id = frame_id;
470 marker.action = marker.ADD;
473 marker.type = marker.SPHERE;
474 marker.pose.position = optional_position(bulb).value();
475 marker.pose.orientation = geometry_msgs::msg::Quaternion();
476 marker.scale.x = 0.3;
477 marker.scale.y = 0.3;
478 marker.scale.z = 0.3;
480 color_names::makeColorMsg(boost::lexical_cast<std::string>(std::get<Color>(bulb.value)));
481 markers.push_back(marker);
486 template <
typename... Ts>
489 bulbs.emplace(std::forward<decltype(
xs)>(
xs)...);
498 explicit operator simulation_api_schema::TrafficSignal()
const
500 simulation_api_schema::TrafficSignal traffic_signal_proto;
502 traffic_signal_proto.set_id(
way_id);
503 for (
const auto & bulb :
bulbs) {
505 traffic_light_bulb_proto.set_confidence(
confidence);
506 *traffic_signal_proto.add_traffic_light_status() = traffic_light_bulb_proto;
508 return traffic_signal_proto;
511 explicit operator traffic_simulator_msgs::msg::TrafficLightV1()
const
513 traffic_simulator_msgs::msg::TrafficLightV1 traffic_signal;
514 traffic_signal.lanelet_way_id =
way_id;
515 for (
const auto & bulb :
bulbs) {
516 auto traffic_light_bulb =
static_cast<traffic_simulator_msgs::msg::TrafficLightBulbV1
>(bulb);
518 traffic_signal.traffic_light_bulbs.push_back(traffic_light_bulb);
520 return traffic_signal;
Definition: hdmap_utils.hpp:62
Definition: junit5.hpp:25
std::string string
Definition: junit5.hpp:26
Definition: traffic_light.hpp:212
constexpr auto is(const Shape shape) const
Definition: traffic_light.hpp:234
std::tuple< Color, Status, Shape > Value
Definition: traffic_light.hpp:213
constexpr auto hash() const -> Hash
Definition: traffic_light.hpp:241
constexpr Bulb(const Value value)
Definition: traffic_light.hpp:219
constexpr Bulb(const Color color={}, const Status status={}, const Shape shape={})
Definition: traffic_light.hpp:221
Bulb(const std::string &name)
Definition: traffic_light.hpp:226
constexpr friend auto operator<(const Bulb &lhs, const Bulb &rhs) -> bool
Definition: traffic_light.hpp:248
constexpr auto is(const Color color) const
Definition: traffic_light.hpp:230
friend auto operator<<(std::ostream &os, const Bulb &bulb) -> std::ostream &
Definition: traffic_light.cpp:156
auto make(const std::string &s) -> Value
Definition: traffic_light.cpp:130
constexpr auto is(const Shape::Category category) const
Definition: traffic_light.hpp:236
const Value value
Definition: traffic_light.hpp:215
std::uint32_t Hash
Definition: traffic_light.hpp:217
constexpr auto is(const Status status) const
Definition: traffic_light.hpp:232
Definition: traffic_light.hpp:44
Value
Definition: traffic_light.hpp:45
@ white
Definition: traffic_light.hpp:49
@ green
Definition: traffic_light.hpp:46
@ red
Definition: traffic_light.hpp:48
@ yellow
Definition: traffic_light.hpp:47
friend auto operator<<(std::ostream &os, const Color &color) -> std::ostream &
Definition: traffic_light.cpp:37
constexpr Color(const Value value=green)
Definition: traffic_light.hpp:59
Color(const std::string &name)
Definition: traffic_light.hpp:61
static const std::unordered_map< std::string, Value > table
Definition: traffic_light.hpp:63
enum traffic_simulator::TrafficLight::Color::Value value
friend auto operator>>(std::istream &is, Color &color) -> std::istream &
Definition: traffic_light.cpp:29
static auto make(const std::string &name) -> Color
Definition: traffic_light.cpp:20
constexpr auto is(const Color given) const
Definition: traffic_light.hpp:78
Definition: traffic_light.hpp:132
Value
Definition: traffic_light.hpp:145
@ up
Definition: traffic_light.hpp:151
@ upper_right
Definition: traffic_light.hpp:156
@ left
Definition: traffic_light.hpp:149
@ cross
Definition: traffic_light.hpp:148
@ lower_right
Definition: traffic_light.hpp:155
@ upper_left
Definition: traffic_light.hpp:154
@ lower_left
Definition: traffic_light.hpp:153
@ down
Definition: traffic_light.hpp:150
@ circle
Definition: traffic_light.hpp:147
@ right
Definition: traffic_light.hpp:152
constexpr auto category() const
Definition: traffic_light.hpp:195
enum traffic_simulator::TrafficLight::Shape::Value value
static auto make(const std::string &name) -> Shape
Definition: traffic_light.cpp:85
constexpr auto is(const Category given) const
Definition: traffic_light.hpp:202
friend auto operator>>(std::istream &is, Shape &shape) -> std::istream &
Definition: traffic_light.cpp:94
Category
Definition: traffic_light.hpp:133
friend auto operator<<(std::ostream &os, const Shape &shape) -> std::ostream &
Definition: traffic_light.cpp:102
constexpr auto is(const Value given) const
Definition: traffic_light.hpp:200
constexpr Shape(const Value value=circle)
Definition: traffic_light.hpp:173
static const std::unordered_map< std::string, Shape::Value > table
Definition: traffic_light.hpp:177
Shape(const std::string &name)
Definition: traffic_light.hpp:175
Definition: traffic_light.hpp:88
constexpr auto is(const Value given) const
Definition: traffic_light.hpp:120
constexpr Status(const Value value=solid_on)
Definition: traffic_light.hpp:103
static const std::unordered_map< std::string, Value > table
Definition: traffic_light.hpp:107
Status(const std::string &name)
Definition: traffic_light.hpp:105
Value
Definition: traffic_light.hpp:89
@ solid_off
Definition: traffic_light.hpp:91
@ unknown
Definition: traffic_light.hpp:93
@ solid_on
Definition: traffic_light.hpp:90
@ flashing
Definition: traffic_light.hpp:92
friend auto operator<<(std::ostream &os, const Status &status) -> std::ostream &
Definition: traffic_light.cpp:70
enum traffic_simulator::TrafficLight::Status::Value value
static auto make(const std::string &name) -> Status
Definition: traffic_light.cpp:53
friend auto operator>>(std::istream &is, Status &status) -> std::istream &
Definition: traffic_light.cpp:62
Definition: traffic_light.hpp:42
auto clear()
Definition: traffic_light.hpp:443
const lanelet::Ids regulatory_elements_ids
Definition: traffic_light.hpp:435
double confidence
Definition: traffic_light.hpp:437
const lanelet::Id way_id
Definition: traffic_light.hpp:433
TrafficLight(const lanelet::Id, const hdmap_utils::HdMapUtils &)
Definition: traffic_light.cpp:163
const std::map< Bulb::Hash, std::optional< geometry_msgs::msg::Point > > positions
Definition: traffic_light.hpp:441
auto empty() const
Definition: traffic_light.hpp:492
auto contains(const Color &color, const Status &status, const Shape &shape) const
Definition: traffic_light.hpp:447
std::set< Bulb > bulbs
Definition: traffic_light.hpp:439
auto set(const std::string &states) -> void
Definition: traffic_light.cpp:197
auto contains(const std::string &name) const
Definition: traffic_light.hpp:452
auto draw(Markers &markers, const Now &now, const std::string &frame_id) const
Definition: traffic_light.hpp:455
friend auto operator<<(std::ostream &os, const TrafficLight &traffic_light) -> std::ostream &
Definition: traffic_light.cpp:215
auto contains(const Bulb &bulb) const
Definition: traffic_light.hpp:445
auto emplace(Ts &&... xs)
Definition: traffic_light.hpp:487
traffic_simulator::TrafficLight TrafficLight
Definition: test_traffic_light.cpp:23
TrafficLight::Bulb Bulb
Definition: test_traffic_light.cpp:27