-
Notifications
You must be signed in to change notification settings - Fork 500
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
Servo: Ensure yaml param types are correct #427
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thankyou for doing this! Simple change that will clean warnings out of the logs.
@tylerjw is the CI failure here the typical Servo "flaky test" that you've been seeing recently? I think so, because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In MoveIt I introduced parseDouble
two years ago to solve this exact use-case with ROS parameters.
Apparently this was discarded in the transition (because ROS2 does not use xmlrpc for parameter handling?).
The problem is still the same though and I would propose to add an appropriate method back and use it throughout the code base (apparently servo could use it).
If you fix it in our configurations, you will just mask the problem and users will still run into it for no reason.
Codecov Report
@@ Coverage Diff @@
## main #427 +/- ##
==========================================
+ Coverage 51.98% 52.00% +0.02%
==========================================
Files 223 223
Lines 23342 23340 -2
==========================================
+ Hits 12132 12135 +3
+ Misses 11210 11205 -5
Continue to review full report at Codecov.
|
The other option is to put the |
The other option is to put the `cast` functionality into `rosparam_shortcuts`.
Sounds like a good idea. I think even rclcpp should implement that fallback, but the next best option would probably be rosparam_shortcuts.
|
I understand your frustration but actually this problem is actually an improvement imo. There has been a push to add variant types and implicit casts to rclcpp which have been rejected for a reason. A double is declared as double and an int is declared as int, otherwise you end up having arbitrary number types in configs which make parameters even more confusing (unless each parameter has has the type commented inside the yaml file). The exception is also very clear and trivial to fix. I'm all for adding an implicit cast function to |
I understand your frustration but actually this _problem_ is actually an improvement imo.
There has been a push to add variant types and implicit casts to rclcpp which have been rejected for a reason
Sure it's not a bug, it's a feature of the superior new framework. ;)
The feature, no implicit cast from int to double of user-provided values, is the same in ROS though and we added a workaround for it.
The reasons you cite were "we don't want it" and "it requires some significant refactoring to do correctly throughout the API".
I don't expect this ever to happen in rclcpp and it sounds like a good idea to provide the helper with rosparam_shortcuts.
A double is declared as double and an int is declared as int
Agreed. But the parameter should be *declared* on the code side and the documentation, not in the user-provided configuration.
This also seems to be part of the issue in supporting it in the auto-supporting rclcpp API.
The exception is also very clear and trivial to fix.
Sure, you just have to fix it every time you write `0` when the system expects `0.0`.
It's just another useless pitfall and I guess it's only my robotics systems that are full enough of those.
I'm all for adding an implicit cast function to `rosparam_shortcuts` but would not support using it as a convention throughout the code base.
I'm all for cleaning the example configurations to use the correct types (because they are actually part of the documentation), once it's actually supported to pass number literals without a ".0" suffix in.
|
I'll make a PR to ensure the types are handled well in |
Right now there is a warning when it does the implicit conversion. What more do we want? I don't think it is a good idea to have implicit conversions without a warning. If the type should be an integer, it should be declared that way. I think this PR is a good change and we should fix our parameters to have explicit types and where that type is implied based on a literal we should include the @AndyZe the failure you are seeing here is the "flaky test" issue. Re-run this a few times and you'll see that. I also have not reproduced this failure locally, although I haven't put much effort into it. There is a chance it could be reproduced locally. |
I think this PR is a good change
Yes.
Right now there is a warning when it does the implicit conversion. What more do we want?
For starters it would be nice to have a warning that does not look like the value is ignored. ;)
Bust mostly, to have [this logic](https://github.com/ros-planning/moveit2/blob/main/moveit_ros/moveit_servo/src/servo_parameters.cpp#L69) in a reusable place and not reinvent the wheel wherever we run into it. Also to prevent errors.
Looking at the code in detail, does this actually behave correctly? To me it looks like the parameter will actually be *declared* int in the node if it is specified like that in the configuration. Doesn't that mean that users can never set a dynamic parameter declared like that to double values at runtime?
|
I agree with @v4hn -- Servo shouldn't be using unique parsing code that was put together in a rush for GSoC. I also have my doubts about that parsing function. |
I've been working with Boston to create a standard way of doing ros2 parameters in the rosparam_shortcuts package. If we could move whatever we want for this there and servo could just use it, that would be great. |
I tested that the Servo parsing code casts the int's to doubles correctly. It does seem to work! So I'm going to remove the warning for int->double only. I think this is a good fix for now and I'll make an issue to standardize Servo parsing code in the future. This is my debug code:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked more carefully at the up-conversion code and thought of something that could go wrong as a result of it. I now think it is maybe a bad idea at all because we are not just accepting an int we are changing the type that it is declared as.
{ | ||
node->undeclare_parameter(param_name); | ||
// Implicitly cast to double | ||
output_value = node->declare_parameter<int>(param_name, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem I see with doing this is that if we use the dynamic parameter system and someone initially hits this because their yaml has an int in it then later they use the parameter service to update with a double it will fail to set the second time.
I think we should maybe only catch the exception to print a useful error message and exit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'm fine with that. That will force people to quickly ensure their yaml files are correct ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. May this be the last push I make on this silly PR ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's exactly what I pointed out above @tylerjw , thanks for confirming.
My question is whether it's possible, with the current rclcpp interfaces, to get the specified integer parameter, but still declare the parameter as double. If that's not possible, it's a shortcoming of rclcpp because user-configurations should not define/restrict a node's parameter types.
If it's possible, it would be a good idea to provide that functionality with rosparam_shortcuts (and use it here among other places).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand how to accept integers but still declare the parameter as a double with the current system in ROS2. I think I now understand what you were saying up above. I'm sorry it took me a while to get here.
I hope I'm just missing something and that it is possible to still declare the parameter as a double and up-convert any integer that comes in. If that's not possible maybe we could find a way to contribute it upstream (a new "number" type maybe).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I missed your comment about dynamic parameters at first, too
Avoid warnings like this:
InvalidParameterTypeException(moveit_servo.collision_check_rate): parameter 'moveit_servo.collision_check_rate' has invalid type: expected [double] got [integer]