diff --git a/rclc_examples/src/example_parameter_server.c b/rclc_examples/src/example_parameter_server.c
index 2832639b..9c2a12b2 100644
--- a/rclc_examples/src/example_parameter_server.c
+++ b/rclc_examples/src/example_parameter_server.c
@@ -36,8 +36,10 @@ void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
rclc_parameter_set_int(¶m_server, "param2", (int64_t) value);
}
-bool on_parameter_changed(const Parameter * old_param, const Parameter * new_param)
+bool on_parameter_changed(const Parameter * old_param, const Parameter * new_param, void * context)
{
+ (void) context;
+
if (old_param == NULL) {
printf("Creating new parameter %s\n", new_param->name.data);
} else if (new_param == NULL) {
@@ -46,13 +48,19 @@ bool on_parameter_changed(const Parameter * old_param, const Parameter * new_par
printf("Parameter %s modified.", old_param->name.data);
switch (old_param->value.type) {
case RCLC_PARAMETER_BOOL:
- printf(" Old value: %d, New value: %d (bool)", old_param->value.bool_value, new_param->value.bool_value);
+ printf(
+ " Old value: %d, New value: %d (bool)", old_param->value.bool_value,
+ new_param->value.bool_value);
break;
case RCLC_PARAMETER_INT:
- printf(" Old value: %ld, New value: %ld (int)", old_param->value.integer_value, new_param->value.integer_value);
+ printf(
+ " Old value: %ld, New value: %ld (int)", old_param->value.integer_value,
+ new_param->value.integer_value);
break;
case RCLC_PARAMETER_DOUBLE:
- printf(" Old value: %f, New value: %f (double)", old_param->value.double_value, new_param->value.double_value);
+ printf(
+ " Old value: %f, New value: %f (double)", old_param->value.double_value,
+ new_param->value.double_value);
break;
default:
break;
@@ -106,7 +114,7 @@ int main()
// Add parameters constrains
rclc_add_parameter_description(¶m_server, "param2", "Second parameter", "Only even numbers");
- rclc_add_parameter_constraints_integer(¶m_server, "param2", -10, 120, 2);
+ rclc_add_parameter_constraints_integer(¶m_server, "param2", -10, 120, 2);
rclc_add_parameter_description(¶m_server, "param3", "Third parameter", "");
rclc_set_parameter_read_only(¶m_server, "param3", true);
diff --git a/rclc_parameter/include/rclc_parameter/rclc_parameter.h b/rclc_parameter/include/rclc_parameter/rclc_parameter.h
index 23618308..f02cf8df 100644
--- a/rclc_parameter/include/rclc_parameter/rclc_parameter.h
+++ b/rclc_parameter/include/rclc_parameter/rclc_parameter.h
@@ -68,10 +68,10 @@ typedef struct rcl_interfaces__msg__ParameterEvent ParameterEvent;
// Number of RCLC executor handles required for a parameter server
#define RCLC_PARAMETER_EXECUTOR_HANDLES_NUMBER 5
-#define PARAMETER_MODIFICATION_REJECTED 4001
-#define PARAMETER_TYPE_MISMATCH 4002
-#define UNSUPORTED_ON_LOW_MEM 4003
-#define DISABLE_ON_CALLBACK 40004
+#define RCLC_PARAMETER_MODIFICATION_REJECTED 4001
+#define RCLC_PARAMETER_TYPE_MISMATCH 4002
+#define RCLC_PARAMETER_UNSUPORTED_ON_LOW_MEM 4003
+#define RCLC_PARAMETER_DISABLED_ON_CALLBACK 40004
/**
* Parameter event callback.
@@ -92,11 +92,13 @@ typedef struct rcl_interfaces__msg__ParameterEvent ParameterEvent;
*
* \param[in] param Parameter actual value, `NULL` for new parameter request.
* \param[in] new_value Parameter new value, `NULL` for parameter removal request.
+ * \param[in] context Context of the callback.
* \return `true` to accept the parameter event. The operation will be rejected on `false` return.
*/
-typedef bool (* ModifiedParameter_Callback)(
+typedef bool (* rclc_parameter_callback_t)(
const Parameter * old_param,
- const Parameter * new_param);
+ const Parameter * new_param,
+ void * context);
// Allowed RCLC parameter types
typedef enum rclc_parameter_type_t
@@ -146,7 +148,8 @@ typedef struct rclc_parameter_server_t
ParameterEvent event_list;
- ModifiedParameter_Callback on_modification;
+ rclc_parameter_callback_t on_modification;
+ void * context;
bool on_callback;
bool notify_changed_over_dds;
@@ -236,7 +239,31 @@ RCLC_PARAMETER_PUBLIC
rcl_ret_t rclc_executor_add_parameter_server(
rclc_executor_t * executor,
rclc_parameter_server_t * parameter_server,
- ModifiedParameter_Callback on_modification);
+ rclc_parameter_callback_t on_modification);
+
+/**
+ * Adds a RCLC parameter server to an RCLC executor
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | No
+ *
+ * \param[in] executor RCLC executor
+ * \param[in] parameter_server preallocated rclc_parameter_server_t
+ * \param[in] on_modification on parameter modification callback
+ * \param[in] context context of the parameter modification callback
+ * \return `RCL_RET_OK` if success
+ */
+RCLC_PARAMETER_PUBLIC
+rcl_ret_t rclc_executor_add_parameter_server_with_context(
+ rclc_executor_t * executor,
+ rclc_parameter_server_t * parameter_server,
+ rclc_parameter_callback_t on_modification,
+ void * context);
/**
* Adds a RCLC parameter to a server
diff --git a/rclc_parameter/src/rclc_parameter/parameter_server.c b/rclc_parameter/src/rclc_parameter/parameter_server.c
index 40607a50..67235b46 100644
--- a/rclc_parameter/src/rclc_parameter/parameter_server.c
+++ b/rclc_parameter/src/rclc_parameter/parameter_server.c
@@ -256,9 +256,9 @@ rclc_parameter_server_set_service_callback(
if (ret == RCL_RET_INVALID_ARGUMENT) {
rclc_parameter_set_string(message, "Set parameter error");
- } else if (ret == PARAMETER_MODIFICATION_REJECTED) {
+ } else if (ret == RCLC_PARAMETER_MODIFICATION_REJECTED) {
rclc_parameter_set_string(message, "Rejected by server");
- } else if (ret == PARAMETER_TYPE_MISMATCH) {
+ } else if (ret == RCLC_PARAMETER_TYPE_MISMATCH) {
rclc_parameter_set_string(message, "Type mismatch");
} else {
response->results.data[i].successful = true;
@@ -1067,7 +1067,19 @@ rcl_ret_t
rclc_executor_add_parameter_server(
rclc_executor_t * executor,
rclc_parameter_server_t * parameter_server,
- ModifiedParameter_Callback on_modification)
+ rclc_parameter_callback_t on_modification)
+{
+ return rclc_executor_add_parameter_server_with_context(
+ executor, parameter_server,
+ on_modification, NULL);
+}
+
+rcl_ret_t
+rclc_executor_add_parameter_server_with_context(
+ rclc_executor_t * executor,
+ rclc_parameter_server_t * parameter_server,
+ rclc_parameter_callback_t on_modification,
+ void * context)
{
RCL_CHECK_FOR_NULL_WITH_MSG(
executor, "executor is a null pointer", return RCL_RET_INVALID_ARGUMENT);
@@ -1077,6 +1089,7 @@ rclc_executor_add_parameter_server(
rcl_ret_t ret;
parameter_server->on_modification = on_modification;
+ parameter_server->context = context;
ret = rclc_executor_add_service_with_context(
executor, ¶meter_server->list_service,
@@ -1121,7 +1134,7 @@ rclc_add_parameter(
parameter_name, "parameter_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
size_t index = parameter_server->parameter_list.size;
@@ -1223,7 +1236,7 @@ rclc_delete_parameter(
parameter_name, "parameter_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
// Find parameter
@@ -1286,7 +1299,7 @@ rclc_parameter_set_bool(
parameter_name, "parameter_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
Parameter * parameter =
@@ -1297,18 +1310,16 @@ rclc_parameter_set_bool(
}
if (parameter->value.type != RCLC_PARAMETER_BOOL) {
- return PARAMETER_TYPE_MISMATCH;
+ return RCLC_PARAMETER_TYPE_MISMATCH;
}
- if (parameter_server->on_modification) {
- Parameter new_parameter = *parameter;
- new_parameter.value.bool_value = value;
+ Parameter new_parameter = *parameter;
+ new_parameter.value.bool_value = value;
- if (RCL_RET_OK !=
- rclc_parameter_execute_callback(parameter_server, parameter, &new_parameter))
- {
- return PARAMETER_MODIFICATION_REJECTED;
- }
+ if (RCL_RET_OK !=
+ rclc_parameter_execute_callback(parameter_server, parameter, &new_parameter))
+ {
+ return RCLC_PARAMETER_MODIFICATION_REJECTED;
}
if (parameter_server->notify_changed_over_dds) {
@@ -1333,7 +1344,7 @@ rclc_parameter_set_int(
parameter_name, "parameter_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
Parameter * parameter =
@@ -1344,18 +1355,16 @@ rclc_parameter_set_int(
}
if (parameter->value.type != RCLC_PARAMETER_INT) {
- return PARAMETER_TYPE_MISMATCH;
+ return RCLC_PARAMETER_TYPE_MISMATCH;
}
- if (parameter_server->on_modification) {
- Parameter new_parameter = *parameter;
- new_parameter.value.integer_value = value;
+ Parameter new_parameter = *parameter;
+ new_parameter.value.integer_value = value;
- if (RCL_RET_OK !=
- rclc_parameter_execute_callback(parameter_server, parameter, &new_parameter))
- {
- return PARAMETER_MODIFICATION_REJECTED;
- }
+ if (RCL_RET_OK !=
+ rclc_parameter_execute_callback(parameter_server, parameter, &new_parameter))
+ {
+ return RCLC_PARAMETER_MODIFICATION_REJECTED;
}
if (parameter_server->notify_changed_over_dds) {
@@ -1380,7 +1389,7 @@ rclc_parameter_set_double(
parameter_name, "parameter_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
Parameter * parameter =
@@ -1391,18 +1400,16 @@ rclc_parameter_set_double(
}
if (parameter->value.type != RCLC_PARAMETER_DOUBLE) {
- return PARAMETER_TYPE_MISMATCH;
+ return RCLC_PARAMETER_TYPE_MISMATCH;
}
- if (parameter_server->on_modification) {
- Parameter new_parameter = *parameter;
- new_parameter.value.double_value = value;
+ Parameter new_parameter = *parameter;
+ new_parameter.value.double_value = value;
- if (RCL_RET_OK !=
- rclc_parameter_execute_callback(parameter_server, parameter, &new_parameter))
- {
- return PARAMETER_MODIFICATION_REJECTED;
- }
+ if (RCL_RET_OK !=
+ rclc_parameter_execute_callback(parameter_server, parameter, &new_parameter))
+ {
+ return RCLC_PARAMETER_MODIFICATION_REJECTED;
}
if (parameter_server->notify_changed_over_dds) {
@@ -1544,7 +1551,7 @@ rcl_ret_t rclc_add_parameter_description(
const char * additional_constraints)
{
if (parameter_server->low_mem_mode) {
- return UNSUPORTED_ON_LOW_MEM;
+ return RCLC_PARAMETER_UNSUPORTED_ON_LOW_MEM;
}
size_t index = rclc_parameter_search_index(¶meter_server->parameter_list, parameter_name);
@@ -1576,7 +1583,7 @@ rcl_ret_t rclc_set_parameter_read_only(
const char * parameter_name, bool read_only)
{
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
size_t index = rclc_parameter_search_index(¶meter_server->parameter_list, parameter_name);
@@ -1599,7 +1606,7 @@ rcl_ret_t rclc_add_parameter_constraints_double(
double to_value, double step)
{
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
size_t index = rclc_parameter_search_index(¶meter_server->parameter_list, parameter_name);
@@ -1628,7 +1635,7 @@ rcl_ret_t rclc_add_parameter_constraints_integer(
int64_t to_value, uint64_t step)
{
if (parameter_server->on_callback) {
- return DISABLE_ON_CALLBACK;
+ return RCLC_PARAMETER_DISABLED_ON_CALLBACK;
}
size_t index = rclc_parameter_search_index(¶meter_server->parameter_list, parameter_name);
@@ -1659,11 +1666,11 @@ rcl_ret_t rclc_parameter_execute_callback(
if (parameter_server->on_modification) {
parameter_server->on_callback = true;
- ret = parameter_server->on_modification(old_param, new_param);
+ ret = parameter_server->on_modification(old_param, new_param, parameter_server->context);
parameter_server->on_callback = false;
}
- return ret ? RCL_RET_OK : PARAMETER_MODIFICATION_REJECTED;
+ return ret ? RCL_RET_OK : RCLC_PARAMETER_MODIFICATION_REJECTED;
}
#if __cplusplus
diff --git a/rclc_parameter/test/rclc_parameter/test_parameter.cpp b/rclc_parameter/test/rclc_parameter/test_parameter.cpp
index e957004a..0c3d1351 100644
--- a/rclc_parameter/test/rclc_parameter/test_parameter.cpp
+++ b/rclc_parameter/test/rclc_parameter/test_parameter.cpp
@@ -110,16 +110,10 @@ class ParameterTestBase : public ::testing::TestWithParam(10000)),
+ : callback_calls(0),
+ default_spin_timeout(std::chrono::duration(10000)),
options(GetParam())
- {
- callcack_calls = 0;
- user_return = true;
- strncpy(old_parameter_name, "", sizeof(old_parameter_name));
- strncpy(new_parameter_name, "", sizeof(new_parameter_name));
- new_parameter_value.type = RCLC_PARAMETER_NOT_SET;
- old_parameter_value.type = RCLC_PARAMETER_NOT_SET;
- }
+ {}
~ParameterTestBase() {}
@@ -142,9 +136,10 @@ class ParameterTestBase : public ::testing::TestWithParamname.data, sizeof(new_parameter_name));
- rclc_parameter_value_copy(&new_parameter_value, &new_param->value);
- }
-
- if (old_param == NULL) {
- strncpy(old_parameter_name, "null", sizeof(old_parameter_name));
- old_parameter_value.type = RCLC_PARAMETER_NOT_SET;
- } else {
- strncpy(old_parameter_name, old_param->name.data, sizeof(old_parameter_name));
- rclc_parameter_value_copy(&old_parameter_value, &old_param->value);
- }
-
- callcack_calls++;
- return user_return;
+ ParameterTestBase * obj = reinterpret_cast(context);
+ obj->callback_calls++;
+ return obj->on_parameter_changed(old_param, new_param);
}
protected:
// Callback
- static int callcack_calls;
- static bool user_return;
- static char old_parameter_name[RCLC_PARAMETER_MAX_STRING_LENGTH];
- static char new_parameter_name[RCLC_PARAMETER_MAX_STRING_LENGTH];
- static ParameterValue new_parameter_value;
- static ParameterValue old_parameter_value;
+ size_t callback_calls;
+ std::function on_parameter_changed;
// Rclcpp
std::shared_ptr param_client_node;
@@ -233,15 +212,8 @@ class ParameterTestBase : public ::testing::TestWithParam bool {
+ EXPECT_EQ(strcmp(old_param->name.data, param_name), 0);
+ EXPECT_EQ(strcmp(new_param->name.data, param_name), 0);
+ EXPECT_EQ(old_param->value.type, RCLC_PARAMETER_BOOL);
+ EXPECT_EQ(new_param->value.type, RCLC_PARAMETER_BOOL);
+ EXPECT_EQ(old_param->value.bool_value, get_value);
+ EXPECT_EQ(new_param->value.bool_value, set_value);
+ return true;
+ };
+
ASSERT_EQ(rclc_parameter_set_bool(¶m_server, param_name, set_value), RCL_RET_OK);
- ASSERT_EQ(strcmp(old_parameter_name, param_name), 0);
- ASSERT_EQ(strcmp(new_parameter_name, param_name), 0);
- ASSERT_EQ(old_parameter_value.type, RCLC_PARAMETER_BOOL);
- ASSERT_EQ(new_parameter_value.type, RCLC_PARAMETER_BOOL);
- ASSERT_EQ(old_parameter_value.bool_value, get_value);
- ASSERT_EQ(new_parameter_value.bool_value, set_value);
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- expected_callcack_calls++;
+ EXPECT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Get new value
ASSERT_EQ(rclc_parameter_get_bool(¶m_server, param_name, &get_value), RCL_RET_OK);
@@ -279,15 +255,19 @@ TEST_P(ParameterTestBase, rclc_set_get_parameter) {
ASSERT_EQ(get_value, 0);
// Set value
+ on_parameter_changed = [&](const Parameter * old_param, const Parameter * new_param) -> bool {
+ EXPECT_EQ(strcmp(old_param->name.data, param_name), 0);
+ EXPECT_EQ(strcmp(new_param->name.data, param_name), 0);
+ EXPECT_EQ(old_param->value.type, RCLC_PARAMETER_INT);
+ EXPECT_EQ(new_param->value.type, RCLC_PARAMETER_INT);
+ EXPECT_EQ(old_param->value.integer_value, get_value);
+ EXPECT_EQ(new_param->value.integer_value, set_value);
+ return true;
+ };
+
ASSERT_EQ(rclc_parameter_set_int(¶m_server, param_name, set_value), RCL_RET_OK);
- ASSERT_EQ(strcmp(old_parameter_name, param_name), 0);
- ASSERT_EQ(strcmp(new_parameter_name, param_name), 0);
- ASSERT_EQ(old_parameter_value.type, RCLC_PARAMETER_INT);
- ASSERT_EQ(new_parameter_value.type, RCLC_PARAMETER_INT);
- ASSERT_EQ(old_parameter_value.integer_value, 0);
- ASSERT_EQ(new_parameter_value.integer_value, set_value);
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Get new value
ASSERT_EQ(rclc_parameter_get_int(¶m_server, param_name, &get_value), RCL_RET_OK);
@@ -304,17 +284,21 @@ TEST_P(ParameterTestBase, rclc_set_get_parameter) {
ASSERT_EQ(get_value, 0.0);
// Set value
+ on_parameter_changed = [&](const Parameter * old_param, const Parameter * new_param) -> bool {
+ EXPECT_EQ(strcmp(old_param->name.data, param_name), 0);
+ EXPECT_EQ(strcmp(new_param->name.data, param_name), 0);
+ EXPECT_EQ(old_param->value.type, RCLC_PARAMETER_DOUBLE);
+ EXPECT_EQ(new_param->value.type, RCLC_PARAMETER_DOUBLE);
+ EXPECT_EQ(old_param->value.double_value, get_value);
+ EXPECT_EQ(new_param->value.double_value, set_value);
+ return true;
+ };
+
ASSERT_EQ(
rclc_parameter_set_double(
¶m_server, param_name, set_value), RCL_RET_OK);
- ASSERT_EQ(strcmp(old_parameter_name, param_name), 0);
- ASSERT_EQ(strcmp(new_parameter_name, param_name), 0);
- ASSERT_EQ(old_parameter_value.type, RCLC_PARAMETER_DOUBLE);
- ASSERT_EQ(new_parameter_value.type, RCLC_PARAMETER_DOUBLE);
- ASSERT_EQ(old_parameter_value.double_value, 0.0);
- ASSERT_EQ(new_parameter_value.double_value, set_value);
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Get new value
ASSERT_EQ(rclc_parameter_get_double(¶m_server, param_name, &get_value), RCL_RET_OK);
@@ -322,7 +306,6 @@ TEST_P(ParameterTestBase, rclc_set_get_parameter) {
}
// Fail with user reject
- user_return = false;
{
const char * param_name = "param3";
double set_value = 0.05;
@@ -333,11 +316,15 @@ TEST_P(ParameterTestBase, rclc_set_get_parameter) {
ASSERT_EQ(rclc_parameter_get_double(¶m_server, param_name, &first_get_value), RCL_RET_OK);
// Set value
+ on_parameter_changed = [&](const Parameter *, const Parameter *) -> bool {
+ return false;
+ };
+
ASSERT_EQ(
rclc_parameter_set_double(
¶m_server, param_name,
- set_value), PARAMETER_MODIFICATION_REJECTED);
- ASSERT_EQ(callcack_calls, 4);
+ set_value), RCLC_PARAMETER_MODIFICATION_REJECTED);
+ ASSERT_EQ(callback_calls, expected_callback_calls);
// Get value
ASSERT_EQ(rclc_parameter_get_double(¶m_server, param_name, &second_get_value), RCL_RET_OK);
@@ -346,7 +333,7 @@ TEST_P(ParameterTestBase, rclc_set_get_parameter) {
}
TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
- int expected_callcack_calls = 1;
+ size_t expected_callback_calls = 1;
// List parameters check
std::vector param_names = {"param1", "param2", "param3"};
@@ -367,18 +354,21 @@ TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
bool get_value = parameters_client->get_parameter(param_name);
ASSERT_EQ(get_value, false);
+ // Prepare RCLC callback
+ on_parameter_changed = [&](const Parameter *, const Parameter * new_param) -> bool {
+ EXPECT_EQ(new_param->value.type, RCLC_PARAMETER_BOOL);
+ EXPECT_EQ(strcmp(new_param->name.data, param_name.c_str()), 0);
+ EXPECT_EQ(new_param->value.bool_value, param[0].as_bool());
+ return true;
+ };
+
// Set value
auto result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_TRUE(result[0].successful);
ASSERT_EQ(result[0].reason, "");
-
- // Check callback values
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- ASSERT_EQ(new_parameter_value.type, RCLC_PARAMETER_BOOL);
- ASSERT_EQ(new_parameter_name, param_name);
- ASSERT_EQ(new_parameter_value.bool_value, param[0].as_bool());
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Get new value
get_value = parameters_client->get_parameter(param_name);
@@ -393,6 +383,14 @@ TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
int get_value = parameters_client->get_parameter(param_name);
ASSERT_EQ(get_value, false);
+ // Prepare RCLC callback
+ on_parameter_changed = [&](const Parameter *, const Parameter * new_param) -> bool {
+ EXPECT_EQ(new_param->value.type, RCLC_PARAMETER_INT);
+ EXPECT_EQ(strcmp(new_param->name.data, param_name.c_str()), 0);
+ EXPECT_EQ(new_param->value.integer_value, param[0].as_int());
+ return true;
+ };
+
// Set value
auto result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
@@ -400,11 +398,8 @@ TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
ASSERT_EQ(result[0].reason, "");
// Check callback values
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- ASSERT_EQ(new_parameter_value.type, RCLC_PARAMETER_INT);
- ASSERT_EQ(new_parameter_name, param_name);
- ASSERT_EQ(new_parameter_value.integer_value, param[0].as_int());
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Get new value
get_value = parameters_client->get_parameter(param_name);
@@ -419,6 +414,14 @@ TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
double get_value = parameters_client->get_parameter(param_name);
ASSERT_EQ(get_value, false);
+ // Prepare RCLC callback
+ on_parameter_changed = [&](const Parameter *, const Parameter * new_param) -> bool {
+ EXPECT_EQ(new_param->value.type, RCLC_PARAMETER_DOUBLE);
+ EXPECT_EQ(strcmp(new_param->name.data, param_name.c_str()), 0);
+ EXPECT_EQ(new_param->value.double_value, param[0].as_double());
+ return true;
+ };
+
// Set value
auto result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
@@ -426,11 +429,8 @@ TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
ASSERT_EQ(result[0].reason, "");
// Check callback values
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- ASSERT_EQ(new_parameter_value.type, RCLC_PARAMETER_DOUBLE);
- ASSERT_EQ(new_parameter_name, param_name);
- ASSERT_EQ(new_parameter_value.double_value, param[0].as_double());
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Get new value
get_value = parameters_client->get_parameter(param_name);
@@ -438,7 +438,6 @@ TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
}
// Fail with user reject
- user_return = false;
{
std::vector param = {rclcpp::Parameter(param_names[2], -0.05)};
const std::string param_name = param[0].get_name();
@@ -446,13 +445,18 @@ TEST_P(ParameterTestBase, rclcpp_set_get_parameter) {
// Get initial value
double first_get_value = parameters_client->get_parameter(param_name);
+ // Prepare RCLC callback
+ on_parameter_changed = [&](const Parameter *, const Parameter *) -> bool {
+ return false;
+ };
+
// Set value
auto result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_FALSE(result[0].successful);
ASSERT_EQ(result[0].reason, "Rejected by server");
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Get value
double second_get_value = parameters_client->get_parameter(param_name);
@@ -465,6 +469,12 @@ TEST_P(ParameterTestBase, rclc_delete_parameter) {
const char * param_name = "param1";
bool param_value;
+ // Fail if callback is call
+ on_parameter_changed = [&](const Parameter *, const Parameter *) -> bool {
+ EXPECT_TRUE(false); // Callback should not be called
+ return false;
+ };
+
ASSERT_EQ(rclc_parameter_get_bool(¶m_server, param_name, ¶m_value), RCL_RET_OK);
// Delete parameter
@@ -475,32 +485,46 @@ TEST_P(ParameterTestBase, rclc_delete_parameter) {
// Fail on deleted parameter
EXPECT_EQ(rclc_delete_parameter(¶m_server, param_name), RCL_RET_ERROR);
+
+ // No callback calls
+ ASSERT_EQ(callback_calls, 0U);
}
TEST_P(ParameterTestBase, rclcpp_delete_parameter) {
- int expected_callcack_calls = 1;
+ size_t expected_callback_calls = 1;
// Use RCLCPP to delete and check parameters
- user_return = false;
const std::vector parameters = {"param1"};
+
+ on_parameter_changed = [&](const Parameter * old_param, const Parameter * new_param) -> bool {
+ EXPECT_NE(old_param, nullptr);
+ EXPECT_EQ(new_param, nullptr);
+ return false;
+ };
+
auto result = parameters_client->delete_parameters(parameters, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_FALSE(result[0].successful);
ASSERT_EQ(result[0].reason, "Rejected by server");
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
auto list_params = parameters_client->list_parameters({}, 4, default_spin_timeout);
ASSERT_EQ(list_params.names.size(), 3u);
ASSERT_EQ(list_params.names[0], parameters[0]);
- user_return = true;
+ on_parameter_changed = [&](const Parameter * old_param, const Parameter * new_param) -> bool {
+ EXPECT_NE(old_param, nullptr);
+ EXPECT_EQ(new_param, nullptr);
+ return true;
+ };
+
result = parameters_client->delete_parameters(parameters, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_TRUE(result[0].successful);
ASSERT_EQ(result[0].reason, "");
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
// Use auxiliar RCLCPP node for check
list_params = parameters_client->list_parameters({}, 4, default_spin_timeout);
@@ -508,23 +532,30 @@ TEST_P(ParameterTestBase, rclcpp_delete_parameter) {
ASSERT_EQ(
std::find(
list_params.names.begin(),
- list_params.names.end(), parameters[0]), list_params.names.end());
+ list_params.names.end(),
+ parameters[0]),
+ list_params.names.end());
}
TEST_P(ParameterTestBase, rclcpp_add_parameter) {
std::vector param = {rclcpp::Parameter("param4", 10.5)};
if (options.allow_undeclared_parameters) {
- int expected_callcack_calls = 1;
+ size_t expected_callback_calls = 1;
// Reject add parameter
- user_return = false;
+ on_parameter_changed = [&](const Parameter * old_param, const Parameter * new_param) -> bool {
+ EXPECT_EQ(old_param, nullptr);
+ EXPECT_NE(new_param, nullptr);
+ return false;
+ };
+
auto result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_FALSE(result[0].successful);
ASSERT_EQ(result[0].reason, "New parameter rejected");
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
- expected_callcack_calls++;
+ ASSERT_EQ(callback_calls, expected_callback_calls);
+ expected_callback_calls++;
auto list_params = parameters_client->list_parameters({}, 4, default_spin_timeout);
ASSERT_EQ(list_params.names.size(), 3u);
@@ -534,12 +565,17 @@ TEST_P(ParameterTestBase, rclcpp_add_parameter) {
param[0].get_name()), list_params.names.end());
// Accept add parameter
- user_return = true;
+ on_parameter_changed = [&](const Parameter * old_param, const Parameter * new_param) -> bool {
+ EXPECT_EQ(old_param, nullptr);
+ EXPECT_NE(new_param, nullptr);
+ return true;
+ };
+
result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_TRUE(result[0].successful);
ASSERT_EQ(result[0].reason, "New parameter added");
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
+ ASSERT_EQ(callback_calls, expected_callback_calls);
list_params = parameters_client->list_parameters({}, 4, default_spin_timeout);
ASSERT_EQ(list_params.names.size(), 4u);
@@ -550,21 +586,30 @@ TEST_P(ParameterTestBase, rclcpp_add_parameter) {
ASSERT_EQ(param_value, 10.5);
// Reject parameter on full server
- user_return = false;
+ on_parameter_changed = [&](const Parameter *, const Parameter *) -> bool {
+ EXPECT_TRUE(false); // Callback should not be called
+ return false;
+ };
+
param.clear();
param.push_back(rclcpp::Parameter("param5", 12.2));
result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_FALSE(result[0].successful);
ASSERT_EQ(result[0].reason, "Parameter server is full");
- ASSERT_EQ(callcack_calls, expected_callcack_calls);
+ ASSERT_EQ(callback_calls, expected_callback_calls);
} else {
+ on_parameter_changed = [&](const Parameter *, const Parameter *) -> bool {
+ EXPECT_TRUE(false); // Callback should not be called
+ return false;
+ };
+
// Reject add parameter
auto result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_FALSE(result[0].successful);
ASSERT_EQ(result[0].reason, "Parameter not found");
- ASSERT_EQ(callcack_calls, 0);
+ ASSERT_EQ(callback_calls, 0U);
auto list_params = parameters_client->list_parameters({}, 4, default_spin_timeout);
ASSERT_EQ(list_params.names.size(), 3u);
@@ -581,11 +626,16 @@ TEST_P(ParameterTestBase, rclcpp_read_only_parameter) {
std::vector param = {rclcpp::Parameter("param2", 50)};
// Reject set parameter on read only parameter
+ on_parameter_changed = [&](const Parameter *, const Parameter *) -> bool {
+ EXPECT_TRUE(false); // Callback should not be called
+ return false;
+ };
+
auto result = parameters_client->set_parameters(param, default_spin_timeout);
ASSERT_FALSE(result.empty());
ASSERT_FALSE(result[0].successful);
ASSERT_EQ(result[0].reason, "Read only parameter");
- ASSERT_EQ(callcack_calls, 0);
+ ASSERT_EQ(callback_calls, 0U);
// Check read only flag on descriptor
std::vector params = {param[0].get_name()};
@@ -668,7 +718,9 @@ TEST_P(ParameterTestBase, rclcpp_parameter_description_low) {
// Set parameter constrains
ASSERT_EQ(
- rclc_add_parameter_description(¶m_server, "param2", "", ""), UNSUPORTED_ON_LOW_MEM);
+ rclc_add_parameter_description(
+ ¶m_server, "param2", "",
+ ""), RCLC_PARAMETER_UNSUPORTED_ON_LOW_MEM);
ASSERT_EQ(
rclc_add_parameter_constraints_integer(
¶m_server, "param2", int_from, int_to,
@@ -742,6 +794,10 @@ TEST_P(ParameterTestBase, notify_changed_over_dds) {
std::this_thread::sleep_for(500ms);
// Parameter change event
+ on_parameter_changed = [&](const Parameter *, const Parameter *) -> bool {
+ return true;
+ };
+
ASSERT_EQ(rclc_parameter_set_bool(¶m_server, "param1", false), RCL_RET_OK);
ASSERT_EQ(
rclcpp::spin_until_future_complete(