|
20 | 20 | #include <rcl/node.h> |
21 | 21 | #include <rcl/publisher.h> |
22 | 22 | #include <rcl/rcl.h> |
| 23 | +#include <rcl/remap.h> |
23 | 24 | #include <rcl/time.h> |
24 | 25 | #include <rcl/validate_topic_name.h> |
25 | | -#include <rcl_yaml_param_parser/parser.h> |
26 | 26 | #include <rcl_interfaces/msg/parameter_type__struct.h> |
| 27 | +#include <rcl_yaml_param_parser/parser.h> |
27 | 28 | #include <rcutils/allocator.h> |
28 | 29 | #include <rcutils/format_string.h> |
29 | 30 | #include <rcutils/strdup.h> |
@@ -917,19 +918,23 @@ _get_info_by_topic( |
917 | 918 | rcl_ret_t fini_ret; |
918 | 919 | if (RCL_RET_OK != ret) { |
919 | 920 | if (RCL_RET_BAD_ALLOC == ret) { |
920 | | - PyErr_Format(PyExc_MemoryError, "Failed to get information by topic for %s: %s", |
| 921 | + PyErr_Format( |
| 922 | + PyExc_MemoryError, "Failed to get information by topic for %s: %s", |
921 | 923 | type, rcl_get_error_string().str); |
922 | 924 | } else if (RCL_RET_UNSUPPORTED == ret) { |
923 | | - PyErr_Format(PyExc_NotImplementedError, "Failed to get information by topic for %s: " |
| 925 | + PyErr_Format( |
| 926 | + PyExc_NotImplementedError, "Failed to get information by topic for %s: " |
924 | 927 | "function not supported by RMW_IMPLEMENTATION", type); |
925 | 928 | } else { |
926 | | - PyErr_Format(RCLError, "Failed to get information by topic for %s: %s", |
| 929 | + PyErr_Format( |
| 930 | + RCLError, "Failed to get information by topic for %s: %s", |
927 | 931 | type, rcl_get_error_string().str); |
928 | 932 | } |
929 | 933 | rcl_reset_error(); |
930 | 934 | fini_ret = rcl_topic_endpoint_info_array_fini(&info_array, &allocator); |
931 | 935 | if (fini_ret != RCL_RET_OK) { |
932 | | - PyErr_Format(RCLError, "rcl_topic_endpoint_info_array_fini failed: %s", |
| 936 | + PyErr_Format( |
| 937 | + RCLError, "rcl_topic_endpoint_info_array_fini failed: %s", |
933 | 938 | rcl_get_error_string().str); |
934 | 939 | rcl_reset_error(); |
935 | 940 | } |
@@ -1327,7 +1332,7 @@ _expand_topic_name_with_exceptions(const char * topic, const char * node, const |
1327 | 1332 | * \param[in] topic_name topic string to be expanded |
1328 | 1333 | * \param[in] node_name name of the node to be used during expansion |
1329 | 1334 | * \param[in] node_namespace namespace of the node to be used during expansion |
1330 | | - * \return expanded node namespace |
| 1335 | + * \return expanded topic name |
1331 | 1336 | */ |
1332 | 1337 | static PyObject * |
1333 | 1338 | rclpy_expand_topic_name(PyObject * Py_UNUSED(self), PyObject * args) |
@@ -1356,23 +1361,86 @@ rclpy_expand_topic_name(PyObject * Py_UNUSED(self), PyObject * args) |
1356 | 1361 | } |
1357 | 1362 |
|
1358 | 1363 | char * expanded_topic = _expand_topic_name_with_exceptions(topic, node_name, node_namespace); |
1359 | | - |
1360 | 1364 | if (!expanded_topic) { |
1361 | 1365 | // exception already set |
1362 | 1366 | return NULL; |
1363 | 1367 | } |
1364 | 1368 |
|
1365 | 1369 | PyObject * result = PyUnicode_FromString(expanded_topic); |
1366 | | - if (!result) { |
1367 | | - return NULL; |
1368 | | - } |
1369 | 1370 |
|
1370 | 1371 | rcl_allocator_t allocator = rcl_get_default_allocator(); |
1371 | 1372 | allocator.deallocate(expanded_topic, allocator.state); |
1372 | 1373 |
|
1373 | 1374 | return result; |
1374 | 1375 | } |
1375 | 1376 |
|
| 1377 | +static char * |
| 1378 | +_remap_topic_name_with_exceptions(const rcl_node_t * node_handle, const char * topic_name) |
| 1379 | +{ |
| 1380 | + // Get the node options |
| 1381 | + const rcl_node_options_t * node_options = rcl_node_get_options(node_handle); |
| 1382 | + if (node_options == NULL) { |
| 1383 | + return NULL; |
| 1384 | + } |
| 1385 | + const rcl_arguments_t * global_args = NULL; |
| 1386 | + if (node_options->use_global_arguments) { |
| 1387 | + global_args = &(node_handle->context->global_arguments); |
| 1388 | + } |
| 1389 | + |
| 1390 | + char * remapped_topic = NULL; |
| 1391 | + rcl_ret_t ret = rcl_remap_topic_name( |
| 1392 | + &(node_options->arguments), |
| 1393 | + global_args, |
| 1394 | + topic_name, |
| 1395 | + rcl_node_get_name(node_handle), |
| 1396 | + rcl_node_get_namespace(node_handle), |
| 1397 | + node_options->allocator, |
| 1398 | + &remapped_topic); |
| 1399 | + if (ret != RCL_RET_OK) { |
| 1400 | + PyErr_Format(PyExc_RuntimeError, "Failed to remap topic name %s", topic_name); |
| 1401 | + return NULL; |
| 1402 | + } |
| 1403 | + |
| 1404 | + return remapped_topic; |
| 1405 | +} |
| 1406 | + |
| 1407 | +/// Remap a topic name |
| 1408 | +/** |
| 1409 | + * Raises ValueError if the capsule is not the correct type |
| 1410 | + * |
| 1411 | + * \param[in] pynode Capsule pointing to the node |
| 1412 | + * \param[in] topic_name topic string to be remapped |
| 1413 | + * \return remapped topic name |
| 1414 | + */ |
| 1415 | +static PyObject * |
| 1416 | +rclpy_remap_topic_name(PyObject * Py_UNUSED(self), PyObject * args) |
| 1417 | +{ |
| 1418 | + PyObject * pynode; |
| 1419 | + const char * topic_name; |
| 1420 | + |
| 1421 | + if (!PyArg_ParseTuple(args, "Os", &pynode, &topic_name)) { |
| 1422 | + return NULL; |
| 1423 | + } |
| 1424 | + |
| 1425 | + const rcl_node_t * node = (const rcl_node_t *)PyCapsule_GetPointer(pynode, "rcl_node_t"); |
| 1426 | + if (node == NULL) { |
| 1427 | + return NULL; |
| 1428 | + } |
| 1429 | + |
| 1430 | + char * remapped_topic_name = _remap_topic_name_with_exceptions(node, topic_name); |
| 1431 | + if (remapped_topic_name == NULL) { |
| 1432 | + return PyUnicode_FromString(topic_name); |
| 1433 | + } |
| 1434 | + |
| 1435 | + PyObject * result = PyUnicode_FromString(remapped_topic_name); |
| 1436 | + |
| 1437 | + const rcl_node_options_t * node_options = rcl_node_get_options(node_handle); |
| 1438 | + rcl_allocator_t allocator = node_options->allocator, |
| 1439 | + allocator.deallocate(remapped_topic_name, allocator.state); |
| 1440 | + |
| 1441 | + return result; |
| 1442 | +} |
| 1443 | + |
1376 | 1444 | /// PyCapsule destructor for publisher |
1377 | 1445 | static void |
1378 | 1446 | _rclpy_destroy_publisher(PyObject * pyentity) |
@@ -4986,6 +5054,10 @@ static PyMethodDef rclpy_methods[] = { |
4986 | 5054 | "rclpy_expand_topic_name", rclpy_expand_topic_name, METH_VARARGS, |
4987 | 5055 | "Expand a topic name." |
4988 | 5056 | }, |
| 5057 | + { |
| 5058 | + "rclpy_remap_topic_name", rclpy_remap_topic_name, METH_VARARGS, |
| 5059 | + "Remap a topic name." |
| 5060 | + }, |
4989 | 5061 | { |
4990 | 5062 | "rclpy_get_validation_error_for_topic_name", |
4991 | 5063 | rclpy_get_validation_error_for_topic_name, METH_VARARGS, |
|
0 commit comments