Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use py::class_ for rmw_qos_profile_t #741

Merged
merged 2 commits into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions rclpy/rclpy/qos.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class QoSProfile:
"""Define Quality of Service policies."""

# default QoS profile not exposed to the user to encourage them to think about QoS settings
__qos_profile_default_dict = _rclpy.rclpy_get_rmw_qos_profile('qos_profile_default')
__qos_profile_default_dict = \
_rclpy.rmw_qos_profile_t.predefined('qos_profile_default').to_dict()

__slots__ = [
'_history',
Expand Down Expand Up @@ -241,7 +242,7 @@ def avoid_ros_namespace_conventions(self, value):
self._avoid_ros_namespace_conventions = value

def get_c_qos_profile(self):
return _rclpy.rclpy_convert_from_py_qos_policy(
return _rclpy.rmw_qos_profile_t(
self.history,
self.depth,
self.reliability,
Expand Down Expand Up @@ -419,26 +420,26 @@ class LivelinessPolicy(QoSPolicyEnum):
# 2. ros2/rmw : rmw/include/rmw/qos_profiles.h

#: Used for initialization. Should not be used as the actual QoS profile.
qos_profile_unknown = QoSProfile(**_rclpy.rclpy_get_rmw_qos_profile(
'qos_profile_unknown'))
qos_profile_unknown = QoSProfile(**_rclpy.rmw_qos_profile_t.predefined(
'qos_profile_unknown').to_dict())
#: Uses the default QoS settings defined in the DDS vendor tool
qos_profile_system_default = QoSProfile(**_rclpy.rclpy_get_rmw_qos_profile(
'qos_profile_system_default'))
qos_profile_system_default = QoSProfile(**_rclpy.rmw_qos_profile_t.predefined(
'qos_profile_system_default').to_dict())
#: For sensor data, using best effort reliability and small
#: queue depth
qos_profile_sensor_data = QoSProfile(**_rclpy.rclpy_get_rmw_qos_profile(
'qos_profile_sensor_data'))
qos_profile_sensor_data = QoSProfile(**_rclpy.rmw_qos_profile_t.predefined(
'qos_profile_sensor_data').to_dict())
#: For services, using reliable reliability and volatile durability
qos_profile_services_default = QoSProfile(**_rclpy.rclpy_get_rmw_qos_profile(
'qos_profile_services_default'))
qos_profile_services_default = QoSProfile(**_rclpy.rmw_qos_profile_t.predefined(
'qos_profile_services_default').to_dict())
#: For parameter communication. Similar to service QoS profile but with larger
#: queue depth so that requests do not get lost.
qos_profile_parameters = QoSProfile(**_rclpy.rclpy_get_rmw_qos_profile(
'qos_profile_parameters'))
qos_profile_parameters = QoSProfile(**_rclpy.rmw_qos_profile_t.predefined(
'qos_profile_parameters').to_dict())
#: For parameter change events. Currently same as the QoS profile for
#: parameters.
qos_profile_parameter_events = QoSProfile(**_rclpy.rclpy_get_rmw_qos_profile(
'qos_profile_parameter_events'))
qos_profile_parameter_events = QoSProfile(**_rclpy.rmw_qos_profile_t.predefined(
'qos_profile_parameter_events').to_dict())

# Separate rcl_action profile defined at
# ros2/rcl : rcl/rcl_action/include/rcl_action/default_qos.h
Expand Down
77 changes: 30 additions & 47 deletions rclpy/src/rclpy/_rclpy_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,6 @@ rclpy_action_wait_set_is_ready(py::capsule pyentity, py::capsule pywait_set)
throw std::runtime_error(error_text);
}

void
copy_qos_profile(rmw_qos_profile_t & profile, py::capsule pyprofile)
{
auto qos_profile = get_pointer<rmw_qos_profile_t *>(pyprofile, "rmw_qos_profile_t");
profile = *qos_profile;
}

/// Create an action client.
/**
* This function will create an action client for the given action name.
Expand All @@ -329,16 +322,11 @@ copy_qos_profile(rmw_qos_profile_t & profile, py::capsule pyprofile)
* \param[in] pynode Capsule pointing to the node to add the action client to.
* \param[in] pyaction_type Action module associated with the action client.
* \param[in] pyaction_name Python object containing the action name.
* \param[in] pygoal_service_qos Capsule pointing to a rmw_qos_profile_t object
* for the goal service.
* \param[in] pyresult_service_qos Capsule pointing to a rmw_qos_profile_t object
* for the result service.
* \param[in] pycancel_service_qos Capsule pointing to a rmw_qos_profile_t object
* for the cancel service.
* \param[in] pyfeedback_qos Capsule pointing to a rmw_qos_profile_t object
* for the feedback subscriber.
* \param[in] pystatus_qos Capsule pointing to a rmw_qos_profile_t object for the
* status subscriber.
* \param[in] goal_service_qos rmw_qos_profile_t object for the goal service.
* \param[in] result_service_qos rmw_qos_profile_t object for the result service.
* \param[in] cancel_service_qos rmw_qos_profile_t object for the cancel service.
* \param[in] feedback_qos rmw_qos_profile_t object for the feedback subscriber.
* \param[in] status_qos rmw_qos_profile_t object for the status subscriber.
* \return Capsule named 'rcl_action_client_t', or
* \return NULL on failure.
*/
Expand All @@ -347,11 +335,11 @@ rclpy_action_create_client(
py::capsule pynode,
py::object pyaction_type,
const char * action_name,
py::capsule pygoal_service_qos,
py::capsule pyresult_service_qos,
py::capsule pycancel_service_qos,
py::capsule pyfeedback_topic_qos,
py::capsule pystatus_topic_qos)
const rmw_qos_profile_t & goal_service_qos,
const rmw_qos_profile_t & result_service_qos,
const rmw_qos_profile_t & cancel_service_qos,
const rmw_qos_profile_t & feedback_topic_qos,
const rmw_qos_profile_t & status_topic_qos)
{
rcl_node_t * node = static_cast<rcl_node_t *>(
rclpy_handle_get_pointer_from_capsule(pynode.ptr(), "rcl_node_t"));
Expand All @@ -368,11 +356,11 @@ rclpy_action_create_client(

rcl_action_client_options_t action_client_ops = rcl_action_client_get_default_options();

copy_qos_profile(action_client_ops.goal_service_qos, pygoal_service_qos);
copy_qos_profile(action_client_ops.result_service_qos, pyresult_service_qos);
copy_qos_profile(action_client_ops.cancel_service_qos, pycancel_service_qos);
copy_qos_profile(action_client_ops.feedback_topic_qos, pyfeedback_topic_qos);
copy_qos_profile(action_client_ops.status_topic_qos, pystatus_topic_qos);
action_client_ops.goal_service_qos = goal_service_qos;
action_client_ops.result_service_qos = result_service_qos;
action_client_ops.cancel_service_qos = cancel_service_qos;
action_client_ops.feedback_topic_qos = feedback_topic_qos;
action_client_ops.status_topic_qos = status_topic_qos;

auto deleter = [](rcl_action_client_t * ptr) {PyMem_Free(ptr);};
auto action_client = std::unique_ptr<rcl_action_client_t, decltype(deleter)>(
Expand Down Expand Up @@ -423,16 +411,11 @@ rclpy_action_create_client(
* \param[in] pynode Capsule pointing to the node to add the action server to.
* \param[in] pyaction_type Action module associated with the action server.
* \param[in] pyaction_name Python object containing the action name.
* \param[in] pygoal_service_qos Capsule pointing to a rmw_qos_profile_t object
* for the goal service.
* \param[in] pyresult_service_qos Capsule pointing to a rmw_qos_profile_t object
* for the result service.
* \param[in] pycancel_service_qos Capsule pointing to a rmw_qos_profile_t object
* for the cancel service.
* \param[in] pyfeedback_qos Capsule pointing to a rmw_qos_profile_t object
* for the feedback subscriber.
* \param[in] pystatus_qos Capsule pointing to a rmw_qos_profile_t object for the
* status subscriber.
* \param[in] goal_service_qos rmw_qos_profile_t object for the goal service.
* \param[in] result_service_qos rmw_qos_profile_t object for the result service.
* \param[in] cancel_service_qos rmw_qos_profile_t object for the cancel service.
* \param[in] feedback_qos rmw_qos_profile_t object for the feedback subscriber.
* \param[in] status_qos rmw_qos_profile_t object for the status subscriber.
* \return Capsule named 'rcl_action_server_t', or
* \return NULL on failure.
*/
Expand All @@ -442,11 +425,11 @@ rclpy_action_create_server(
py::capsule pyclock,
py::object pyaction_type,
const char * action_name,
py::capsule pygoal_service_qos,
py::capsule pyresult_service_qos,
py::capsule pycancel_service_qos,
py::capsule pyfeedback_topic_qos,
py::capsule pystatus_topic_qos,
const rmw_qos_profile_t & goal_service_qos,
const rmw_qos_profile_t & result_service_qos,
const rmw_qos_profile_t & cancel_service_qos,
const rmw_qos_profile_t & feedback_topic_qos,
const rmw_qos_profile_t & status_topic_qos,
double result_timeout)
{
rcl_node_t * node = static_cast<rcl_node_t *>(
Expand All @@ -469,11 +452,11 @@ rclpy_action_create_server(

rcl_action_server_options_t action_server_ops = rcl_action_server_get_default_options();

copy_qos_profile(action_server_ops.goal_service_qos, pygoal_service_qos);
copy_qos_profile(action_server_ops.result_service_qos, pyresult_service_qos);
copy_qos_profile(action_server_ops.cancel_service_qos, pycancel_service_qos);
copy_qos_profile(action_server_ops.feedback_topic_qos, pyfeedback_topic_qos);
copy_qos_profile(action_server_ops.status_topic_qos, pystatus_topic_qos);
action_server_ops.goal_service_qos = goal_service_qos;
action_server_ops.result_service_qos = result_service_qos;
action_server_ops.cancel_service_qos = cancel_service_qos;
action_server_ops.feedback_topic_qos = feedback_topic_qos;
action_server_ops.status_topic_qos = status_topic_qos;
action_server_ops.result_timeout.nanoseconds = (rcl_duration_value_t)RCL_S_TO_NS(result_timeout);

auto deleter = [](rcl_action_server_t * ptr) {PyMem_Free(ptr);};
Expand Down
10 changes: 1 addition & 9 deletions rclpy/src/rclpy/_rclpy_pybind11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,7 @@ PYBIND11_MODULE(_rclpy_pybind11, m) {
"rclpy_remove_ros_args", &rclpy::remove_ros_args,
"Remove ROS-specific arguments from argument vector.");

m.def(
"rclpy_convert_from_py_qos_policy", &rclpy::convert_from_py_qos_policy,
"Convert rclpy.qos.QoSProfile arguments into a rmw_qos_profile_t.");
m.def(
"rclpy_convert_to_py_qos_policy", &rclpy::convert_to_py_qos_policy,
"Convert a rmw_qos_profile_t into rclpy.qos.QoSProfile keyword arguments.");
m.def(
"rclpy_get_rmw_qos_profile", &rclpy::get_rmw_qos_profile,
"Fetch a predefined rclpy.qos.QoSProfile keyword arguments.");
rclpy::define_rmw_qos_profile(m);

m.def(
"rclpy_logging_fini", rclpy::logging_fini,
Expand Down
10 changes: 3 additions & 7 deletions rclpy/src/rclpy/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Client::destroy()
}

Client::Client(
py::capsule pynode, py::object pysrv_type, const char * service_name, py::capsule pyqos_profile)
py::capsule pynode, py::object pysrv_type, const char * service_name, py::object pyqos_profile)
: node_handle_(std::make_shared<Handle>(pynode))
{
auto node = node_handle_->cast<rcl_node_t *>("rcl_node_t");
Expand All @@ -51,11 +51,7 @@ Client::Client(
rcl_client_options_t client_ops = rcl_client_get_default_options();

if (!pyqos_profile.is_none()) {
if (0 != strcmp("rmw_qos_profile_t", pyqos_profile.name())) {
throw py::value_error("capsule is not an rmw_qos_profile_t");
}
auto qos_profile = static_cast<rmw_qos_profile_t *>(pyqos_profile);
client_ops.qos = *qos_profile;
client_ops.qos = pyqos_profile.cast<rmw_qos_profile_t>();
}

// Create a client
Expand Down Expand Up @@ -171,7 +167,7 @@ void
define_client(py::object module)
{
py::class_<Client, Destroyable>(module, "Client")
.def(py::init<py::capsule, py::object, const char *, py::capsule>())
.def(py::init<py::capsule, py::object, const char *, py::object>())
.def_property_readonly(
"pointer", [](const Client & client) {
return reinterpret_cast<size_t>(client.rcl_ptr());
Expand Down
4 changes: 2 additions & 2 deletions rclpy/src/rclpy/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class Client : public Destroyable
* \param[in] pynode Capsule pointing to the node to add the client to
* \param[in] pysrv_type Service module associated with the client
* \param[in] service_name Python object containing the service name
* \param[in] pyqos_profile QoSProfile Python object for this client
* \param[in] pyqos rmw_qos_profile_t object for this client
*/
Client(py::capsule pynode, py::object pysrv_type, const char * service_name, py::capsule pyqos);
Client(py::capsule pynode, py::object pysrv_type, const char * service_name, py::object pyqos);

~Client() = default;

Expand Down
8 changes: 2 additions & 6 deletions rclpy/src/rclpy/publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ _rclpy_destroy_publisher(void * p)
py::capsule
publisher_create(
py::capsule pynode, py::object pymsg_type, std::string topic,
py::capsule pyqos_profile)
py::object pyqos_profile)
{
auto node = static_cast<rcl_node_t *>(
rclpy_handle_get_pointer_from_capsule(pynode.ptr(), "rcl_node_t"));
Expand All @@ -72,11 +72,7 @@ publisher_create(
rcl_publisher_options_t publisher_ops = rcl_publisher_get_default_options();

if (!pyqos_profile.is_none()) {
if (0 != strcmp("rmw_qos_profile_t", pyqos_profile.name())) {
throw py::value_error("capsule is not an rmw_qos_profile_t");
}
auto qos_profile = static_cast<rmw_qos_profile_t *>(pyqos_profile);
publisher_ops.qos = *qos_profile;
publisher_ops.qos = pyqos_profile.cast<rmw_qos_profile_t>();
}

// Use smart pointer to make sure memory is free'd on error
Expand Down
4 changes: 2 additions & 2 deletions rclpy/src/rclpy/publisher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ namespace rclpy
* \param[in] pynode Capsule pointing to the node to add the publisher to
* \param[in] pymsg_type Message type associated with the publisher
* \param[in] topic The name of the topic to attach the publisher to
* \param[in] pyqos_profile QoSProfile object with the profile of this publisher
* \param[in] pyqos_profile rmw_qos_profile_t object for this publisher
* \return Capsule of the pointer to the created rcl_publisher_t * structure, or
*/
py::capsule
publisher_create(
py::capsule pynode, py::object pymsg_type, std::string topic,
py::capsule pyqos_profile);
py::object pyqos_profile);

/// Get the name of the logger associated with the node of the publisher.
/**
Expand Down
Loading