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