ros-visualization / rqt

63 stars 71 forks source link

ROS 2 dynamic reconfigure with bounded parameters #264

Closed oKermorgant closed 1 year ago

oKermorgant commented 2 years ago

Hi,

Using Galactic here. The Dynamic reconfigure plugin is able to detect if some parameters have been declared with bound constraints. In this case, rqt displays a slider instead of a text input and the bounds are well-detected.

However constraints can also contain a step size. It seems that this value is ignored in the slider, which (seems to) defaults to:

If this step is not compliant with the one configured in the parameter then requested changes are ignored, as they do not satisfy the constraints. This is typically the case for step > 1 for int (with step == 2, slider still allows odd values but they are ignored by the node). For double parameters this is very unlikely that the constraints are set such that step = (max-min)/1000, in this case the slider is unusable as it will not produce any value that is allowed by the node.

Here is a basic node that describes the issue:

#include <rclcpp/rclcpp.hpp>
#include <rclcpp/node.hpp>
#include <iostream>

using namespace std::chrono_literals;

struct ParamNode : public rclcpp::Node
{
  explicit ParamNode() : Node("param_node")
  {
    timer = create_wall_timer(1s, [&]()
    {
      static auto count{0};
      std::cout << " @ " << count++ << ": "
                << " double = " << get_parameter("double").as_double()
                << " / int = " << get_parameter("int").as_int() << std::endl;
    });

    rcl_interfaces::msg::ParameterDescriptor descr;
    descr.name = "double";
    descr.floating_point_range = {rcl_interfaces::msg::FloatingPointRange()
                                  .set__step(0.01)
                                  .set__from_value(0.)
                                  .set__to_value(10.) // ok, 10 = 1000 * 0.01
                                  .set__to_value(3.14)  // nope
                                 };

    declare_parameter<double>(descr.name, 2., descr);

    descr.name = "int";
    descr.floating_point_range.clear();
    descr.integer_range = {rcl_interfaces::msg::IntegerRange()
                           .set__from_value(0)
                           .set__to_value(10)
                           .set__step(2)      // slider can still produce odd numbers
                           };
    declare_parameter<int>(descr.name, 2, descr);
  }

  rclcpp::TimerBase::SharedPtr timer;
};

int main(int argc, char** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<ParamNode>());
}