blob: 4ed9866915173e48b9f25fc6152b578b9995590c [file] [log] [blame]
Jim Ostrowski17ce54d2020-10-24 17:24:01 -07001#include <iostream>
2#include <map>
3
Philipp Schrader790cb542023-07-05 21:06:52 -07004#include "gflags/gflags.h"
5
Jim Ostrowski17ce54d2020-10-24 17:24:01 -07006#include "aos/configuration.h"
7#include "aos/events/shm_event_loop.h"
8#include "aos/init.h"
9#include "aos/json_to_flatbuffer.h"
Jim Ostrowski17ce54d2020-10-24 17:24:01 -070010
11DEFINE_bool(all, false,
12 "If true, print out the channels for all nodes in the config file, "
13 "not just the channels which are visible on this node.");
Austin Schuh8e2dfc62022-08-17 16:36:00 -070014DEFINE_string(config, "aos_config.json", "File path of aos configuration");
Jim Ostrowski17ce54d2020-10-24 17:24:01 -070015DEFINE_bool(short_types, true,
16 "Whether to show a shortened version of the type name");
17
18int main(int argc, char **argv) {
19 gflags::SetUsageMessage(
20 "\nCreates graph of nodes and message channels based on the robot config "
21 "file. \n\n"
22 "To save to file, run as: \n"
23 "\t aos_graph_nodes > /tmp/graph.dot\n\n"
24 "To display graph, run as: \n"
25 "\t aos_graph_nodes | dot -Tx11");
26 aos::InitGoogle(&argc, &argv);
27
28 // Cycle through this list of colors-- here's some defaults.
29 // Can use color names or Hex values of RGB, e.g., red = "#FF0000"
30 std::vector<std::string> color_list = {"red", "blue", "orange", "green",
31 "violet", "gold3", "magenta"};
32 int color_index = 0;
33
34 std::string channel_name;
35 std::string message_type;
36
37 // Map from source nodes to color for them
38 std::map<std::string, std::string> color_map;
39
40 if (argc > 1) {
41 LOG(ERROR) << "ERROR: Got unexpected arguments\n\n";
42 gflags::ShowUsageWithFlagsRestrict(argv[0], "aos/aos_graph_nodes.cc");
43 return -1;
44 }
45
46 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
47 aos::configuration::ReadConfig(FLAGS_config);
48
49 const aos::Configuration *config_msg = &config.message();
50 aos::ShmEventLoop event_loop(config_msg);
51 event_loop.SkipTimingReport();
52 event_loop.SkipAosLog();
53
54 // Open output file and print header
55 std::stringstream graph_out;
56 graph_out << "digraph g {" << std::endl;
57
58 for (const aos::Channel *channel : *config_msg->channels()) {
59 VLOG(1) << "Found channel " << channel->type()->string_view();
60 if (FLAGS_all || aos::configuration::ChannelIsReadableOnNode(
61 channel, event_loop.node())) {
62 flatbuffers::string_view type_name = channel->type()->string_view();
63 if (FLAGS_short_types) {
64 // Strip down to just the top level of the message type
65 type_name = channel->type()->string_view().substr(
66 channel->type()->string_view().rfind(".") + 1, std::string::npos);
67 }
68
69 VLOG(1) << "Found: " << channel->name()->string_view() << ' '
70 << channel->type()->string_view();
71
72 CHECK(channel->has_source_node())
73 << ": Could not find source node for channel "
74 << channel->type()->string_view();
75 std::string source_node_name = channel->source_node()->c_str();
76 VLOG(1) << "Source node name:" << channel->source_node()->c_str();
77
78 // If we haven't seen this node yet, add to our list, with new color
79 if (color_map.count(source_node_name) == 0) {
80 color_map[source_node_name] = color_list[color_index];
81 color_index = (color_index + 1) % color_list.size();
82 }
83
84 if (channel->has_destination_nodes()) {
85 for (const aos::Connection *connection :
86 *channel->destination_nodes()) {
87 VLOG(1) << "Destination Node: " << connection->name()->string_view();
Austin Schuh24aa4f02021-02-07 21:57:34 -080088 graph_out << "\t\"" << source_node_name << "\" -> \""
89 << connection->name()->c_str() << "\" [label=\""
Jim Ostrowski17ce54d2020-10-24 17:24:01 -070090 << channel->name()->c_str() << "\\n"
91 << type_name << "\" color=\"" << color_map[source_node_name]
92 << "\"];" << std::endl;
93 }
94 }
95 }
96 }
97
98 // Write out all the nodes at the end, with their respective colors
Austin Schuh24aa4f02021-02-07 21:57:34 -080099 for (const auto &node_color : color_map) {
Austin Schuh60e77942022-05-16 17:48:24 -0700100 graph_out << "\t\"" << node_color.first << "\" [color=\""
101 << node_color.second << "\"];" << std::endl;
Jim Ostrowski17ce54d2020-10-24 17:24:01 -0700102 }
103
104 // Close out the file
105 graph_out << "}" << std::endl;
106
107 std::cout << graph_out.str();
108 return 0;
109}