@@ -123,6 +123,11 @@ struct TrafficLight
123
123
124
124
constexpr operator Value () const noexcept { return value; }
125
125
126
+ friend constexpr auto operator <(const Status & lhs, const Status & rhs) -> bool
127
+ {
128
+ return lhs.value < rhs.value ;
129
+ }
130
+
126
131
friend auto operator >>(std::istream & is, Status & status) -> std::istream &;
127
132
128
133
friend auto operator <<(std::ostream & os, const Status & status) -> std::ostream &;
@@ -438,7 +443,7 @@ struct TrafficLight
438
443
439
444
std::set<Bulb> bulbs;
440
445
441
- const std::map<Bulb::Hash , std::optional<geometry_msgs::msg::Point>> positions;
446
+ const std::map<Color , std::optional<geometry_msgs::msg::Point>> positions;
442
447
443
448
auto clear () { bulbs.clear (); }
444
449
@@ -454,31 +459,45 @@ struct TrafficLight
454
459
template <typename Markers, typename Now>
455
460
auto draw (Markers & markers, const Now & now, const std::string & frame_id) const
456
461
{
457
- auto optional_position = [this ](auto && bulb) {
458
- try {
459
- return positions.at (bulb.hash () & 0b1111'0000'1111'1111 ); // NOTE: Ignore status
460
- } catch (const std::out_of_range &) {
461
- return std::optional<geometry_msgs::msg::Point>(std::nullopt );
462
- }
462
+ auto create_bulb_marker = [&](const Color & color, const bool is_on) {
463
+ visualization_msgs::msg::Marker marker;
464
+ marker.header .stamp = now;
465
+ marker.header .frame_id = frame_id;
466
+ marker.action = visualization_msgs::msg::Marker::ADD;
467
+ marker.ns = " bulb" ;
468
+ marker.id = way_id << 2 | static_cast <int >(color.value );
469
+ marker.type = visualization_msgs::msg::Marker::SPHERE;
470
+ marker.pose .position = positions.at (color).value ();
471
+ marker.pose .orientation = geometry_msgs::msg::Quaternion ();
472
+ marker.scale .x = 0.3 ;
473
+ marker.scale .y = 0.3 ;
474
+ marker.scale .z = 0.3 ;
475
+ marker.color = color_names::makeColorMsg (boost::lexical_cast<std::string>(color));
476
+ marker.color .a = is_on ? 1.0 : 0.3 ;
477
+ return marker;
463
478
};
464
479
480
+ std::set<Color> added_colors;
481
+
482
+ // Place on markers for actual bulbs
465
483
for (const auto & bulb : bulbs) {
466
- if (optional_position (bulb).has_value () and bulb.is (Shape::Category::circle)) {
467
- visualization_msgs::msg::Marker marker;
468
- marker.header .stamp = now;
469
- marker.header .frame_id = frame_id;
470
- marker.action = visualization_msgs::msg::Marker::ADD;
471
- marker.ns = " bulb" ;
472
- marker.id = way_id;
473
- marker.type = visualization_msgs::msg::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 ;
479
- marker.color =
480
- color_names::makeColorMsg (boost::lexical_cast<std::string>(std::get<Color>(bulb.value )));
481
- markers.push_back (marker);
484
+ // NOTE: Status is ignored intentionally
485
+ if (bulb.is (Shape::Category::circle)) {
486
+ const auto color = std::get<Color>(bulb.value );
487
+ const auto position = positions.find (color);
488
+ if (position == positions.end () or not position->second .has_value ()) {
489
+ continue ;
490
+ }
491
+
492
+ markers.push_back (create_bulb_marker (color, true ));
493
+ added_colors.insert (color);
494
+ }
495
+ }
496
+
497
+ // Place solidOff markers for other positions
498
+ for (const auto & [color, position] : positions) {
499
+ if (position.has_value () and added_colors.find (color) == added_colors.end ()) {
500
+ markers.push_back (create_bulb_marker (color, false ));
482
501
}
483
502
}
484
503
}
0 commit comments