1010import time
1111import rclpy
1212from rclpy .node import Node
13+ from rclpy .client import Client
14+ from rcl_interfaces .msg import Parameter , ParameterType , ParameterValue
1315from controller_manager_msgs .srv import ListControllers
1416from controller_manager_msgs .srv import SwitchController
1517from geometry_msgs .msg import PoseStamped
1618from geometry_msgs .msg import WrenchStamped
19+ from rcl_interfaces .srv import GetParameters , SetParameters
20+ from typing import Any
1721
1822
1923def generate_test_description ():
@@ -52,7 +56,6 @@ def __init__(self, *args):
5256 def setUpClass (cls ):
5357 rclpy .init ()
5458 cls .node = Node ("test_startup" )
55- cls .setup_interfaces (cls )
5659
5760 cls .our_controllers = [
5861 "cartesian_motion_controller" ,
@@ -65,6 +68,8 @@ def setUpClass(cls):
6568 "invalid_cartesian_compliance_controller" ,
6669 ]
6770
71+ cls .setup_interfaces (cls )
72+
6873 @classmethod
6974 def tearDownClass (cls ):
7075 cls .node .destroy_node ()
@@ -86,6 +91,20 @@ def setup_interfaces(self):
8691 if not self .switch_controller .wait_for_service (timeout .nanoseconds / 1e9 ):
8792 self .fail ("Service switch_controllers not available" )
8893
94+ self .get_parameter_clients = {
95+ controller : self .node .create_client (
96+ GetParameters , f"/{ controller } /get_parameters"
97+ )
98+ for controller in self .our_controllers [0 :3 ]
99+ }
100+
101+ self .set_parameter_clients = {
102+ controller : self .node .create_client (
103+ SetParameters , f"/{ controller } /set_parameters"
104+ )
105+ for controller in self .our_controllers [0 :3 ]
106+ }
107+
89108 self .target_pose_pub = self .node .create_publisher (
90109 PoseStamped , "target_frame" , 3
91110 )
@@ -192,6 +211,31 @@ def publish_nan_targets():
192211 )
193212 self .stop_controller (name )
194213
214+ def test_solver_parameters (self ):
215+ """Check whether we can set and get nested solver parameters"""
216+ example_param = "solver.forward_dynamics.link_mass"
217+ default_value = 0.1
218+ new_value = 0.7
219+
220+ for client in self .get_parameter_clients .values ():
221+ result = self .get_parameters (client , [example_param ])
222+ result = result .values [0 ].double_value
223+ self .assertTrue (result == default_value )
224+
225+ for client in self .set_parameter_clients .values ():
226+ param = Parameter (
227+ name = example_param ,
228+ value = ParameterValue (
229+ double_value = new_value , type = ParameterType .PARAMETER_DOUBLE
230+ ),
231+ )
232+ self .set_parameters (client , [param ])
233+
234+ for client in self .get_parameter_clients .values ():
235+ result = self .get_parameters (client , [example_param ])
236+ result = result .values [0 ].double_value
237+ self .assertTrue (result == new_value )
238+
195239 def check_state (self , controller , state ):
196240 """Check the controller's state
197241
@@ -223,3 +267,16 @@ def perform_switch(self, req):
223267 req .strictness = req .BEST_EFFORT
224268 future = self .switch_controller .call_async (req )
225269 rclpy .spin_until_future_complete (self .node , future )
270+
271+ def set_parameters (self , client : Client , params : list [Parameter ]) -> None :
272+ req = SetParameters .Request ()
273+ req .parameters = params
274+ future = client .call_async (req )
275+ rclpy .spin_until_future_complete (self .node , future )
276+
277+ def get_parameters (self , client : Client , names : list [str ]) -> Any :
278+ req = GetParameters .Request ()
279+ req .names = names
280+ future = client .call_async (req )
281+ rclpy .spin_until_future_complete (self .node , future )
282+ return future .result ()
0 commit comments