Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"error updating parameters: don't know parameter" when invoke "rosrun dynamic_reconfigure dynparam load" #163

Open
caijimin opened this issue Sep 27, 2020 · 1 comment

Comments

@caijimin
Copy link

We use ros-kinetic-dynamic-reconfigure 1.5.49-0xenial-20180316-113241-0800.
And occasionally rosrun dynamic_reconfigure dynparam load command reports error updating parameters: don't know parameter xxx. After spent some time to investigate the symptom, I think race condition exits in src/dynamic_reconfigure/client.py

168     def update_configuration(self, changes):
169         """
170         Change the server's configuration
171 
172         @param changes: dictionary of key value pairs for the parameters that are changing
173         @type  changes: {str: value}
174         """
175         # Retrieve the parameter descriptions
176         if self.param_description is None:
177             self.get_parameter_descriptions()
178 
179         # Cast the parameters to the appropriate types
180         if self.param_description is not None:
181             for name, value in list(changes.items())[:]:
182                 if name != 'groups':
183                     dest_type = self._param_types.get(name)
184                     if dest_type is None:
185                         raise DynamicReconfigureParameterException('don\'t know parameter: %s' % name)

Line 185 "error updating parameters: don't know parameter xxx” is reported because the parameter xxx is not exist in map self._param_types.

From below code excerpt, we can see self._param_types is initialized after line 338 after self.param_description is extracted in line

331.
329     def _descriptions_msg(self, msg):
330         self.group_description = decode_description(msg)
331         self.param_description = extract_params(self.group_description)
332 
333         # Build map from parameter name to type
334         self._param_types = {}
335         for p in self.param_description:
336             n, t = p.get('name'), p.get('type')
337             if n is not None and t is not None:
338                 self._param_types[n] = self._param_type_from_string(t)     <<---------
339 
340         with self._cv:
341             self._cv.notifyAll()
342         if self._description_callback is not None:
343             self._description_callback(self.param_description)

Function get_parameter_descriptions will return after self.param_description is NOT None

121     def get_parameter_descriptions(self, timeout=None):
122         """
123         UNSTABLE. Return a description of the parameters for the server.
124         Do not use this method as the type that is returned may change.
125 
126         @param timeout: time to wait before giving up
127         @type  timeout: float
128         """
129         if timeout is None or timeout == 0.0:
130             with self._cv:
131                 while self.param_description is None:
132                     if rospy.is_shutdown():
133                         return None
134                     self._cv.wait()
135         else:
136             start_time = time.time()
137             with self._cv:
138                 while self.param_description is None:
139                     if rospy.is_shutdown():
140                         return None
141                     secs_left = timeout - (time.time() - start_time)
142                     if secs_left <= 0.0:
143                         break
144                     self._cv.wait(secs_left)
145 
146         return self.param_description

But self.param_description is NOT None doesn’t mean self._param_types is successfully initialized, if thread 1 is executing Line 333 ~338, some parameters maybe not set.

333         # Build map from parameter name to type
334         self._param_types = {}
335         for p in self.param_description:
336             n, t = p.get('name'), p.get('type')
337             if n is not None and t is not None:
338                 self._param_types[n] = self._param_type_from_string(t)

Thread 2 execute line 183 will report error.

183                     dest_type = self._param_types.get(name)
184                     if dest_type is None:
185                         raise DynamicReconfigureParameterException('don\'t know parameter: %s' % name)

Could we fix it by add self._param_types_inited to indicate whether self._param_types is already initialized

@@ -76,6 +76,7 @@
         self.group_description = None
 
         self._param_types = None
+        self._param_types_inited = False
 
         self._cv = threading.Condition()
 
@@ -128,14 +129,14 @@
         """
         if timeout is None or timeout == 0.0:
             with self._cv:
-                while self.param_description is None:
+                while self._param_types_inited is False:
                     if rospy.is_shutdown():
                         return None
                     self._cv.wait()
         else:
             start_time = time.time()
             with self._cv:
-                while self.param_description is None:
+                while self._param_types_inited is False:
                     if rospy.is_shutdown():
                         return None
                     secs_left = timeout - (time.time() - start_time)
@@ -337,6 +338,7 @@
             if n is not None and t is not None:
                 self._param_types[n] = self._param_type_from_string(t)
 
+        self._param_types_inited = True
         with self._cv:
             self._cv.notifyAll()
         if self._description_callback is not None:
@szalik-m
Copy link

szalik-m commented Nov 4, 2020

+1 to this issue. It appears more often if you use longer parameter list, which, indeed, can explained by running time of 333 ~ 338 lines.

augustinmanecy added a commit to augustinmanecy/dynamic_reconfigure that referenced this issue Mar 3, 2021
When using rqt_reconfigure with node with a lot of parameters, it seems some parameters are most of time not found when trying to update the configuration.
The parameters are listed in rqt_dynamic_reconfigure, but when trying to change value of some parameters "update_configuration" raise the exception line 185:
```bash
error updating parameters: don't know parameter xxx
``` 
rqt_reconfigure returns:
```bash
```
When equivalent commands set and get succed each time:
```bash
rosrun dynparam get <node_name> <param> 
rosrun dynparam set <node_name> <param> <value>
```
Not sure of what exactly happen as it is not fully repeatable, but the solution proposed in issue ros#163 seems to do the job.
augustinmanecy added a commit to augustinmanecy/dynamic_reconfigure that referenced this issue Mar 3, 2021
When using rqt_reconfigure with node with a lot of parameters, it seems some parameters are most of time not found when trying to update the configuration.
The parameters are listed in rqt_dynamic_reconfigure, but when trying to change value of some parameters "update_configuration" raise the exception line 185:
```bash
error updating parameters: don't know parameter xxx
``` 
rqt_reconfigure returns:
```bash
```
When equivalent commands set and get succed each time:
```bash
rosrun dynparam get <node_name> <param> 
rosrun dynparam set <node_name> <param> <value>
```
Not sure of what exactly happen as it is not fully repeatable, but the solution proposed in issue ros#163 seems to do the job.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants