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

Servo: Ensure yaml param types are correct #427

Merged
merged 6 commits into from
Apr 20, 2021

Conversation

AndyZe
Copy link
Member

@AndyZe AndyZe commented Apr 17, 2021

Avoid warnings like this:

InvalidParameterTypeException(moveit_servo.collision_check_rate): parameter 'moveit_servo.collision_check_rate' has invalid type: expected [double] got [integer]

Copy link
Member

@tylerjw tylerjw left a 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.

@AndyZe
Copy link
Member Author

AndyZe commented Apr 18, 2021

@tylerjw is the CI failure here the typical Servo "flaky test" that you've been seeing recently?

I think so, because BuildAndTest / foxy-ci-testing + clang-tidy passed but BuildAndTest / foxy-ci + ccov did not. It also passes locally.

@AndyZe AndyZe changed the title Ensure yaml param types are correct Servo: Ensure yaml param types are correct Apr 18, 2021
v4hn
v4hn previously requested changes Apr 18, 2021
Copy link
Contributor

@v4hn v4hn left a 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
Copy link

codecov bot commented Apr 18, 2021

Codecov Report

Merging #427 (e7c5e5e) into main (2bd2261) will increase coverage by 0.02%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            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     
Impacted Files Coverage Δ
moveit_ros/moveit_servo/src/servo_parameters.cpp 64.92% <0.00%> (-2.32%) ⬇️
...nning_scene_monitor/src/planning_scene_monitor.cpp 56.11% <0.00%> (-0.12%) ⬇️
moveit_ros/moveit_servo/src/pose_tracking.cpp 76.48% <0.00%> (+0.59%) ⬆️
...meterization/work_space/pose_model_state_space.cpp 81.14% <0.00%> (+0.63%) ⬆️
.../ompl_interface/src/detail/constrained_sampler.cpp 59.46% <0.00%> (+16.22%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2bd2261...e7c5e5e. Read the comment docs.

@AndyZe
Copy link
Member Author

AndyZe commented Apr 19, 2021

The other option is to put the cast functionality into rosparam_shortcuts.

@v4hn
Copy link
Contributor

v4hn commented Apr 19, 2021 via email

@henningkayser
Copy link
Member

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.

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 rosparam_shortcuts but would not support using it as a convention throughout the code base.

@v4hn
Copy link
Contributor

v4hn commented Apr 19, 2021 via email

@AndyZe
Copy link
Member Author

AndyZe commented Apr 19, 2021

I'll make a PR to ensure the types are handled well in rosparam_shortcuts 👍

@tylerjw
Copy link
Member

tylerjw commented Apr 19, 2021

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.

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 .0 so it is obvious to anyone reading the config that this is a floating point value and not an integer.

@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.

@v4hn
Copy link
Contributor

v4hn commented Apr 19, 2021 via email

@AndyZe
Copy link
Member Author

AndyZe commented Apr 19, 2021

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.

@tylerjw
Copy link
Member

tylerjw commented Apr 19, 2021

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.

@AndyZe
Copy link
Member Author

AndyZe commented Apr 20, 2021

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:

  catch (const rclcpp::exceptions::InvalidParameterTypeException& e)
  {
    RCLCPP_WARN_STREAM(logger, "InvalidParameterTypeException(" << param_name << "): " << e.what());

    // Catch a <double> parameter written in the yaml as "1" being considered an <int>
    if (std::is_same<T, double>::value)
    {
      node->undeclare_parameter(param_name);
      output_value = node->declare_parameter<int>(param_name, 0);
      RCLCPP_ERROR_STREAM(logger, "Param name: " << param_name);
      RCLCPP_ERROR_STREAM(logger, "Param value: " << output_value);
      RCLCPP_ERROR_STREAM(logger, "Param type: " << typeid(output_value).name());
      RCLCPP_ERROR_STREAM(logger, "===");
    }

Copy link
Member

@tylerjw tylerjw left a 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.

moveit_ros/moveit_servo/src/servo_parameters.cpp Outdated Show resolved Hide resolved
{
node->undeclare_parameter(param_name);
// Implicitly cast to double
output_value = node->declare_parameter<int>(param_name, 0);
Copy link
Member

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.

Copy link
Member Author

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 ;)

Copy link
Member Author

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 ;)

Copy link
Contributor

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).

Copy link
Member

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).

Copy link
Member Author

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

@v4hn v4hn dismissed their stale review April 20, 2021 18:44

Everyone's ignoring me anyway.

@AndyZe AndyZe merged commit 2be91d2 into moveit:main Apr 20, 2021
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

Successfully merging this pull request may close these issues.

None yet

4 participants