diff --git a/docs/en/middleware/uxrce_dds.md b/docs/en/middleware/uxrce_dds.md index 5ab96699cf..d73e475415 100644 --- a/docs/en/middleware/uxrce_dds.md +++ b/docs/en/middleware/uxrce_dds.md @@ -274,6 +274,9 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable. The uXRCE-DDS client module can synchronize the timestamp of the messages exchanged over the bridge. This is the default configuration. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled. + - [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX): Index-based namespace definition + Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. + See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. ::: info Many ports are already have a default configuration. @@ -347,7 +350,7 @@ Therefore, ## Customizing the Namespace -Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)) or at runtime (which is useful for multi vehicle operations): +Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)), at runtime, or through a parameter (which is useful for multi vehicle operations): - One possibility is to use the `-n` option when starting the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) from command line. This technique can be used both in simulation and real vehicles. @@ -376,6 +379,22 @@ will generate topics under the namespaces: ::: +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. + This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. + This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. + +::: info +PX4 parameters cannot carry rich text strings. +Therefore, you cannot use [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to automatically start a client with an arbitrary message namespace through PX4. +You can however specify a namespace when starting the client, using the `-n` argument: + +```sh +# In etc/extras.txt on the MicroSD card +uxrce_dds_client start -n fancy_uav +``` + +This can be included in `etc/extras.txt` as part of a custom [System Startup](../concept/system_startup.md). + ## PX4 ROS 2 QoS Settings PX4 QoS settings for publishers are incompatible with the default QoS settings for ROS 2 subscribers. diff --git a/src/modules/uxrce_dds_client/module.yaml b/src/modules/uxrce_dds_client/module.yaml index 773475f1f5..3e9d03fcc9 100644 --- a/src/modules/uxrce_dds_client/module.yaml +++ b/src/modules/uxrce_dds_client/module.yaml @@ -129,3 +129,16 @@ parameters: reboot_required: true default: -1 unit: s + + UXRCE_DDS_NS_IDX: + description: + short: Define an index-based message namespace + long: | + Defines an index-based namespace for DDS messages, e.g, uav_0, uav_1, up to uav_9999 + A value less than zero leaves the namespace empty + type: int32 + min: -1 + max: 9999 + category: System + reboot_required: true + default: -1 diff --git a/src/modules/uxrce_dds_client/uxrce_dds_client.cpp b/src/modules/uxrce_dds_client/uxrce_dds_client.cpp index d8beb4f609..d5f2b57042 100644 --- a/src/modules/uxrce_dds_client/uxrce_dds_client.cpp +++ b/src/modules/uxrce_dds_client/uxrce_dds_client.cpp @@ -49,6 +49,7 @@ #include #include +static constexpr char NAMESPACE_PREFIX[] = "uav_"; #define PARTICIPANT_XML_SIZE 512 static constexpr uint8_t TIMESYNC_MAX_TIMEOUTS = 10; @@ -1028,6 +1029,23 @@ UxrceddsClient *UxrceddsClient::instantiate(int argc, char *argv[]) } } + if (client_namespace == nullptr) { + int32_t ns_idx = -1; + param_get(param_find("UXRCE_DDS_NS_IDX"), &ns_idx); + + if (ns_idx > -1) { + if (ns_idx < 10000) { + // Allocate buffer for prefix + '\0' + 4 digits + static char client_namespace_buf[sizeof(NAMESPACE_PREFIX) + 4]; + snprintf(client_namespace_buf, sizeof client_namespace_buf, "%s%u", NAMESPACE_PREFIX, (uint16_t)ns_idx); + client_namespace = client_namespace_buf; + + } else { + PX4_WARN("namespace index must be between 0 and 9999 inclusive; ignoring index-based namespace"); + } + } + } + #if defined(UXRCE_DDS_CLIENT_UDP) if (port[0] == '\0') { @@ -1092,7 +1110,7 @@ $ uxrce_dds_client start -t udp -h 127.0.0.1 -p 15555 PRINT_MODULE_USAGE_PARAM_INT('b', 0, 0, 3000000, "Baudrate (can also be p:)", true); PRINT_MODULE_USAGE_PARAM_STRING('h', nullptr, "", "Agent IP. If not provided, defaults to UXRCE_DDS_AG_IP", true); PRINT_MODULE_USAGE_PARAM_INT('p', -1, 0, 65535, "Agent listening port. If not provided, defaults to UXRCE_DDS_PRT", true); - PRINT_MODULE_USAGE_PARAM_STRING('n', nullptr, nullptr, "Client DDS namespace", true); + PRINT_MODULE_USAGE_PARAM_STRING('n', nullptr, nullptr, "Client DDS namespace. If not provided but UXRCE_DDS_NS_IDX is between 0 and 9999 inclusive, then uav_ + UXRCE_DDS_NS_IDX will be used", true); PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); return 0;