diff --git a/rmw/include/rmw/qos_profiles.h b/rmw/include/rmw/qos_profiles.h index 89b30e97..b0343507 100644 --- a/rmw/include/rmw/qos_profiles.h +++ b/rmw/include/rmw/qos_profiles.h @@ -100,6 +100,32 @@ static const rmw_qos_profile_t rmw_qos_profile_system_default = false }; +/// Match majority of endpoints currently available while maintaining the highest level of service +/** + * Reliability, durability, deadline, liveliness, and liveliness lease duration policies will be + * chosen at the time of creating a subscription or publisher. + * + * The actual QoS policy can be retrieved after the endpoint is created with + * `rmw_get_subscriptions_info_by_topic` or `rmw_get_publishers_info_by_topic`. + * + * The middleware is not expected to update policies after creating a subscription or + * publisher, even if one or more policies are incompatible with newly discovered endpoints. + * Therefore, this profile should be used with care since non-deterministic behavior + * can occur due to races with discovery. + */ +static const rmw_qos_profile_t rmw_qos_profile_best_available = +{ + RMW_QOS_POLICY_HISTORY_KEEP_LAST, + 10, + RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE, + RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE, + RMW_QOS_DEADLINE_BEST_AVAILABLE, + RMW_QOS_LIFESPAN_DEFAULT, + RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE, + RMW_QOS_LIVELINESS_LEASE_DURATION_BEST_AVAILABLE, + false +}; + static const rmw_qos_profile_t rmw_qos_profile_unknown = { RMW_QOS_POLICY_HISTORY_UNKNOWN, diff --git a/rmw/include/rmw/types.h b/rmw/include/rmw/types.h index 2dd31534..59f261d1 100644 --- a/rmw/include/rmw/types.h +++ b/rmw/include/rmw/types.h @@ -382,7 +382,26 @@ typedef enum RMW_PUBLIC_TYPE rmw_qos_reliability_policy_e RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT, /// Reliability policy has not yet been set - RMW_QOS_POLICY_RELIABILITY_UNKNOWN + RMW_QOS_POLICY_RELIABILITY_UNKNOWN, + + /// Will match the majority of endpoints and use a reliable policy if possible + /** + * A policy will be chosen at the time of creating a subscription or publisher. + * A reliable policy will by chosen if it matches with all discovered endpoints, + * otherwise a best effort policy will be chosen. + * + * The QoS policy reported by functions like `rmw_subscription_get_actual_qos` or + * `rmw_publisher_get_actual_qos` may be best available, reliable, or best effort. + * + * Services and clients are not supported and default to the reliability value in + * `rmw_qos_profile_services_default`. + * + * The middleware is not expected to update the policy after creating a subscription or + * publisher, even if the chosen policy is incompatible with newly discovered endpoints. + * Therefore, this policy should be used with care since non-deterministic behavior + * can occur due to races with discovery. + */ + RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE } rmw_qos_reliability_policy_t; /// QoS history enumerations describing how samples endure @@ -414,7 +433,29 @@ typedef enum RMW_PUBLIC_TYPE rmw_qos_durability_policy_e RMW_QOS_POLICY_DURABILITY_VOLATILE, /// Durability policy has not yet been set - RMW_QOS_POLICY_DURABILITY_UNKNOWN + RMW_QOS_POLICY_DURABILITY_UNKNOWN, + + /// Will match the majority of endpoints and use a transient local policy if possible + /** + * A policy will be chosen at the time of creating a subscription or publisher. + * A transient local policy will by chosen if it matches with all discovered endpoints, + * otherwise a volatile policy will be chosen. + * + * In the case that a volatile policy is chosen for a subscription, any messages sent before + * the subscription was created by transient local publishers will not be received. + * + * The QoS policy reported by functions like `rmw_subscription_get_actual_qos` or + * `rmw_publisher_get_actual_qos` may be best available, transient local, or volatile. + * + * Services and clients are not supported and default to the durability value in + * `rmw_qos_profile_services_default`. + * + * The middleware is not expected to update the policy after creating a subscription or + * publisher, even if the chosen policy is incompatible with newly discovered endpoints. + * Therefore, this policy should be used with care since non-deterministic behavior + * can occur due to races with discovery. + */ + RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE } rmw_qos_durability_policy_t; #define RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE_DEPRECATED_MSG \ @@ -453,17 +494,80 @@ typedef enum RMW_PUBLIC_TYPE rmw_qos_liveliness_policy_e RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC = 3, /// Liveliness policy has not yet been set - RMW_QOS_POLICY_LIVELINESS_UNKNOWN = 4 + RMW_QOS_POLICY_LIVELINESS_UNKNOWN = 4, + + /// Will match the majority of endpoints and use a manual by topic policy if possible + /** + * A policy will be chosen at the time of creating a subscription or publisher. + * A manual by topic policy will by chosen if it matches with all discovered endpoints, + * otherwise an automatic policy will be chosen. + * + * The QoS policy reported by functions like `rmw_subscription_get_actual_qos` or + * `rmw_publisher_get_actual_qos` may be best available, automatic, or manual by topic. + * + * Services and clients are not supported and default to the liveliness value in + * `rmw_qos_profile_services_default`. + * + * The middleware is not expected to update the policy after creating a subscription or + * publisher, even if the chosen policy is incompatible with newly discovered endpoints. + * Therefore, this policy should be used with care since non-deterministic behavior + * can occur due to races with discovery. + */ + RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE = 5 } rmw_qos_liveliness_policy_t; /// QoS Deadline default. #define RMW_QOS_DEADLINE_DEFAULT RMW_DURATION_UNSPECIFIED +/// Will match the majority of endpoints while maintaining as strict a policy as possible +/** + * Value is RMW_DURATION_INFINITE - 1. + * + * A policy will be chosen at the time of creating a subscription or publisher. + * For a subscription, the deadline will be the maximum value of all discovered publisher + * deadlines. + * For a publisher, the deadline will be the minimum value of all discovered subscription + * deadlines. + * + * The QoS policy reported by functions like `rmw_subscription_get_actual_qos` or + * `rmw_publisher_get_actual_qos` may be best available or the actual deadline value. + * + * Services and clients are not supported and default to the deadline value in + * `rmw_qos_profile_services_default`. + * + * The middleware is not expected to update the policy after creating a subscription or + * publisher, even if the chosen policy is incompatible with newly discovered endpoints. + * Therefore, this policy should be used with care since non-deterministic behavior + * can occur due to races with discovery. + */ +#define RMW_QOS_DEADLINE_BEST_AVAILABLE {9223372036LL, 854775806LL} /// QoS Lifespan default. #define RMW_QOS_LIFESPAN_DEFAULT RMW_DURATION_UNSPECIFIED /// QoS Liveliness lease duration default. #define RMW_QOS_LIVELINESS_LEASE_DURATION_DEFAULT RMW_DURATION_UNSPECIFIED +/// Will match the majority of endpoints while maintaining as strict a policy as possible +/** + * Value is RMW_DURATION_INFINITE - 1. + * + * A policy will be chosen at the time of creating a subscription or publisher. + * For a subscription, the lease duration will be the maximum value of all discovered publisher + * lease durations. + * For a publisher, the lease duration will be the minimum value of all discovered subscription + * lease durations. + * + * The QoS policy reported by functions like `rmw_subscription_get_actual_qos` or + * `rmw_publisher_get_actual_qos` may be best available or the actual lease duration value. + * + * Services and clients are not supported and default to the lease duration value in + * `rmw_qos_profile_services_default`. + * + * The middleware is not expected to update the policy after creating a subscription or + * publisher, even if the chosen policy is incompatible with newly discovered endpoints. + * Therefore, this policy should be used with care since non-deterministic behavior + * can occur due to races with discovery. + */ +#define RMW_QOS_LIVELINESS_LEASE_DURATION_BEST_AVAILABLE {9223372036LL, 854775806LL} /// ROS MiddleWare quality of service profile. typedef struct RMW_PUBLIC_TYPE rmw_qos_profile_s diff --git a/rmw/src/qos_string_conversions.c b/rmw/src/qos_string_conversions.c index 98265786..d5783280 100644 --- a/rmw/src/qos_string_conversions.c +++ b/rmw/src/qos_string_conversions.c @@ -53,6 +53,8 @@ rmw_qos_durability_policy_to_str(enum rmw_qos_durability_policy_e value) return "transient_local"; case RMW_QOS_POLICY_DURABILITY_VOLATILE: return "volatile"; + case RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE: + return "best_available"; case RMW_QOS_POLICY_DURABILITY_UNKNOWN: // fallthrough default: return NULL; @@ -85,6 +87,8 @@ rmw_qos_liveliness_policy_to_str(enum rmw_qos_liveliness_policy_e value) return "automatic"; case RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC: return "manual_by_topic"; + case RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE: + return "best_available"; case RMW_QOS_POLICY_LIVELINESS_UNKNOWN: // fallthrough default: return NULL; @@ -101,6 +105,8 @@ rmw_qos_reliability_policy_to_str(enum rmw_qos_reliability_policy_e value) return "reliable"; case RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT: return "best_effort"; + case RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE: + return "best_available"; case RMW_QOS_POLICY_RELIABILITY_UNKNOWN: // fallthrough default: return NULL; @@ -157,6 +163,9 @@ rmw_qos_durability_policy_from_str(const char * str) if (RMW_QOS_STREQ_WITH_LITERAL("volatile", str)) { return RMW_QOS_POLICY_DURABILITY_VOLATILE; } + if (RMW_QOS_STREQ_WITH_LITERAL("best_available", str)) { + return RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE; + } return RMW_QOS_POLICY_DURABILITY_UNKNOWN; } @@ -189,6 +198,9 @@ rmw_qos_liveliness_policy_from_str(const char * str) if (RMW_QOS_STREQ_WITH_LITERAL("manual_by_topic", str)) { return RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC; } + if (RMW_QOS_STREQ_WITH_LITERAL("best_available", str)) { + return RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE; + } return RMW_QOS_POLICY_LIVELINESS_UNKNOWN; } @@ -205,5 +217,8 @@ rmw_qos_reliability_policy_from_str(const char * str) if (RMW_QOS_STREQ_WITH_LITERAL("best_effort", str)) { return RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; } + if (RMW_QOS_STREQ_WITH_LITERAL("best_available", str)) { + return RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE; + } return RMW_QOS_POLICY_RELIABILITY_UNKNOWN; } diff --git a/rmw/test/test_qos_string_conversions.cpp b/rmw/test/test_qos_string_conversions.cpp index 126ad399..922001c6 100644 --- a/rmw/test/test_qos_string_conversions.cpp +++ b/rmw/test/test_qos_string_conversions.cpp @@ -41,15 +41,18 @@ TEST(test_qos_policy_stringify, test_policy_values) { TEST_QOS_POLICY_VALUE_STRINGIFY(durability, RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT); TEST_QOS_POLICY_VALUE_STRINGIFY(durability, RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL); TEST_QOS_POLICY_VALUE_STRINGIFY(durability, RMW_QOS_POLICY_DURABILITY_VOLATILE); + TEST_QOS_POLICY_VALUE_STRINGIFY(durability, RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE); TEST_QOS_POLICY_VALUE_STRINGIFY(history, RMW_QOS_POLICY_HISTORY_KEEP_LAST); TEST_QOS_POLICY_VALUE_STRINGIFY(history, RMW_QOS_POLICY_HISTORY_KEEP_ALL); TEST_QOS_POLICY_VALUE_STRINGIFY(history, RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT); TEST_QOS_POLICY_VALUE_STRINGIFY(liveliness, RMW_QOS_POLICY_LIVELINESS_AUTOMATIC); TEST_QOS_POLICY_VALUE_STRINGIFY(liveliness, RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC); TEST_QOS_POLICY_VALUE_STRINGIFY(liveliness, RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT); + TEST_QOS_POLICY_VALUE_STRINGIFY(liveliness, RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE); TEST_QOS_POLICY_VALUE_STRINGIFY(reliability, RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT); TEST_QOS_POLICY_VALUE_STRINGIFY(reliability, RMW_QOS_POLICY_RELIABILITY_RELIABLE); TEST_QOS_POLICY_VALUE_STRINGIFY(reliability, RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT); + TEST_QOS_POLICY_VALUE_STRINGIFY(reliability, RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE); TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(durability, DURABILITY); TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(history, HISTORY);