Skip to content

Commit

Permalink
Expose the assert_liveliness API for Publishers and Nodes
Browse files Browse the repository at this point in the history
Signed-off-by: Emerson Knapp <eknapp@amazon.com>
  • Loading branch information
Emerson Knapp committed May 3, 2019
1 parent 63cbc5f commit dc6f263
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
10 changes: 10 additions & 0 deletions rclpy/rclpy/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,3 +835,13 @@ def count_subscribers(self, topic_name: str) -> int:
:return: the number of subscribers on the topic.
"""
return self._count_publishers_or_subscribers(topic_name, _rclpy.rclpy_count_subscribers)

def assert_liveliness(self) -> None:
"""
Manually assert that this Node is alive.
If the QoS Liveliness policy is set to RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE, the
application must call this at least as often as ``QoSProfile.liveliness_lease_duration``.
"""
_rclpy.rclpy_assert_liveliness(self.node_handle)

9 changes: 9 additions & 0 deletions rclpy/rclpy/publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,12 @@ def handle(self):

def destroy(self):
self.handle.destroy()

def assert_liveliness(self) -> None:
"""
Manually assert that this Publisher is alive.
If the QoS Liveliness policy is set to RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC, the
application must call this at least as often as ``QoSProfile.liveliness_lease_duration``.
"""
_rclpy.rclpy_assert_liveliness(self.publisher_handle)
51 changes: 51 additions & 0 deletions rclpy/src/rclpy/_rclpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -3604,6 +3604,53 @@ rclpy_get_rmw_qos_profile(PyObject * Py_UNUSED(self), PyObject * args)
return pyqos_profile;
}

/// Manually assert that an entity is alive.
/**
* When using RMW_QOS_POLICY_MANUAL_BY_*, the application must call this function at least as
* often as the qos policy liveliness_lease_duration.
* The passed entity can be a Publisher or a Node.
*
* Raises RuntimeError on failure to assert liveliness
* Raises TypeError if passed object is not a valid Publisher or Node
*
* \param[in] pyentity A capsule containing an rcl_node_t or rcl_publisher_t
* \return None
*/
static PyObject *
rclpy_assert_liveliness(PyObject * Py_UNUSED(self), PyObject * args)
{
PyObject * pyentity;

if (!PyArg_ParseTuple(args, "O", &pyentity)) {
return NULL;
}

if (PyCapsule_IsValid(pyentity, "rcl_node_t")) {
rcl_node_t * node = (rcl_node_t *)PyCapsule_GetPointer(pyentity, "rcl_node_t");
if (RCL_RET_OK != rcl_node_assert_liveliness(node)) {
PyErr_Format(PyExc_RuntimeError,
"Failed assert liveliness on the Node: %s", rcl_get_error_string().str);
rcl_reset_error();
return NULL;
}
} else if (PyCapsule_IsValid(pyentity, "rcl_publisher_t")) {
rcl_publisher_t * publisher = (rcl_publisher_t *)PyCapsule_GetPointer(
pyentity, "rcl_publisher_t");
if (RCL_RET_OK != rcl_publisher_assert_liveliness(publisher)) {
PyErr_Format(PyExc_RuntimeError,
"Failed to assert liveliness on the Publisher: %s", rcl_get_error_string().str);
rcl_reset_error();
return NULL;
}
} else {
PyErr_Format(PyExc_TypeError,
"Passed capsule is not a valid Node or Publisher.");
return NULL;
}

Py_RETURN_NONE;
}

/// Destructor for a time point
void
_rclpy_destroy_time_point(PyObject * pycapsule)
Expand Down Expand Up @@ -4784,6 +4831,10 @@ static PyMethodDef rclpy_methods[] = {
"rclpy_get_rmw_qos_profile", rclpy_get_rmw_qos_profile, METH_VARARGS,
"Get QOS profile."
},
{
"rclpy_assert_liveliness", rclpy_assert_liveliness, METH_VARARGS,
"Assert the liveliness of an entity."
},

{
"rclpy_create_time_point", rclpy_create_time_point, METH_VARARGS,
Expand Down

0 comments on commit dc6f263

Please sign in to comment.