From ee5258f4a99c9df69e1a8b339b4a2ec71bb53ee6 Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Thu, 24 Dec 2020 09:11:26 -0500 Subject: [PATCH] Support instrumentation for linking a timer to a node Signed-off-by: Christophe Bedard --- .../tracetools_analysis/data_model/ros2.py | 13 ++++++++++++- .../tracetools_analysis/processor/ros2.py | 10 ++++++++++ .../tracetools_analysis/utils/ros2.py | 8 ++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/tracetools_analysis/tracetools_analysis/data_model/ros2.py b/tracetools_analysis/tracetools_analysis/data_model/ros2.py index 75f4c6f..28ebb22 100644 --- a/tracetools_analysis/tracetools_analysis/data_model/ros2.py +++ b/tracetools_analysis/tracetools_analysis/data_model/ros2.py @@ -78,6 +78,10 @@ class Ros2DataModel(DataModel): 'period', 'tid']) self.timers.set_index(['timer_handle'], inplace=True, drop=True) + self.timer_node_links = pd.DataFrame(columns=['timer_handle', + 'timestamp', + 'node_handle']) + self.timer_node_links.set_index(['timer_handle'], inplace=True, drop=True) self.callback_objects = pd.DataFrame(columns=['reference', 'timestamp', @@ -142,6 +146,11 @@ class Ros2DataModel(DataModel): ) -> None: self.timers.loc[handle] = [timestamp, period, tid] + def add_timer_node_link( + self, handle, timestamp, node_handle + ) -> None: + self.timer_node_links.loc[handle] = [timestamp, node_handle] + def add_callback_object( self, reference, timestamp, callback_object ) -> None: @@ -205,6 +214,9 @@ class Ros2DataModel(DataModel): print('Timers:') print(self.timers.to_string()) print() + print('Timer-node links:') + print(self.timer_node_links.to_string()) + print() print('Callback objects:') print(self.callback_objects.to_string()) print() @@ -215,7 +227,6 @@ class Ros2DataModel(DataModel): print(self.callback_instances.to_string()) print() print('Lifecycle state machines:') - print() print(self.lifecycle_state_machines.to_string()) print() print('Lifecycle transitions:') diff --git a/tracetools_analysis/tracetools_analysis/processor/ros2.py b/tracetools_analysis/tracetools_analysis/processor/ros2.py index d340e05..a37731c 100644 --- a/tracetools_analysis/tracetools_analysis/processor/ros2.py +++ b/tracetools_analysis/tracetools_analysis/processor/ros2.py @@ -63,6 +63,8 @@ class Ros2Handler(EventHandler): self._handle_rcl_timer_init, 'ros2:rclcpp_timer_callback_added': self._handle_rclcpp_timer_callback_added, + 'ros2:rclcpp_timer_link_node': + self._handle_rclcpp_timer_link_node, 'ros2:rclcpp_callback_register': self._handle_rclcpp_callback_register, 'ros2:callback_start': @@ -198,6 +200,14 @@ class Ros2Handler(EventHandler): callback_object = get_field(event, 'callback') self.data.add_callback_object(handle, timestamp, callback_object) + def _handle_rclcpp_timer_link_node( + self, event: Dict, metadata: EventMetadata, + ) -> None: + handle = get_field(event, 'timer_handle') + timestamp = metadata.timestamp + node_handle = get_field(event, 'node_handle') + self.data.add_timer_node_link(handle, timestamp, node_handle) + def _handle_rclcpp_callback_register( self, event: Dict, metadata: EventMetadata, ) -> None: diff --git a/tracetools_analysis/tracetools_analysis/utils/ros2.py b/tracetools_analysis/tracetools_analysis/utils/ros2.py index 761b3e5..1b2a902 100644 --- a/tracetools_analysis/tracetools_analysis/utils/ros2.py +++ b/tracetools_analysis/tracetools_analysis/utils/ros2.py @@ -228,14 +228,18 @@ class Ros2DataModelUtil(DataModelUtil): :param timer_handle: the timer handle value :return: a dictionary with name:value info, or `None` if it fails """ - # TODO find a way to link a timer to a specific node if timer_handle not in self.data.timers.index: return None + node_handle = self.data.timer_node_links.loc[timer_handle, 'node_handle'] + node_handle_info = self.get_node_handle_info(node_handle) + if node_handle_info is None: + return None + tid = self.data.timers.loc[timer_handle, 'tid'] period_ns = self.data.timers.loc[timer_handle, 'period'] period_ms = period_ns / 1000000.0 - return {'tid': tid, 'period': f'{period_ms:.0f} ms'} + return {**node_handle_info, 'tid': tid, 'period': f'{period_ms:.0f} ms'} def get_publisher_handle_info( self,