Skip to content

Commit

Permalink
Creates PublisherHandle and updates publisher.py (#1310)
Browse files Browse the repository at this point in the history
* PublisherHandle

Signed-off-by: Michael Carlstrom <[email protected]>

* create-publisher more generic

Signed-off-by: Michael Carlstrom <[email protected]>

---------

Signed-off-by: Michael Carlstrom <[email protected]>
Signed-off-by: Shane Loretz <[email protected]>
Co-authored-by: Shane Loretz <[email protected]>
  • Loading branch information
InvincibleRMC and sloretz authored Aug 7, 2024
1 parent 35d494c commit d97669b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
2 changes: 1 addition & 1 deletion rclpy/rclpy/event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def __exit__(self, t, v, tb):
"""Mark event as not-in-use to allow destruction after waiting on it."""
self.__event.__exit__(t, v, tb)

def destroy(self):
def destroy(self) -> None:
self.__event.destroy_when_not_in_use()


Expand Down
6 changes: 5 additions & 1 deletion rclpy/rclpy/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@
NodeNameNonExistentError = _rclpy.NodeNameNonExistentError


class NodeHandle:
pass


class Node:
"""
A Node in the ROS graph.
Expand Down Expand Up @@ -1534,7 +1538,7 @@ def create_publisher(
callback_group: Optional[CallbackGroup] = None,
event_callbacks: Optional[PublisherEventCallbacks] = None,
qos_overriding_options: Optional[QoSOverridingOptions] = None,
publisher_class: Type[Publisher] = Publisher,
publisher_class: Type[Publisher[MsgT]] = Publisher[MsgT],
) -> Publisher[MsgT]:
"""
Create a new publisher.
Expand Down
44 changes: 38 additions & 6 deletions rclpy/rclpy/publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
# limitations under the License.

from types import TracebackType
from typing import Generic, List, Optional, Type, TypeVar, Union
from typing import Generic, List, Optional, Protocol, Type, TYPE_CHECKING, TypeVar, Union

from rclpy.callback_groups import CallbackGroup
from rclpy.duration import Duration
from rclpy.destroyable import DestroyableType
from rclpy.duration import Duration, DurationType
from rclpy.event_handler import EventHandler, PublisherEventCallbacks
from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy
from rclpy.qos import QoSProfile
Expand All @@ -25,12 +26,43 @@
# Left to support Legacy TypeVars.
MsgType = TypeVar('MsgType')

if TYPE_CHECKING:
from rclpy.node import NodeHandle


class PublisherHandle(DestroyableType, Protocol[MsgT]):

def __init__(self, arg0: 'NodeHandle', arg1: Type[MsgT], arg2: str, arg3: object) -> None:
"""Create PublisherHandle."""

@property
def pointer(self) -> int:
"""Get the address of the entity as an integer."""

def get_logger_name(self) -> str:
"""Get the name of the logger associated with the node of the publisher."""

def get_subscription_count(self) -> int:
"""Count subscribers from a publisher."""

def get_topic_name(self) -> str:
"""Retrieve the topic name from a Publisher."""

def publish(self, arg0: MsgT) -> None:
"""Publish a message."""

def publish_raw(self, arg0: bytes) -> None:
"""Publish a serialized message."""

def wait_for_all_acked(self, arg0: DurationType) -> bool:
"""Wait until all published message data is acknowledged."""


class Publisher(Generic[MsgT]):

def __init__(
self,
publisher_impl: _rclpy.Publisher,
publisher_impl: PublisherHandle[MsgT],
msg_type: Type[MsgT],
topic: str,
qos_profile: QoSProfile,
Expand Down Expand Up @@ -86,10 +118,10 @@ def topic_name(self) -> str:
return self.__publisher.get_topic_name()

@property
def handle(self):
def handle(self) -> PublisherHandle[MsgT]:
return self.__publisher

def destroy(self):
def destroy(self) -> None:
"""
Destroy a container for a ROS publisher.
Expand Down Expand Up @@ -130,7 +162,7 @@ def wait_for_all_acked(self, timeout: Duration = Duration(seconds=-1)) -> bool:
with self.handle:
return self.__publisher.wait_for_all_acked(timeout._duration_handle)

def __enter__(self) -> 'Publisher':
def __enter__(self) -> 'Publisher[MsgT]':
return self

def __exit__(
Expand Down
2 changes: 1 addition & 1 deletion rclpy/rclpy/type_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Msg(Protocol, metaclass=MsgMetaClass):
pass


MsgT = TypeVar('MsgT', bound=Msg)
MsgT = TypeVar('MsgT', bound=Msg, contravariant=True)

SrvRequestT = TypeVar('SrvRequestT', bound=Msg)
SrvResponseT = TypeVar('SrvResponseT', bound=Msg)
Expand Down

0 comments on commit d97669b

Please sign in to comment.