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