@@ -63,6 +63,7 @@ using spark_dsg::SceneGraphLayer;
6363using spark_dsg::SceneGraphNode;
6464using spark_dsg::TraversabilityNodeAttributes;
6565using spark_dsg::TraversabilityState;
66+ using spark_dsg::TravNodeAttributes;
6667using visualization_msgs::msg::Marker;
6768using visualization_msgs::msg::MarkerArray;
6869
@@ -128,74 +129,96 @@ void TraversabilityPlugin::drawBoundaries(const Config& config,
128129 marker.ns = " boundaries" ;
129130 marker.pose .orientation .w = 1.0 ;
130131 marker.scale .x = config.line_width ;
131-
132- // Start and stop indices for the corner points of the boundary along the state
133- // direction.
134- static const std::array<std::pair<size_t , size_t >, 4 > state_pairs = {
135- std::make_pair (1 , 0 ),
136- std::make_pair (1 , 2 ),
137- std::make_pair (2 , 3 ),
138- std::make_pair (0 , 3 )};
139-
132+ marker.scale .y = config.line_width ;
133+ marker.scale .z = config.line_width ;
140134 for (const auto & [node_id, node] : layer.nodes ()) {
141- const auto & attrs = node->attributes <TraversabilityNodeAttributes>();
142-
143135 // Reset the marker.
144136 marker.id = id++;
145137 marker.points .clear ();
146138 marker.colors .clear ();
147139
148- // Get the world frame positions of the boundary points, adjusted for the line width
149- // for non-overlapping rendering. bot-right, bot-left, top-left, top-right
150- std::vector<Eigen::Vector3d> pts;
151- pts.reserve (4 );
152- pts.emplace_back (attrs.boundary .max .x () - config.line_width ,
153- attrs.boundary .min .y () + config.line_width ,
154- 0 );
155- pts.emplace_back (attrs.boundary .min .x () + config.line_width ,
156- attrs.boundary .min .y () + config.line_width ,
157- 0 );
158- pts.emplace_back (attrs.boundary .min .x () + config.line_width ,
159- attrs.boundary .max .y () - config.line_width ,
160- 0 );
161- pts.emplace_back (attrs.boundary .max .x () - config.line_width ,
162- attrs.boundary .max .y () - config.line_width ,
163- 0 );
164- for (auto & point : pts) {
165- point += attrs.position ;
166- point.z () = config.slice_height ;
140+ auto block_attrs = node->tryAttributes <TraversabilityNodeAttributes>();
141+ if (block_attrs) {
142+ drawBlockBoundary (config, *block_attrs, marker);
143+ } else {
144+ auto region_attrs = node->tryAttributes <TravNodeAttributes>();
145+ if (region_attrs) {
146+ drawRegionBoundary (config, *region_attrs, marker);
147+ }
167148 }
168149
169- // Draw the boundary points as a line segment, where individual states break up the
170- // line in equal parts if present.
171- for (size_t i = 0 ; i < 4 ; ++i) {
172- const auto & states = attrs.boundary .states [i];
173- const size_t start = state_pairs[i].first ;
174- const size_t end = state_pairs[i].second ;
175- tf2::convert (pts[start], marker.points .emplace_back ()); // First point.
176-
177- if (states.empty ()) {
178- // Single unknown boundary.
179- addBoundaryPoint (config, marker, pts[end], TraversabilityState::UNKNOWN, true );
180- continue ;
181- }
150+ tracker_.add (marker, msg);
151+ }
152+ }
182153
183- // Add line segments for continuous states.
184- auto current_state = states[0 ];
185- for (size_t j = 1 ; j < states.size (); ++j) {
186- if (states[j] != current_state) {
187- const double fraction = static_cast <double >(j) / (states.size () - 1 );
188- Eigen::Vector3d segment_point =
189- pts[start] * (1.0 - fraction) + pts[end] * fraction;
190- addBoundaryPoint (config, marker, segment_point, current_state);
191- current_state = states[j];
192- }
154+ void TraversabilityPlugin::drawBlockBoundary (
155+ const Config& config,
156+ const spark_dsg::TraversabilityNodeAttributes& attrs,
157+ visualization_msgs::msg::Marker& marker) const {
158+ // Get the world frame positions of the boundary points, adjusted for the line width
159+ // for non-overlapping rendering. bot-right, bot-left, top-left, top-right
160+ std::vector<Eigen::Vector3d> pts;
161+ pts.reserve (4 );
162+ pts.emplace_back (attrs.boundary .max .x () - config.line_width ,
163+ attrs.boundary .min .y () + config.line_width ,
164+ 0 );
165+ pts.emplace_back (attrs.boundary .min .x () + config.line_width ,
166+ attrs.boundary .min .y () + config.line_width ,
167+ 0 );
168+ pts.emplace_back (attrs.boundary .min .x () + config.line_width ,
169+ attrs.boundary .max .y () - config.line_width ,
170+ 0 );
171+ pts.emplace_back (attrs.boundary .max .x () - config.line_width ,
172+ attrs.boundary .max .y () - config.line_width ,
173+ 0 );
174+ for (auto & point : pts) {
175+ point += attrs.position ;
176+ point.z () = config.slice_height ;
177+ }
178+
179+ // Draw the boundary points as a line segment, where individual states break up the
180+ // line in equal parts if present.
181+ for (size_t i = 0 ; i < 4 ; ++i) {
182+ const auto & states = attrs.boundary .states [i];
183+ const size_t start = state_pairs_[i].first ;
184+ const size_t end = state_pairs_[i].second ;
185+ tf2::convert (pts[start], marker.points .emplace_back ()); // First point.
186+
187+ if (states.empty ()) {
188+ // Single unknown boundary.
189+ addBoundaryPoint (config, marker, pts[end], TraversabilityState::UNKNOWN, true );
190+ continue ;
191+ }
192+
193+ // Add line segments for continuous states.
194+ auto current_state = states[0 ];
195+ for (size_t j = 1 ; j < states.size (); ++j) {
196+ if (states[j] != current_state) {
197+ const double fraction = static_cast <double >(j) / (states.size () - 1 );
198+ Eigen::Vector3d segment_point =
199+ pts[start] * (1.0 - fraction) + pts[end] * fraction;
200+ addBoundaryPoint (config, marker, segment_point, current_state);
201+ current_state = states[j];
193202 }
194- addBoundaryPoint (config, marker, pts[end], current_state, true );
195203 }
204+ addBoundaryPoint (config, marker, pts[end], current_state, true );
205+ }
206+ }
196207
197- // Wrap around the last point to the first point.
198- tracker_.add (marker, msg);
208+ void TraversabilityPlugin::drawRegionBoundary (
209+ const Config& config,
210+ const TravNodeAttributes& attrs,
211+ visualization_msgs::msg::Marker& marker) const {
212+ marker.type = Marker::LINE_STRIP;
213+ for (size_t i = 0 ; i < attrs.radii .size (); ++i) {
214+ tf2::convert (attrs.getBoundaryPoint (i), marker.points .emplace_back ());
215+ marker.colors .emplace_back (
216+ visualizer::makeColorMsg (config.colors [static_cast <size_t >(attrs.states [i])]));
217+ }
218+ // Close the circle.
219+ if (!attrs.radii .empty ()) {
220+ marker.points .emplace_back (marker.points .front ());
221+ marker.colors .emplace_back (marker.colors .front ());
199222 }
200223}
201224
0 commit comments