diff --git a/.gitignore b/.gitignore
index c6587a5..dae35a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,9 @@ cache/
*.log
*.svg
*.gv
+
+traces/
+venv310/
+**/build/
+**/install/
+**/log/
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4f1aa19
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "dependencies/src/ros2_tracing"]
+ path = dependencies/src/ros2_tracing
+ url = git@github.com:ros2/ros2_tracing.git
+[submodule "dependencies/src/tracetools_analysis"]
+ path = dependencies/src/tracetools_analysis
+ url = git@gitlab.com:ros-tracing/tracetools_analysis.git
diff --git a/dependencies/colcon_defaults.yaml b/dependencies/colcon_defaults.yaml
new file mode 100644
index 0000000..628bd9b
--- /dev/null
+++ b/dependencies/colcon_defaults.yaml
@@ -0,0 +1,11 @@
+{
+ "build":{
+ "symlink-install": true,
+ "cmake-args": [
+ "-DCMAKE_BUILD_TYPE=RelWithDebInfo",
+ "-DCMAKE_EXPORT_COMPILE_COMMANDS=True",
+ # no tests
+ "-DBUILD_TESTING=OFF",
+ ],
+ }
+}
diff --git a/dependencies/src/ros2_tracing b/dependencies/src/ros2_tracing
new file mode 160000
index 0000000..548634d
--- /dev/null
+++ b/dependencies/src/ros2_tracing
@@ -0,0 +1 @@
+Subproject commit 548634dd2837d65c043436c8186614e924be5c6c
diff --git a/dependencies/src/tracetools_analysis b/dependencies/src/tracetools_analysis
new file mode 160000
index 0000000..838b972
--- /dev/null
+++ b/dependencies/src/tracetools_analysis
@@ -0,0 +1 @@
+Subproject commit 838b97200023a1be6f9bae32240ee4118a15b6b9
diff --git a/latency_graph/latency_graph_plots.py b/latency_graph/latency_graph_plots.py
index dce6363..a085f1a 100644
--- a/latency_graph/latency_graph_plots.py
+++ b/latency_graph/latency_graph_plots.py
@@ -113,9 +113,9 @@ def plot_latency_graph_overview(lat_graph: lg.LatencyGraph, excl_node_patterns,
input_nodes = [n.full_name for n in lvl_nodes if any(re.search(p, n.full_name) for p in input_node_patterns)]
output_nodes = [n.full_name for n in lvl_nodes if any(re.search(p, n.full_name) for p in output_node_patterns)]
- print(', '.join(map(lambda n: n, input_nodes)))
- print(', '.join(map(lambda n: n, output_nodes)))
- print(', '.join(map(lambda n: n.full_name, lvl_nodes)))
+ print("Input Nodes:", ', '.join(map(lambda n: n, input_nodes)))
+ print("Output Nodes:", ', '.join(map(lambda n: n, output_nodes)))
+ print("Intermediate Nodes:", ', '.join(map(lambda n: n.full_name, lvl_nodes)))
def _collect_callbacks(n: lg.LGHierarchyLevel):
callbacks = []
diff --git a/latency_graph/latency_graph_structure.py b/latency_graph/latency_graph_structure.py
index c97e234..7b9edb8 100644
--- a/latency_graph/latency_graph_structure.py
+++ b/latency_graph/latency_graph_structure.py
@@ -221,7 +221,7 @@ class LatencyGraph:
nodes_to_cbs[node] = set()
nodes_to_cbs[node].add(cb)
- print(f"[ENTKÄFERN] {ownerless_cbs} callbacks have no owner, filtering them out.")
+ print(f"[DEBUG] {ownerless_cbs} callbacks have no owner, filtering them out.")
##################################################
# Find in/out topics for each callback
diff --git a/message_tree/message_tree_algorithms.py b/message_tree/message_tree_algorithms.py
index e0f0713..1159092 100644
--- a/message_tree/message_tree_algorithms.py
+++ b/message_tree/message_tree_algorithms.py
@@ -108,6 +108,8 @@ def build_dep_trees(end_topics, lat_graph, tr, excluded_path_patterns, time_limi
end_topic: TrTopic
print(f"====={end_topic.name}")
+ tree_count = 0
+
pubs = end_topic.publishers
for pub in pubs:
msgs = list(pub.instances)
@@ -115,6 +117,8 @@ def build_dep_trees(end_topics, lat_graph, tr, excluded_path_patterns, time_limi
msg: TrPublishInstance
tree = get_dep_tree(msg, lat_graph, tr, excluded_path_patterns, time_limit_s, exact_path=exact_path)
all_trees.append(tree)
+ tree_count += 1
+ print(f"Found {tree_count} trees for topic {end_topic.name}")
return all_trees
diff --git a/trace-analysis.ipynb b/trace-analysis.ipynb
index 9716f54..e8c4136 100644
--- a/trace-analysis.ipynb
+++ b/trace-analysis.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {
"collapsed": false
},
@@ -37,11 +37,44 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "User Settings:\n",
+ " TRACING_WS_BUILD_PATH................... := /home/niklas/dataflow-analysis/dependencies/build\n",
+ " TR_PATH................................. := /home/niklas/dataflow-analysis/traces/full_topology_tracing-20250603152153/ust\n",
+ " OUT_PATH................................ := /home/niklas/dataflow-analysis/out\n",
+ " 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",
+ " E2E_PLOT_TIMESTAMP...................... := 100\n",
+ " E2E_TIME_LIMIT_S........................ := 500\n",
+ " 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"
+ ]
+ }
+ ],
"source": [
"##################################################\n",
"# User Settings\n",
@@ -59,12 +92,12 @@
"\n",
"# The path to the build folder of a ROS2 workspace that contains the\n",
"# tracetools_read and tracetools_analysis folders.\n",
- "TRACING_WS_BUILD_PATH = \"/path/to/tracing_ws/build\"\n",
+ "TRACING_WS_BUILD_PATH = \"/home/niklas/dataflow-analysis/dependencies/build\"\n",
"\n",
"# 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",
- "TR_PATH = \"/path/to/tracing/session-name/ust\"\n",
+ "TR_PATH = \"/home/niklas/dataflow-analysis/traces/full_topology_tracing-20250603152153/ust\"\n",
"\n",
"# Path to the folder all artifacts from this notebook are saved to.\n",
"# This entails plots as well as data tables.\n",
@@ -89,9 +122,9 @@
"\n",
"# Whether to compute data flow graphs.\n",
"# If you are only interested in E2E latencies, set this to False\n",
- "DFG_ENABLED = False\n",
+ "DFG_ENABLED = True\n",
"# Whether to plot data flow graphs (ignored if DFG_ENABLED is False)\n",
- "DFG_PLOT = False\n",
+ "DFG_PLOT = True\n",
"\n",
"# The maximum node namespace hierarchy level to be plotted.\n",
"# Top-level (1): e.g. /sensing, /control, etc.\n",
@@ -100,10 +133,10 @@
"\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",
- "DFG_INPUT_NODE_PATTERNS = [r\"^/sensing\"]\n",
+ "DFG_INPUT_NODE_PATTERNS = [r\"^/input_\"]\n",
"# RegEx pattern for nodes that shall be marked as system outputs\n",
"# These will be plotted with a double border\n",
- "DFG_OUTPUT_NODE_PATTERNS = [r\"^/control/external_cmd_converter\"]\n",
+ "DFG_OUTPUT_NODE_PATTERNS = [r\"^/output_\"]\n",
"# RegEx for nodes which shall not be plotted in the DFG\n",
"DFG_EXCL_NODE_PATTERNS = [r\"^/rviz2\"]\n",
"\n",
@@ -113,24 +146,23 @@
"E2E_PLOT = True\n",
"# 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",
- "E2E_PLOT_TIMESTAMP = 1000\n",
+ "E2E_PLOT_TIMESTAMP = 100\n",
"# 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",
- "E2E_TIME_LIMIT_S = 2\n",
+ "E2E_TIME_LIMIT_S = 500\n",
"\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",
- "E2E_OUTPUT_TOPIC_PATTERNS = [r\"^/control/command/control_cmd$\"]\n",
+ "E2E_OUTPUT_TOPIC_PATTERNS = [r\"^/output/\"]\n",
"# 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",
- "E2E_INPUT_TOPIC_PATTERNS = [r\"pointcloud\"]\n",
+ "E2E_INPUT_TOPIC_PATTERNS = [r\"^/input/\"]\n",
"\n",
"# 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",
- "E2E_EXCL_PATH_PATTERNS = [r\"^/parameter_events\", \"hazard\", \"turn_indicator\", \"gear_cmd\", \"emergency_cmd\", \"emergency_state\",\n",
- " \"external_cmd\", \"/control/operation_mode\"]\n",
+ "E2E_EXCL_PATH_PATTERNS = [r\"^/parameter_events\"]\n",
"\n",
"# To specify paths of interest, topic/callback name patterns that HAVE TO OCCUR in each E2E path can be specified as RegEx here.\n",
"#E2E_INCL_PATH_PATTERNS = [\"BehaviorPathPlanner\", \"BehaviorVelocityPlanner\", \"pointcloud_preprocessor::Filter\", r\"^/sensing/.*?pointcloud\"]\n",
@@ -138,35 +170,7 @@
"\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",
- "E2E_EXACT_PATH = [\n",
- " \"void(pointcloud_preprocessor::Filter)(sensor_msgs::msg::PointCloud2,pcl_msgs::msg::PointIndices)\",\n",
- " \"/localization/util/downsample/pointcloud\",\n",
- " \"void(NDTScanMatcher)(sensor_msgs::msg::PointCloud2)\",\n",
- " \"/localization/pose_estimator/pose_with_covariance\",\n",
- " \"void(EKFLocalizer)(geometry_msgs::msg::PoseWithCovarianceStamped)\",\n",
- " \"void(EKFLocalizer)()\",\n",
- " \"/localization/pose_twist_fusion_filter/kinematic_state\",\n",
- " \"void(StopFilter)(nav_msgs::msg::Odometry)\",\n",
- " \"/localization/kinematic_state\",\n",
- " \"void(behavior_path_planner::BehaviorPathPlannerNode)(nav_msgs::msg::Odometry)\",\n",
- " \"void(behavior_path_planner::BehaviorPathPlannerNode)()\",\n",
- " \"/planning/scenario_planning/lane_driving/behavior_planning/path_with_lane_id\",\n",
- " \"void(behavior_velocity_planner::BehaviorVelocityPlannerNode)(autoware_auto_planning_msgs::msg::PathWithLaneId)\",\n",
- " \"/planning/scenario_planning/lane_driving/behavior_planning/path\",\n",
- " \"void(ObstacleAvoidancePlanner)(autoware_auto_planning_msgs::msg::Path)\",\n",
- " \"/planning/scenario_planning/lane_driving/motion_planning/obstacle_avoidance_planner/trajectory\",\n",
- " \"void(motion_planning::ObstacleStopPlannerNode)(autoware_auto_planning_msgs::msg::Trajectory)\",\n",
- " \"/planning/scenario_planning/lane_driving/trajectory\",\n",
- " \"void(ScenarioSelectorNode)(autoware_auto_planning_msgs::msg::Trajectory)\",\n",
- " \"/planning/scenario_planning/scenario_selector/trajectory\",\n",
- " \"void(motion_velocity_smoother::MotionVelocitySmootherNode)(autoware_auto_planning_msgs::msg::Trajectory)\",\n",
- " \"/planning/scenario_planning/trajectory\",\n",
- " \"void(autoware::motion::control::trajectory_follower_nodes::Controller)(autoware_auto_planning_msgs::msg::Trajectory)\",\n",
- " \"void(autoware::motion::control::trajectory_follower_nodes::Controller)()\",\n",
- " \"/control/trajectory_follower/control_cmd\",\n",
- " \"void(vehicle_cmd_gate::VehicleCmdGate)(autoware_auto_control_msgs::msg::AckermannControlCommand)\",\n",
- " \"/control/command/control_cmd\",\n",
- "]\n",
+ "E2E_EXACT_PATH = []\n",
"\n",
"# For development purposes only. Leave this at False.\n",
"DEBUG = False\n",
@@ -215,7 +219,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {
"collapsed": false
},
@@ -247,11 +251,58 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[CACHE] Cache disabled for tr_objects.\n",
+ "found converted file: /home/niklas/dataflow-analysis/traces/full_topology_tracing-20250603152153/ust/converted\n",
+ " [100%] [Ros2Handler]\n",
+ "[TrContext] Processing ROS 2 objects from traces...\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ " ├─ Processing TrNodes: 100%|██████████| 16/16 [00:00<00:00, 189573.06it/s]\n",
+ " ├─ Processing TrPublishers: 100%|██████████| 48/48 [00:00<00:00, 352585.98it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[DEBUG] Duplicate Indices in id\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ " ├─ Processing TrSubscriptions: 100%|██████████| 31/31 [00:00<00:00, 183131.58it/s]\n",
+ " ├─ Processing TrTimers: 100%|██████████| 6/6 [00:00<00:00, 92521.41it/s]\n",
+ " ├─ Processing TrTimerNodeLinks: 100%|██████████| 6/6 [00:00<00:00, 107088.61it/s]\n",
+ " ├─ Processing TrSubscriptionObjects: 100%|██████████| 31/31 [00:00<00:00, 331692.41it/s]\n",
+ " ├─ Processing TrCallbackObjects: 100%|██████████| 133/133 [00:00<00:00, 617082.34it/s]\n",
+ " ├─ Processing TrCallbackSymbols: 100%|██████████| 133/133 [00:00<00:00, 238394.20it/s]\n",
+ " ├─ Processing TrPublishInstances: 100%|██████████| 20207/20207 [00:00<00:00, 268376.27it/s]\n",
+ " ├─ Processing TrCallbackInstances: 100%|██████████| 20311/20311 [00:00<00:00, 293063.09it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Done.\n"
+ ]
+ }
+ ],
"source": [
"def _load_traces():\n",
" file = load_file(TR_PATH)\n",
@@ -284,11 +335,50 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "/camera/debayered................................................................................................................. | 499 msgs\n",
+ "/camera/geometric................................................................................................................. | 499 msgs\n",
+ "/camera/radiometric............................................................................................................... | 499 msgs\n",
+ "/flight/plan...................................................................................................................... | 3596 msgs\n",
+ "/input/baro/alt................................................................................................................... | 601 msgs\n",
+ "/input/camera/raw................................................................................................................. | 499 msgs\n",
+ "/input/gps/fix.................................................................................................................... | 703 msgs\n",
+ "/input/imu/data................................................................................................................... | 499 msgs\n",
+ "/input/lidar/scan................................................................................................................. | 998 msgs\n",
+ "/input/operator/commands.......................................................................................................... | 798 msgs\n",
+ "/output/camera/mapped............................................................................................................. | 499 msgs\n",
+ "/output/classifier/classification................................................................................................. | 499 msgs\n",
+ "/output/flight/cmd................................................................................................................ | 3595 msgs\n",
+ "/output/telemetry/radio........................................................................................................... | 2302 msgs\n",
+ "/parameter_events................................................................................................................. | 16 msgs\n",
+ "/rosout........................................................................................................................... | 0 msgs\n",
+ "/sensors/fused.................................................................................................................... | 1803 msgs\n",
+ "/telemetry/data................................................................................................................... | 2302 msgs\n",
+ "\n",
+ "[DEBUG] INPUT TOPICS\n",
+ "--[DEBUG] ^/input/ :/input/baro/alt.......................................................................... | 601 msgs\n",
+ "--[DEBUG] ^/input/ :/input/camera/raw........................................................................ | 499 msgs\n",
+ "--[DEBUG] ^/input/ :/input/gps/fix........................................................................... | 703 msgs\n",
+ "--[DEBUG] ^/input/ :/input/imu/data.......................................................................... | 499 msgs\n",
+ "--[DEBUG] ^/input/ :/input/lidar/scan........................................................................ | 998 msgs\n",
+ "--[DEBUG] ^/input/ :/input/operator/commands................................................................. | 798 msgs\n",
+ "\n",
+ "[DEBUG] OUTPUT TOPICS\n",
+ "--[DEBUG] ^/output/ :/output/camera/mapped.................................................................... | 499 msgs\n",
+ "--[DEBUG] ^/output/ :/output/classifier/classification........................................................ | 499 msgs\n",
+ "--[DEBUG] ^/output/ :/output/flight/cmd....................................................................... | 3595 msgs\n",
+ "--[DEBUG] ^/output/ :/output/telemetry/radio.................................................................. | 2302 msgs\n"
+ ]
+ }
+ ],
"source": [
"##################################################\n",
"# Print (All/Input/Output) Topic Message Counts\n",
@@ -323,11 +413,43 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[CACHE] Cache disabled for lat_graph.\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Finding CB nodes: 100%|██████████| 133/133 [00:00<00:00, 299111.22it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[DEBUG] 96 callbacks have no owner, filtering them out.\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Processing node publications: 100%|██████████| 16/16 [00:00<00:00, 278.22it/s]\n",
+ "Processing CB subscriptions: 100%|██████████| 37/37 [00:00<00:00, 615.30it/s]\n",
+ "Building graph edges: 100%|██████████| 18/18 [00:00<00:00, 160975.42it/s]\n",
+ "Building graph nodes: 100%|██████████| 37/37 [00:00<00:00, 2422.60it/s]\n"
+ ]
+ }
+ ],
"source": [
"import latency_graph.latency_graph_structure as lg\n",
"\n",
@@ -351,11 +473,595 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 7,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Processing INPUT: 1\n",
+ " Processing OUTPUT: 1\n",
+ " Processing input_camera_node: 2\n",
+ " Processing debayer_node: 2\n",
+ " Processing radiometric_node: 2\n",
+ " Processing geometric_node: 2\n",
+ " Processing output_mapping_node: 2\n",
+ " Processing output_smoke_classifier_node: 2\n",
+ " Processing input_gps_node: 2\n",
+ " Processing input_imu_node: 2\n",
+ " Processing input_baro_node: 2\n",
+ " Processing sensor_fusion_node: 4\n",
+ " Processing input_lidar_node: 2\n",
+ " Processing input_operator_cmd_node: 2\n",
+ " Processing flight_mgmt_node: 4\n",
+ " Processing output_flight_control_node: 2\n",
+ " Processing telemetry_node: 3\n",
+ " Processing output_radio_tx_node: 2\n"
+ ]
+ },
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"%%skip_if_false DFG_ENABLED\n",
"%%skip_if_false DFG_PLOT\n",
@@ -381,14 +1087,330 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 8,
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%%%skip_if_false DFG_ENABLED\n"
}
},
- "outputs": [],
+ "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",
+ "Input Nodes: /input_camera_node, /input_gps_node, /input_imu_node, /input_baro_node, /input_lidar_node, /input_operator_cmd_node\n",
+ "Output Nodes: /output_mapping_node, /output_smoke_classifier_node, /output_flight_control_node, /output_radio_tx_node\n",
+ "Intermediate Nodes: /INPUT, /OUTPUT, /input_camera_node, /debayer_node, /radiometric_node, /geometric_node, /output_mapping_node, /output_smoke_classifier_node, /input_gps_node, /input_imu_node, /input_baro_node, /sensor_fusion_node, /input_lidar_node, /input_operator_cmd_node, /flight_mgmt_node, /output_flight_control_node, /telemetry_node, /output_radio_tx_node\n",
+ "/input_lidar_node /flight_mgmt_node 1\n",
+ "/input_gps_node /sensor_fusion_node 1\n",
+ "/input_operator_cmd_node /flight_mgmt_node 1\n",
+ "/debayer_node /radiometric_node 1\n",
+ "/radiometric_node /geometric_node 1\n",
+ "/radiometric_node /output_smoke_classifier_node 1\n",
+ "/input_baro_node /sensor_fusion_node 1\n",
+ "/flight_mgmt_node /output_flight_control_node 3\n",
+ "/input_camera_node /debayer_node 1\n",
+ "/output_mapping_node /telemetry_node 1\n",
+ "/telemetry_node /output_radio_tx_node 2\n",
+ "/sensor_fusion_node /telemetry_node 3\n",
+ "/sensor_fusion_node /flight_mgmt_node 3\n",
+ "/input_imu_node /sensor_fusion_node 1\n",
+ "/geometric_node /output_mapping_node 1\n"
+ ]
+ },
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"%%skip_if_false DFG_ENABLED\n",
"%%skip_if_false DFG_PLOT\n",
@@ -400,6 +1422,11 @@
"\n",
"from latency_graph.latency_graph_plots import plot_latency_graph_overview\n",
"\n",
+ "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",
"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\"))"
]
},
@@ -415,11 +1442,88 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 9,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Found 4 end topics for E2E latency calculations: /output/telemetry/radio, /output/camera/mapped, /output/classifier/classification, /output/flight/cmd\n",
+ "Using 133 callback objects, 20311 callback instances, and 20207 publish instances for E2E latency calculations.\n",
+ "[CACHE] Cache disabled for trees.\n",
+ "=====/output/telemetry/radio\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Processing output messages: 100%|██████████| 2302/2302 [00:11<00:00, 203.94it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Found 2302 trees for topic /output/telemetry/radio\n",
+ "=====/output/camera/mapped\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Processing output messages: 100%|██████████| 499/499 [00:00<00:00, 7355.95it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Found 499 trees for topic /output/camera/mapped\n",
+ "=====/output/classifier/classification\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Processing output messages: 100%|██████████| 499/499 [00:00<00:00, 1005.12it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Found 499 trees for topic /output/classifier/classification\n",
+ "=====/output/flight/cmd\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Processing output messages: 100%|██████████| 3595/3595 [00:09<00:00, 360.81it/s]"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Found 3595 trees for topic /output/flight/cmd\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "\n"
+ ]
+ }
+ ],
"source": [
"%%skip_if_false E2E_ENABLED\n",
"\n",
@@ -427,8 +1531,13 @@
"\n",
"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",
+ "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",
"def _build_dep_trees():\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",
+ " 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",
"\n",
"try:\n",
" trees = cached(\"trees\", _build_dep_trees, [TR_PATH], not CACHING_ENABLED)\n",
@@ -440,11 +1549,22 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 10,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'Skipped (evaluated BW_ENABLED to False)'"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"%%skip_if_false E2E_ENABLED\n",
"%%skip_if_false BW_ENABLED\n",
@@ -463,33 +1583,164474 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 11,
"metadata": {
"collapsed": false
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Dependency Trees:\n",
+ "\n",
+ "Tree 1/6895:\n",
+ "Publish Instance: /output/telemetry/radio\n",
+ "Callback Instance: RadioNode::RadioNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /telemetry/data\n",
+ " Callback Instance: TelemetryNode::TelemetryNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /sensors/fused\n",
+ " Callback Instance: FusionNode::FusionNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /input/gps/fix\n",
+ " Callback Instance: GPSNode::GPSNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda()#1}\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ "\n",
+ "Tree 2/6895:\n",
+ "Publish Instance: /output/telemetry/radio\n",
+ "Callback Instance: RadioNode::RadioNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /telemetry/data\n",
+ " Callback Instance: TelemetryNode::TelemetryNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /sensors/fused\n",
+ " Callback Instance: FusionNode::FusionNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /input/baro/alt\n",
+ " Callback Instance: BaroNode::BaroNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda()#1}\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ "\n",
+ "Tree 3/6895:\n",
+ "Publish Instance: /output/telemetry/radio\n",
+ "Callback Instance: RadioNode::RadioNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /telemetry/data\n",
+ " Callback Instance: TelemetryNode::TelemetryNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /output/camera/mapped\n",
+ " Callback Instance: MappingNode::MappingNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /camera/geometric\n",
+ " Callback Instance: GeometricNode::GeometricNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /camera/radiometric\n",
+ " Callback Instance: RadiometricNode::RadiometricNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /camera/debayered\n",
+ " Callback Instance: DebayerNode::DebayerNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /input/camera/raw\n",
+ " Callback Instance: CameraNode::CameraNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda()#1}\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ "\n",
+ "Tree 4/6895:\n",
+ "Publish Instance: /output/telemetry/radio\n",
+ "Callback Instance: RadioNode::RadioNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /telemetry/data\n",
+ " Callback Instance: TelemetryNode::TelemetryNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /sensors/fused\n",
+ " Callback Instance: FusionNode::FusionNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /input/imu/data\n",
+ " Callback Instance: IMUNode::IMUNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda()#1}\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ "\n",
+ "Tree 5/6895:\n",
+ "Publish Instance: /output/telemetry/radio\n",
+ "Callback Instance: RadioNode::RadioNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /telemetry/data\n",
+ " Callback Instance: TelemetryNode::TelemetryNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /sensors/fused\n",
+ " Callback Instance: FusionNode::FusionNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /input/gps/fix\n",
+ " Callback Instance: GPSNode::GPSNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda()#1}\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ "\n",
+ "Tree 6/6895:\n",
+ "Publish Instance: /output/telemetry/radio\n",
+ "Callback Instance: RadioNode::RadioNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /telemetry/data\n",
+ " Callback Instance: TelemetryNode::TelemetryNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /sensors/fused\n",
+ " Callback Instance: FusionNode::FusionNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /input/baro/alt\n",
+ " Callback Instance: BaroNode::BaroNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda()#1}\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ " Callback Instance: std::_Bind))(std::shared_ptr > >)>\n",
+ "\n",
+ "Tree 7/6895:\n",
+ "Publish Instance: /output/telemetry/radio\n",
+ "Callback Instance: RadioNode::RadioNode(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /telemetry/data\n",
+ " Callback Instance: TelemetryNode::TelemetryNode(std::__cxx11::basic_string, std::allocator > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::__cxx11::basic_string, std::allocator > const&, int, double)::{lambda(std::shared_ptr > >)#1}\n",
+ " Publish Instance: /output/camera/mapped\n",
+ " Callback Instance: MappingNode::MappingNode(std::__cxx11::basic_string, std::allocator