2022-05-23 13:03:38 +02:00
{
"cells": [
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 1,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2022-05-23 13:03:38 +02:00
"outputs": [],
"source": [
"import os\n",
"import sys\n",
2022-09-15 18:04:45 +02:00
"import re\n",
"from tqdm import tqdm\n",
2022-12-25 20:47:56 +09:00
"from typing import Iterable\n",
2022-07-20 13:35:06 +02:00
"\n",
2022-05-23 13:03:38 +02:00
"import numpy as np\n",
"import pandas as pd\n",
"from matplotlib import pyplot as plt\n",
"\n",
2022-09-15 16:17:24 +02:00
"from misc.utils import cached, parse_as\n",
2022-08-29 22:17:52 +02:00
"\n",
2022-11-07 17:46:09 +09:00
"# TODO: This has no effect for some reason (goal is to make graphs in notebook large and hi-res)\n",
2022-10-07 15:35:34 +09:00
"plt.rcParams['figure.dpi'] = 300\n",
"\n",
2022-09-14 14:08:47 +02:00
"%matplotlib inline"
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
2022-10-13 19:13:39 +09:00
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
2023-02-15 17:02:20 +09:00
},
"source": [
"# User Settings"
]
2022-10-13 19:13:39 +09:00
},
2022-09-15 15:26:32 +02:00
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 2,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"User Settings:\n",
" TRACING_WS_BUILD_PATH................... := /home/niklas/dataflow-analysis/dependencies/build\n",
2025-06-09 14:12:01 +00:00
" EXPERIMENT_NAME......................... := ros_single_timed_20-20250609154040\n",
" TR_PATH................................. := /home/niklas/dataflow-analysis/traces/ros_single_timed_20-20250609154040/ust\n",
" OUT_PATH................................ := /home/niklas/dataflow-analysis/out/ros_single_timed_20-20250609154040\n",
2025-06-03 13:43:48 +00:00
" CACHING_ENABLED......................... := False\n",
" BW_ENABLED.............................. := False\n",
" BW_PATH................................. := /home/niklas/dataflow-analysis/path/to/messages.h5\n",
" CL_ENABLED.............................. := False\n",
" CL_PATH................................. := /path/to/code_analysis/output\n",
" DFG_ENABLED............................. := True\n",
" DFG_PLOT................................ := True\n",
" DFG_MAX_HIER_LEVEL...................... := 100\n",
" DFG_INPUT_NODE_PATTERNS................. := ^/input_\n",
" DFG_OUTPUT_NODE_PATTERNS................ := ^/output_\n",
" DFG_EXCL_NODE_PATTERNS.................. := ^/rviz2\n",
" E2E_ENABLED............................. := True\n",
" E2E_PLOT................................ := True\n",
2025-06-09 14:12:01 +00:00
" E2E_PLOT_TIMESTAMP...................... := 5\n",
" E2E_TIME_LIMIT_S........................ := 1000\n",
2025-06-03 13:43:48 +00:00
" E2E_OUTPUT_TOPIC_PATTERNS............... := ^/output/\n",
" E2E_INPUT_TOPIC_PATTERNS................ := ^/input/\n",
" E2E_EXCL_PATH_PATTERNS.................. := ^/parameter_events\n",
" E2E_INCL_PATH_PATTERNS.................. := \n",
" E2E_EXACT_PATH.......................... := \n",
" DEBUG................................... := False\n",
" MANUAL_CACHE............................ := False\n"
]
}
],
2022-05-23 13:03:38 +02:00
"source": [
2022-09-12 19:24:26 +02:00
"##################################################\n",
"# User Settings\n",
"##################################################\n",
"# Change these to influence the execution of the\n",
"# notebook.\n",
"# You can override these from the command line\n",
"# by defining environment variables with the\n",
"# name of the constants below, prefixed with\n",
"# \"ANA_NB_\".\n",
"# For example, the environment variable\n",
"# \"ANA_NB_TR_PATH\" will override the \"TR_PATH\"\n",
"# setting below.\n",
"##################################################\n",
"\n",
"# The path to the build folder of a ROS2 workspace that contains the\n",
"# tracetools_read and tracetools_analysis folders.\n",
2025-06-03 13:43:48 +00:00
"TRACING_WS_BUILD_PATH = \"/home/niklas/dataflow-analysis/dependencies/build\"\n",
2022-09-12 19:24:26 +02:00
"\n",
2025-06-06 08:24:47 +00:00
"# The name of the experiment that is being analyzed.\n",
"# This will be used to name output directory.\n",
2025-06-09 14:12:01 +00:00
"EXPERIMENT_NAME = \"ros_single_timed_20-20250609154040\"\n",
2025-06-06 08:24:47 +00:00
"\n",
2022-09-12 19:24:26 +02:00
"# Path to trace directory (e.g. ~/.ros/my-trace/ust) or to a converted trace file.\n",
"# Using the path \"/ust\" at the end is optional but greatly reduces processing time\n",
"# if kernel traces are also present.\n",
2025-06-06 08:24:47 +00:00
"TR_PATH = f\"/home/niklas/dataflow-analysis/traces/{EXPERIMENT_NAME}/ust\"\n",
2022-09-12 19:24:26 +02:00
"\n",
"# Path to the folder all artifacts from this notebook are saved to.\n",
"# This entails plots as well as data tables.\n",
2025-06-06 08:24:47 +00:00
"OUT_PATH = f\"out/{EXPERIMENT_NAME}/\"\n",
2022-09-12 19:24:26 +02:00
"\n",
2022-09-15 16:17:24 +02:00
"# Whether to cache the results of long computations per set of inputs\n",
2022-09-15 18:04:45 +02:00
"CACHING_ENABLED = False\n",
2022-09-15 16:17:24 +02:00
"\n",
2022-09-12 19:24:26 +02:00
"# Whether to annotate topics/publications with bandwidth/message size\n",
2022-12-25 20:47:56 +09:00
"BW_ENABLED = False\n",
2022-10-28 22:37:48 +09:00
"# Path to a HDF5 file as output by ma-hw-perf-tools/messages/record.bash\n",
2022-09-12 19:24:26 +02:00
"# Used to annotate message sizes in E2E latency calculations\n",
2023-02-15 17:02:20 +09:00
"BW_PATH = \"path/to/messages.h5\"\n",
2022-09-12 19:24:26 +02:00
"\n",
"# Whether to use dependencies extracted by the Clang-tools to supplement\n",
"# automatic node-internal data flow annotations.\n",
"# If in doubt, set to False.\n",
"CL_ENABLED = False\n",
"# Path to the output directory of the ROS2 dependency checker.\n",
"# Will only be used if CL_ENABLED is True.\n",
2023-02-15 17:02:20 +09:00
"CL_PATH = \"/path/to/code_analysis/output\"\n",
2022-09-12 19:24:26 +02:00
"\n",
"# Whether to compute data flow graphs.\n",
"# If you are only interested in E2E latencies, set this to False\n",
2025-06-03 13:43:48 +00:00
"DFG_ENABLED = True\n",
2022-09-12 19:24:26 +02:00
"# Whether to plot data flow graphs (ignored if DFG_ENABLED is False)\n",
2025-06-03 13:43:48 +00:00
"DFG_PLOT = True\n",
2022-09-12 19:24:26 +02:00
"\n",
"# The maximum node namespace hierarchy level to be plotted.\n",
"# Top-level (1): e.g. /sensing, /control, etc.\n",
"# Level 3: e.g. /sensing/lidar/pointcloud_processor\n",
"DFG_MAX_HIER_LEVEL = 100\n",
"\n",
"# RegEx pattern for nodes that shall be marked as system inputs\n",
"# These will be plotted with a start arrow as known from automata diagrams\n",
2025-06-03 13:43:48 +00:00
"DFG_INPUT_NODE_PATTERNS = [r\"^/input_\"]\n",
2022-09-12 19:24:26 +02:00
"# RegEx pattern for nodes that shall be marked as system outputs\n",
"# These will be plotted with a double border\n",
2025-06-03 13:43:48 +00:00
"DFG_OUTPUT_NODE_PATTERNS = [r\"^/output_\"]\n",
2022-09-12 19:24:26 +02:00
"# RegEx for nodes which shall not be plotted in the DFG\n",
2022-12-25 20:47:56 +09:00
"DFG_EXCL_NODE_PATTERNS = [r\"^/rviz2\"]\n",
2022-09-12 19:24:26 +02:00
"\n",
"# Whether to compute E2E latencies.\n",
"E2E_ENABLED = True\n",
"# Whether to plot end-to-end latency information (ignored if E2E_ENABLED is False)\n",
2022-09-19 15:39:17 +02:00
"E2E_PLOT = True\n",
2022-09-12 19:24:26 +02:00
"# The index of the output message that shall be used in plots that visualize a specific\n",
"# message dependency tree. This index has to be 0 <= n < #output messages\n",
2025-06-09 14:12:01 +00:00
"E2E_PLOT_TIMESTAMP = 5\n",
2022-09-12 19:24:26 +02:00
"# E2E latency threshold. Every E2E latency higher than this is discarded.\n",
"# Set this as low as comfortably possible to speed up calculations.\n",
"# WARNING: If you set this too low (i.e. to E2E latencies that plausibly can happen)\n",
"# your results will be wrong)\n",
2025-06-09 14:12:01 +00:00
"E2E_TIME_LIMIT_S = 1000\n",
2022-09-12 19:24:26 +02:00
"\n",
"# All topics containing any of these RegEx patterns are considered output topics in E2E latency calculations\n",
"# E.g. r\"^/control/\" will cover all control topics\n",
2025-06-03 13:43:48 +00:00
"E2E_OUTPUT_TOPIC_PATTERNS = [r\"^/output/\"]\n",
2022-09-12 19:24:26 +02:00
"# All topics containing any of these RegEx patterns are considered input topics in E2E latency calculations\n",
"# E.g. r\"^/sensing/\" will cover all sensing topics\n",
2025-06-03 13:43:48 +00:00
"E2E_INPUT_TOPIC_PATTERNS = [r\"^/input/\"]\n",
2022-09-12 19:24:26 +02:00
"\n",
2022-09-20 15:42:24 +02:00
"# E2E paths are uniquely identified by a string like \"/topic/1 -> void(Node1)(args1) -> /topic/2 -> void(Node2)(args2) -> void(Node2)(args3) -> ...\".\n",
"# Certain patterns only occur in initial setup or in scenario switching and can be excluded via RegEx patterns here.\n",
2025-06-03 13:43:48 +00:00
"E2E_EXCL_PATH_PATTERNS = [r\"^/parameter_events\"]\n",
2022-09-20 15:42:24 +02:00
"\n",
2022-11-07 17:46:09 +09:00
"# To specify paths of interest, topic/callback name patterns that HAVE TO OCCUR in each E2E path can be specified as RegEx here.\n",
2022-12-25 20:47:56 +09:00
"#E2E_INCL_PATH_PATTERNS = [\"BehaviorPathPlanner\", \"BehaviorVelocityPlanner\", \"pointcloud_preprocessor::Filter\", r\"^/sensing/.*?pointcloud\"]\n",
"E2E_INCL_PATH_PATTERNS = []\n",
"\n",
"# If an exact path through the system is known, this variabe can be set to a list (order matters!) of all elements on the path.\n",
"# The first item ist the one at the \"input end\" of the system, the last one the \"output end\".\n",
2025-06-03 13:43:48 +00:00
"E2E_EXACT_PATH = []\n",
2022-09-20 15:42:24 +02:00
"\n",
2022-11-07 17:46:09 +09:00
"# For development purposes only. Leave this at False.\n",
2022-10-14 00:15:33 +09:00
"DEBUG = False\n",
2022-10-13 19:13:39 +09:00
"\n",
2022-11-07 17:46:09 +09:00
"# For development purposes only. Leave this at False.\n",
"MANUAL_CACHE = False\n",
"\n",
"##################################################\n",
"# End of User Settings\n",
"##################################################\n",
"\n",
"# This code overrides the above constants with environment variables, with values from the environment.\n",
"# Values will be parsed through Python's literal_eval() function. Thus, strings have to be specified\n",
"# including \" or '.\n",
2022-09-12 19:24:26 +02:00
"for env_key, env_value in os.environ.items():\n",
" if env_key.startswith(\"ANA_NB_\"):\n",
" key = env_key.removeprefix(\"ANA_NB_\")\n",
" if key not in globals().keys():\n",
" continue\n",
" value = parse_as(type(globals()[key]), env_value)\n",
" globals()[key] = value\n",
"\n",
2022-09-15 18:04:45 +02:00
"\n",
2022-09-12 19:24:26 +02:00
"# Convert input paths to absolute paths\n",
"def _expand_path(path):\n",
" return os.path.realpath(os.path.expandvars(os.path.expanduser(path)))\n",
"\n",
2022-09-15 18:04:45 +02:00
"\n",
2022-09-12 19:24:26 +02:00
"TRACING_WS_BUILD_PATH = _expand_path(TRACING_WS_BUILD_PATH)\n",
"TR_PATH = _expand_path(TR_PATH)\n",
"OUT_PATH = _expand_path(OUT_PATH)\n",
"BW_PATH = _expand_path(BW_PATH)\n",
2022-09-14 14:08:47 +02:00
"CL_PATH = _expand_path(CL_PATH)\n",
"\n",
2022-09-16 19:11:35 +02:00
"os.makedirs(OUT_PATH, exist_ok=True)\n",
"\n",
2022-11-07 17:46:09 +09:00
"# Print parsed user settings\n",
2022-09-16 19:11:35 +02:00
"print(\"User Settings:\")\n",
2022-09-16 19:14:33 +02:00
"for k, v in globals().copy().items():\n",
2022-09-16 19:11:35 +02:00
" if not k.isupper():\n",
" continue\n",
2022-12-25 20:47:56 +09:00
" if isinstance(v, Iterable) and not isinstance(v, str):\n",
" v = (\"\\n \" + (\" \" * 44)).join(list(map(str, v)))\n",
2022-09-16 19:11:35 +02:00
" print(f\" {k:.<40s} := {v}\")"
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 3,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2022-09-12 19:24:26 +02:00
"outputs": [],
"source": [
2022-11-07 17:46:09 +09:00
"# The last few imports can only be resolved using the user-specified paths above\n",
2022-09-12 19:24:26 +02:00
"sys.path.append(os.path.join(TRACING_WS_BUILD_PATH, \"tracetools_read/\"))\n",
"sys.path.append(os.path.join(TRACING_WS_BUILD_PATH, \"tracetools_analysis/\"))\n",
2022-10-13 19:13:39 +09:00
"# noinspection PyUnresolvedReferences\n",
2022-09-12 19:24:26 +02:00
"from tracetools_read.trace import *\n",
2022-10-13 19:13:39 +09:00
"# noinspection PyUnresolvedReferences\n",
2022-09-12 19:24:26 +02:00
"from tracetools_analysis.loading import load_file\n",
2022-10-13 19:13:39 +09:00
"# noinspection PyUnresolvedReferences\n",
2022-09-12 19:24:26 +02:00
"from tracetools_analysis.processor.ros2 import Ros2Handler\n",
"\n",
2022-11-07 17:46:09 +09:00
"from tracing_interop.tr_types import *"
2023-02-15 17:02:20 +09:00
]
2022-09-12 19:24:26 +02:00
},
2022-05-23 21:28:40 +02:00
{
"cell_type": "markdown",
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2022-09-15 15:26:32 +02:00
"source": [
2022-11-07 17:46:09 +09:00
"# Load Trace Data\n",
"\n",
"Load (and, if necessary, convert) tracing data obtained through ros2_tracing. Build indices for fast analysis."
2023-02-15 17:02:20 +09:00
]
2022-05-23 21:28:40 +02:00
},
2022-05-23 13:03:38 +02:00
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 4,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[CACHE] Cache disabled for tr_objects.\n",
2025-06-09 14:12:01 +00:00
"found converted file: /home/niklas/dataflow-analysis/traces/ros_single_timed_20-20250609154040/ust/converted\n",
2025-06-03 13:43:48 +00:00
" [100%] [Ros2Handler]\n",
"[TrContext] Processing ROS 2 objects from traces...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
" ├─ Processing TrNodes: 100%|██████████| 23/23 [00:00<00:00, 259325.25it/s]\n",
" ├─ Processing TrPublishers: 100%|██████████| 69/69 [00:00<00:00, 404765.00it/s]\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[DEBUG] Duplicate Indices in id\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
" ├─ Processing TrSubscriptions: 100%|██████████| 43/43 [00:00<00:00, 191256.70it/s]\n",
" ├─ Processing TrTimers: 100%|██████████| 14/14 [00:00<00:00, 229376.00it/s]\n",
" ├─ Processing TrTimerNodeLinks: 100%|██████████| 14/14 [00:00<00:00, 216679.91it/s]\n",
" ├─ Processing TrSubscriptionObjects: 100%|██████████| 43/43 [00:00<00:00, 516776.71it/s]\n",
" ├─ Processing TrCallbackObjects: 100%|██████████| 195/195 [00:00<00:00, 357781.84it/s]\n",
" ├─ Processing TrCallbackSymbols: 100%|██████████| 195/195 [00:00<00:00, 700847.71it/s]\n",
" ├─ Processing TrPublishInstances: 100%|██████████| 2688/2688 [00:00<00:00, 849351.30it/s]\n",
" ├─ Processing TrCallbackInstances: 100%|██████████| 4208/4208 [00:00<00:00, 781302.84it/s]"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n"
]
2025-06-09 14:12:01 +00:00
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n"
]
2025-06-03 13:43:48 +00:00
}
],
2022-05-24 20:35:30 +02:00
"source": [
2022-07-20 13:35:06 +02:00
"def _load_traces():\n",
" file = load_file(TR_PATH)\n",
" handler = Ros2Handler.process(file)\n",
2022-08-29 22:17:52 +02:00
" return TrContext(handler)\n",
2022-07-20 13:35:06 +02:00
"\n",
2022-08-09 18:36:53 +02:00
"\n",
2022-09-15 18:04:45 +02:00
"_tracing_context = cached(\"tr_objects\", _load_traces, [TR_PATH], not CACHING_ENABLED)\n",
2022-07-20 13:35:06 +02:00
"_tr_globals = [\"nodes\", \"publishers\", \"subscriptions\", \"timers\", \"timer_node_links\", \"subscription_objects\",\n",
" \"callback_objects\", \"callback_symbols\", \"publish_instances\", \"callback_instances\", \"topics\"]\n",
"\n",
2022-11-07 17:46:09 +09:00
"# Help the IDE recognize those identifiers by assigning a dummy value to their name.\n",
2022-12-25 20:47:56 +09:00
"nodes: Index = Index([])\n",
"publishers: Index = Index([])\n",
"subscriptions: Index = Index([])\n",
"timers: Index = Index([])\n",
"timer_node_links: Index = Index([])\n",
"subscription_objects: Index = Index([])\n",
"callback_objects: Index = Index([])\n",
"callback_symbols: Index = Index([])\n",
"publish_instances: Index = Index([])\n",
"callback_instances: Index = Index([])\n",
"topics: Index = Index([])\n",
2022-07-20 13:35:06 +02:00
"\n",
"for name in _tr_globals:\n",
" globals()[name] = getattr(_tracing_context, name)\n",
2022-05-30 16:51:06 +02:00
"\n",
2022-09-12 19:24:26 +02:00
"print(\"Done.\")"
2023-02-15 17:02:20 +09:00
]
2022-09-14 18:27:41 +02:00
},
2022-09-16 13:36:42 +02:00
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 5,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"/cameraA/debayered................................................................................................................ | 97 msgs\n",
"/cameraA/geometric................................................................................................................ | 96 msgs\n",
"/cameraA/radiometric.............................................................................................................. | 97 msgs\n",
"/cameraB/debayered................................................................................................................ | 115 msgs\n",
"/cameraB/radiometric.............................................................................................................. | 114 msgs\n",
"/flight/plan...................................................................................................................... | 127 msgs\n",
"/input/baroA/alt.................................................................................................................. | 119 msgs\n",
"/input/baroB/alt.................................................................................................................. | 121 msgs\n",
"/input/cameraA/raw................................................................................................................ | 98 msgs\n",
"/input/cameraB/raw................................................................................................................ | 116 msgs\n",
"/input/gpsA/fix................................................................................................................... | 121 msgs\n",
"/input/gpsB/fix................................................................................................................... | 121 msgs\n",
"/input/imuA/data.................................................................................................................. | 119 msgs\n",
"/input/imuB/data.................................................................................................................. | 121 msgs\n",
"/input/lidar/scan................................................................................................................. | 120 msgs\n",
"/input/operator/commands.......................................................................................................... | 120 msgs\n",
"/output/cameraA/mapped............................................................................................................ | 95 msgs\n",
"/output/classifier/classification................................................................................................. | 112 msgs\n",
"/output/flight/cmd................................................................................................................ | 125 msgs\n",
"/output/telemetry/radio........................................................................................................... | 127 msgs\n",
"/parameter_events................................................................................................................. | 23 msgs\n",
2025-06-03 13:43:48 +00:00
"/rosout........................................................................................................................... | 0 msgs\n",
2025-06-09 14:12:01 +00:00
"/sensorsA/fused................................................................................................................... | 127 msgs\n",
"/sensorsB/fused................................................................................................................... | 128 msgs\n",
"/telemetry/data................................................................................................................... | 129 msgs\n",
2025-06-03 13:43:48 +00:00
"\n",
"[DEBUG] INPUT TOPICS\n",
2025-06-09 14:12:01 +00:00
"--[DEBUG] ^/input/ :/input/baroA/alt......................................................................... | 119 msgs\n",
"--[DEBUG] ^/input/ :/input/baroB/alt......................................................................... | 121 msgs\n",
"--[DEBUG] ^/input/ :/input/cameraA/raw....................................................................... | 98 msgs\n",
"--[DEBUG] ^/input/ :/input/cameraB/raw....................................................................... | 116 msgs\n",
"--[DEBUG] ^/input/ :/input/gpsA/fix.......................................................................... | 121 msgs\n",
"--[DEBUG] ^/input/ :/input/gpsB/fix.......................................................................... | 121 msgs\n",
"--[DEBUG] ^/input/ :/input/imuA/data......................................................................... | 119 msgs\n",
"--[DEBUG] ^/input/ :/input/imuB/data......................................................................... | 121 msgs\n",
"--[DEBUG] ^/input/ :/input/lidar/scan........................................................................ | 120 msgs\n",
"--[DEBUG] ^/input/ :/input/operator/commands................................................................. | 120 msgs\n",
2025-06-03 13:43:48 +00:00
"\n",
"[DEBUG] OUTPUT TOPICS\n",
2025-06-09 14:12:01 +00:00
"--[DEBUG] ^/output/ :/output/cameraA/mapped................................................................... | 95 msgs\n",
"--[DEBUG] ^/output/ :/output/classifier/classification........................................................ | 112 msgs\n",
"--[DEBUG] ^/output/ :/output/flight/cmd....................................................................... | 125 msgs\n",
"--[DEBUG] ^/output/ :/output/telemetry/radio.................................................................. | 127 msgs\n"
2025-06-03 13:43:48 +00:00
]
}
],
2022-09-16 13:36:42 +02:00
"source": [
2022-11-07 17:46:09 +09:00
"##################################################\n",
"# Print (All/Input/Output) Topic Message Counts\n",
"##################################################\n",
"\n",
2022-09-16 16:38:23 +02:00
"for topic in sorted(topics, key=lambda t: t.name):\n",
2022-09-16 13:36:42 +02:00
" topic: TrTopic\n",
2022-12-25 20:47:56 +09:00
" print(f\"{topic.name:.<130s} | {sum(map(lambda p: len(p.instances), topic.publishers)):>5d} msgs\")\n",
2022-09-20 12:44:04 +02:00
"\n",
2022-11-07 17:46:09 +09:00
"print(\"\\n[DEBUG] INPUT TOPICS\")\n",
2022-09-20 12:44:04 +02:00
"for t in sorted(topics, key=lambda t: t.name):\n",
" for f in E2E_INPUT_TOPIC_PATTERNS:\n",
" if re.search(f, t.name):\n",
2022-12-25 20:47:56 +09:00
" print(f\"--[DEBUG] {f:<30s}:{t.name:.<89s} | {sum(map(lambda p: len(p.instances), t.publishers)):>5d} msgs\")\n",
2022-09-20 12:44:04 +02:00
"\n",
2022-11-07 17:46:09 +09:00
"print(\"\\n[DEBUG] OUTPUT TOPICS\")\n",
2022-09-20 12:44:04 +02:00
"for t in sorted(topics, key=lambda t: t.name):\n",
" for f in E2E_OUTPUT_TOPIC_PATTERNS:\n",
" if re.search(f, t.name):\n",
2022-12-25 20:47:56 +09:00
" print(f\"--[DEBUG] {f:<30s}:{t.name:.<89s} | {sum(map(lambda p: len(p.instances), t.publishers)):>5d} msgs\")"
2023-02-15 17:02:20 +09:00
]
2022-09-16 13:36:42 +02:00
},
2022-05-23 21:28:40 +02:00
{
"cell_type": "markdown",
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2022-09-15 15:26:32 +02:00
"source": [
2022-11-07 17:46:09 +09:00
"# Analyze ROS Graph\n",
"Reconstruct namespace hierarchy, data flow graph between callbacks."
2023-02-15 17:02:20 +09:00
]
2022-05-23 21:28:40 +02:00
},
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 6,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[CACHE] Cache disabled for lat_graph.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Finding CB nodes: 100%|██████████| 195/195 [00:00<00:00, 288192.14it/s]\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"[DEBUG] 138 callbacks have no owner, filtering them out.\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Processing node publications: 100%|██████████| 23/23 [00:00<00:00, 3026.19it/s]\n",
"Processing CB subscriptions: 100%|██████████| 57/57 [00:00<00:00, 5516.15it/s]\n",
"Building graph edges: 100%|██████████| 25/25 [00:00<00:00, 205603.14it/s]\n",
"Building graph nodes: 100%|██████████| 57/57 [00:00<00:00, 2461.40it/s]\n"
2025-06-03 13:43:48 +00:00
]
}
],
2022-05-23 21:28:40 +02:00
"source": [
2022-10-13 19:13:39 +09:00
"import latency_graph.latency_graph_structure as lg\n",
2022-07-20 13:35:06 +02:00
"\n",
2022-09-15 18:04:45 +02:00
"\n",
2022-09-12 19:24:26 +02:00
"def _make_latency_graph():\n",
" return lg.LatencyGraph(_tracing_context)\n",
2022-07-20 13:35:06 +02:00
"\n",
2022-09-15 18:04:45 +02:00
"\n",
"lat_graph = cached(\"lat_graph\", _make_latency_graph, [TR_PATH], not CACHING_ENABLED)"
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
2022-10-13 19:13:39 +09:00
{
"cell_type": "markdown",
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2022-10-13 19:13:39 +09:00
"source": [
2022-11-07 17:46:09 +09:00
"## Plot ROS Graph (full)\n",
"Plot the DFG hierarchically by node namespace. Plot each internal and external dependency between callbacks as one arrow."
2023-02-15 17:02:20 +09:00
]
2022-10-13 19:13:39 +09:00
},
2022-09-15 15:26:32 +02:00
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 7,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Processing INPUT: 1\n",
" Processing OUTPUT: 1\n",
2025-06-09 14:12:01 +00:00
" Processing input_cameraA_node: 2\n",
" Processing debayerA_node: 2\n",
" Processing radiometricA_node: 2\n",
2025-06-03 13:43:48 +00:00
" Processing geometric_node: 2\n",
" Processing output_mapping_node: 2\n",
2025-06-09 14:12:01 +00:00
" Processing input_cameraB_node: 2\n",
" Processing debayerB_node: 2\n",
" Processing radiometricB_node: 2\n",
2025-06-03 13:43:48 +00:00
" Processing output_smoke_classifier_node: 2\n",
2025-06-09 14:12:01 +00:00
" Processing input_gpsA_node: 2\n",
" Processing input_imuA_node: 2\n",
" Processing input_baroA_node: 2\n",
" Processing fusionA_node: 5\n",
2025-06-03 13:43:48 +00:00
" Processing input_lidar_node: 2\n",
2025-06-09 14:12:01 +00:00
" Processing input_cmd_node: 2\n",
" Processing mgmt_node: 5\n",
" Processing output_control_node: 2\n",
" Processing input_gpsB_node: 2\n",
" Processing input_imuB_node: 2\n",
" Processing input_baroB_node: 2\n",
" Processing fusionB_node: 5\n",
" Processing telemetry_node: 4\n",
" Processing output_radio_node: 2\n"
2025-06-03 13:43:48 +00:00
]
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.43.0 (0)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
2025-06-09 14:12:01 +00:00
"<svg width=\"12834pt\" height=\"1743pt\"\n",
" viewBox=\"0.00 0.00 12834.00 1743.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 1739)\">\n",
2025-06-03 13:43:48 +00:00
"<title>G</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-1739 12830,-1739 12830,4 -4,4\"/>\n",
2025-06-03 13:43:48 +00:00
"<g id=\"clust1\" class=\"cluster\">\n",
"<title>cluster___INPUT</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"7002,-174 7002,-235 7084,-235 7084,-174 7002,-174\"/>\n",
"<text text-anchor=\"middle\" x=\"7043\" y=\"-219.8\" font-family=\"Times,serif\" font-size=\"14.00\">INPUT</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust2\" class=\"cluster\">\n",
"<title>cluster___OUTPUT</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"7335,0 7335,-61 7432,-61 7432,0 7335,0\"/>\n",
"<text text-anchor=\"middle\" x=\"7383.5\" y=\"-45.8\" font-family=\"Times,serif\" font-size=\"14.00\">OUTPUT</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust3\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___input_cameraA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"618,-866 618,-966 1809,-966 1809,-866 618,-866\"/>\n",
"<text text-anchor=\"middle\" x=\"1213.5\" y=\"-950.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_cameraA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust4\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___debayerA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1829,-905 1829,-1005 3603,-1005 3603,-905 1829,-905\"/>\n",
"<text text-anchor=\"middle\" x=\"2716\" y=\"-989.8\" font-family=\"Times,serif\" font-size=\"14.00\">debayerA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust5\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___radiometricA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"3623,-905 3623,-1005 5451,-1005 5451,-905 3623,-905\"/>\n",
"<text text-anchor=\"middle\" x=\"4537\" y=\"-989.8\" font-family=\"Times,serif\" font-size=\"14.00\">radiometricA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust6\" class=\"cluster\">\n",
"<title>cluster___geometric_node</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"5471,-866 5471,-966 7273,-966 7273,-866 5471,-866\"/>\n",
"<text text-anchor=\"middle\" x=\"6372\" y=\"-950.8\" font-family=\"Times,serif\" font-size=\"14.00\">geometric_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust7\" class=\"cluster\">\n",
"<title>cluster___output_mapping_node</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"7330.5,-846 7330.5,-946 9110.5,-946 9110.5,-846 7330.5,-846\"/>\n",
"<text text-anchor=\"middle\" x=\"8220.5\" y=\"-930.8\" font-family=\"Times,serif\" font-size=\"14.00\">output_mapping_node</text>\n",
"</g>\n",
"<g id=\"clust20\" class=\"cluster\">\n",
"<title>cluster___input_gpsB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"5801,-758 5801,-858 6943,-858 6943,-758 5801,-758\"/>\n",
"<text text-anchor=\"middle\" x=\"6372\" y=\"-842.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_gpsB_node</text>\n",
"</g>\n",
"<g id=\"clust21\" class=\"cluster\">\n",
"<title>cluster___input_imuB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"5800.5,-650 5800.5,-750 6943.5,-750 6943.5,-650 5800.5,-650\"/>\n",
"<text text-anchor=\"middle\" x=\"6372\" y=\"-734.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_imuB_node</text>\n",
"</g>\n",
"<g id=\"clust22\" class=\"cluster\">\n",
"<title>cluster___input_baroB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"5798,-542 5798,-642 6946,-642 6946,-542 5798,-542\"/>\n",
"<text text-anchor=\"middle\" x=\"6372\" y=\"-626.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_baroB_node</text>\n",
"</g>\n",
"<g id=\"clust23\" class=\"cluster\">\n",
"<title>cluster___fusionB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"7293,-587 7293,-804 9148,-804 9148,-587 7293,-587\"/>\n",
"<text text-anchor=\"middle\" x=\"8220.5\" y=\"-788.8\" font-family=\"Times,serif\" font-size=\"14.00\">fusionB_node</text>\n",
"</g>\n",
"<g id=\"clust24\" class=\"cluster\">\n",
"<title>cluster___telemetry_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"9168,-680 9168,-858 11071,-858 11071,-680 9168,-680\"/>\n",
"<text text-anchor=\"middle\" x=\"10119.5\" y=\"-842.8\" font-family=\"Times,serif\" font-size=\"14.00\">telemetry_node</text>\n",
"</g>\n",
"<g id=\"clust25\" class=\"cluster\">\n",
"<title>cluster___output_radio_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"11091,-797 11091,-897 12826,-897 12826,-797 11091,-797\"/>\n",
"<text text-anchor=\"middle\" x=\"11958.5\" y=\"-881.8\" font-family=\"Times,serif\" font-size=\"14.00\">output_radio_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust8\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___input_cameraB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"0,-213 0,-313 1191,-313 1191,-213 0,-213\"/>\n",
"<text text-anchor=\"middle\" x=\"595.5\" y=\"-297.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_cameraB_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust9\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___debayerB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1211,-174 1211,-274 2985,-274 2985,-174 1211,-174\"/>\n",
"<text text-anchor=\"middle\" x=\"2098\" y=\"-258.8\" font-family=\"Times,serif\" font-size=\"14.00\">debayerB_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust10\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___radiometricB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"3005,-213 3005,-313 4833,-313 4833,-213 3005,-213\"/>\n",
"<text text-anchor=\"middle\" x=\"3919\" y=\"-297.8\" font-family=\"Times,serif\" font-size=\"14.00\">radiometricB_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust11\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___output_smoke_classifier_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"4853,-213 4853,-313 6736,-313 6736,-213 4853,-213\"/>\n",
"<text text-anchor=\"middle\" x=\"5794.5\" y=\"-297.8\" font-family=\"Times,serif\" font-size=\"14.00\">output_smoke_classifier_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust12\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___input_gpsA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"406,-1635 406,-1735 1548,-1735 1548,-1635 406,-1635\"/>\n",
"<text text-anchor=\"middle\" x=\"977\" y=\"-1719.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_gpsA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust13\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___input_imuA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"405.5,-1527 405.5,-1627 1548.5,-1627 1548.5,-1527 405.5,-1527\"/>\n",
"<text text-anchor=\"middle\" x=\"977\" y=\"-1611.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_imuA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust14\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___input_baroA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"403,-1419 403,-1519 1551,-1519 1551,-1419 403,-1419\"/>\n",
"<text text-anchor=\"middle\" x=\"977\" y=\"-1503.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_baroA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust15\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___fusionA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1571,-1488 1571,-1705 3426,-1705 3426,-1488 1571,-1488\"/>\n",
"<text text-anchor=\"middle\" x=\"2498.5\" y=\"-1689.8\" font-family=\"Times,serif\" font-size=\"14.00\">fusionA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust16\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___input_lidar_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1921,-1376 1921,-1476 3076,-1476 3076,-1376 1921,-1376\"/>\n",
"<text text-anchor=\"middle\" x=\"2498.5\" y=\"-1460.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_lidar_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust17\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___input_cmd_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1886.5,-1268 1886.5,-1368 3110.5,-1368 3110.5,-1268 1886.5,-1268\"/>\n",
"<text text-anchor=\"middle\" x=\"2498.5\" y=\"-1352.8\" font-family=\"Times,serif\" font-size=\"14.00\">input_cmd_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<g id=\"clust18\" class=\"cluster\">\n",
2025-06-09 14:12:01 +00:00
"<title>cluster___mgmt_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"3446,-1371 3446,-1588 5478,-1588 5478,-1371 3446,-1371\"/>\n",
"<text text-anchor=\"middle\" x=\"4462\" y=\"-1572.8\" font-family=\"Times,serif\" font-size=\"14.00\">mgmt_node</text>\n",
"</g>\n",
"<g id=\"clust19\" class=\"cluster\">\n",
"<title>cluster___output_control_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"5498,-1449 5498,-1549 7258,-1549 7258,-1449 5498,-1449\"/>\n",
"<text text-anchor=\"middle\" x=\"6378\" y=\"-1533.8\" font-family=\"Times,serif\" font-size=\"14.00\">output_control_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- INPUT -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>INPUT</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"none\" stroke=\"black\" points=\"7010,-182 7010,-203 7016,-203 7016,-182 7010,-182\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7016,-182 7016,-203 7070,-203 7070,-182 7016,-182\"/>\n",
"<text text-anchor=\"start\" x=\"7019\" y=\"-188.8\" font-family=\"Times,serif\" font-size=\"14.00\">INPUT</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7070,-182 7070,-203 7076,-203 7076,-182 7070,-182\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- OUTPUT -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>OUTPUT</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"none\" stroke=\"black\" points=\"7343.5,-8 7343.5,-29 7349.5,-29 7349.5,-8 7343.5,-8\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7349.5,-8 7349.5,-29 7418.5,-29 7418.5,-8 7349.5,-8\"/>\n",
"<text text-anchor=\"start\" x=\"7352.5\" y=\"-14.8\" font-family=\"Times,serif\" font-size=\"14.00\">OUTPUT</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7418.5,-8 7418.5,-29 7424.5,-29 7424.5,-8 7418.5,-8\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297581776 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node3\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651297581776</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"626.5,-913 626.5,-934 632.5,-934 632.5,-913 626.5,-913\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"632.5,-913 632.5,-934 1795.5,-934 1795.5,-913 632.5,-913\"/>\n",
"<text text-anchor=\"start\" x=\"635.5\" y=\"-919.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(CameraNode::CameraNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1795.5,-913 1795.5,-934 1801.5,-934 1801.5,-913 1795.5,-913\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297813008 -->\n",
"<g id=\"node6\" class=\"node\">\n",
"<title>187651297813008</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1837,-913 1837,-934 1843,-934 1843,-913 1837,-913\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1843,-913 1843,-934 3589,-934 3589,-913 1843,-913\"/>\n",
"<text text-anchor=\"start\" x=\"1846\" y=\"-919.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(DebayerNode::DebayerNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3589,-913 3589,-934 3595,-934 3595,-913 3589,-913\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297581776->187651297813008 -->\n",
"<g id=\"edge20\" class=\"edge\">\n",
"<title>187651297581776:out->187651297813008:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1802.5,-923C1813.2,-923 1818.13,-923 1825.59,-923\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"1826,-926.5 1836,-923 1826,-919.5 1826,-926.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297579760 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node4\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651297579760</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"979.5,-874 979.5,-895 985.5,-895 985.5,-874 979.5,-874\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"985.5,-874 985.5,-895 1442.5,-895 1442.5,-874 985.5,-874\"/>\n",
"<text text-anchor=\"start\" x=\"988.5\" y=\"-880.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1442.5,-874 1442.5,-895 1448.5,-895 1448.5,-874 1442.5,-874\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297803888 -->\n",
"<g id=\"node5\" class=\"node\">\n",
"<title>187651297803888</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2482,-952 2482,-973 2488,-973 2488,-952 2482,-952\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2488,-952 2488,-973 2945,-973 2945,-952 2488,-952\"/>\n",
"<text text-anchor=\"start\" x=\"2491\" y=\"-958.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2945,-952 2945,-973 2951,-973 2951,-952 2945,-952\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297997136 -->\n",
"<g id=\"node8\" class=\"node\">\n",
"<title>187651297997136</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3631,-913 3631,-934 3637,-934 3637,-913 3631,-913\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3637,-913 3637,-934 5437,-934 5437,-913 3637,-913\"/>\n",
"<text text-anchor=\"start\" x=\"3640\" y=\"-919.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(RadiometricNode::RadiometricNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5437,-913 5437,-934 5443,-934 5443,-913 5437,-913\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297813008->187651297997136 -->\n",
"<g id=\"edge18\" class=\"edge\">\n",
"<title>187651297813008:out->187651297997136:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M3596,-923C3607.1,-923 3612.08,-923 3619.93,-923\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"3620,-926.5 3630,-923 3620,-919.5 3620,-926.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297978064 -->\n",
"<g id=\"node7\" class=\"node\">\n",
"<title>187651297978064</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4303,-952 4303,-973 4309,-973 4309,-952 4303,-952\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4309,-952 4309,-973 4766,-973 4766,-952 4309,-952\"/>\n",
"<text text-anchor=\"start\" x=\"4312\" y=\"-958.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4766,-952 4766,-973 4772,-973 4772,-952 4766,-952\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298203760 -->\n",
"<g id=\"node9\" class=\"node\">\n",
"<title>187651298203760</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5479,-913 5479,-934 5485,-934 5485,-913 5479,-913\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5485,-913 5485,-934 7259,-934 7259,-913 5485,-913\"/>\n",
"<text text-anchor=\"start\" x=\"5488\" y=\"-919.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(GeometricNode::GeometricNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7259,-913 7259,-934 7265,-934 7265,-913 7259,-913\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651297997136->187651298203760 -->\n",
"<g id=\"edge5\" class=\"edge\">\n",
"<title>187651297997136:out->187651298203760:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M5444,-923C5455.1,-923 5460.08,-923 5467.93,-923\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"5468,-926.5 5478,-923 5468,-919.5 5468,-926.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298399984 -->\n",
"<g id=\"node11\" class=\"node\">\n",
"<title>187651298399984</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7338.5,-893 7338.5,-914 7344.5,-914 7344.5,-893 7338.5,-893\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7344.5,-893 7344.5,-914 9096.5,-914 9096.5,-893 7344.5,-893\"/>\n",
"<text text-anchor=\"start\" x=\"7347.5\" y=\"-899.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(MappingNode::MappingNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9096.5,-893 9096.5,-914 9102.5,-914 9102.5,-893 9096.5,-893\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298203760->187651298399984 -->\n",
"<g id=\"edge6\" class=\"edge\">\n",
"<title>187651298203760:out->187651298399984:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M7266,-923C7295.26,-923 7302.9,-907.27 7327.26,-903.71\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"7327.77,-907.19 7337.5,-903 7327.28,-900.2 7327.77,-907.19\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298185168 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node10\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651298185168</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6138,-874 6138,-895 6144,-895 6144,-874 6138,-874\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6144,-874 6144,-895 6601,-895 6601,-874 6144,-874\"/>\n",
"<text text-anchor=\"start\" x=\"6147\" y=\"-880.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6601,-874 6601,-895 6607,-895 6607,-874 6601,-874\"/>\n",
"</g>\n",
"<!-- 187651301889184 -->\n",
"<g id=\"node56\" class=\"node\">\n",
"<title>187651301889184</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9176.5,-766 9176.5,-787 9182.5,-787 9182.5,-766 9176.5,-766\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9182.5,-766 9182.5,-787 11057.5,-787 11057.5,-766 9182.5,-766\"/>\n",
"<text text-anchor=\"start\" x=\"9185.5\" y=\"-772.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(TelemetryNode::TelemetryNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"11057.5,-766 11057.5,-787 11063.5,-787 11063.5,-766 11057.5,-766\"/>\n",
"</g>\n",
"<!-- 187651298399984->187651301889184 -->\n",
"<g id=\"edge7\" class=\"edge\">\n",
"<title>187651298399984:out->187651301889184:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M9103.5,-903C9124.83,-903 9134.18,-901.25 9148,-885 9177.72,-850.07 9133.95,-787.42 9165.21,-777.37\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"9166.05,-780.79 9175.5,-776 9165.12,-773.86 9166.05,-780.79\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298374800 -->\n",
"<g id=\"node12\" class=\"node\">\n",
"<title>187651298374800</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7986.5,-854 7986.5,-875 7992.5,-875 7992.5,-854 7986.5,-854\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7992.5,-854 7992.5,-875 8449.5,-875 8449.5,-854 7992.5,-854\"/>\n",
"<text text-anchor=\"start\" x=\"7995.5\" y=\"-860.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"8449.5,-854 8449.5,-875 8455.5,-875 8455.5,-854 8449.5,-854\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298585440 -->\n",
"<g id=\"node13\" class=\"node\">\n",
"<title>187651298585440</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"361.5,-260 361.5,-281 367.5,-281 367.5,-260 361.5,-260\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"367.5,-260 367.5,-281 824.5,-281 824.5,-260 367.5,-260\"/>\n",
"<text text-anchor=\"start\" x=\"370.5\" y=\"-266.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"824.5,-260 824.5,-281 830.5,-281 830.5,-260 824.5,-260\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298608000 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node14\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651298608000</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"8.5,-221 8.5,-242 14.5,-242 14.5,-221 8.5,-221\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"14.5,-221 14.5,-242 1177.5,-242 1177.5,-221 14.5,-221\"/>\n",
"<text text-anchor=\"start\" x=\"17.5\" y=\"-227.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(CameraNode::CameraNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1177.5,-221 1177.5,-242 1183.5,-242 1183.5,-221 1177.5,-221\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298776400 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node15\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651298776400</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1219,-221 1219,-242 1225,-242 1225,-221 1219,-221\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1225,-221 1225,-242 2971,-242 2971,-221 1225,-221\"/>\n",
"<text text-anchor=\"start\" x=\"1228\" y=\"-227.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(DebayerNode::DebayerNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2971,-221 2971,-242 2977,-242 2977,-221 2971,-221\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298608000->187651298776400 -->\n",
"<g id=\"edge15\" class=\"edge\">\n",
"<title>187651298608000:out->187651298776400:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1184.5,-231C1195.2,-231 1200.13,-231 1207.59,-231\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"1208,-234.5 1218,-231 1208,-227.5 1208,-234.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299008832 -->\n",
"<g id=\"node18\" class=\"node\">\n",
"<title>187651299008832</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3013,-221 3013,-242 3019,-242 3019,-221 3013,-221\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3019,-221 3019,-242 4819,-242 4819,-221 3019,-221\"/>\n",
"<text text-anchor=\"start\" x=\"3022\" y=\"-227.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(RadiometricNode::RadiometricNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4819,-221 4819,-242 4825,-242 4825,-221 4819,-221\"/>\n",
"</g>\n",
"<!-- 187651298776400->187651299008832 -->\n",
"<g id=\"edge12\" class=\"edge\">\n",
"<title>187651298776400:out->187651299008832:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M2978,-231C2989.1,-231 2994.08,-231 3001.93,-231\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"3002,-234.5 3012,-231 3002,-227.5 3002,-234.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651298782000 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node16\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651298782000</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1864,-182 1864,-203 1870,-203 1870,-182 1864,-182\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1870,-182 1870,-203 2327,-203 2327,-182 1870,-182\"/>\n",
"<text text-anchor=\"start\" x=\"1873\" y=\"-188.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2327,-182 2327,-203 2333,-203 2333,-182 2327,-182\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299013232 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node17\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651299013232</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3685,-260 3685,-281 3691,-281 3691,-260 3685,-260\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3691,-260 3691,-281 4148,-281 4148,-260 3691,-260\"/>\n",
"<text text-anchor=\"start\" x=\"3694\" y=\"-266.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4148,-260 4148,-281 4154,-281 4154,-260 4148,-260\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299234352 -->\n",
"<g id=\"node20\" class=\"node\">\n",
"<title>187651299234352</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4861.5,-221 4861.5,-242 4867.5,-242 4867.5,-221 4861.5,-221\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4867.5,-221 4867.5,-242 6722.5,-242 6722.5,-221 4867.5,-221\"/>\n",
"<text text-anchor=\"start\" x=\"4870.5\" y=\"-227.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(SmokeClassifierNode::SmokeClassifierNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6722.5,-221 6722.5,-242 6728.5,-242 6728.5,-221 6722.5,-221\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299008832->187651299234352 -->\n",
"<g id=\"edge19\" class=\"edge\">\n",
"<title>187651299008832:out->187651299234352:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M4826,-231C4837.26,-231 4842.32,-231 4850.28,-231\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"4850.5,-234.5 4860.5,-231 4850.5,-227.5 4850.5,-234.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299220704 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node19\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651299220704</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5560.5,-260 5560.5,-281 5566.5,-281 5566.5,-260 5560.5,-260\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5566.5,-260 5566.5,-281 6023.5,-281 6023.5,-260 5566.5,-260\"/>\n",
"<text text-anchor=\"start\" x=\"5569.5\" y=\"-266.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6023.5,-260 6023.5,-281 6029.5,-281 6029.5,-260 6023.5,-260\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299395024 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node21\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651299395024</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"743,-1682 743,-1703 749,-1703 749,-1682 743,-1682\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"749,-1682 749,-1703 1206,-1703 1206,-1682 749,-1682\"/>\n",
"<text text-anchor=\"start\" x=\"752\" y=\"-1688.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1206,-1682 1206,-1703 1212,-1703 1212,-1682 1206,-1682\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299420688 -->\n",
"<g id=\"node22\" class=\"node\">\n",
"<title>187651299420688</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"414,-1643 414,-1664 420,-1664 420,-1643 414,-1643\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"420,-1643 420,-1664 1534,-1664 1534,-1643 420,-1643\"/>\n",
"<text text-anchor=\"start\" x=\"423\" y=\"-1649.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(GPSNode::GPSNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1534,-1643 1534,-1664 1540,-1664 1540,-1643 1534,-1643\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299976736 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node31\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651299976736</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1579.5,-1613 1579.5,-1634 1585.5,-1634 1585.5,-1613 1579.5,-1613\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1585.5,-1613 1585.5,-1634 3412.5,-1634 3412.5,-1613 1585.5,-1613\"/>\n",
"<text text-anchor=\"start\" x=\"1588.5\" y=\"-1619.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3412.5,-1613 3412.5,-1634 3418.5,-1634 3418.5,-1613 3412.5,-1613\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299420688->187651299976736 -->\n",
"<g id=\"edge8\" class=\"edge\">\n",
"<title>187651299420688:out->187651299976736:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1541,-1653C1558.18,-1653 1558.17,-1633.57 1568.63,-1625.99\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"1569.94,-1629.25 1578.5,-1623 1567.91,-1622.55 1569.94,-1629.25\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299196848 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node23\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651299196848</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"414,-1574 414,-1595 420,-1595 420,-1574 414,-1574\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"420,-1574 420,-1595 1535,-1595 1535,-1574 420,-1574\"/>\n",
"<text text-anchor=\"start\" x=\"423\" y=\"-1580.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(IMUNode::IMUNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1535,-1574 1535,-1595 1541,-1595 1541,-1574 1535,-1574\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300001904 -->\n",
"<g id=\"node28\" class=\"node\">\n",
"<title>187651300001904</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1579.5,-1574 1579.5,-1595 1585.5,-1595 1585.5,-1574 1579.5,-1574\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1585.5,-1574 1585.5,-1595 3412.5,-1595 3412.5,-1574 1585.5,-1574\"/>\n",
"<text text-anchor=\"start\" x=\"1588.5\" y=\"-1580.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3412.5,-1574 3412.5,-1595 3418.5,-1595 3418.5,-1574 3412.5,-1574\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299196848->187651300001904 -->\n",
"<g id=\"edge9\" class=\"edge\">\n",
"<title>187651299196848:out->187651300001904:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1542,-1584C1554.17,-1584 1559.49,-1584 1568.23,-1584\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"1568.5,-1587.5 1578.5,-1584 1568.5,-1580.5 1568.5,-1587.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299594752 -->\n",
"<g id=\"node24\" class=\"node\">\n",
"<title>187651299594752</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"743,-1535 743,-1556 749,-1556 749,-1535 743,-1535\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"749,-1535 749,-1556 1206,-1556 1206,-1535 749,-1535\"/>\n",
"<text text-anchor=\"start\" x=\"752\" y=\"-1541.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1206,-1535 1206,-1556 1212,-1556 1212,-1535 1206,-1535\"/>\n",
"</g>\n",
"<!-- 187651299808512 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node25\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651299808512</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"411,-1466 411,-1487 417,-1487 417,-1466 411,-1466\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"417,-1466 417,-1487 1537,-1487 1537,-1466 417,-1466\"/>\n",
"<text text-anchor=\"start\" x=\"420\" y=\"-1472.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(BaroNode::BaroNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1537,-1466 1537,-1487 1543,-1487 1543,-1466 1537,-1466\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300018672 -->\n",
"<g id=\"node29\" class=\"node\">\n",
"<title>187651300018672</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1579.5,-1496 1579.5,-1517 1585.5,-1517 1585.5,-1496 1579.5,-1496\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1585.5,-1496 1585.5,-1517 3412.5,-1517 3412.5,-1496 1585.5,-1496\"/>\n",
"<text text-anchor=\"start\" x=\"1588.5\" y=\"-1502.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3412.5,-1496 3412.5,-1517 3418.5,-1517 3418.5,-1496 3412.5,-1496\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299808512->187651300018672 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>187651299808512:out->187651300018672:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1544,-1476C1560.19,-1476 1559.58,-1495.05 1568.95,-1502.79\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"1567.91,-1506.13 1578.5,-1506 1570.14,-1499.5 1567.91,-1506.13\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299801984 -->\n",
"<g id=\"node26\" class=\"node\">\n",
"<title>187651299801984</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"743,-1427 743,-1448 749,-1448 749,-1427 743,-1427\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"749,-1427 749,-1448 1206,-1448 1206,-1427 749,-1427\"/>\n",
"<text text-anchor=\"start\" x=\"752\" y=\"-1433.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1206,-1427 1206,-1448 1212,-1448 1212,-1427 1206,-1427\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299999568 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node27\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651299999568</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2264.5,-1652 2264.5,-1673 2270.5,-1673 2270.5,-1652 2264.5,-1652\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2270.5,-1652 2270.5,-1673 2727.5,-1673 2727.5,-1652 2270.5,-1652\"/>\n",
"<text text-anchor=\"start\" x=\"2273.5\" y=\"-1658.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2727.5,-1652 2727.5,-1673 2733.5,-1673 2733.5,-1652 2727.5,-1652\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299954176 -->\n",
"<g id=\"node30\" class=\"node\">\n",
"<title>187651299954176</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1659.5,-1535 1659.5,-1556 1665.5,-1556 1665.5,-1535 1659.5,-1535\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1665.5,-1535 1665.5,-1556 3332.5,-1556 3332.5,-1535 1665.5,-1535\"/>\n",
"<text text-anchor=\"start\" x=\"1668.5\" y=\"-1541.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3332.5,-1535 3332.5,-1556 3338.5,-1556 3338.5,-1535 3332.5,-1535\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300614704 -->\n",
"<g id=\"node36\" class=\"node\">\n",
"<title>187651300614704</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3454,-1535 3454,-1556 3460,-1556 3460,-1535 3454,-1535\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3460,-1535 3460,-1556 5464,-1556 5464,-1535 3460,-1535\"/>\n",
"<text text-anchor=\"start\" x=\"3463\" y=\"-1541.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FlightManagementNode::FlightManagementNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5464,-1535 5464,-1556 5470,-1556 5470,-1535 5464,-1535\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651299954176->187651300614704 -->\n",
"<g id=\"edge17\" class=\"edge\">\n",
"<title>187651299954176:out->187651300614704:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M3339.5,-1545C3386.4,-1545 3400.6,-1545 3442.89,-1545\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"3443,-1548.5 3453,-1545 3443,-1541.5 3443,-1548.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300193360 -->\n",
"<g id=\"node32\" class=\"node\">\n",
"<title>187651300193360</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1929.5,-1423 1929.5,-1444 1935.5,-1444 1935.5,-1423 1929.5,-1423\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1935.5,-1423 1935.5,-1444 3062.5,-1444 3062.5,-1423 1935.5,-1423\"/>\n",
"<text text-anchor=\"start\" x=\"1938.5\" y=\"-1429.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(LidarNode::LidarNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3062.5,-1423 3062.5,-1444 3068.5,-1444 3068.5,-1423 3062.5,-1423\"/>\n",
"</g>\n",
"<!-- 187651300629424 -->\n",
"<g id=\"node40\" class=\"node\">\n",
"<title>187651300629424</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3454,-1418 3454,-1439 3460,-1439 3460,-1418 3454,-1418\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3460,-1418 3460,-1439 5464,-1439 5464,-1418 3460,-1418\"/>\n",
"<text text-anchor=\"start\" x=\"3463\" y=\"-1424.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FlightManagementNode::FlightManagementNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5464,-1418 5464,-1439 5470,-1439 5470,-1418 5464,-1418\"/>\n",
"</g>\n",
"<!-- 187651300193360->187651300629424 -->\n",
"<g id=\"edge4\" class=\"edge\">\n",
"<title>187651300193360:out->187651300629424:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M3069.5,-1433C3236.46,-1433 3280.74,-1428.2 3442.67,-1428.01\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"3443,-1431.51 3453,-1428 3443,-1424.51 3443,-1431.51\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300222176 -->\n",
"<g id=\"node33\" class=\"node\">\n",
"<title>187651300222176</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2264.5,-1384 2264.5,-1405 2270.5,-1405 2270.5,-1384 2264.5,-1384\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2270.5,-1384 2270.5,-1405 2727.5,-1405 2727.5,-1384 2270.5,-1384\"/>\n",
"<text text-anchor=\"start\" x=\"2273.5\" y=\"-1390.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2727.5,-1384 2727.5,-1405 2733.5,-1405 2733.5,-1384 2727.5,-1384\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300401584 -->\n",
"<g id=\"node34\" class=\"node\">\n",
"<title>187651300401584</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2264.5,-1315 2264.5,-1336 2270.5,-1336 2270.5,-1315 2264.5,-1315\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2270.5,-1315 2270.5,-1336 2727.5,-1336 2727.5,-1315 2270.5,-1315\"/>\n",
"<text text-anchor=\"start\" x=\"2273.5\" y=\"-1321.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"2727.5,-1315 2727.5,-1336 2733.5,-1336 2733.5,-1315 2727.5,-1315\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300020784 -->\n",
"<g id=\"node35\" class=\"node\">\n",
"<title>187651300020784</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1894.5,-1276 1894.5,-1297 1900.5,-1297 1900.5,-1276 1894.5,-1276\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1900.5,-1276 1900.5,-1297 3096.5,-1297 3096.5,-1276 1900.5,-1276\"/>\n",
"<text text-anchor=\"start\" x=\"1903.5\" y=\"-1282.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(CommandNode::CommandNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3096.5,-1276 3096.5,-1297 3102.5,-1297 3102.5,-1276 3096.5,-1276\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300635248 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node39\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651300635248</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3454,-1379 3454,-1400 3460,-1400 3460,-1379 3454,-1379\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3460,-1379 3460,-1400 5464,-1400 5464,-1379 3460,-1379\"/>\n",
"<text text-anchor=\"start\" x=\"3463\" y=\"-1385.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FlightManagementNode::FlightManagementNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5464,-1379 5464,-1400 5470,-1400 5470,-1379 5464,-1379\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300020784->187651300635248 -->\n",
"<g id=\"edge14\" class=\"edge\">\n",
"<title>187651300020784:out->187651300635248:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M3103.5,-1286C3247.11,-1286 3312.47,-1218.05 3426,-1306 3453.31,-1327.16 3422.62,-1376.47 3442.99,-1387\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"3442.51,-1390.47 3453,-1389 3443.88,-1383.61 3442.51,-1390.47\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300599024 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node37\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651300599024</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4228,-1496 4228,-1517 4234,-1517 4234,-1496 4228,-1496\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4234,-1496 4234,-1517 4691,-1517 4691,-1496 4234,-1496\"/>\n",
"<text text-anchor=\"start\" x=\"4237\" y=\"-1502.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"4691,-1496 4691,-1517 4697,-1517 4697,-1496 4691,-1496\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- 187651300655552 -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node38\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>187651300655552</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3534,-1457 3534,-1478 3540,-1478 3540,-1457 3534,-1457\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"3540,-1457 3540,-1478 5384,-1478 5384,-1457 3540,-1457\"/>\n",
"<text text-anchor=\"start\" x=\"3543\" y=\"-1463.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FlightManagementNode::FlightManagementNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5384,-1457 5384,-1478 5390,-1478 5390,-1457 5384,-1457\"/>\n",
"</g>\n",
"<!-- 187651300874016 -->\n",
"<g id=\"node42\" class=\"node\">\n",
"<title>187651300874016</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5506,-1457 5506,-1478 5512,-1478 5512,-1457 5506,-1457\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5512,-1457 5512,-1478 7244,-1478 7244,-1457 5512,-1457\"/>\n",
"<text text-anchor=\"start\" x=\"5515\" y=\"-1463.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(ControlNode::ControlNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7244,-1457 7244,-1478 7250,-1478 7250,-1457 7244,-1457\"/>\n",
"</g>\n",
"<!-- 187651300655552->187651300874016 -->\n",
"<g id=\"edge10\" class=\"edge\">\n",
"<title>187651300655552:out->187651300874016:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M5391,-1467C5438.1,-1467 5452.36,-1467 5494.85,-1467\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"5495,-1470.5 5505,-1467 5495,-1463.5 5495,-1470.5\"/>\n",
"</g>\n",
"<!-- 187651300821520 -->\n",
"<g id=\"node41\" class=\"node\">\n",
"<title>187651300821520</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6144,-1496 6144,-1517 6150,-1517 6150,-1496 6144,-1496\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6150,-1496 6150,-1517 6607,-1517 6607,-1496 6150,-1496\"/>\n",
"<text text-anchor=\"start\" x=\"6153\" y=\"-1502.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6607,-1496 6607,-1517 6613,-1517 6613,-1496 6607,-1496\"/>\n",
"</g>\n",
"<!-- 187651301038384 -->\n",
"<g id=\"node43\" class=\"node\">\n",
"<title>187651301038384</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6138,-805 6138,-826 6144,-826 6144,-805 6138,-805\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6144,-805 6144,-826 6601,-826 6601,-805 6144,-805\"/>\n",
"<text text-anchor=\"start\" x=\"6147\" y=\"-811.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6601,-805 6601,-826 6607,-826 6607,-805 6601,-805\"/>\n",
"</g>\n",
"<!-- 187651301095136 -->\n",
"<g id=\"node44\" class=\"node\">\n",
"<title>187651301095136</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5809,-766 5809,-787 5815,-787 5815,-766 5809,-766\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5815,-766 5815,-787 6929,-787 6929,-766 5815,-766\"/>\n",
"<text text-anchor=\"start\" x=\"5818\" y=\"-772.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(GPSNode::GPSNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6929,-766 6929,-787 6935,-787 6935,-766 6929,-766\"/>\n",
"</g>\n",
"<!-- 187651301657264 -->\n",
"<g id=\"node49\" class=\"node\">\n",
"<title>187651301657264</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7301.5,-751 7301.5,-772 7307.5,-772 7307.5,-751 7301.5,-751\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7307.5,-751 7307.5,-772 9134.5,-772 9134.5,-751 7307.5,-751\"/>\n",
"<text text-anchor=\"start\" x=\"7310.5\" y=\"-757.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9134.5,-751 9134.5,-772 9140.5,-772 9140.5,-751 9134.5,-751\"/>\n",
"</g>\n",
"<!-- 187651301095136->187651301657264 -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>187651301095136:out->187651301657264:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M6936,-776C7094.65,-776 7136.58,-761.64 7290.22,-761.02\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"7290.51,-764.52 7300.5,-761 7290.49,-757.52 7290.51,-764.52\"/>\n",
"</g>\n",
"<!-- 187651301229376 -->\n",
"<g id=\"node45\" class=\"node\">\n",
"<title>187651301229376</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5809,-697 5809,-718 5815,-718 5815,-697 5809,-697\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5815,-697 5815,-718 6930,-718 6930,-697 5815,-697\"/>\n",
"<text text-anchor=\"start\" x=\"5818\" y=\"-703.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(IMUNode::IMUNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6930,-697 6930,-718 6936,-718 6936,-697 6930,-697\"/>\n",
"</g>\n",
"<!-- 187651301630272 -->\n",
"<g id=\"node53\" class=\"node\">\n",
"<title>187651301630272</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7301.5,-712 7301.5,-733 7307.5,-733 7307.5,-712 7301.5,-712\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7307.5,-712 7307.5,-733 9134.5,-733 9134.5,-712 7307.5,-712\"/>\n",
"<text text-anchor=\"start\" x=\"7310.5\" y=\"-718.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9134.5,-712 9134.5,-733 9140.5,-733 9140.5,-712 9134.5,-712\"/>\n",
"</g>\n",
"<!-- 187651301229376->187651301630272 -->\n",
"<g id=\"edge11\" class=\"edge\">\n",
"<title>187651301229376:out->187651301630272:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M6937,-707C7095.22,-707 7137.03,-721.36 7290.24,-721.98\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"7290.49,-725.48 7300.5,-722 7290.51,-718.48 7290.49,-725.48\"/>\n",
"</g>\n",
"<!-- 187651301237840 -->\n",
"<g id=\"node46\" class=\"node\">\n",
"<title>187651301237840</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6138,-658 6138,-679 6144,-679 6144,-658 6138,-658\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6144,-658 6144,-679 6601,-679 6601,-658 6144,-658\"/>\n",
"<text text-anchor=\"start\" x=\"6147\" y=\"-664.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6601,-658 6601,-679 6607,-679 6607,-658 6601,-658\"/>\n",
"</g>\n",
"<!-- 187651301432256 -->\n",
"<g id=\"node47\" class=\"node\">\n",
"<title>187651301432256</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6138,-589 6138,-610 6144,-610 6144,-589 6138,-589\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6144,-589 6144,-610 6601,-610 6601,-589 6144,-589\"/>\n",
"<text text-anchor=\"start\" x=\"6147\" y=\"-595.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6601,-589 6601,-610 6607,-610 6607,-589 6601,-589\"/>\n",
"</g>\n",
"<!-- 187651301442864 -->\n",
"<g id=\"node48\" class=\"node\">\n",
"<title>187651301442864</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5806,-550 5806,-571 5812,-571 5812,-550 5806,-550\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"5812,-550 5812,-571 6932,-571 6932,-550 5812,-550\"/>\n",
"<text text-anchor=\"start\" x=\"5815\" y=\"-556.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(BaroNode::BaroNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"6932,-550 6932,-571 6938,-571 6938,-550 6932,-550\"/>\n",
"</g>\n",
"<!-- 187651301667504 -->\n",
"<g id=\"node50\" class=\"node\">\n",
"<title>187651301667504</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7301.5,-595 7301.5,-616 7307.5,-616 7307.5,-595 7301.5,-595\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7307.5,-595 7307.5,-616 9134.5,-616 9134.5,-595 7307.5,-595\"/>\n",
"<text text-anchor=\"start\" x=\"7310.5\" y=\"-601.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9134.5,-595 9134.5,-616 9140.5,-616 9140.5,-595 9134.5,-595\"/>\n",
"</g>\n",
"<!-- 187651301442864->187651301667504 -->\n",
"<g id=\"edge13\" class=\"edge\">\n",
"<title>187651301442864:out->187651301667504:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M6939,-560C7087.71,-560 7135.96,-522.25 7273,-580 7284.18,-584.71 7284.86,-595.99 7290.98,-601.64\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"7289.91,-604.98 7300.5,-605 7292.23,-598.37 7289.91,-604.98\"/>\n",
"</g>\n",
"<!-- 187651301655312 -->\n",
"<g id=\"node51\" class=\"node\">\n",
"<title>187651301655312</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7986.5,-673 7986.5,-694 7992.5,-694 7992.5,-673 7986.5,-673\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7992.5,-673 7992.5,-694 8449.5,-694 8449.5,-673 7992.5,-673\"/>\n",
"<text text-anchor=\"start\" x=\"7995.5\" y=\"-679.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"8449.5,-673 8449.5,-694 8455.5,-694 8455.5,-673 8449.5,-673\"/>\n",
"</g>\n",
"<!-- 187651301623936 -->\n",
"<g id=\"node52\" class=\"node\">\n",
"<title>187651301623936</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7381.5,-634 7381.5,-655 7387.5,-655 7387.5,-634 7381.5,-634\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"7387.5,-634 7387.5,-655 9054.5,-655 9054.5,-634 7387.5,-634\"/>\n",
"<text text-anchor=\"start\" x=\"7390.5\" y=\"-640.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(FusionNode::FusionNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9054.5,-634 9054.5,-655 9060.5,-655 9060.5,-634 9054.5,-634\"/>\n",
"</g>\n",
"<!-- 187651301873008 -->\n",
"<g id=\"node55\" class=\"node\">\n",
"<title>187651301873008</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9176.5,-727 9176.5,-748 9182.5,-748 9182.5,-727 9176.5,-727\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9182.5,-727 9182.5,-748 11057.5,-748 11057.5,-727 9182.5,-727\"/>\n",
"<text text-anchor=\"start\" x=\"9185.5\" y=\"-733.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(TelemetryNode::TelemetryNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"11057.5,-727 11057.5,-748 11063.5,-748 11063.5,-727 11057.5,-727\"/>\n",
"</g>\n",
"<!-- 187651301623936->187651301873008 -->\n",
"<g id=\"edge16\" class=\"edge\">\n",
"<title>187651301623936:out->187651301873008:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M9061.5,-644C9101.06,-644 9118.44,-638.7 9148,-665 9170.39,-684.92 9148.43,-725.11 9165.53,-734.84\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"9164.99,-738.3 9175.5,-737 9166.47,-731.46 9164.99,-738.3\"/>\n",
"</g>\n",
"<!-- 187651301854592 -->\n",
"<g id=\"node54\" class=\"node\">\n",
"<title>187651301854592</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9256.5,-805 9256.5,-826 9262.5,-826 9262.5,-805 9256.5,-805\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9262.5,-805 9262.5,-826 10977.5,-826 10977.5,-805 9262.5,-805\"/>\n",
"<text text-anchor=\"start\" x=\"9265.5\" y=\"-811.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(TelemetryNode::TelemetryNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))()</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"10977.5,-805 10977.5,-826 10983.5,-826 10983.5,-805 10977.5,-805\"/>\n",
"</g>\n",
"<!-- 187651302065632 -->\n",
"<g id=\"node59\" class=\"node\">\n",
"<title>187651302065632</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"11099.5,-805 11099.5,-826 11105.5,-826 11105.5,-805 11099.5,-805\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"11105.5,-805 11105.5,-826 12812.5,-826 12812.5,-805 11105.5,-805\"/>\n",
"<text text-anchor=\"start\" x=\"11108.5\" y=\"-811.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(RadioNode::RadioNode(std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,std::__cxx11::basic_string<char,std::char_traits<char>,>,int,double))(std_msgs::msg::String)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"12812.5,-805 12812.5,-826 12818.5,-826 12818.5,-805 12812.5,-805\"/>\n",
"</g>\n",
"<!-- 187651301854592->187651302065632 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>187651301854592:out->187651302065632:in</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M10984.5,-815C11031.6,-815 11045.86,-815 11088.35,-815\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"11088.5,-818.5 11098.5,-815 11088.5,-811.5 11088.5,-818.5\"/>\n",
"</g>\n",
"<!-- 187651301845808 -->\n",
"<g id=\"node57\" class=\"node\">\n",
"<title>187651301845808</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9885.5,-688 9885.5,-709 9891.5,-709 9891.5,-688 9885.5,-688\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"9891.5,-688 9891.5,-709 10348.5,-709 10348.5,-688 9891.5,-688\"/>\n",
"<text text-anchor=\"start\" x=\"9894.5\" y=\"-694.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"10348.5,-688 10348.5,-709 10354.5,-709 10354.5,-688 10348.5,-688\"/>\n",
"</g>\n",
"<!-- 187651302090656 -->\n",
"<g id=\"node58\" class=\"node\">\n",
"<title>187651302090656</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"11724.5,-844 11724.5,-865 11730.5,-865 11730.5,-844 11724.5,-844\"/>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"11730.5,-844 11730.5,-865 12187.5,-865 12187.5,-844 11730.5,-844\"/>\n",
"<text text-anchor=\"start\" x=\"11733.5\" y=\"-850.8\" font-family=\"Times,serif\" font-size=\"14.00\">void(rclcpp::TimeSource)(rcl_interfaces::msg::ParameterEvent)</text>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"12187.5,-844 12187.5,-865 12193.5,-865 12193.5,-844 12187.5,-844\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
2025-06-09 14:12:01 +00:00
"<graphviz.graphs.Digraph at 0x7f5e079a48b0>"
2025-06-03 13:43:48 +00:00
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
2022-07-20 13:35:06 +02:00
"source": [
2022-09-12 19:24:26 +02:00
"%%skip_if_false DFG_ENABLED\n",
"%%skip_if_false DFG_PLOT\n",
"\n",
2022-07-20 13:35:06 +02:00
"#################################################\n",
2022-10-13 19:13:39 +09:00
"# Plot full DFG, down to the callback level\n",
2022-07-20 13:35:06 +02:00
"#################################################\n",
"\n",
2022-10-13 19:13:39 +09:00
"from latency_graph.latency_graph_plots import plot_latency_graph_full\n",
"\n",
2022-12-25 20:47:56 +09:00
"plot_latency_graph_full(lat_graph, _tracing_context, os.path.join(OUT_PATH, \"latency_graph_full\"))"
2023-02-15 17:02:20 +09:00
]
2022-10-13 19:13:39 +09:00
},
{
"cell_type": "markdown",
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2022-10-13 19:13:39 +09:00
"source": [
2022-11-07 17:46:09 +09:00
"## Plot Latency Graph (overview)\n",
"Plot the DFG down to a certain hierarchy level in a flattened manner. Aggregate dependencies from multiple callbacks into corresponding node-node dependencies."
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 8,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%%%skip_if_false DFG_ENABLED\n"
}
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Plotting DFG overview with max hierarchy level 100...\n",
"Input Node Patterns: ['^/input_']\n",
"Output Node Patterns: ['^/output_']\n",
"Excluded Node Patterns: ['^/rviz2']\n",
2025-06-09 14:12:01 +00:00
"Input Nodes: /input_cameraA_node, /input_cameraB_node, /input_gpsA_node, /input_imuA_node, /input_baroA_node, /input_lidar_node, /input_cmd_node, /input_gpsB_node, /input_imuB_node, /input_baroB_node\n",
"Output Nodes: /output_mapping_node, /output_smoke_classifier_node, /output_control_node, /output_radio_node\n",
"Intermediate Nodes: /INPUT, /OUTPUT, /input_cameraA_node, /debayerA_node, /radiometricA_node, /geometric_node, /output_mapping_node, /input_cameraB_node, /debayerB_node, /radiometricB_node, /output_smoke_classifier_node, /input_gpsA_node, /input_imuA_node, /input_baroA_node, /fusionA_node, /input_lidar_node, /input_cmd_node, /mgmt_node, /output_control_node, /input_gpsB_node, /input_imuB_node, /input_baroB_node, /fusionB_node, /telemetry_node, /output_radio_node\n",
"/input_baroA_node /fusionA_node 1\n",
"/telemetry_node /output_radio_node 1\n",
"/input_gpsB_node /fusionB_node 1\n",
"/input_lidar_node /mgmt_node 1\n",
"/radiometricA_node /geometric_node 1\n",
"/geometric_node /output_mapping_node 1\n",
2025-06-06 08:24:47 +00:00
"/output_mapping_node /telemetry_node 1\n",
2025-06-09 14:12:01 +00:00
"/input_gpsA_node /fusionA_node 1\n",
"/input_imuA_node /fusionA_node 1\n",
"/mgmt_node /output_control_node 1\n",
"/input_imuB_node /fusionB_node 1\n",
"/debayerB_node /radiometricB_node 1\n",
"/input_baroB_node /fusionB_node 1\n",
"/input_cmd_node /mgmt_node 1\n",
"/input_cameraB_node /debayerB_node 1\n",
"/fusionB_node /telemetry_node 1\n",
"/fusionA_node /mgmt_node 1\n",
"/debayerA_node /radiometricA_node 1\n",
"/radiometricB_node /output_smoke_classifier_node 1\n",
"/input_cameraA_node /debayerA_node 1\n"
2025-06-03 13:43:48 +00:00
]
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.43.0 (0)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
2025-06-09 14:12:01 +00:00
"<svg width=\"1531pt\" height=\"633pt\"\n",
" viewBox=\"0.00 0.00 1531.00 633.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 629)\">\n",
2025-06-03 13:43:48 +00:00
"<title>G</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-629 1527,-629 1527,4 -4,4\"/>\n",
2025-06-03 13:43:48 +00:00
"<!-- /INPUT -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>/INPUT</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"979,-104 911,-104 911,-68 979,-68 979,-104\"/>\n",
"<text text-anchor=\"middle\" x=\"945\" y=\"-82.3\" font-family=\"Times,serif\" font-size=\"14.00\">/INPUT</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /OUTPUT -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>/OUTPUT</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1115,-36 1032,-36 1032,0 1115,0 1115,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"1073.5\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">/OUTPUT</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraA_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node3\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_cameraA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"393,-206 224,-206 224,-170 393,-170 393,-206\"/>\n",
"<text text-anchor=\"middle\" x=\"308.5\" y=\"-184.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_cameraA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /debayerA_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node5\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/debayerA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"559,-206 429,-206 429,-170 559,-170 559,-206\"/>\n",
"<text text-anchor=\"middle\" x=\"494\" y=\"-184.3\" font-family=\"Times,serif\" font-size=\"14.00\">/debayerA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraA_node->/debayerA_node -->\n",
"<g id=\"edge30\" class=\"edge\">\n",
"<title>/input_cameraA_node->/debayerA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M393.2,-188C401.73,-188 410.36,-188 418.78,-188\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"418.93,-191.5 428.93,-188 418.93,-184.5 418.93,-191.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraA_node__before -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node4\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_cameraA_node__before</title>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraA_node__before->/input_cameraA_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"edge1\" class=\"edge\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_cameraA_node__before->/input_cameraA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M188.09,-188C189.13,-188 199.42,-188 213.57,-188\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"213.91,-191.5 223.91,-188 213.91,-184.5 213.91,-191.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /radiometricA_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node6\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/radiometricA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"750,-206 595,-206 595,-170 750,-170 750,-206\"/>\n",
"<text text-anchor=\"middle\" x=\"672.5\" y=\"-184.3\" font-family=\"Times,serif\" font-size=\"14.00\">/radiometricA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /debayerA_node->/radiometricA_node -->\n",
"<g id=\"edge28\" class=\"edge\">\n",
"<title>/debayerA_node->/radiometricA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M559.22,-188C567.51,-188 576.1,-188 584.68,-188\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"584.72,-191.5 594.72,-188 584.72,-184.5 584.72,-191.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /geometric_node -->\n",
"<g id=\"node7\" class=\"node\">\n",
"<title>/geometric_node</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"927.5,-206 793.5,-206 793.5,-170 927.5,-170 927.5,-206\"/>\n",
"<text text-anchor=\"middle\" x=\"860.5\" y=\"-184.3\" font-family=\"Times,serif\" font-size=\"14.00\">/geometric_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /radiometricA_node->/geometric_node -->\n",
2025-06-06 08:24:47 +00:00
"<g id=\"edge15\" class=\"edge\">\n",
2025-06-09 14:12:01 +00:00
"<title>/radiometricA_node->/geometric_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M750.23,-188C761.07,-188 772.22,-188 783.06,-188\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"783.34,-191.5 793.34,-188 783.34,-184.5 783.34,-191.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /output_mapping_node -->\n",
"<g id=\"node8\" class=\"node\">\n",
"<title>/output_mapping_node</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1154,-231 975,-231 975,-195 1154,-195 1154,-231\"/>\n",
"<polygon fill=\"none\" stroke=\"#666666\" points=\"1158,-235 971,-235 971,-191 1158,-191 1158,-235\"/>\n",
"<text text-anchor=\"middle\" x=\"1064.5\" y=\"-209.3\" font-family=\"Times,serif\" font-size=\"14.00\">/output_mapping_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /geometric_node->/output_mapping_node -->\n",
2025-06-09 14:12:01 +00:00
"<g id=\"edge16\" class=\"edge\">\n",
2025-06-03 13:43:48 +00:00
"<title>/geometric_node->/output_mapping_node</title>\n",
2025-06-09 14:12:01 +00:00
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M927.64,-196.19C938.21,-197.49 949.37,-198.87 960.55,-200.26\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"960.46,-203.77 970.81,-201.53 961.32,-196.83 960.46,-203.77\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /telemetry_node -->\n",
2025-06-09 14:12:01 +00:00
"<g id=\"node34\" class=\"node\">\n",
2025-06-03 13:43:48 +00:00
"<title>/telemetry_node</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1326,-260 1194,-260 1194,-224 1326,-224 1326,-260\"/>\n",
"<text text-anchor=\"middle\" x=\"1260\" y=\"-238.3\" font-family=\"Times,serif\" font-size=\"14.00\">/telemetry_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /output_mapping_node->/telemetry_node -->\n",
2025-06-09 14:12:01 +00:00
"<g id=\"edge17\" class=\"edge\">\n",
2025-06-03 13:43:48 +00:00
"<title>/output_mapping_node->/telemetry_node</title>\n",
2025-06-09 14:12:01 +00:00
"<path fill=\"none\" stroke=\"tomato\" stroke-width=\"0.2\" d=\"M1158.28,-226.91C1166.83,-228.19 1175.43,-229.47 1183.79,-230.73\"/>\n",
"<polygon fill=\"tomato\" stroke=\"tomato\" stroke-width=\"0.2\" points=\"1183.46,-234.22 1193.86,-232.24 1184.49,-227.29 1183.46,-234.22\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraB_node -->\n",
"<g id=\"node9\" class=\"node\">\n",
"<title>/input_cameraB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"207,-108 37,-108 37,-72 207,-72 207,-108\"/>\n",
"<text text-anchor=\"middle\" x=\"122\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_cameraB_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /debayerB_node -->\n",
"<g id=\"node11\" class=\"node\">\n",
"<title>/debayerB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"374,-108 243,-108 243,-72 374,-72 374,-108\"/>\n",
"<text text-anchor=\"middle\" x=\"308.5\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">/debayerB_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraB_node->/debayerB_node -->\n",
"<g id=\"edge25\" class=\"edge\">\n",
"<title>/input_cameraB_node->/debayerB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M207.15,-90C215.66,-90 224.27,-90 232.68,-90\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"232.81,-93.5 242.81,-90 232.81,-86.5 232.81,-93.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraB_node__before -->\n",
"<g id=\"node10\" class=\"node\">\n",
"<title>/input_cameraB_node__before</title>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cameraB_node__before->/input_cameraB_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"edge2\" class=\"edge\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_cameraB_node__before->/input_cameraB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.09,-90C2.12,-90 12.35,-90 26.44,-90\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"26.74,-93.5 36.74,-90 26.74,-86.5 26.74,-93.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /radiometricB_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node12\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/radiometricB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"566,-108 410,-108 410,-72 566,-72 566,-108\"/>\n",
"<text text-anchor=\"middle\" x=\"488\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">/radiometricB_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /debayerB_node->/radiometricB_node -->\n",
"<g id=\"edge22\" class=\"edge\">\n",
"<title>/debayerB_node->/radiometricB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M374.08,-90C382.42,-90 391.06,-90 399.69,-90\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"399.79,-93.5 409.79,-90 399.79,-86.5 399.79,-93.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /output_smoke_classifier_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node13\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/output_smoke_classifier_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"839,-108 606,-108 606,-72 839,-72 839,-108\"/>\n",
"<polygon fill=\"none\" stroke=\"#666666\" points=\"843,-112 602,-112 602,-68 843,-68 843,-112\"/>\n",
"<text text-anchor=\"middle\" x=\"722.5\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">/output_smoke_classifier_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /radiometricB_node->/output_smoke_classifier_node -->\n",
"<g id=\"edge29\" class=\"edge\">\n",
"<title>/radiometricB_node->/output_smoke_classifier_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M566.1,-90C574.36,-90 582.93,-90 591.59,-90\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"591.8,-93.5 601.8,-90 591.8,-86.5 591.8,-93.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_gpsA_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node14\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_gpsA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"448.5,-444 306.5,-444 306.5,-408 448.5,-408 448.5,-444\"/>\n",
"<text text-anchor=\"middle\" x=\"377.5\" y=\"-422.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_gpsA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /fusionA_node -->\n",
"<g id=\"node20\" class=\"node\">\n",
"<title>/fusionA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"616,-516 500,-516 500,-480 616,-480 616,-516\"/>\n",
"<text text-anchor=\"middle\" x=\"558\" y=\"-494.3\" font-family=\"Times,serif\" font-size=\"14.00\">/fusionA_node</text>\n",
"</g>\n",
"<!-- /input_gpsA_node->/fusionA_node -->\n",
"<g id=\"edge18\" class=\"edge\">\n",
"<title>/input_gpsA_node->/fusionA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M428.85,-444.09C436.63,-447 444.55,-450.04 452,-453 470.04,-460.17 489.63,-468.44 506.95,-475.91\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"505.75,-479.21 516.32,-479.97 508.54,-472.78 505.75,-479.21\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_gpsA_node__before -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"node15\" class=\"node\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_gpsA_node__before</title>\n",
"</g>\n",
"<!-- /input_gpsA_node__before->/input_gpsA_node -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>/input_gpsA_node__before->/input_gpsA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M267.08,-426C268.17,-426 280.34,-426 296.2,-426\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"296.48,-429.5 306.48,-426 296.48,-422.5 296.48,-429.5\"/>\n",
"</g>\n",
"<!-- /input_imuA_node -->\n",
"<g id=\"node16\" class=\"node\">\n",
"<title>/input_imuA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"449,-552 306,-552 306,-516 449,-516 449,-552\"/>\n",
"<text text-anchor=\"middle\" x=\"377.5\" y=\"-530.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_imuA_node</text>\n",
"</g>\n",
"<!-- /input_imuA_node->/fusionA_node -->\n",
"<g id=\"edge19\" class=\"edge\">\n",
"<title>/input_imuA_node->/fusionA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M449.05,-519.77C462.48,-517.06 476.51,-514.23 489.83,-511.55\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"490.75,-514.93 499.87,-509.52 489.37,-508.07 490.75,-514.93\"/>\n",
"</g>\n",
"<!-- /input_imuA_node__before -->\n",
"<g id=\"node17\" class=\"node\">\n",
"<title>/input_imuA_node__before</title>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_imuA_node__before->/input_imuA_node -->\n",
2025-06-03 13:43:48 +00:00
"<g id=\"edge4\" class=\"edge\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_imuA_node__before->/input_imuA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M267.08,-534C268.16,-534 280.1,-534 295.73,-534\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"295.87,-537.5 305.87,-534 295.87,-530.5 295.87,-537.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_baroA_node -->\n",
"<g id=\"node18\" class=\"node\">\n",
"<title>/input_baroA_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"452,-498 303,-498 303,-462 452,-462 452,-498\"/>\n",
"<text text-anchor=\"middle\" x=\"377.5\" y=\"-476.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_baroA_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_baroA_node->/fusionA_node -->\n",
"<g id=\"edge11\" class=\"edge\">\n",
"<title>/input_baroA_node->/fusionA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M452.13,-487.43C464.59,-488.68 477.46,-489.98 489.74,-491.22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"489.6,-494.72 499.9,-492.24 490.3,-487.76 489.6,-494.72\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_baroA_node__before -->\n",
"<g id=\"node19\" class=\"node\">\n",
"<title>/input_baroA_node__before</title>\n",
"</g>\n",
"<!-- /input_baroA_node__before->/input_baroA_node -->\n",
"<g id=\"edge5\" class=\"edge\">\n",
"<title>/input_baroA_node__before->/input_baroA_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M267.08,-480C268.08,-480 278.53,-480 292.61,-480\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"292.86,-483.5 302.86,-480 292.86,-476.5 292.86,-483.5\"/>\n",
"</g>\n",
"<!-- /mgmt_node -->\n",
"<g id=\"node25\" class=\"node\">\n",
"<title>/mgmt_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"768,-571 664,-571 664,-535 768,-535 768,-571\"/>\n",
"<text text-anchor=\"middle\" x=\"716\" y=\"-549.3\" font-family=\"Times,serif\" font-size=\"14.00\">/mgmt_node</text>\n",
"</g>\n",
"<!-- /fusionA_node->/mgmt_node -->\n",
"<g id=\"edge27\" class=\"edge\">\n",
"<title>/fusionA_node->/mgmt_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M610.08,-516.01C624.22,-520.99 639.71,-526.45 654.34,-531.61\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"653.21,-534.93 663.81,-534.95 655.54,-528.32 653.21,-534.93\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /input_lidar_node -->\n",
2025-06-09 14:12:01 +00:00
"<g id=\"node21\" class=\"node\">\n",
2025-06-03 13:43:48 +00:00
"<title>/input_lidar_node</title>\n",
2025-06-09 14:12:01 +00:00
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"628,-625 488,-625 488,-589 628,-589 628,-625\"/>\n",
"<text text-anchor=\"middle\" x=\"558\" y=\"-603.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_lidar_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_lidar_node->/mgmt_node -->\n",
"<g id=\"edge14\" class=\"edge\">\n",
"<title>/input_lidar_node->/mgmt_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M611.38,-588.87C625.12,-584.11 640.05,-578.95 654.18,-574.05\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"655.51,-577.3 663.82,-570.72 653.22,-570.68 655.51,-577.3\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"<!-- /input_lidar_node__before -->\n",
2025-06-09 14:12:01 +00:00
"<g id=\"node22\" class=\"node\">\n",
2025-06-03 13:43:48 +00:00
"<title>/input_lidar_node__before</title>\n",
"</g>\n",
"<!-- /input_lidar_node__before->/input_lidar_node -->\n",
2025-06-09 14:12:01 +00:00
"<g id=\"edge6\" class=\"edge\">\n",
2025-06-03 13:43:48 +00:00
"<title>/input_lidar_node__before->/input_lidar_node</title>\n",
2025-06-09 14:12:01 +00:00
"<path fill=\"none\" stroke=\"black\" d=\"M378.63,-607C381.5,-607 431.51,-607 477.84,-607\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"477.96,-610.5 487.96,-607 477.96,-603.5 477.96,-610.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cmd_node -->\n",
"<g id=\"node23\" class=\"node\">\n",
"<title>/input_cmd_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"626.5,-571 489.5,-571 489.5,-535 626.5,-535 626.5,-571\"/>\n",
"<text text-anchor=\"middle\" x=\"558\" y=\"-549.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_cmd_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cmd_node->/mgmt_node -->\n",
"<g id=\"edge24\" class=\"edge\">\n",
"<title>/input_cmd_node->/mgmt_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M626.52,-553C635.51,-553 644.7,-553 653.58,-553\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"653.85,-556.5 663.85,-553 653.85,-549.5 653.85,-556.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cmd_node__before -->\n",
"<g id=\"node24\" class=\"node\">\n",
"<title>/input_cmd_node__before</title>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_cmd_node__before->/input_cmd_node -->\n",
"<g id=\"edge7\" class=\"edge\">\n",
"<title>/input_cmd_node__before->/input_cmd_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M378.63,-570.99C381.53,-570.69 432.54,-565.55 479.27,-560.84\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"479.87,-564.3 489.47,-559.81 479.16,-557.33 479.87,-564.3\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /output_control_node -->\n",
"<g id=\"node26\" class=\"node\">\n",
"<title>/output_control_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"975,-571 808,-571 808,-535 975,-535 975,-571\"/>\n",
"<polygon fill=\"none\" stroke=\"#666666\" points=\"979,-575 804,-575 804,-531 979,-531 979,-575\"/>\n",
"<text text-anchor=\"middle\" x=\"891.5\" y=\"-549.3\" font-family=\"Times,serif\" font-size=\"14.00\">/output_control_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /mgmt_node->/output_control_node -->\n",
2025-06-06 08:24:47 +00:00
"<g id=\"edge20\" class=\"edge\">\n",
2025-06-09 14:12:01 +00:00
"<title>/mgmt_node->/output_control_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M768.12,-553C776.32,-553 785.05,-553 793.91,-553\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"793.95,-556.5 803.95,-553 793.95,-549.5 793.95,-556.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_gpsB_node -->\n",
"<g id=\"node27\" class=\"node\">\n",
"<title>/input_gpsB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"932,-368 789,-368 789,-332 932,-332 932,-368\"/>\n",
"<text text-anchor=\"middle\" x=\"860.5\" y=\"-346.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_gpsB_node</text>\n",
"</g>\n",
"<!-- /fusionB_node -->\n",
"<g id=\"node33\" class=\"node\">\n",
"<title>/fusionB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1122.5,-301 1006.5,-301 1006.5,-265 1122.5,-265 1122.5,-301\"/>\n",
"<text text-anchor=\"middle\" x=\"1064.5\" y=\"-279.3\" font-family=\"Times,serif\" font-size=\"14.00\">/fusionB_node</text>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
2025-06-09 14:12:01 +00:00
"<!-- /input_gpsB_node->/fusionB_node -->\n",
2025-06-06 08:24:47 +00:00
"<g id=\"edge13\" class=\"edge\">\n",
2025-06-09 14:12:01 +00:00
"<title>/input_gpsB_node->/fusionB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M915.9,-331.96C941.6,-323.43 972.47,-313.19 999.31,-304.29\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"1000.62,-307.55 1009,-301.08 998.41,-300.9 1000.62,-307.55\"/>\n",
"</g>\n",
"<!-- /input_gpsB_node__before -->\n",
"<g id=\"node28\" class=\"node\">\n",
"<title>/input_gpsB_node__before</title>\n",
"</g>\n",
"<!-- /input_gpsB_node__before->/input_gpsB_node -->\n",
"<g id=\"edge8\" class=\"edge\">\n",
"<title>/input_gpsB_node__before->/input_gpsB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M673.63,-350C676.66,-350 730.07,-350 778.87,-350\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"778.87,-353.5 788.87,-350 778.87,-346.5 778.87,-353.5\"/>\n",
"</g>\n",
"<!-- /input_imuB_node -->\n",
"<g id=\"node29\" class=\"node\">\n",
"<title>/input_imuB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"932.5,-314 788.5,-314 788.5,-278 932.5,-278 932.5,-314\"/>\n",
"<text text-anchor=\"middle\" x=\"860.5\" y=\"-292.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_imuB_node</text>\n",
"</g>\n",
"<!-- /input_imuB_node->/fusionB_node -->\n",
"<g id=\"edge21\" class=\"edge\">\n",
"<title>/input_imuB_node->/fusionB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M932.72,-291.42C953.32,-290.09 975.73,-288.65 996.09,-287.34\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"996.46,-290.82 1006.22,-286.69 996.01,-283.84 996.46,-290.82\"/>\n",
"</g>\n",
"<!-- /input_imuB_node__before -->\n",
"<g id=\"node30\" class=\"node\">\n",
"<title>/input_imuB_node__before</title>\n",
"</g>\n",
"<!-- /input_imuB_node__before->/input_imuB_node -->\n",
"<g id=\"edge9\" class=\"edge\">\n",
"<title>/input_imuB_node__before->/input_imuB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M673.63,-296C676.64,-296 729.49,-296 778.06,-296\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"778.34,-299.5 788.34,-296 778.34,-292.5 778.34,-299.5\"/>\n",
"</g>\n",
"<!-- /input_baroB_node -->\n",
"<g id=\"node31\" class=\"node\">\n",
"<title>/input_baroB_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"935,-260 786,-260 786,-224 935,-224 935,-260\"/>\n",
"<text text-anchor=\"middle\" x=\"860.5\" y=\"-238.3\" font-family=\"Times,serif\" font-size=\"14.00\">/input_baroB_node</text>\n",
"</g>\n",
"<!-- /input_baroB_node->/fusionB_node -->\n",
"<g id=\"edge23\" class=\"edge\">\n",
"<title>/input_baroB_node->/fusionB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M935.28,-256.98C955.25,-261.03 976.74,-265.39 996.32,-269.36\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"995.87,-272.84 1006.37,-271.4 997.26,-265.98 995.87,-272.84\"/>\n",
"</g>\n",
"<!-- /input_baroB_node__before -->\n",
"<g id=\"node32\" class=\"node\">\n",
"<title>/input_baroB_node__before</title>\n",
"</g>\n",
"<!-- /input_baroB_node__before->/input_baroB_node -->\n",
"<g id=\"edge10\" class=\"edge\">\n",
"<title>/input_baroB_node__before->/input_baroB_node</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M673.63,-242C676.6,-242 727.88,-242 775.82,-242\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"775.98,-245.5 785.98,-242 775.98,-238.5 775.98,-245.5\"/>\n",
"</g>\n",
"<!-- /fusionB_node->/telemetry_node -->\n",
"<g id=\"edge26\" class=\"edge\">\n",
"<title>/fusionB_node->/telemetry_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M1122.51,-270.92C1141.77,-266.84 1163.56,-262.22 1184,-257.89\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"1184.85,-261.29 1193.9,-255.79 1183.39,-254.44 1184.85,-261.29\"/>\n",
"</g>\n",
"<!-- /output_radio_node -->\n",
"<g id=\"node35\" class=\"node\">\n",
"<title>/output_radio_node</title>\n",
"<polygon fill=\"#f5f5f5\" stroke=\"#666666\" points=\"1519,-260 1366,-260 1366,-224 1519,-224 1519,-260\"/>\n",
"<polygon fill=\"none\" stroke=\"#666666\" points=\"1523,-264 1362,-264 1362,-220 1523,-220 1523,-264\"/>\n",
"<text text-anchor=\"middle\" x=\"1442.5\" y=\"-238.3\" font-family=\"Times,serif\" font-size=\"14.00\">/output_radio_node</text>\n",
"</g>\n",
"<!-- /telemetry_node->/output_radio_node -->\n",
"<g id=\"edge12\" class=\"edge\">\n",
"<title>/telemetry_node->/output_radio_node</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"0.2\" d=\"M1326.16,-242C1334.51,-242 1343.17,-242 1351.82,-242\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0.2\" points=\"1351.95,-245.5 1361.95,-242 1351.95,-238.5 1351.95,-245.5\"/>\n",
2025-06-03 13:43:48 +00:00
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
2025-06-09 14:12:01 +00:00
"<graphviz.graphs.Digraph at 0x7f5e07769990>"
2025-06-03 13:43:48 +00:00
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
2022-05-30 16:51:06 +02:00
"source": [
2022-09-12 19:24:26 +02:00
"%%skip_if_false DFG_ENABLED\n",
"%%skip_if_false DFG_PLOT\n",
"\n",
2022-10-13 19:13:39 +09:00
"#################################################\n",
"# Plot overview of DFG, down to a certain\n",
"# hierarchy level\n",
"#################################################\n",
2022-08-29 22:17:52 +02:00
"\n",
2022-10-13 19:13:39 +09:00
"from latency_graph.latency_graph_plots import plot_latency_graph_overview\n",
2022-06-28 10:06:42 +02:00
"\n",
2025-06-03 13:43:48 +00:00
"print(f\"Plotting DFG overview with max hierarchy level {DFG_MAX_HIER_LEVEL}...\")\n",
"print(f\"Input Node Patterns: {DFG_INPUT_NODE_PATTERNS}\")\n",
"print(f\"Output Node Patterns: {DFG_OUTPUT_NODE_PATTERNS}\")\n",
"print(f\"Excluded Node Patterns: {DFG_EXCL_NODE_PATTERNS}\")\n",
"\n",
2022-12-25 20:47:56 +09:00
"plot_latency_graph_overview(lat_graph, DFG_EXCL_NODE_PATTERNS, DFG_INPUT_NODE_PATTERNS, DFG_OUTPUT_NODE_PATTERNS, DFG_MAX_HIER_LEVEL, os.path.join(OUT_PATH, \"latency_graph_overview\"))"
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
{
2022-10-13 19:13:39 +09:00
"cell_type": "markdown",
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2022-08-29 22:17:52 +02:00
"source": [
2022-11-07 17:46:09 +09:00
"# Analyze Message Flow\n",
"Build dependency trees ending in the specified output topics."
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 9,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Found 4 end topics for E2E latency calculations: /output/flight/cmd, /output/telemetry/radio, /output/cameraA/mapped, /output/classifier/classification\n",
"Using 195 callback objects, 4208 callback instances, and 2688 publish instances for E2E latency calculations.\n",
2025-06-03 13:43:48 +00:00
"[CACHE] Cache disabled for trees.\n",
2025-06-09 14:12:01 +00:00
"=====/output/flight/cmd\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Processing output messages: 100%|██████████| 125/125 [00:01<00:00, 73.48it/s]\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Found 125 trees for topic /output/flight/cmd\n",
"=====/output/telemetry/radio\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Processing output messages: 100%|██████████| 127/127 [00:01<00:00, 78.03it/s]\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Found 127 trees for topic /output/telemetry/radio\n",
"=====/output/cameraA/mapped\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Processing output messages: 100%|██████████| 95/95 [00:00<00:00, 1460.40it/s]\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Found 95 trees for topic /output/cameraA/mapped\n",
2025-06-06 08:24:47 +00:00
"=====/output/classifier/classification\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Processing output messages: 100%|██████████| 112/112 [00:00<00:00, 281.79it/s]"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Found 112 trees for topic /output/classifier/classification\n"
2025-06-03 13:43:48 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n"
]
}
],
2022-08-29 22:17:52 +02:00
"source": [
2022-09-12 19:24:26 +02:00
"%%skip_if_false E2E_ENABLED\n",
"\n",
2022-10-13 19:13:39 +09:00
"from message_tree.message_tree_algorithms import build_dep_trees\n",
"\n",
2022-09-12 19:24:26 +02:00
"end_topics = [t for t in _tracing_context.topics if any(re.search(f, t.name) for f in E2E_OUTPUT_TOPIC_PATTERNS)]\n",
"\n",
2025-06-03 13:43:48 +00:00
"print(f\"Found {len(end_topics)} end topics for E2E latency calculations: {', '.join(t.name for t in end_topics)}\")\n",
"\n",
"print(f\"Using {len(_tracing_context.callback_objects)} callback objects, {len(_tracing_context.callback_instances)} callback instances, and {len(_tracing_context.publish_instances)} publish instances for E2E latency calculations.\")\n",
"\n",
2022-10-13 19:13:39 +09:00
"def _build_dep_trees():\n",
2025-06-03 13:43:48 +00:00
" return build_dep_trees(end_topics, lat_graph, _tracing_context, E2E_EXCL_PATH_PATTERNS, E2E_TIME_LIMIT_S)\n",
" #return build_dep_trees(end_topics, lat_graph, _tracing_context, E2E_EXCL_PATH_PATTERNS, E2E_TIME_LIMIT_S, exact_path=E2E_EXACT_PATH)\n",
2022-09-12 19:24:26 +02:00
"\n",
2022-09-19 12:39:53 +02:00
"try:\n",
2022-10-13 19:13:39 +09:00
" trees = cached(\"trees\", _build_dep_trees, [TR_PATH], not CACHING_ENABLED)\n",
2022-09-19 12:39:53 +02:00
"except Exception as e:\n",
" import traceback\n",
" print(e)\n",
" traceback.print_exc()"
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 10,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
"data": {
"text/plain": [
"'Skipped (evaluated BW_ENABLED to False)'"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
2022-08-29 22:17:52 +02:00
"source": [
2022-09-12 19:24:26 +02:00
"%%skip_if_false E2E_ENABLED\n",
"%%skip_if_false BW_ENABLED\n",
"\n",
2022-11-07 17:46:09 +09:00
"##################################################\n",
"# Get message bandwidths from `ros2 multitopic bw`\n",
"# output.\n",
"##################################################\n",
"\n",
2022-10-28 22:37:48 +09:00
"from bw_interop.process_bw_output import get_topic_messages\n",
"msgs = get_topic_messages(BW_PATH)\n",
2022-08-29 22:17:52 +02:00
"\n",
2022-10-28 22:37:48 +09:00
"from bw_interop.bw_plots import dds_lat_msg_size_scatter\n",
"plot_topic = \"\""
2023-02-15 17:02:20 +09:00
]
2022-09-15 15:26:32 +02:00
},
2022-10-14 00:15:33 +09:00
{
"cell_type": "code",
2025-06-03 13:43:48 +00:00
"execution_count": 11,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
2025-06-06 08:24:47 +00:00
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Extracting E2E paths: 100%|██████████| 459/459 [00:00<00:00, 24623.78it/s]"
2025-06-06 08:24:47 +00:00
]
},
2025-06-03 13:43:48 +00:00
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Found 1298 E2E paths in total.\n"
2025-06-03 13:43:48 +00:00
]
2025-06-06 08:24:47 +00:00
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n"
]
2025-06-03 13:43:48 +00:00
}
],
2022-10-14 00:15:33 +09:00
"source": [
"%%skip_if_false E2E_ENABLED\n",
"\n",
"from message_tree.message_tree_algorithms import e2e_paths_sorted_desc\n",
2022-10-28 22:37:48 +09:00
"from message_tree.message_tree_algorithms import owner\n",
2025-06-03 13:43:48 +00:00
"from message_tree.message_tree_structure import DepTree\n",
"\n",
"# set of seen publush topics to avoid duplicates\n",
"seen_publish_topics = set()\n",
"\n",
"def _print_elem(elem, indent=0):\n",
" if isinstance(elem, TrTopic):\n",
" print(f\"{' ' * indent}Topic: {elem.name}\")\n",
" elif isinstance(elem, TrCallbackObject):\n",
" print(f\"{' ' * indent}Callback: {elem.name} ({elem.elem.name})\")\n",
" elif isinstance(elem, TrPublishInstance):\n",
" #if elem.publisher.topic_name in seen_publish_topics:\n",
" # print(f\"{' ' * indent}Publish Instance: {elem.publisher.topic_name} (already seen)\")\n",
" # return False\n",
" #seen_publish_topics.add(elem.publisher.topic_name)\n",
" print(f\"{' ' * indent}Publish Instance: {elem.publisher.topic_name}\")\n",
" elif isinstance(elem, TrCallbackInstance):\n",
" print(f\"{' ' * indent}Callback Instance: {elem.callback_obj.callback_symbol.symbol}\")\n",
" else:\n",
" print(f\"{' ' * indent}Unknown element type: {type(elem)}\")\n",
" return True\n",
"\n",
"def _traverse_print_tree(tree, indent=0):\n",
" \"\"\"Recursively traverse a dependency tree and print its structure.\"\"\"\n",
" for i, node in enumerate(tree):\n",
" if isinstance(node, DepTree):\n",
" if not _print_elem(node.head, indent):\n",
" continue\n",
" _traverse_print_tree(node.deps, indent + 2)\n",
" elif isinstance(node, list):\n",
" for entry in node:\n",
" if entry is not None and isinstance(entry, DepTree):\n",
" if not _print_elem(entry.head, indent):\n",
" continue\n",
" _traverse_print_tree(entry.deps, indent + 2)\n",
" else:\n",
" print(f\"{' ' * indent}List of {len(node)} elements, but not a DepTree.\")\n",
" else:\n",
" if not _print_elem(node, indent):\n",
" continue\n",
"\n",
"def _print_trees():\n",
" print(\"Dependency Trees:\")\n",
" for i, tree in enumerate(trees):\n",
" print(f\"\\nTree {i + 1}/{len(trees)}:\")\n",
" _traverse_print_tree(tree)\n",
" print(\"\\nEnd of Dependency Trees\\n\")\n",
" print(f\"Published topics seen so far: {len(seen_publish_topics)}:, {', '.join(seen_publish_topics)}\")\n",
2025-06-06 08:24:47 +00:00
"#_print_trees()\n",
2025-06-03 13:43:48 +00:00
"\n",
2022-10-28 22:37:48 +09:00
"\n",
2022-11-07 17:46:09 +09:00
"##################################################\n",
"# Find and filter relevant E2E paths in trees\n",
"##################################################\n",
2025-06-03 13:43:48 +00:00
"trees_paths = [e2e_paths_sorted_desc(tree, E2E_INPUT_TOPIC_PATTERNS) for tree in tqdm(trees, mininterval=10.0, desc=\"Extracting E2E paths\")]\n",
"all_paths = [p for paths in trees_paths for p in paths]\n",
2022-10-14 00:15:33 +09:00
"\n",
2025-06-03 13:43:48 +00:00
"def _print_paths():\n",
" for i, path in enumerate(all_paths):\n",
" print(f\"Path {i+1}/{len(all_paths)}:\")\n",
" for j, elem in enumerate(path):\n",
" if isinstance(elem, TrTopic):\n",
" print(f\" {j+1:>3d}: Topic: {elem.name}\")\n",
" elif isinstance(elem, TrCallbackObject):\n",
" print(f\" {j+1:>3d}: Callback: {elem.name} ({elem.node.name})\")\n",
" elif isinstance(elem, TrPublishInstance):\n",
" print(f\" {j+1:>3d}: Publish Instance: {elem.publisher.topic_name}\")\n",
" elif isinstance(elem, TrCallbackInstance):\n",
" print(f\" {j+1:>3d}: Callback Instance: {elem.callback_obj.callback_symbol.symbol}\")\n",
" else:\n",
" print(f\" {j+1:>3d}: Unknown element type: {elem}\")\n",
" print()\n",
2025-06-06 08:24:47 +00:00
"#_print_paths()\n",
2025-06-03 13:43:48 +00:00
"\n",
"print(f\"Found {len(all_paths)} E2E paths in total.\")"
2023-02-15 17:02:20 +09:00
]
2022-10-14 00:15:33 +09:00
},
2022-09-15 15:26:32 +02:00
{
"cell_type": "code",
2025-06-06 08:24:47 +00:00
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Aggregating E2E path cohorts: 100%|██████████| 1298/1298 [00:00<00:00, 256306.51it/s]"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 11 cohorts of E2E paths.\n"
]
},
2025-06-09 14:12:01 +00:00
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n"
]
},
2025-06-06 08:24:47 +00:00
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead tr th {\n",
" text-align: left;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th>path</th>\n",
" <th colspan=\"4\" halign=\"left\">e2e_latency</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th></th>\n",
" <th>count</th>\n",
" <th>mean</th>\n",
" <th>min</th>\n",
" <th>max</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
2025-06-09 14:12:01 +00:00
" <th>6</th>\n",
" <td>void(GPSNode::GPSNode(std::__cxx11::basic_stri...</td>\n",
" <td>123</td>\n",
" <td>0.472754</td>\n",
" <td>0.155679</td>\n",
" <td>0.589257</td>\n",
" </tr>\n",
" <tr>\n",
2025-06-06 08:24:47 +00:00
" <th>10</th>\n",
" <td>void(LidarNode::LidarNode(std::__cxx11::basic_...</td>\n",
2025-06-09 14:12:01 +00:00
" <td>123</td>\n",
" <td>0.305507</td>\n",
" <td>0.134326</td>\n",
" <td>0.384916</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
2025-06-09 14:12:01 +00:00
" <th>0</th>\n",
" <td>void(BaroNode::BaroNode(std::__cxx11::basic_st...</td>\n",
" <td>122</td>\n",
" <td>0.475270</td>\n",
" <td>0.180133</td>\n",
" <td>0.629801</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
2025-06-09 14:12:01 +00:00
" <th>8</th>\n",
" <td>void(IMUNode::IMUNode(std::__cxx11::basic_stri...</td>\n",
" <td>122</td>\n",
" <td>0.477690</td>\n",
" <td>0.155617</td>\n",
" <td>0.636953</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>void(CommandNode::CommandNode(std::__cxx11::ba...</td>\n",
" <td>122</td>\n",
" <td>0.304512</td>\n",
" <td>0.139173</td>\n",
" <td>0.382762</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>void(GPSNode::GPSNode(std::__cxx11::basic_stri...</td>\n",
2025-06-09 14:12:01 +00:00
" <td>121</td>\n",
" <td>0.458383</td>\n",
" <td>0.172521</td>\n",
" <td>0.567640</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>void(BaroNode::BaroNode(std::__cxx11::basic_st...</td>\n",
2025-06-09 14:12:01 +00:00
" <td>120</td>\n",
" <td>0.456218</td>\n",
" <td>0.205201</td>\n",
" <td>0.565442</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>void(IMUNode::IMUNode(std::__cxx11::basic_stri...</td>\n",
2025-06-09 14:12:01 +00:00
" <td>120</td>\n",
" <td>0.458216</td>\n",
" <td>0.205263</td>\n",
" <td>0.565517</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
2025-06-09 14:12:01 +00:00
" <th>3</th>\n",
2025-06-06 08:24:47 +00:00
" <td>void(CameraNode::CameraNode(std::__cxx11::basi...</td>\n",
2025-06-09 14:12:01 +00:00
" <td>118</td>\n",
" <td>0.831055</td>\n",
" <td>0.320465</td>\n",
" <td>1.448288</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>void(CameraNode::CameraNode(std::__cxx11::basi...</td>\n",
2025-06-09 14:12:01 +00:00
" <td>112</td>\n",
" <td>0.174314</td>\n",
" <td>0.117773</td>\n",
" <td>0.584865</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" <tr>\n",
2025-06-09 14:12:01 +00:00
" <th>2</th>\n",
2025-06-06 08:24:47 +00:00
" <td>void(CameraNode::CameraNode(std::__cxx11::basi...</td>\n",
2025-06-09 14:12:01 +00:00
" <td>95</td>\n",
" <td>0.379984</td>\n",
" <td>0.074686</td>\n",
" <td>0.810526</td>\n",
2025-06-06 08:24:47 +00:00
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" path e2e_latency \\\n",
" count mean \n",
2025-06-09 14:12:01 +00:00
"6 void(GPSNode::GPSNode(std::__cxx11::basic_stri... 123 0.472754 \n",
"10 void(LidarNode::LidarNode(std::__cxx11::basic_... 123 0.305507 \n",
"0 void(BaroNode::BaroNode(std::__cxx11::basic_st... 122 0.475270 \n",
"8 void(IMUNode::IMUNode(std::__cxx11::basic_stri... 122 0.477690 \n",
"5 void(CommandNode::CommandNode(std::__cxx11::ba... 122 0.304512 \n",
"7 void(GPSNode::GPSNode(std::__cxx11::basic_stri... 121 0.458383 \n",
"1 void(BaroNode::BaroNode(std::__cxx11::basic_st... 120 0.456218 \n",
"9 void(IMUNode::IMUNode(std::__cxx11::basic_stri... 120 0.458216 \n",
"3 void(CameraNode::CameraNode(std::__cxx11::basi... 118 0.831055 \n",
"4 void(CameraNode::CameraNode(std::__cxx11::basi... 112 0.174314 \n",
"2 void(CameraNode::CameraNode(std::__cxx11::basi... 95 0.379984 \n",
2025-06-06 08:24:47 +00:00
"\n",
" \n",
" min max \n",
2025-06-09 14:12:01 +00:00
"6 0.155679 0.589257 \n",
"10 0.134326 0.384916 \n",
"0 0.180133 0.629801 \n",
"8 0.155617 0.636953 \n",
"5 0.139173 0.382762 \n",
"7 0.172521 0.567640 \n",
"1 0.205201 0.565442 \n",
"9 0.205263 0.565517 \n",
"3 0.320465 1.448288 \n",
"4 0.117773 0.584865 \n",
"2 0.074686 0.810526 "
2025-06-06 08:24:47 +00:00
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%skip_if_false E2E_ENABLED\n",
"\n",
"from message_tree.message_tree_algorithms import aggregate_e2e_paths\n",
"\n",
"##################################################\n",
"# Group dataflows by DFG path\n",
"##################################################\n",
"\n",
"cohorts = aggregate_e2e_paths(all_paths)\n",
"print(f\"Found {len(cohorts)} cohorts of E2E paths.\")\n",
"cohort_pairs = [(k, v) for k, v in cohorts.items()]\n",
"cohort_pairs.sort(key=lambda kv: len(kv[1]), reverse=True)\n",
"\n",
"path_records = [{\"path\": path_key,\n",
" \"timestamp\": path[-1].timestamp,\n",
" \"e2e_latency\": path[-1].timestamp - path[0].timestamp} \\\n",
" for path_key, paths in cohort_pairs for path in paths if path]\n",
"\n",
"out_df = pd.DataFrame.from_records(path_records)\n",
"out_df.to_csv(os.path.join(OUT_PATH, \"e2e.csv\"), sep=\"\\t\", index=False)\n",
"\n",
"df_print = out_df[['path', 'e2e_latency']].groupby(\"path\").agg(['count', 'mean', 'min', 'max']).reset_index()\n",
"#df_print['path'] = df_print['path'].apply(lambda path: \" -> \".join(filter(lambda part: part.startswith(\"/\"), path.split(\" -> \"))))\n",
"df_print = df_print.sort_values((\"e2e_latency\", \"count\"), ascending=False)\n",
"df_print.to_csv(os.path.join(OUT_PATH, \"e2e_overview.csv\"), sep=\"\\t\", index=False)\n",
"df_print"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import pickle\n",
"# with open(\"state.pkl\", \"wb\") as f:\n",
"# pickle.dump((trees_paths, all_paths, cohorts), f)\n",
"with open(os.path.join(OUT_PATH, \"state.pkl\"), \"wb\") as f:\n",
" pickle.dump((trees_paths, all_paths, cohorts), f)"
]
},
{
"cell_type": "code",
2025-06-09 14:12:01 +00:00
"execution_count": null,
2023-02-15 17:02:20 +09:00
"metadata": {
"collapsed": false
},
2025-06-03 13:43:48 +00:00
"outputs": [
{
2025-06-06 08:24:47 +00:00
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 123/123 [00:00<00:00, 91439.10it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['GPSNode', '/input/gpsA/fix', 'FusionNode', '/fusionA_node', 'FusionNode', '/sensorsA/fused', 'FlightManagementNode', '/mgmt_node', 'FlightManagementNode', '/flight/plan', 'ControlNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 123/123 [00:00<00:00, 134769.96it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['LidarNode', '/input/lidar/scan', 'FlightManagementNode', '/mgmt_node', 'FlightManagementNode', '/flight/plan', 'ControlNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 122/122 [00:00<00:00, 90263.73it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['IMUNode', '/input/imuA/data', 'FusionNode', '/fusionA_node', 'FusionNode', '/sensorsA/fused', 'FlightManagementNode', '/mgmt_node', 'FlightManagementNode', '/flight/plan', 'ControlNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 122/122 [00:00<00:00, 65368.56it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['BaroNode', '/input/baroA/alt', 'FusionNode', '/fusionA_node', 'FusionNode', '/sensorsA/fused', 'FlightManagementNode', '/mgmt_node', 'FlightManagementNode', '/flight/plan', 'ControlNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 122/122 [00:00<00:00, 130271.15it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['CommandNode', '/input/operator/commands', 'FlightManagementNode', '/mgmt_node', 'FlightManagementNode', '/flight/plan', 'ControlNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"/tmp/ipykernel_256141/3060490163.py:48: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`). Consider using `matplotlib.pyplot.close()`.\n",
" fig, axes = plt.subplots(1, 3, num=f\"E2E type breakdown histograms {name}\\n{EXPERIMENT_NAME}\", dpi=300, figsize=(16, 9))\n",
"Calculating breakdowns: 100%|██████████| 121/121 [00:00<00:00, 98126.60it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['GPSNode', '/input/gpsB/fix', 'FusionNode', '/fusionB_node', 'FusionNode', '/sensorsB/fused', 'TelemetryNode', '/telemetry_node', 'TelemetryNode', '/telemetry/data', 'RadioNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 120/120 [00:00<00:00, 98342.42it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['IMUNode', '/input/imuB/data', 'FusionNode', '/fusionB_node', 'FusionNode', '/sensorsB/fused', 'TelemetryNode', '/telemetry_node', 'TelemetryNode', '/telemetry/data', 'RadioNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 120/120 [00:00<00:00, 98074.14it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['BaroNode', '/input/baroB/alt', 'FusionNode', '/fusionB_node', 'FusionNode', '/sensorsB/fused', 'TelemetryNode', '/telemetry_node', 'TelemetryNode', '/telemetry/data', 'RadioNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 118/118 [00:00<00:00, 53662.35it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['CameraNode', '/input/cameraA/raw', 'DebayerNode', '/cameraA/debayered', 'RadiometricNode', '/cameraA/radiometric', 'GeometricNode', '/cameraA/geometric', 'MappingNode', '/output/cameraA/mapped', 'TelemetryNode', '/telemetry_node', 'TelemetryNode', '/telemetry/data', 'RadioNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 95/95 [00:00<00:00, 113715.43it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['CameraNode', '/input/cameraA/raw', 'DebayerNode', '/cameraA/debayered', 'RadiometricNode', '/cameraA/radiometric', 'GeometricNode', '/cameraA/geometric', 'MappingNode']\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Calculating breakdowns: 100%|██████████| 112/112 [00:00<00:00, 137357.32it/s]\n"
2025-06-06 08:24:47 +00:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
2025-06-09 14:12:01 +00:00
"Labels: ['CameraNode', '/input/cameraB/raw', 'DebayerNode', '/cameraB/debayered', 'RadiometricNode', '/cameraB/radiometric', 'SmokeClassifierNode']\n",
2025-06-06 08:24:47 +00:00
"Done.\n"
]
},
{
"data": {
2025-06-09 14:12:01 +00:00
"image/png": "iVBORw0KGgoAAAANSUhEUgAAD1AAAAnqCAYAAAAzIHOrAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAuIwAALiMBeKU/dgABAABJREFUeJzs3XdYFNf7NvB76VUBaRJRsCtWBHtB7L3GrthLTMzXFGOMscYYNZrE3ruxxh4rigbFimLFjqIICihN6cz7h6/8nJ1l2cYu4v25Lq5kz84559md2TPFeebIBEEQQEREREREREREREREREREREREREREREREREREREREVAQYGToAIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiXWECNRERERERERERERERERERERERERERERERERERERERFRlMoCYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIioiKDCdRERERERERERERERERERERERERERERERERERERERFRkMIGaiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiKDCZQExERERERERERERERERERERERERERERERERERERFRkcEEaiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiKjKYQE1EREREREREREREREREREREREREREREREREREREREUGE6iJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiKjIYAI1EREREREREREREREREREREREREREREREREREREREVGUygJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiKiIoMJ1EREREREREREREREREREREREREREREREREREREREVGQwgZqIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIoMJlATEREREREREREREREREREREREREREREREREREREVGRwQRqIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIqMphATURERERERERERERERERERERERERERERERERERERERQYTqImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIqMhgAjURERERERERERERERERERERERERERERERERERERERUZTKAmIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIqIigwnURERERERERERERERERERERERERERERERERERERERUZDCBmoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIigwmUBMRERERERERERERERERERERERERERERERERERERUZHBBGoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIioymEBNRERERERERERERERERERERERERERERERERERERERFBhOoiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIioyGACNRERERERERERERERERERERERERERERERERERERERFRlMoCYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIioiKDCdRERERERERERERERERERERERERERERERERERERERFRkMIGaiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiKDCZQExEREREREREREdFHw8PDAzKZLPdv8ODBhg5JZX5+fqLY/fz8DB0SGdCpU6dE24NMJsOpU6cMHRYREZFB8DiJiIqCFy9eYO7cuejcuTM8PT1RvHhxGBkZica3rl27iupMmzZNcl5ARJ+OrKws7Nq1C8OGDUONGjXg7OwMMzMzybiQkJCQW+fx48eS99evX59vX5rWM7TBgweLYvbw8DB0SEQK8ZyGiIiIiIiIqHAyMXQARERERERERPTpyMjIwN27dxEeHo64uDgkJibC1NQU9vb2cHJyQp06dfDZZ58ZOkwiIiIiIiIiIiIileTk5GDmzJmYPXs20tPTDR0OEX0kzp49iwEDBuDx48eGDoWIiIiIiIiIiKjIYgI1ERERERERURH1+PFjeHp6FkjbxYsXF814kJfMzEycOnUKJ06cQFBQEK5cuYKsrCyldUqVKoXPP/8cY8aMQYUKFTSO0c/PD6dPn9a4vjJ79uyRzBajS6dOnULz5s1FZQEBAR/FbBBEhdXgwYOxYcMGteqYm5ujWLFisLe3R+XKlVGrVi20adMGDRs2LKAoiYgoP+qM50ZGRrCxsUHx4sXh6OiIGjVqwNvbGx06dEC5cuUKOFIikjdt2jRMnz7dIH2vW7cOgwcPNkjfREQklpycjJIlS+LNmzeicjs7O0RHR8PCwsJAkWluxIgRWLt2raHDIKKPSFBQEFq3bp3vv5cQERERERERERGRdowMHQARERERERERFT3Xr1/HsGHD4OLigtatW2POnDm4ePGiSjcDPXv2DH/88QcqVaqE4cOHIykpSQ8Rk6HIZDLR37Rp0wwdElGu9PR0xMbG4t69e9i/fz9mzJiBRo0aoVy5cli7di0EQTB0iEREpEROTg6SkpLw9OlTXL16FRs2bMDXX3+NChUqwM/PD0FBQYYOkYiI6KPl4eEhOp/nQwpIVdu3b5ckTwNAQkIC/vnnHwNEpJ09e/YoTJ42NjZG2bJlUaNGDdSsWTP3r6AeeEkfDz8/P9H46efnZ+iQPlqDBw8WfZceHh6GDkklqamp6Nevn8J/L3FxcUG1atVE40bNmjVhbGxsgEgJ4DEPEREREREREdHHjjNQExEREREREZHO7d69W+tZVwRBwJo1a3D8+HEcP34cFStW1FF0RETaefToEYYNG4b169dj3759sLe3N3RIRESkBkEQcPr0abRo0QKjRo3CokWLYGLCfzIjIiIi0oc1a9Yofa9///56jEZ7v//+u+i1iYkJ5s6di5EjR8La2tpAURFRYbZ582bExMSIyjp27IgFCxagQoUKBoqKiIiIiIiIiIioaOLdIERERERERESfEGtra5QvX17rdmxtbTWqZ25uDl9fXzRs2BBubm5wdnZGdnY2oqOjERISgsOHDyM9PV1UJzIyEv7+/ggODtZ6hpYqVarAzMxMqzYAoHjx4lq3QUSGV65cOdjY2Ch8TxAEpKSkIC4uDklJSQqXCQ4Ohp+fH4KDg1GsWLGCDJWIiJTIazzPyclBQkICXrx4gYyMDMn7giBg+fLlSE1Nxbp16yCTyfQRLtEny9XVFTVr1lSrTmRkJF6/fi0qc3d3h4ODg1rtqLs8EREVjNu3b+P8+fN5vn/q1Ck8evQIZcuW1WNUmouNjUVISIiobPz48Rg/fryBIiKij8HevXtFr93d3bFz505YWFgYJiAiIiIiIiIiIqIijAnURERERERERJ8QHx8fnDp1Sq99mpiYoH379hgyZAjatm2r9Cag6OhofP/999iyZYuoPCoqCkOHDkVQUJBWsRw6dAgeHh5atUFERcfq1avh5+eX73JPnjzBvn37sGDBAjx58kT03vXr1zFp0iQsXry4gKIkIqL85Deep6en49KlS1i9ejU2bdqEnJwc0fsbNmxA06ZNMXTo0AKOlOjTNnr0aIwePVqtOoMHD8aGDRtEZTNmzMDgwYN1GBkVBvq+VkFEhiE/+7RMJoMgCLmvBUHA2rVr8csvv+g7NI1cvHhRUta7d2+12pg2bRqmTZumo4iI6GMgP3Z06dJFL8nTHh4eojGXiIiIiIiIiIjoU2Bk6ACIiIiIiIiIqGiytLTE+PHj8fTpU+zbtw9du3bN9yagkiVLYvPmzZgxY4bkvVOnTuGff/4pqHCJiPJUpkwZjBs3Drdv30a7du0k7y9btgzPnz83QGRERKQKc3NzNG7cGOvXr8exY8dgZWUlWWbq1KlIS0szQHREREREn4bMzExs2rRJVNaiRQv4+PiIyjZs2CB54E1hFRkZKSmrVKmSASIhoo9Famoq4uLiRGUcN4iIiIiIiIiIiAoOE6iJiIiIiIiISOfatm2LR48eYcGCBXB1dVW7/s8//4yOHTtKyjdu3KiL8IiINGJlZYXt27dLxrWcnBzs2bPHQFEREZE6WrRogWXLlknKnz17hqC
2025-06-06 08:24:47 +00:00
"text/plain": [
"<Figure size 4800x2700 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
2025-06-03 13:43:48 +00:00
}
],
2022-10-28 22:37:48 +09:00
"source": [
2025-06-06 08:24:47 +00:00
"import matplotlib.patches as mpatches\n",
2025-06-09 14:12:01 +00:00
"from collections import Counter\n",
2025-06-06 08:24:47 +00:00
"\n",
"from message_tree.message_tree_algorithms import e2e_latency_breakdown, label_latency_item\n",
"from message_tree.message_tree_plots import e2e_breakdown_stack\n",
2025-06-03 13:43:48 +00:00
"\n",
2022-11-07 17:46:09 +09:00
"##################################################\n",
2025-06-06 08:24:47 +00:00
"# 1. Filter DFG paths through must-be-included and cannot-be-included patterns\n",
2022-11-07 17:46:09 +09:00
"##################################################\n",
2022-10-28 22:37:48 +09:00
"\n",
2025-06-06 08:24:47 +00:00
"cohorts_filt = {\n",
" k: v for k, v in cohorts.items()\n",
" if all(re.search(f.removeprefix(\"^\").removesuffix(\"$\"), k) for f in E2E_INCL_PATH_PATTERNS)\n",
"}\n",
2022-10-28 22:37:48 +09:00
"\n",
2025-06-06 08:24:47 +00:00
"##################################################\n",
"# 2. Iterate through filtered DFG paths\n",
"##################################################\n",
2022-10-28 22:37:48 +09:00
"\n",
2025-06-06 08:24:47 +00:00
"for relevant_path, relevant_dataflows in cohorts_filt.items():\n",
" # Construct a filesystem-safe name for output files\n",
2025-06-03 13:43:48 +00:00
" topics = [topic for topic in relevant_path.split(\" -> \") if topic.startswith(\"/\") and not topic.startswith(\"/void\")]\n",
2025-06-06 08:24:47 +00:00
" name = f\"{topics[0][1:]}-{topics[-1][1:]}\"\n",
2025-06-03 13:43:48 +00:00
" name = name.replace(\"/\", \"_\").replace(\" \", \"_\").replace(\":\", \"_\")\n",
"\n",
2025-06-06 08:24:47 +00:00
" # Break down E2E latency for all dataflows on this path\n",
2025-06-03 13:43:48 +00:00
" e2e_breakdowns = list(map(e2e_latency_breakdown, relevant_dataflows))\n",
2025-06-06 08:24:47 +00:00
" flattened_breakdowns = [item for breakdown in e2e_breakdowns for item in breakdown]\n",
2025-06-03 13:43:48 +00:00
"\n",
2025-06-06 08:24:47 +00:00
" # Save information about the chosen path\n",
2025-06-03 13:43:48 +00:00
" with open(os.path.join(OUT_PATH, f\"plot_e2es_path_{name}.txt\"), \"w\") as f:\n",
" f.write(f\"Number of path instances: {len(relevant_dataflows)}\\n\")\n",
2025-06-06 08:24:47 +00:00
" f.write(\" \" + \"\\n -> \".join(relevant_path.split(\" -> \")))\n",
2025-06-03 13:43:48 +00:00
" f.write(\"\\n\")\n",
"\n",
2025-06-06 08:24:47 +00:00
" # Unique items for deduplicated analysis\n",
" conv_items_unique = set(flattened_breakdowns)\n",
2025-06-03 13:43:48 +00:00
"\n",
2025-06-06 08:24:47 +00:00
" ##################################################\n",
" # 3. Plot histograms of DDS/idle/cpu time breakdowns\n",
" ##################################################\n",
" def e2e_breakdown_type_hist(items):\n",
2025-06-03 13:43:48 +00:00
" \"\"\"\n",
2025-06-06 08:24:47 +00:00
" For all e2e breakdown items (unique) of the form `(\"<type>\", <duration>)`, plots a histogram for each encountered type (dds, idle, cpu).\n",
2025-06-03 13:43:48 +00:00
" \"\"\"\n",
" plot_types = (\"dds\", \"idle\", \"cpu\")\n",
2025-06-09 14:12:01 +00:00
" plt.close(f\"E2E type breakdown histograms {name}\\n{EXPERIMENT_NAME}\")\n",
" fig, axes = plt.subplots(1, 3, num=f\"E2E type breakdown histograms {name}\\n{EXPERIMENT_NAME}\", dpi=300, figsize=(16, 9))\n",
" fig.suptitle(f\"E2E Latency Breakdown by Resource Type {name}\\n{EXPERIMENT_NAME}\")\n",
2025-06-03 13:43:48 +00:00
"\n",
2025-06-06 08:24:47 +00:00
" for plot_type, ax in zip(plot_types, axes):\n",
" durations = [item.duration * 1000 for item in items if item.type == plot_type]\n",
2025-06-03 13:43:48 +00:00
" df = pd.Series(durations)\n",
2025-06-06 08:24:47 +00:00
" df.to_csv(\n",
" os.path.join(OUT_PATH, f\"plot_e2es_{plot_type}_portion_{name}.csv\"),\n",
" header=[f\"e2e_latency_{plot_type}_portion_ms\"],\n",
" index=False\n",
" )\n",
" ax.set_title(plot_type)\n",
2025-06-03 13:43:48 +00:00
" ax.hist(durations, bins=50)\n",
2025-06-06 08:24:47 +00:00
" ax.set_xlabel(\"Duration [ms]\")\n",
2025-06-09 14:12:01 +00:00
" ax.set_ylabel(\"Occurrences [#]\")\n",
2025-06-03 13:43:48 +00:00
" return fig\n",
"\n",
2025-06-06 08:24:47 +00:00
" fig = e2e_breakdown_type_hist(conv_items_unique)\n",
2025-06-03 13:43:48 +00:00
" plt.savefig(os.path.join(OUT_PATH, f\"plot_e2e_portions_{name}.png\"))\n",
2022-11-07 17:46:09 +09:00
"\n",
2025-06-03 13:43:48 +00:00
" ##################################################\n",
2025-06-06 08:24:47 +00:00
" # 4. Plot histogram of all E2E latencies observed\n",
2025-06-03 13:43:48 +00:00
" ##################################################\n",
2025-06-06 08:24:47 +00:00
" e2e_latencies = [(path[-1].timestamp - path[0].timestamp) * 1000 for path in relevant_dataflows]\n",
" pd.Series(e2e_latencies).to_csv(\n",
" os.path.join(OUT_PATH, f\"plot_e2es_{name}.csv\"),\n",
" index=False, header=[\"e2e_latency_ms\"]\n",
" )\n",
"\n",
2025-06-09 14:12:01 +00:00
" plt.close(f\"E2E histogram {name}\\n{EXPERIMENT_NAME}\")\n",
" fig, ax = plt.subplots(num=f\"E2E histogram {name}\\n{EXPERIMENT_NAME}\", dpi=300, figsize=(16, 9))\n",
" fig.suptitle(f\"E2E Latency Histogram {name}\\n{EXPERIMENT_NAME}\")\n",
2025-06-06 08:24:47 +00:00
" ax.hist(e2e_latencies, bins=30)\n",
" ax.set_xlabel(\"E2E Latency [ms]\")\n",
2025-06-09 14:12:01 +00:00
" ax.set_ylabel(\"Occurrences [#]\")\n",
2025-06-06 08:24:47 +00:00
" mean_latency = np.mean(e2e_latencies)\n",
" std_latency = np.std(e2e_latencies)\n",
" min_latency = np.min(e2e_latencies)\n",
" max_latency = np.max(e2e_latencies)\n",
" ax.axvline(mean_latency, c=\"red\", linewidth=2)\n",
2025-06-03 13:43:48 +00:00
" _, max_ylim = ax.get_ylim()\n",
2025-06-06 08:24:47 +00:00
" # Create a multi-line string with all stats\n",
" stats_text = (\n",
" f\"Mean: {mean_latency:.2f} ms\\n\"\n",
" f\"Std: {std_latency:.2f} ms\\n\"\n",
" f\"Min: {min_latency:.2f} ms\\n\"\n",
" f\"Max: {max_latency:.2f} ms\"\n",
" )\n",
" # Place text near top right of plot\n",
" ax.text(\n",
" mean_latency * 1.02, # or just use ax.get_xlim()[1]*0.98 for far right\n",
" max_ylim * 0.98, # near the top\n",
" stats_text,\n",
" verticalalignment='top',\n",
" horizontalalignment='left',\n",
" fontsize=10,\n",
" bbox=dict(facecolor='white', alpha=0.7, boxstyle='round,pad=0.3')\n",
" )\n",
" plt.savefig(os.path.join(OUT_PATH, f\"plot_e2es_{name}.png\"))\n",
2022-10-28 22:37:48 +09:00
"\n",
2025-06-06 08:24:47 +00:00
" ##################################################\n",
" # 5. Violin plot of per-component/stage latencies on the DFG path (across all dataflows)\n",
" ##################################################\n",
" plt.close(\"E2E path breakdown\")\n",
2025-06-09 14:12:01 +00:00
" fig, ax = plt.subplots(num=f\"E2E path breakdown {name}\\n{EXPERIMENT_NAME}\", dpi=300, figsize=(16, 5))\n",
" fig.suptitle(f\"E2E Latency Path Breakdown {name}\\n{EXPERIMENT_NAME}\")\n",
2025-06-06 08:24:47 +00:00
"\n",
" component_breakdowns = [e2e_latency_breakdown(p) for p in tqdm(relevant_dataflows, desc=\"Calculating breakdowns\")]\n",
" # Transpose: Each element in component_durations is all values for one component\n",
" component_durations = list(zip(*component_breakdowns))\n",
" component_latency_items = component_durations\n",
"\n",
" def extract_class_name(symbol: str) -> str:\n",
" # Try to extract class name in pattern: void(ClassName::ClassName...\n",
" m = re.search(r'void\\((\\w+)::', symbol)\n",
" if m:\n",
" return m.group(1)\n",
" # If pattern not found, fallback: find last word before first '('\n",
" m = re.search(r'(\\w+)\\s*\\(', symbol)\n",
" if m:\n",
" return m.group(1)\n",
" return symbol # fallback to original if all fails\n",
"\n",
" # For labeling, types etc (assume first dataflow is representative)\n",
" labels = [extract_class_name(label_latency_item(item)) for item in e2e_latency_breakdown(relevant_dataflows[0])]\n",
" print(f\"Labels: {labels}\")\n",
" types = [item.type for item in e2e_latency_breakdown(relevant_dataflows[0])]\n",
" # Convert durations from seconds to ms\n",
" component_durations_ms = [list(map(lambda item: item.duration * 1000, d)) for d in component_durations]\n",
"\n",
" legend_entries = []\n",
"\n",
" def add_label(violin, label):\n",
" color = violin[\"bodies\"][0].get_facecolor().flatten()\n",
" legend_entries.append((mpatches.Patch(color=color), label))\n",
"\n",
2025-06-09 14:12:01 +00:00
" #counter = Counter(types)\n",
" ## Print all unique elements and their count\n",
" #for element, count in counter.items():\n",
" # print(f'{element}: {count}')\n",
"\n",
2025-06-06 08:24:47 +00:00
" for comp_type in (\"idle\", \"dds\", \"cpu\"):\n",
" indices = [i for i, t in enumerate(types) if t == comp_type]\n",
" xs = [component_durations_ms[i] for i in indices]\n",
" if not xs:\n",
" continue\n",
" vln = ax.violinplot(xs, indices)\n",
" add_label(vln, comp_type)\n",
" # Export CSVs per component\n",
" for i, x in zip(indices, xs):\n",
" pd.Series(x).to_csv(\n",
" os.path.join(OUT_PATH, f\"plot_e2es_violin_{i:02d}.csv\"),\n",
" index=False, header=[\"duration_ms\"]\n",
" )\n",
" ax.set_ylabel(\"Latency contribution [ms]\")\n",
" ax.set_xticks(range(len(labels)), labels, rotation=90)\n",
" ax.legend(*zip(*legend_entries))\n",
" plt.savefig(os.path.join(OUT_PATH, f\"plot_e2es_violin_{name}.png\"))\n",
"\n",
" # Save labels and types\n",
" pd.Series(labels).to_csv(os.path.join(OUT_PATH, f\"plot_e2es_violin_labels_{name}.csv\"), index=False, header=[\"label\"])\n",
" pd.Series(types).to_csv(os.path.join(OUT_PATH, f\"plot_e2es_violin_types_{name}.csv\"), index=False, header=[\"type\"])\n",
2022-10-28 22:37:48 +09:00
"\n",
2025-06-06 08:24:47 +00:00
" ##################################################\n",
" # 6. Per-callback timestamp/duration records for relevant components (e.g., \"cpu\" stages)\n",
" ##################################################\n",
" for concat_pc_items in component_latency_items:\n",
" # Defensive check\n",
" if not isinstance(concat_pc_items[0].location[0], TrPublishInstance):\n",
" continue\n",
" records = [(item.location[0].timestamp, item.duration) for item in concat_pc_items]\n",
" pd.DataFrame(records, columns=(\"timestamp\", \"duration\")).to_csv(\n",
" os.path.join(OUT_PATH, f\"dur_ts_{concat_pc_items[0].location[0].publisher.topic_name.replace('/', '__')}_{name}.csv\"),\n",
" index=False\n",
" )\n",
2022-11-07 17:46:09 +09:00
"\n",
2025-06-06 08:24:47 +00:00
" ##################################################\n",
" # 7. Per-callback timing stats (mean, std, min, max) for \"cpu\" stages\n",
" ##################################################\n",
" cpu_indices = [i for i, t in enumerate(types) if t == \"cpu\"]\n",
" cpu_durations = [np.array([item.location[0].duration for item in component_latency_items[i]]) for i in cpu_indices]\n",
" cpu_labels = [labels[i] for i in cpu_indices]\n",
" stats = [(lbl, x.mean(), x.std(), x.min(), x.max()) for x, lbl in zip(cpu_durations, cpu_labels)]\n",
" pd.DataFrame(stats, columns=[\"callback\", \"mean\", \"std\", \"min\", \"max\"]).to_csv(\n",
" os.path.join(OUT_PATH, f\"calc_times_{name}.csv\"), index=False\n",
" )\n",
2022-08-29 22:17:52 +02:00
"\n",
2025-06-06 08:24:47 +00:00
" ##################################################\n",
" # 8. Stacked breakdown plot (from message_tree plots)\n",
" ##################################################\n",
2025-06-09 14:12:01 +00:00
" fig = e2e_breakdown_stack(*e2e_breakdowns, name=f\"{name}\\n{EXPERIMENT_NAME}\")\n",
2025-06-06 08:24:47 +00:00
" fig.set_size_inches(16, 9)\n",
" fig.set_dpi(300)\n",
2022-10-14 00:15:33 +09:00
"\n",
2023-02-15 17:02:20 +09:00
"print(\"Done.\")"
]
2022-05-23 13:03:38 +02:00
}
],
"metadata": {
"kernelspec": {
2025-06-03 13:43:48 +00:00
"display_name": "venv310",
2022-05-23 13:03:38 +02:00
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
2025-06-03 13:43:48 +00:00
"version": "3.10.12"
2022-05-23 13:03:38 +02:00
}
},
"nbformat": 4,
"nbformat_minor": 2
2022-09-20 12:44:04 +02:00
}