Merge branch '19-update-after-tracepoint-to-fix-new-intra-process-communication' into 'master'
Resolve "Update after tracepoint to fix new intra-process communication" Closes #19 See merge request micro-ROS/ros_tracing/tracetools_analysis!28
This commit is contained in:
commit
f16fa313a5
4 changed files with 152 additions and 63 deletions
Binary file not shown.
|
@ -56,6 +56,10 @@ class RosDataModel(DataModel):
|
||||||
'topic_name',
|
'topic_name',
|
||||||
'depth'])
|
'depth'])
|
||||||
self.subscriptions.set_index(['subscription_handle'], inplace=True, drop=True)
|
self.subscriptions.set_index(['subscription_handle'], inplace=True, drop=True)
|
||||||
|
self.subscription_objects = pd.DataFrame(columns=['subscription',
|
||||||
|
'timestamp',
|
||||||
|
'subscription_handle'])
|
||||||
|
self.subscription_objects.set_index(['subscription'], inplace=True, drop=True)
|
||||||
self.services = pd.DataFrame(columns=['service_handle',
|
self.services = pd.DataFrame(columns=['service_handle',
|
||||||
'timestamp',
|
'timestamp',
|
||||||
'node_handle',
|
'node_handle',
|
||||||
|
@ -74,10 +78,10 @@ class RosDataModel(DataModel):
|
||||||
'tid'])
|
'tid'])
|
||||||
self.timers.set_index(['timer_handle'], inplace=True, drop=True)
|
self.timers.set_index(['timer_handle'], inplace=True, drop=True)
|
||||||
|
|
||||||
self.callback_objects = pd.DataFrame(columns=['handle',
|
self.callback_objects = pd.DataFrame(columns=['reference',
|
||||||
'timestamp',
|
'timestamp',
|
||||||
'callback_object'])
|
'callback_object'])
|
||||||
self.callback_objects.set_index(['handle'], inplace=True, drop=True)
|
self.callback_objects.set_index(['reference'], inplace=True, drop=True)
|
||||||
self.callback_symbols = pd.DataFrame(columns=['callback_object',
|
self.callback_symbols = pd.DataFrame(columns=['callback_object',
|
||||||
'timestamp',
|
'timestamp',
|
||||||
'symbol'])
|
'symbol'])
|
||||||
|
@ -104,11 +108,16 @@ class RosDataModel(DataModel):
|
||||||
) -> None:
|
) -> None:
|
||||||
self.publishers.loc[handle] = [timestamp, node_handle, rmw_handle, topic_name, depth]
|
self.publishers.loc[handle] = [timestamp, node_handle, rmw_handle, topic_name, depth]
|
||||||
|
|
||||||
def add_subscription(
|
def add_rcl_subscription(
|
||||||
self, handle, timestamp, node_handle, rmw_handle, topic_name, depth
|
self, handle, timestamp, node_handle, rmw_handle, topic_name, depth
|
||||||
) -> None:
|
) -> None:
|
||||||
self.subscriptions.loc[handle] = [timestamp, node_handle, rmw_handle, topic_name, depth]
|
self.subscriptions.loc[handle] = [timestamp, node_handle, rmw_handle, topic_name, depth]
|
||||||
|
|
||||||
|
def add_rclcpp_subscription(
|
||||||
|
self, subscription_pointer, timestamp, subscription_handle
|
||||||
|
) -> None:
|
||||||
|
self.subscription_objects.loc[subscription_pointer] = [timestamp, subscription_handle]
|
||||||
|
|
||||||
def add_service(
|
def add_service(
|
||||||
self, handle, timestamp, node_handle, rmw_handle, service_name
|
self, handle, timestamp, node_handle, rmw_handle, service_name
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -125,9 +134,9 @@ class RosDataModel(DataModel):
|
||||||
self.timers.loc[handle] = [timestamp, period, tid]
|
self.timers.loc[handle] = [timestamp, period, tid]
|
||||||
|
|
||||||
def add_callback_object(
|
def add_callback_object(
|
||||||
self, handle, timestamp, callback_object
|
self, reference, timestamp, callback_object
|
||||||
) -> None:
|
) -> None:
|
||||||
self.callback_objects.loc[handle] = [timestamp, callback_object]
|
self.callback_objects.loc[reference] = [timestamp, callback_object]
|
||||||
|
|
||||||
def add_callback_symbol(
|
def add_callback_symbol(
|
||||||
self, callback_object, timestamp, symbol
|
self, callback_object, timestamp, symbol
|
||||||
|
@ -156,6 +165,8 @@ class RosDataModel(DataModel):
|
||||||
print()
|
print()
|
||||||
print(f'Subscriptions:\n{self.subscriptions.to_string()}')
|
print(f'Subscriptions:\n{self.subscriptions.to_string()}')
|
||||||
print()
|
print()
|
||||||
|
print(f'Subscription objects:\n{self.subscription_objects.to_string()}')
|
||||||
|
print()
|
||||||
print(f'Services:\n{self.services.to_string()}')
|
print(f'Services:\n{self.services.to_string()}')
|
||||||
print()
|
print()
|
||||||
print(f'Clients:\n{self.clients.to_string()}')
|
print(f'Clients:\n{self.clients.to_string()}')
|
||||||
|
|
|
@ -43,7 +43,9 @@ class Ros2Handler(EventHandler):
|
||||||
'ros2:rcl_publisher_init':
|
'ros2:rcl_publisher_init':
|
||||||
self._handle_rcl_publisher_init,
|
self._handle_rcl_publisher_init,
|
||||||
'ros2:rcl_subscription_init':
|
'ros2:rcl_subscription_init':
|
||||||
self._handle_subscription_init,
|
self._handle_rcl_subscription_init,
|
||||||
|
'ros2:rclcpp_subscription_init':
|
||||||
|
self._handle_rclcpp_subscription_init,
|
||||||
'ros2:rclcpp_subscription_callback_added':
|
'ros2:rclcpp_subscription_callback_added':
|
||||||
self._handle_rclcpp_subscription_callback_added,
|
self._handle_rclcpp_subscription_callback_added,
|
||||||
'ros2:rcl_service_init':
|
'ros2:rcl_service_init':
|
||||||
|
@ -78,7 +80,7 @@ class Ros2Handler(EventHandler):
|
||||||
return self._data_model
|
return self._data_model
|
||||||
|
|
||||||
def _handle_rcl_init(
|
def _handle_rcl_init(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
context_handle = get_field(event, 'context_handle')
|
context_handle = get_field(event, 'context_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -87,7 +89,7 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_context(context_handle, timestamp, pid, version)
|
self.data.add_context(context_handle, timestamp, pid, version)
|
||||||
|
|
||||||
def _handle_rcl_node_init(
|
def _handle_rcl_node_init(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'node_handle')
|
handle = get_field(event, 'node_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -98,7 +100,7 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_node(handle, timestamp, tid, rmw_handle, name, namespace)
|
self.data.add_node(handle, timestamp, tid, rmw_handle, name, namespace)
|
||||||
|
|
||||||
def _handle_rcl_publisher_init(
|
def _handle_rcl_publisher_init(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'publisher_handle')
|
handle = get_field(event, 'publisher_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -108,8 +110,8 @@ class Ros2Handler(EventHandler):
|
||||||
depth = get_field(event, 'queue_depth')
|
depth = get_field(event, 'queue_depth')
|
||||||
self.data.add_publisher(handle, timestamp, node_handle, rmw_handle, topic_name, depth)
|
self.data.add_publisher(handle, timestamp, node_handle, rmw_handle, topic_name, depth)
|
||||||
|
|
||||||
def _handle_subscription_init(
|
def _handle_rcl_subscription_init(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'subscription_handle')
|
handle = get_field(event, 'subscription_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -117,18 +119,28 @@ class Ros2Handler(EventHandler):
|
||||||
rmw_handle = get_field(event, 'rmw_subscription_handle')
|
rmw_handle = get_field(event, 'rmw_subscription_handle')
|
||||||
topic_name = get_field(event, 'topic_name')
|
topic_name = get_field(event, 'topic_name')
|
||||||
depth = get_field(event, 'queue_depth')
|
depth = get_field(event, 'queue_depth')
|
||||||
self.data.add_subscription(handle, timestamp, node_handle, rmw_handle, topic_name, depth)
|
self.data.add_rcl_subscription(
|
||||||
|
handle, timestamp, node_handle, rmw_handle, topic_name, depth,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _handle_rclcpp_subscription_init(
|
||||||
|
self, event: Dict, metadata: EventMetadata,
|
||||||
|
) -> None:
|
||||||
|
subscription_pointer = get_field(event, 'subscription')
|
||||||
|
timestamp = metadata.timestamp
|
||||||
|
handle = get_field(event, 'subscription_handle')
|
||||||
|
self.data.add_rclcpp_subscription(subscription_pointer, timestamp, handle)
|
||||||
|
|
||||||
def _handle_rclcpp_subscription_callback_added(
|
def _handle_rclcpp_subscription_callback_added(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'subscription_handle')
|
subscription_pointer = get_field(event, 'subscription')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
callback_object = get_field(event, 'callback')
|
callback_object = get_field(event, 'callback')
|
||||||
self.data.add_callback_object(handle, timestamp, callback_object)
|
self.data.add_callback_object(subscription_pointer, timestamp, callback_object)
|
||||||
|
|
||||||
def _handle_rcl_service_init(
|
def _handle_rcl_service_init(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'service_handle')
|
handle = get_field(event, 'service_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -138,7 +150,7 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_service(handle, timestamp, node_handle, rmw_handle, service_name)
|
self.data.add_service(handle, timestamp, node_handle, rmw_handle, service_name)
|
||||||
|
|
||||||
def _handle_rclcpp_service_callback_added(
|
def _handle_rclcpp_service_callback_added(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'service_handle')
|
handle = get_field(event, 'service_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -146,7 +158,7 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_callback_object(handle, timestamp, callback_object)
|
self.data.add_callback_object(handle, timestamp, callback_object)
|
||||||
|
|
||||||
def _handle_rcl_client_init(
|
def _handle_rcl_client_init(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'client_handle')
|
handle = get_field(event, 'client_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -156,7 +168,7 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_client(handle, timestamp, node_handle, rmw_handle, service_name)
|
self.data.add_client(handle, timestamp, node_handle, rmw_handle, service_name)
|
||||||
|
|
||||||
def _handle_rcl_timer_init(
|
def _handle_rcl_timer_init(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'timer_handle')
|
handle = get_field(event, 'timer_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -165,7 +177,7 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_timer(handle, timestamp, period, tid)
|
self.data.add_timer(handle, timestamp, period, tid)
|
||||||
|
|
||||||
def _handle_rclcpp_timer_callback_added(
|
def _handle_rclcpp_timer_callback_added(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
handle = get_field(event, 'timer_handle')
|
handle = get_field(event, 'timer_handle')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -173,7 +185,7 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_callback_object(handle, timestamp, callback_object)
|
self.data.add_callback_object(handle, timestamp, callback_object)
|
||||||
|
|
||||||
def _handle_rclcpp_callback_register(
|
def _handle_rclcpp_callback_register(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
callback_object = get_field(event, 'callback')
|
callback_object = get_field(event, 'callback')
|
||||||
timestamp = metadata.timestamp
|
timestamp = metadata.timestamp
|
||||||
|
@ -181,14 +193,14 @@ class Ros2Handler(EventHandler):
|
||||||
self.data.add_callback_symbol(callback_object, timestamp, symbol)
|
self.data.add_callback_symbol(callback_object, timestamp, symbol)
|
||||||
|
|
||||||
def _handle_callback_start(
|
def _handle_callback_start(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
# Add to dict
|
# Add to dict
|
||||||
callback_addr = get_field(event, 'callback')
|
callback_addr = get_field(event, 'callback')
|
||||||
self._callback_instances[callback_addr] = (event, metadata)
|
self._callback_instances[callback_addr] = (event, metadata)
|
||||||
|
|
||||||
def _handle_callback_end(
|
def _handle_callback_end(
|
||||||
self, event: Dict, metadata: EventMetadata
|
self, event: Dict, metadata: EventMetadata,
|
||||||
) -> None:
|
) -> None:
|
||||||
# Fetch from dict
|
# Fetch from dict
|
||||||
callback_object = get_field(event, 'callback')
|
callback_object = get_field(event, 'callback')
|
||||||
|
|
|
@ -38,7 +38,10 @@ class DataModelUtil():
|
||||||
This class provides basic util functions.
|
This class provides basic util functions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, data_model: DataModel) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
data_model: DataModel,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Constructor.
|
Constructor.
|
||||||
|
|
||||||
|
@ -105,7 +108,10 @@ class DataModelUtil():
|
||||||
class ProfileDataModelUtil(DataModelUtil):
|
class ProfileDataModelUtil(DataModelUtil):
|
||||||
"""Profiling data model utility class."""
|
"""Profiling data model utility class."""
|
||||||
|
|
||||||
def __init__(self, data_model: ProfileDataModel) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
data_model: ProfileDataModel,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Constructor.
|
Constructor.
|
||||||
|
|
||||||
|
@ -113,14 +119,20 @@ class ProfileDataModelUtil(DataModelUtil):
|
||||||
"""
|
"""
|
||||||
super().__init__(data_model)
|
super().__init__(data_model)
|
||||||
|
|
||||||
def with_tid(self, tid: int) -> DataFrame:
|
def with_tid(
|
||||||
|
self,
|
||||||
|
tid: int,
|
||||||
|
) -> DataFrame:
|
||||||
return self.data.times.loc[self.data.times['tid'] == tid]
|
return self.data.times.loc[self.data.times['tid'] == tid]
|
||||||
|
|
||||||
def get_tids(self) -> Set[int]:
|
def get_tids(self) -> Set[int]:
|
||||||
"""Get the TIDs in the data model."""
|
"""Get the TIDs in the data model."""
|
||||||
return set(self.data.times['tid'])
|
return set(self.data.times['tid'])
|
||||||
|
|
||||||
def get_call_tree(self, tid: int) -> Dict[str, List[str]]:
|
def get_call_tree(
|
||||||
|
self,
|
||||||
|
tid: int,
|
||||||
|
) -> Dict[str, List[str]]:
|
||||||
depth_names = self.with_tid(tid)[
|
depth_names = self.with_tid(tid)[
|
||||||
['depth', 'function_name', 'parent_name']
|
['depth', 'function_name', 'parent_name']
|
||||||
].drop_duplicates()
|
].drop_duplicates()
|
||||||
|
@ -136,7 +148,10 @@ class ProfileDataModelUtil(DataModelUtil):
|
||||||
tree[parent].add(name)
|
tree[parent].add(name)
|
||||||
return dict(tree)
|
return dict(tree)
|
||||||
|
|
||||||
def get_function_duration_data(self, tid: int) -> List[Dict[str, Union[int, str, DataFrame]]]:
|
def get_function_duration_data(
|
||||||
|
self,
|
||||||
|
tid: int,
|
||||||
|
) -> List[Dict[str, Union[int, str, DataFrame]]]:
|
||||||
"""Get duration data for each function."""
|
"""Get duration data for each function."""
|
||||||
tid_df = self.with_tid(tid)
|
tid_df = self.with_tid(tid)
|
||||||
depth_names = tid_df[['depth', 'function_name', 'parent_name']].drop_duplicates()
|
depth_names = tid_df[['depth', 'function_name', 'parent_name']].drop_duplicates()
|
||||||
|
@ -167,7 +182,10 @@ class ProfileDataModelUtil(DataModelUtil):
|
||||||
class CpuTimeDataModelUtil(DataModelUtil):
|
class CpuTimeDataModelUtil(DataModelUtil):
|
||||||
"""CPU time data model utility class."""
|
"""CPU time data model utility class."""
|
||||||
|
|
||||||
def __init__(self, data_model: CpuTimeDataModel) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
data_model: CpuTimeDataModel,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Constructor.
|
Constructor.
|
||||||
|
|
||||||
|
@ -183,7 +201,10 @@ class CpuTimeDataModelUtil(DataModelUtil):
|
||||||
class RosDataModelUtil(DataModelUtil):
|
class RosDataModelUtil(DataModelUtil):
|
||||||
"""ROS data model utility class."""
|
"""ROS data model utility class."""
|
||||||
|
|
||||||
def __init__(self, data_model: RosDataModel) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
data_model: RosDataModel,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Constructor.
|
Constructor.
|
||||||
|
|
||||||
|
@ -191,7 +212,10 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
"""
|
"""
|
||||||
super().__init__(data_model)
|
super().__init__(data_model)
|
||||||
|
|
||||||
def _prettify(self, original: str) -> str:
|
def _prettify(
|
||||||
|
self,
|
||||||
|
original: str,
|
||||||
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Process symbol to make it more readable.
|
Process symbol to make it more readable.
|
||||||
|
|
||||||
|
@ -263,7 +287,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_callback_durations(
|
def get_callback_durations(
|
||||||
self, callback_obj: int
|
self,
|
||||||
|
callback_obj: int,
|
||||||
) -> DataFrame:
|
) -> DataFrame:
|
||||||
"""
|
"""
|
||||||
Get durations of callback instances for a given callback object.
|
Get durations of callback instances for a given callback object.
|
||||||
|
@ -280,7 +305,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
return self.convert_time_columns(data, ['duration'], ['timestamp'])
|
return self.convert_time_columns(data, ['duration'], ['timestamp'])
|
||||||
|
|
||||||
def get_node_tid_from_name(
|
def get_node_tid_from_name(
|
||||||
self, node_name: str
|
self,
|
||||||
|
node_name: str,
|
||||||
) -> Union[int, None]:
|
) -> Union[int, None]:
|
||||||
"""
|
"""
|
||||||
Get the tid corresponding to a node.
|
Get the tid corresponding to a node.
|
||||||
|
@ -296,7 +322,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
return node_row.iloc[0]['tid'] if not node_row.empty else None
|
return node_row.iloc[0]['tid'] if not node_row.empty else None
|
||||||
|
|
||||||
def get_node_names_from_tid(
|
def get_node_names_from_tid(
|
||||||
self, tid: str
|
self,
|
||||||
|
tid: str,
|
||||||
) -> Union[List[str], None]:
|
) -> Union[List[str], None]:
|
||||||
"""
|
"""
|
||||||
Get the list of node names corresponding to a tid.
|
Get the list of node names corresponding to a tid.
|
||||||
|
@ -309,7 +336,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
]['name'].tolist()
|
]['name'].tolist()
|
||||||
|
|
||||||
def get_callback_owner_info(
|
def get_callback_owner_info(
|
||||||
self, callback_obj: int
|
self,
|
||||||
|
callback_obj: int,
|
||||||
) -> Union[str, None]:
|
) -> Union[str, None]:
|
||||||
"""
|
"""
|
||||||
Get information about the owner of a callback.
|
Get information about the owner of a callback.
|
||||||
|
@ -322,36 +350,37 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
:param callback_obj: the callback object value
|
:param callback_obj: the callback object value
|
||||||
:return: information about the owner of the callback, or `None` if it fails
|
:return: information about the owner of the callback, or `None` if it fails
|
||||||
"""
|
"""
|
||||||
# Get handle corresponding to callback object
|
# Get reference corresponding to callback object
|
||||||
handle = self.data.callback_objects.loc[
|
reference = self.data.callback_objects.loc[
|
||||||
self.data.callback_objects['callback_object'] == callback_obj
|
self.data.callback_objects['callback_object'] == callback_obj
|
||||||
].index.values.astype(int)[0]
|
].index.values.astype(int)[0]
|
||||||
|
|
||||||
type_name = None
|
type_name = None
|
||||||
info = None
|
info = None
|
||||||
# Check if it's a timer first (since it's slightly different than the others)
|
# Check if it's a timer first (since it's slightly different than the others)
|
||||||
if handle in self.data.timers.index:
|
if reference in self.data.timers.index:
|
||||||
type_name = 'Timer'
|
type_name = 'Timer'
|
||||||
info = self.get_timer_handle_info(handle)
|
info = self.get_timer_handle_info(reference)
|
||||||
elif handle in self.data.publishers.index:
|
elif reference in self.data.publishers.index:
|
||||||
type_name = 'Publisher'
|
type_name = 'Publisher'
|
||||||
info = self.get_publisher_handle_info(handle)
|
info = self.get_publisher_handle_info(reference)
|
||||||
elif handle in self.data.subscriptions.index:
|
elif reference in self.data.subscription_objects.index:
|
||||||
type_name = 'Subscription'
|
type_name = 'Subscription'
|
||||||
info = self.get_subscription_handle_info(handle)
|
info = self.get_subscription_reference_info(reference)
|
||||||
elif handle in self.data.services.index:
|
elif reference in self.data.services.index:
|
||||||
type_name = 'Service'
|
type_name = 'Service'
|
||||||
info = self.get_subscription_handle_info(handle)
|
info = self.get_service_handle_info(reference)
|
||||||
elif handle in self.data.clients.index:
|
elif reference in self.data.clients.index:
|
||||||
type_name = 'Client'
|
type_name = 'Client'
|
||||||
info = self.get_client_handle_info(handle)
|
info = self.get_client_handle_info(reference)
|
||||||
|
|
||||||
if info is not None:
|
if info is not None:
|
||||||
info = f'{type_name} -- {self.format_info_dict(info)}'
|
info = f'{type_name} -- {self.format_info_dict(info)}'
|
||||||
return info
|
return info
|
||||||
|
|
||||||
def get_timer_handle_info(
|
def get_timer_handle_info(
|
||||||
self, timer_handle: int
|
self,
|
||||||
|
timer_handle: int,
|
||||||
) -> Union[Mapping[str, Any], None]:
|
) -> Union[Mapping[str, Any], None]:
|
||||||
"""
|
"""
|
||||||
Get information about the owner of a timer.
|
Get information about the owner of a timer.
|
||||||
|
@ -369,7 +398,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
return {'tid': tid, 'period': f'{period_ms:.0f} ms'}
|
return {'tid': tid, 'period': f'{period_ms:.0f} ms'}
|
||||||
|
|
||||||
def get_publisher_handle_info(
|
def get_publisher_handle_info(
|
||||||
self, publisher_handle: int
|
self,
|
||||||
|
publisher_handle: int,
|
||||||
) -> Union[Mapping[str, Any], None]:
|
) -> Union[Mapping[str, Any], None]:
|
||||||
"""
|
"""
|
||||||
Get information about a publisher handle.
|
Get information about a publisher handle.
|
||||||
|
@ -386,30 +416,61 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
publisher_info = {'topic': topic_name}
|
publisher_info = {'topic': topic_name}
|
||||||
return {**node_handle_info, **publisher_info}
|
return {**node_handle_info, **publisher_info}
|
||||||
|
|
||||||
def get_subscription_handle_info(
|
def get_subscription_reference_info(
|
||||||
self, subscription_handle: int
|
self,
|
||||||
|
subscription_reference: int,
|
||||||
) -> Union[Mapping[str, Any], None]:
|
) -> Union[Mapping[str, Any], None]:
|
||||||
"""
|
"""
|
||||||
Get information about a subscription handle.
|
Get information about a subscription handle.
|
||||||
|
|
||||||
:param subscription_handle: the subscription handle value
|
:param subscription_reference: the subscription reference value
|
||||||
:return: a dictionary with name:value info, or `None` if it fails
|
:return: a dictionary with name:value info, or `None` if it fails
|
||||||
"""
|
"""
|
||||||
subscriptions_info = self.data.subscriptions.merge(
|
# First check that the subscription reference exists
|
||||||
self.data.nodes,
|
if subscription_reference not in self.data.subscription_objects.index:
|
||||||
left_on='node_handle',
|
|
||||||
right_index=True)
|
|
||||||
if subscription_handle not in self.data.subscriptions.index:
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
node_handle = subscriptions_info.loc[subscription_handle, 'node_handle']
|
# To get information about a subscription reference, we need 3 dataframes
|
||||||
|
# * subscription_objects
|
||||||
|
# * subscription (reference) <--> subscription_handle
|
||||||
|
# * subscriptions
|
||||||
|
# * subscription_handle <--> topic_name
|
||||||
|
# * subscription_handle <--> node_handle
|
||||||
|
# * nodes
|
||||||
|
# * node_handle <--> (node info)
|
||||||
|
# First, drop unnecessary common columns for debugging simplicity
|
||||||
|
subscription_objects_simple = self.data.subscription_objects.drop(
|
||||||
|
columns=['timestamp'],
|
||||||
|
axis=1,
|
||||||
|
)
|
||||||
|
subscriptions_simple = self.data.subscriptions.drop(
|
||||||
|
columns=['timestamp', 'rmw_handle'],
|
||||||
|
inplace=False,
|
||||||
|
)
|
||||||
|
nodes_simple = self.data.nodes.drop(
|
||||||
|
columns=['timestamp', 'rmw_handle'],
|
||||||
|
inplace=False,
|
||||||
|
)
|
||||||
|
# Then merge the 3 dataframes
|
||||||
|
subscriptions_info = subscription_objects_simple.merge(
|
||||||
|
subscriptions_simple,
|
||||||
|
left_on='subscription_handle',
|
||||||
|
right_index=True,
|
||||||
|
).merge(
|
||||||
|
nodes_simple,
|
||||||
|
left_on='node_handle',
|
||||||
|
right_index=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
node_handle = subscriptions_info.loc[subscription_reference, 'node_handle']
|
||||||
node_handle_info = self.get_node_handle_info(node_handle)
|
node_handle_info = self.get_node_handle_info(node_handle)
|
||||||
topic_name = subscriptions_info.loc[subscription_handle, 'topic_name']
|
topic_name = subscriptions_info.loc[subscription_reference, 'topic_name']
|
||||||
subscription_info = {'topic': topic_name}
|
subscription_info = {'topic': topic_name}
|
||||||
return {**node_handle_info, **subscription_info}
|
return {**node_handle_info, **subscription_info}
|
||||||
|
|
||||||
def get_service_handle_info(
|
def get_service_handle_info(
|
||||||
self, service_handle: int
|
self,
|
||||||
|
service_handle: int,
|
||||||
) -> Union[Mapping[str, Any], None]:
|
) -> Union[Mapping[str, Any], None]:
|
||||||
"""
|
"""
|
||||||
Get information about a service handle.
|
Get information about a service handle.
|
||||||
|
@ -427,7 +488,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
return {**node_handle_info, **service_info}
|
return {**node_handle_info, **service_info}
|
||||||
|
|
||||||
def get_client_handle_info(
|
def get_client_handle_info(
|
||||||
self, client_handle: int
|
self,
|
||||||
|
client_handle: int,
|
||||||
) -> Union[Mapping[str, Any], None]:
|
) -> Union[Mapping[str, Any], None]:
|
||||||
"""
|
"""
|
||||||
Get information about a client handle.
|
Get information about a client handle.
|
||||||
|
@ -445,7 +507,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
return {**node_handle_info, **service_info}
|
return {**node_handle_info, **service_info}
|
||||||
|
|
||||||
def get_node_handle_info(
|
def get_node_handle_info(
|
||||||
self, node_handle: int
|
self,
|
||||||
|
node_handle: int,
|
||||||
) -> Union[Mapping[str, Any], None]:
|
) -> Union[Mapping[str, Any], None]:
|
||||||
"""
|
"""
|
||||||
Get information about a node handle.
|
Get information about a node handle.
|
||||||
|
@ -460,5 +523,8 @@ class RosDataModelUtil(DataModelUtil):
|
||||||
tid = self.data.nodes.loc[node_handle, 'tid']
|
tid = self.data.nodes.loc[node_handle, 'tid']
|
||||||
return {'node': node_name, 'tid': tid}
|
return {'node': node_name, 'tid': tid}
|
||||||
|
|
||||||
def format_info_dict(self, info_dict: Mapping[str, Any]) -> str:
|
def format_info_dict(
|
||||||
|
self,
|
||||||
|
info_dict: Mapping[str, Any],
|
||||||
|
) -> str:
|
||||||
return ', '.join([f'{key}: {val}' for key, val in info_dict.items()])
|
return ', '.join([f'{key}: {val}' for key, val in info_dict.items()])
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue