Parameter Descriptor Simplification #2179
Conversation
812b975 to
03855bf
Compare
| namespace rclcpp | ||
| { | ||
|
|
||
| // Implments ParameterDesription class with builder design pattern |
There was a problem hiding this comment.
| // Implments ParameterDesription class with builder design pattern | |
| // Implements ParameterDescription class with builder design pattern |
|
|
||
| //Builder Method - Mains | ||
| FloatingPointDescription& SetName(std::string name); | ||
| FloatingPointDescription& SetType(std::uint8_t type); |
There was a problem hiding this comment.
I think that many of these methods should be in a base class
| //Builder Method - Mains | ||
| FloatingPointDescription& SetName(std::string name); | ||
| FloatingPointDescription& SetType(std::uint8_t type); | ||
| FloatingPointDescription& SetDescription(std::string description); |
There was a problem hiding this comment.
This should be something like "set description text", because the whole object is a description
Moreover use const reference to pass the string
| ParameterDescription build() const; | ||
|
|
||
| //Builder Method - Mains | ||
| FloatingPointDescription& SetName(std::string name); |
There was a problem hiding this comment.
Use Const reference to pass the string
|
|
||
| // Need the current node in order to begin the configuraiton state forit via the declare_parameter function which setups up the Node | ||
| template<typename ParameterType> | ||
| FloatingPointDescription& DeclareParameter<ParameterType>(ParameterType default_value, std::shared_ptr<rclcpp::Node> required_node) |
There was a problem hiding this comment.
This shouldn't take a node, but rather the required node interfaces
There was a problem hiding this comment.
If any implemented class inherits from the rclcpp::Node class shouldn't that class be able to fall into the rclcpp::Node parameter, or does this engage a bad practice we don't want to follow. The goal is to use the Node as a form of this, where the original issue suggests this code on something like line 48. Where this acts as the encasing class which inherits from rclcpp::Node seen on line 20 of that file.
There was a problem hiding this comment.
Not everything that creates a parameter is derived from rclcpp::Node; for example rclcpp_lifecycle::LifecycleNode doesn't.
The correct approach is to pass the list of node interfaces that you are going to need
There was a problem hiding this comment.
Not everything that creates a parameter is derived from
rclcpp::Node; for examplerclcpp_lifecycle::LifecycleNodedoesn't.
Currently in this pull request I have set up two implementations for the DeclareParameter function for both of those sited nodes, after digging around the codebase I saw an implementation here. Would it be better to follow in the form of template based programming like you had made in that pull request in order to increase viability of the function?
In our case an example would be :
template<typename ParameterType, typename NodeT>
DeclareParameter(ParameterType default_value, std::shared_ptr<NodeT> required_node){
// Implementation
}
| FloatingPointDescription& SetMax(float max); | ||
| FloatingPointDescription& SetStep(float step); | ||
|
|
||
| // Simplification Method - Outside of the base clss that the user should be able to set up easily, they should then be able to call a function which setups up the specifics for this class (The floating point parameter description) |
There was a problem hiding this comment.
| // Simplification Method - Outside of the base clss that the user should be able to set up easily, they should then be able to call a function which setups up the specifics for this class (The floating point parameter description) | |
| // Simplification Method - Outside of the base class that the user should be able to set up easily, they should then be able to call a function which setups the specifics for this class (The floating point parameter description) |
| // The main descriptor object we're meant to adjust | ||
| rcl_interfaces::msg::ParameterDescriptor parameter_descriptor = {}; | ||
|
|
||
| // Copies all the information in ParameterDescriptor.msg - https://github.com/ros2/rcl_interfaces/blob/rolling/rcl_interfaces/msg/ParameterDescriptor.msg |
There was a problem hiding this comment.
Why do we copy all the information? Shouldn't we just store an internal parameter description message and return it as output of a "build" method?
There was a problem hiding this comment.
I interpret this as just returning the entirety of the parameter_descriptor message that we are currently using to store all the values, which makes the build method appropriate.
|
I'm not convinced by the need for creating different classes for each type of constraints we may eventually have on the parameters. Given that we only have 1 parameter description object, having 1 builder class should be sufficient. |
|
I may have failed to grasp the objective the original issue was trying to fix, I was just confused on the direction they were trying to take. Though, now that you've defined it a bit better I may understand, because beforehand it seemed convoluted to use a builder - which takes zero arguments but uses multiple method calls - to create a convience API. From what you've suggested, we should make a builder API with a bunch of small method calls and a large build that returns all the details, for just the ParameterDescription obejct. Then, create two smaller function calls for the Integers ranges highlighed in both the PR and ParameterDescriptor that work as a convience API. |
| FloatingPointDescription& SetMin(float min); | ||
| FloatingPointDescription& SetMax(float max); | ||
| FloatingPointDescription& SetStep(float step); | ||
|
|
There was a problem hiding this comment.
Before I roll out the next set of changes how would we like these three functions: SetMin, SetMax, and SetStep to act? There are multiple aspects to consider when deciding between simplicity and modularity.
Currently these three functions have no use, because the values they set are unused. In order to make them have purpose we would not only set their corresponding value, but also resize the type of range it's trying to target, if that range had not already been set. After we would then call parameter_descriptor.floating_point_range.at(0).corresponding_function. On the other hand we can opt for simplicity by removing the set functions and the values they alter all together, then in the functions that Set the Description Range we can use default values to remove possible arguments because the .msg field specifies bounds that we can have. On top of this discussion, should we also create Set functions for the int range, but with different names i.e SetMinInteger or should we aim to use overloading like SetMin(float/int min)
|
Now with the issue #2184, should both ranges in the functions |
d322451 to
c703c9e
Compare
|
How important are tests to a simple builder class object? I was debating on adding tests but didn't know what they were going to look like. |
fujitatomoya
left a comment
There was a problem hiding this comment.
@CursedRock17 i think this is good enhancement, sorry we did not allocate time for the review. Do you plan to open another PR or find something missing in here? just checking.
|
I was planning on opening this up as an extension in the rcl_interfaces library as |
| ParameterDescription & SetDynamicTyping(bool dynamic_typing); | ||
| ParameterDescription & SetFloatingPointDescriptionRange(float min = 0.0f, float max = 1.0f, | ||
| float step = 0.0f); | ||
| ParameterDescription & SetIntegerDescriptionRange(int min = 0, int max = 1, int step = 0); |
There was a problem hiding this comment.
minor: I don't like having default values for these SetFloatingPointDescriptionRange and SetIntegerDescriptionRange APIs.
I would expect users to always set them all
| return *this; | ||
| } | ||
|
|
||
| ParameterDescription & ParameterDescription::SetIntegerDescriptionRange(int min, int max, int step) |
There was a problem hiding this comment.
should this method and SetFloatingPointDescriptionRange check the parameter type?
e.g. if the parameter is a string you shouldn't try to set these
|
Overall looks good, left some minor comments. |
fujitatomoya
left a comment
There was a problem hiding this comment.
before checking the implementation, i have a question. CC: @CursedRock17
|
|
||
| TEST_F(TestParameterService, parameter_descriptor) { | ||
| { | ||
| rclcpp::ParameterDescription param_description; |
There was a problem hiding this comment.
I was expecting we were going to have the class ParameterDescription templated with ParameterType or something else to support syntactic sugar like following? So that it would be easier to create descriptor for the user application? current code almost provides the same experience with rcl_interfaces::msg::ParameterDescriptor?
| rclcpp::ParameterDescription param_description; | |
| rclcpp::ParameterDescription<PARAMETER_INTEGER> | |
| param_description( | |
| "int_parameter", | |
| "description", | |
| "constraints", | |
| false, | |
| start, end, step | |
| ); | |
| node->declare_parameter(rclcpp::ParameterValue{1}, param_description.build()); |
above is just a pseudo cod. i might be mistaken on this, probably we want to get feedback from @wjwwood @gbalke .
There was a problem hiding this comment.
While this was an option, I went with the advice in the original issue, specifically:
for the API, so that if we add more to the descriptor in the future we won't have to add/subtract/reorder arguments to a function.
The original goal was to make the floating_point_description easier to use, that's why that part is set up in the form of a general function/constructor with all the arguments declared at once.
|
@CursedRock17 can you rebase your branch on top of Rolling? I think that it's too old and it's causing CI failures |
1258e3a to
13cb99e
Compare
13cb99e to
f510db1
Compare
cd3a2cf to
d6482f2
Compare
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
This reverts commit 6431630. Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
This reverts commit 4bbcbe9. Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
d6482f2 to
1482c88
Compare
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
Signed-off-by: CursedRock17 <mtglucas1@gmail.com>
|
I should've commented this earlier, but I didn't expect the changes to pass as the includes don't work. I needed to include the header file in These are the steps I followed to get the includes working, I don't think there's anything wrong now:
|
|
Pulls: #2179 |
|
@fujitatomoya do you mind to take a look ? |
These changes are a direct response to issue #1660 which calls for the simplification of common parameter_descriptor objects.
ParameterDescriptionclass is meant to hold all of the standard information in ParameterDescriptor and then build up classes around it that can alter that information.and
were the main tasks assigned in the creation in this so, to follow builder protocol I created a general first class, then secondary classes that contain the details for a counter such as:
min, max, step. Then I created a function to handle the setting of these functions, where there had to be an overloaded version meant to hold templates given in the example ofthis->declare_parameter<double>("value", 0.5, param_descriptor);I assumed this had to be done because a Node must be initiated through this method, or a general version with arclcpp::ParameterValue.Additionally, this was a function because the builder design patterns aims to stray away from massive constructors, which originally concerned me, because this PR was beginning to turn into that.There are definetly improvements to be made to this PR, especially in the addition of more subclasses - at least an int version - but I wanted to get some early feedback.