Skip to content

Commit 558b804

Browse files
Feature/edge colors (#52)
* first draft of edge color adapters * revert interlayer use color in config * Update hydra_visualizer/src/drawing.cpp Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com> * implement edge color type * PR feedback * fix compilation and test --------- Co-authored-by: Nathan Hughes <nathan.h.hughes@gmail.com>
1 parent 7bb7062 commit 558b804

File tree

8 files changed

+314
-44
lines changed

8 files changed

+314
-44
lines changed

hydra_visualizer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ find_package(visualization_msgs REQUIRED)
3030
add_library(
3131
${PROJECT_NAME}
3232
src/plugins/traversability_plugin.cpp
33+
src/adapters/edge_color.cpp
3334
src/adapters/graph_color.cpp
3435
src/adapters/mesh_color.cpp
3536
src/adapters/text.cpp
Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,69 @@
11
---
22
renderer:
3-
layer_z_step: 5.5 # unit separation between layers
4-
collapse_layers: false # whether or not to apply offsets to each of the layers
3+
layer_z_step: 5.5 # unit separation between layers
4+
collapse_layers: false # whether or not to apply offsets to each of the layers
55
layers:
66
2:
77
z_offset_scale: 2.0
88
visualize: true
9-
nodes: {scale: 0.40, color: {type: LabelColorAdapter}, alpha: 0.8, use_sphere: false}
10-
text: {draw: true, collapse: true, adapter: {type: LabelTextAdapter}, height: 0.5, scale: 0.45}
11-
bounding_boxes: {draw: true, collapse: true, scale: 0.05, edge_scale: 0.05, alpha: 0.9, edge_break_ratio: 0.5}
12-
edges: {interlayer_use_source: true, interlayer_scale: 0.08, interlayer_alpha: 0.9, interlayer_use_color: true}
9+
nodes: { scale: 0.40, color: { type: LabelColorAdapter }, alpha: 0.8, use_sphere: false }
10+
text: { draw: true, collapse: true, adapter: { type: LabelTextAdapter }, height: 0.5, scale: 0.45 }
11+
bounding_boxes: { draw: true, collapse: true, scale: 0.05, edge_scale: 0.05, alpha: 0.9, edge_break_ratio: 0.5 }
12+
edges: { interlayer_use_source: true, interlayer_scale: 0.08, interlayer_alpha: 0.9 }
1313
3:
1414
z_offset_scale: 3.0
1515
visualize: true
16-
nodes: {scale: 0.2, color: {type: ParentColorAdapter, colormap: {palette: colorbrewer}}, alpha: 0.9, use_sphere: true}
16+
nodes:
17+
{
18+
scale: 0.2,
19+
color: { type: ParentColorAdapter, colormap: { palette: colorbrewer } },
20+
alpha: 0.9,
21+
use_sphere: true,
22+
}
1723
edges:
1824
scale: 0.01
1925
alpha: 0.5
20-
use_color: false
26+
color: { type: UniformEdgeColorAdapter }
2127
interlayer_use_source: false
2228
interlayer_scale: 0.08
2329
interlayer_alpha: 0.4
24-
interlayer_use_color: true
2530
interlayer_insertion_skip: 0
2631
4:
2732
z_offset_scale: 4.2
2833
visualize: true
29-
nodes: {scale: 0.6, color: {type: IdColorAdapter, colormap: {palette: colorbrewer}}, alpha: 0.8, use_sphere: false}
30-
text: {draw: true, height: 1.25, scale: 1.0}
34+
nodes:
35+
{
36+
scale: 0.6,
37+
color: { type: IdColorAdapter, colormap: { palette: colorbrewer } },
38+
alpha: 0.8,
39+
use_sphere: false,
40+
}
41+
text: { draw: true, height: 1.25, scale: 1.0 }
3142
edges:
3243
scale: 0.1
3344
alpha: 0.2
34-
use_color: false
45+
color: { type: UniformEdgeColorAdapter }
3546
interlayer_use_source: true
3647
interlayer_scale: 0.08
3748
interlayer_alpha: 0.4
38-
interlayer_use_color: true
3949
interlayer_insertion_skip: 0
4050
partitions:
4151
2:
4252
z_offset_scale: 0.0
4353
visualize: true
44-
nodes: {scale: 0.15, alpha: 0.9, use_sphere: false, color: {type: PartitionColorAdapter}}
45-
edges: {scale: 0.05, alpha: 0.9, draw_interlayer: false}
46-
text: {draw_layer: true, height: 0.9, scale: 0.8}
54+
nodes: { scale: 0.15, alpha: 0.9, use_sphere: false, color: { type: PartitionColorAdapter } }
55+
edges: { scale: 0.05, alpha: 0.9, draw_interlayer: false }
56+
text: { draw_layer: true, height: 0.9, scale: 0.8 }
4757
3:
4858
z_offset_scale: 3.0
4959
visualize: true
50-
nodes: {scale: 0.2, color: {type: LabelColorAdapter}, alpha: 0.9, use_sphere: true}
51-
boundaries: {draw: true, collapse: false, wireframe_scale: 0.1, use_node_color: true, alpha: 1.0}
60+
nodes: { scale: 0.2, color: { type: LabelColorAdapter }, alpha: 0.9, use_sphere: true }
61+
boundaries: { draw: true, collapse: false, wireframe_scale: 0.1, use_node_color: true, alpha: 1.0 }
5262
edges:
5363
scale: 0.01
5464
alpha: 0.5
55-
use_color: false
65+
color: { type: UniformEdgeColorAdapter }
5666
interlayer_use_source: false
5767
interlayer_scale: 0.08
5868
interlayer_alpha: 0.4
59-
interlayer_use_color: true
6069
interlayer_insertion_skip: 0
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/* -----------------------------------------------------------------------------
2+
* Copyright 2022 Massachusetts Institute of Technology.
3+
* All Rights Reserved
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* 1. Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
*
11+
* 2. Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following disclaimer in the documentation
13+
* and/or other materials provided with the distribution.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
*
26+
* Research was sponsored by the United States Air Force Research Laboratory and
27+
* the United States Air Force Artificial Intelligence Accelerator and was
28+
* accomplished under Cooperative Agreement Number FA8750-19-2-1000. The views
29+
* and conclusions contained in this document are those of the authors and should
30+
* not be interpreted as representing the official policies, either expressed or
31+
* implied, of the United States Air Force or the U.S. Government. The U.S.
32+
* Government is authorized to reproduce and distribute reprints for Government
33+
* purposes notwithstanding any copyright notation herein.
34+
* -------------------------------------------------------------------------- */
35+
#pragma once
36+
#include <config_utilities/factory.h>
37+
#include <spark_dsg/color.h>
38+
#include <spark_dsg/dynamic_scene_graph.h>
39+
40+
#include <memory>
41+
42+
#include "hydra_visualizer/color/colormap_utilities.h"
43+
44+
namespace hydra {
45+
46+
#define REGISTER_COLOR_ADAPTER(adapter) \
47+
inline static const auto registration_ = \
48+
config::RegistrationWithConfig<EdgeColorAdapter, adapter, Config>(#adapter)
49+
50+
struct EdgeColorAdapter {
51+
using Ptr = std::shared_ptr<EdgeColorAdapter>;
52+
using EdgeColor = std::pair<spark_dsg::Color, spark_dsg::Color>;
53+
54+
virtual ~EdgeColorAdapter() = default;
55+
56+
/**
57+
* @brief Get color for an edge.
58+
* @param graph Current scene graph node is from
59+
* @param edge Edge to get color for
60+
* @returns Visualizer color for source and target ends of the edge.
61+
*/
62+
virtual EdgeColor getColor(const spark_dsg::DynamicSceneGraph& graph,
63+
const spark_dsg::SceneGraphEdge& edge) const = 0;
64+
65+
/**
66+
* @brief Set any pre-draw information
67+
* @param graph Graph to get information for
68+
*
69+
* Allows color adapters to gather statistics about the scene graph before generating
70+
* any edge colors when drawing the scene graph
71+
*/
72+
virtual void setGraph(const spark_dsg::DynamicSceneGraph& /* graph */,
73+
spark_dsg::LayerId /* layer */) {}
74+
};
75+
76+
struct UniformEdgeColorAdapter : EdgeColorAdapter {
77+
struct Config {
78+
// TODO(lschmid): Consider using the named colors, or even better integrate
79+
// optionally named colors directly into the config utilities parsing.
80+
spark_dsg::Color color;
81+
} const config;
82+
83+
explicit UniformEdgeColorAdapter(const Config& config);
84+
EdgeColor getColor(const spark_dsg::DynamicSceneGraph& graph,
85+
const spark_dsg::SceneGraphEdge& edge) const override;
86+
87+
private:
88+
REGISTER_COLOR_ADAPTER(UniformEdgeColorAdapter);
89+
};
90+
91+
void declare_config(UniformEdgeColorAdapter::Config& config);
92+
93+
struct EdgeValueFunctor {
94+
virtual ~EdgeValueFunctor() = default;
95+
virtual double eval(const spark_dsg::DynamicSceneGraph& graph,
96+
const spark_dsg::SceneGraphEdge& edge) const = 0;
97+
};
98+
99+
struct EdgeWeightFunctor : EdgeValueFunctor {
100+
double eval(const spark_dsg::DynamicSceneGraph& graph,
101+
const spark_dsg::SceneGraphEdge& edge) const override;
102+
103+
inline static const auto registration =
104+
config::Registration<EdgeValueFunctor, EdgeWeightFunctor>("weight");
105+
};
106+
107+
struct ValueEdgeColorAdapter : EdgeColorAdapter {
108+
struct Config {
109+
visualizer::RangeColormap::Config colormap;
110+
std::string value_functor{"weight"};
111+
} const config;
112+
113+
explicit ValueEdgeColorAdapter(const Config& config);
114+
void setGraph(const spark_dsg::DynamicSceneGraph& graph,
115+
spark_dsg::LayerId layer) override;
116+
EdgeColor getColor(const spark_dsg::DynamicSceneGraph& graph,
117+
const spark_dsg::SceneGraphEdge& edge) const override;
118+
119+
private:
120+
double min_value_;
121+
double max_value_;
122+
std::unique_ptr<EdgeValueFunctor> functor_;
123+
const visualizer::RangeColormap colormap_;
124+
REGISTER_COLOR_ADAPTER(ValueEdgeColorAdapter);
125+
};
126+
127+
void declare_config(ValueEdgeColorAdapter::Config& config);
128+
129+
#undef REGISTER_COLOR_ADAPTER
130+
131+
} // namespace hydra

hydra_visualizer/include/hydra_visualizer/layer_info.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <spark_dsg/color.h>
3838
#include <spark_dsg/dynamic_scene_graph.h>
3939

40+
#include "hydra_visualizer/adapters/edge_color.h"
4041
#include "hydra_visualizer/adapters/graph_color.h"
4142
#include "hydra_visualizer/adapters/text.h"
4243

@@ -74,10 +75,9 @@ struct LayerConfig {
7475
double scale = 0.03; //[ 0.001, 1.0]
7576
//! @brief intralayer edge alpha
7677
double alpha = 1.0; //[ 0.0, 1.0]
77-
//! @brief Color to use for edge
78-
NamedColors color = NamedColors::BLACK;
79-
//! @brief show intralayer edge using node colors
80-
bool use_color = true;
78+
//! @brief Color to use for edge. Unspecified uses node colors.
79+
config::VirtualConfig<EdgeColorAdapter, true> color{
80+
UniformEdgeColorAdapter::Config()};
8181
//! @brief draw interlayer edges
8282
bool draw_interlayer = true;
8383
//! @brief use edge source layer for config
@@ -86,7 +86,7 @@ struct LayerConfig {
8686
double interlayer_scale = 0.03; // [0.001, 1.0]
8787
//! @brief interlayer edge alpha
8888
double interlayer_alpha = 1.0; // [0.0, 1.0]
89-
//! @brief show interlayer edge using node colors
89+
//! @brief If true color dsg-mesh edges
9090
bool interlayer_use_color = true;
9191
//! @brief Number of edges to skip when drawing interlayer edges
9292
size_t interlayer_insertion_skip = 0; // [0, 1000]
@@ -155,6 +155,8 @@ class LayerInfo {
155155
using FilterFunction = std::function<bool(const spark_dsg::SceneGraphNode&)>;
156156
using ColorFunction =
157157
std::function<spark_dsg::Color(const spark_dsg::SceneGraphNode&)>;
158+
using EdgeColorFunction = std::function<std::pair<spark_dsg::Color, spark_dsg::Color>(
159+
const spark_dsg::SceneGraphEdge&)>;
158160
using TextFunction = std::function<std::string(const spark_dsg::SceneGraphNode&)>;
159161

160162
LayerInfo(const LayerConfig config);
@@ -163,17 +165,18 @@ class LayerInfo {
163165

164166
bool shouldVisualize(const spark_dsg::SceneGraphNode& node) const;
165167
spark_dsg::Color text_color() const;
166-
spark_dsg::Color edge_color() const;
167168

168169
const LayerConfig config;
169170

170171
double z_offset;
171172
ColorFunction node_color;
173+
EdgeColorFunction edge_color;
172174
TextFunction node_text;
173175
mutable FilterFunction filter;
174176

175177
private:
176-
std::unique_ptr<GraphColorAdapter> color_adapter_;
178+
std::unique_ptr<GraphColorAdapter> node_color_adapter_;
179+
std::unique_ptr<EdgeColorAdapter> edge_color_adapter_;
177180
std::unique_ptr<GraphTextAdapter> text_adapter_;
178181
};
179182

0 commit comments

Comments
 (0)