Skip to content

Commit

Permalink
Support multiple parameter callback
Browse files Browse the repository at this point in the history
Signed-off-by: Abhinav Singh <singhabhinav9051571833@gmail.com>
  • Loading branch information
suab321321 committed Nov 16, 2019
2 parents 3a941ab + e566f3e commit 83230e3
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 16 deletions.
40 changes: 24 additions & 16 deletions rclpy/rclpy/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def __init__(
self.__guards: List[GuardCondition] = []
self.__waitables: List[Waitable] = []
self._default_callback_group = MutuallyExclusiveCallbackGroup()
self._parameters_callback: List[Callable[[List[Parameter]], SetParametersResult]] = []
self._parameters_callbacks: List[Callable[[List[Parameter]], SetParametersResult]] = []
self._rate_group = ReentrantCallbackGroup()
self._allow_undeclared_parameters = allow_undeclared_parameters
self._parameter_overrides = {}
Expand Down Expand Up @@ -714,10 +714,10 @@ def _set_parameters_atomically(

if not result.successful:
return result
elif self._parameters_callback:
for callback in self._parameters_callback:
elif self._parameters_callbacks:
for callback in self._parameters_callbacks:
result = callback(parameter_list)
if(not result.successful):
if not result.successful:
return result
result = SetParametersResult(successful=True)

Expand Down Expand Up @@ -763,24 +763,32 @@ def _set_parameters_atomically(

return result

def add_on_set_paramters_callback(
def add_on_set_parameters_callback(
self,
callback: Callable[[List[Parameter]], SetParametersResult]
) -> None:
"""Add the callback to list."""
prevCallBack = self._parameters_callback
prevCallBack.insert(0, callback)
self._parameters_callback = prevCallBack
"""
Add a callback in front to the list of callbacks.
Calling this function will add a callback in self._parameter_callbacks list.
:param callback: The function that is called whenever parameters are set for the node.
"""
self._parameters_callbacks.insert(0, callback)

def remove_on_set_parameters_callback(
self,
callback: Callable[[List[Parameter]], SetParametersResult]
) -> None:
"""Remove callback from list."""
if callback in self._parameters_callback:
self._parameters_callback.remove(callback)
else:
print('Callback does not exist')
"""
Remove a callback from list of callbacks.
Calling this function will remove the callback from self._parameter_callbacks list.
:param callback: The function that is called whenever parameters are set for the node.
:raises: ValueError if a callback is not present in the list of callback.
"""
self._parameters_callbacks.remove(callback)

def _apply_descriptors(
self,
Expand Down Expand Up @@ -1040,11 +1048,11 @@ def set_parameters_callback(
"""
Register a set parameters callback.
Calling this function will override any previously registered callback.
Calling this function will add a callback in self._parameter_callbacks list.
:param callback: The function that is called whenever parameters are set for the node.
"""
self._parameters_callback = callback
self._parameters_callbacks = [callback]

def _validate_topic_or_service_name(self, topic_or_service_name, *, is_service=False):
name = self.get_name()
Expand Down
144 changes: 144 additions & 0 deletions rclpy/test/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,150 @@ def test_node_set_parameters_rejection(self):
self.assertIsInstance(result[0], SetParametersResult)
self.assertFalse(result[0].successful)

def reject_parameter_callback_1(self, parameter_list):
rejected_parameters = (param for param in parameter_list if 'reject1' in param.name)
return SetParametersResult(successful=(not any(rejected_parameters)))

def reject_parameter_callback_2(self, parameter_list):
rejected_parameters = (param for param in parameter_list if 'reject2' in param.name)
return SetParametersResult(successful=(not any(rejected_parameters)))

def reject_parameter_callback_3(self, parameter_list):
rejected_parameters = (param for param in parameter_list if 'reject3' in param.name)
return SetParametersResult(successful=(not any(rejected_parameters)))

def test_node_set_paramters_rejection_list(self):
# Declare a new paramters and set a list of callbacks so that it's rejected when set.
reject_list_parameter_tuple1 = [
(
'reject1',
True,
ParameterDescriptor()
),
(
'non_reject',
True,
ParameterDescriptor()
),
(
'non_reject',
True,
ParameterDescriptor()
)
]
results = []

self.node.declare_parameters('', reject_list_parameter_tuple1)
self.node.add_on_set_parameters_callback(self.reject_parameter_callback_1)
self.node.add_on_set_parameters_callback(self.reject_parameter_callback_2)
self.node.add_on_set_parameters_callback(self.reject_parameter_callback_3)

result1 = self.node.set_parameters(
[
Parameter(
name=reject_list_parameter_tuple1[0][0],
value=reject_list_parameter_tuple1[0][1]
),
Parameter(
name=reject_list_parameter_tuple1[1][0],
value=reject_list_parameter_tuple1[1][1]
),
Parameter(
name=reject_list_parameter_tuple1[2][0],
value=reject_list_parameter_tuple1[2][1]
)
]
)
results.append(result1)

self.node.undeclare_parameter(reject_list_parameter_tuple1[0][0])
self.node.undeclare_parameter(reject_list_parameter_tuple1[1][0])
self.node.undeclare_parameter(reject_list_parameter_tuple1[2][0])

reject_list_parameter_tuple2 = [
(
'non_reject',
True,
ParameterDescriptor()
),
(
'reject2',
True,
ParameterDescriptor()
),
(
'non_reject',
True,
ParameterDescriptor()
)
]

self.node.declare_parameters('', reject_list_parameter_tuple2)

result2 = self.node.set_parameters(
[
Parameter(
name=reject_list_parameter_tuple2[0][0],
value=reject_list_parameter_tuple2[0][1]
),
Parameter(
name=reject_list_parameter_tuple2[1][0],
value=reject_list_parameter_tuple2[1][1]
),
Parameter(
name=reject_list_parameter_tuple2[2][0],
value=reject_list_parameter_tuple2[2][1]
)
]
)
results.append(result2)

self.node.undeclare_parameter(reject_list_parameter_tuple2[0][0])
self.node.undeclare_parameter(reject_list_parameter_tuple2[1[0]])
self.node.undeclare_parameter(reject_list_parameter_tuple2[2][0])

reject_list_parameter_tuple3 = [
(
'non_reject',
True,
ParameterDescriptor()
),
(
'non_reject',
True,
ParameterDescriptor()
),
(
'reject3',
True,
ParameterDescriptor()
)
]

self.node.declare_parameters('', reject_list_parameter_tuple3)

result3 = self.node.set_parameters(
[
Parameter(
name=reject_list_parameter_tuple3[0][0],
value=reject_list_parameter_tuple3[0][1]
),
Parameter(
name=reject_list_parameter_tuple3[1][0],
value=reject_list_parameter_tuple3[1][1]
),
Parameter(
name=reject_list_parameter_tuple3[2][0],
value=reject_list_parameter_tuple3[2][1]
)
]
)
results.append(result3)
for result in results:
self.assertIsInstance(result, list)
self.assertIsInstance(result[0], SetParametersResult)
self.assertFalse(result[0].successful)

def test_node_set_parameters_read_only(self):
integer_value = 42
string_value = 'hello'
Expand Down

0 comments on commit 83230e3

Please sign in to comment.