-
Notifications
You must be signed in to change notification settings - Fork 194
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
Adding information for array parameters #152
Conversation
@@ -109,17 +109,28 @@ Each parameter consists of a key and a value. | |||
The key is a string value. | |||
The value can be one of the following datatypes: | |||
|
|||
- `float64` |
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 rearranged these to match the order of specification in rcl_interfaces
as in the rclcpp
code.
articles/055_ros_parameter_design.md
Outdated
|
||
The datatypes are chosen as non-complex datatypes, as defined in the [interface definitions article](articles/interface_definition.html) | ||
The datatypes are chosen as non-complex datatypes, as defined in the [interface definitions article](interface_definition.html) |
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.
This link was going to articles/articles/interface_definition.html
.
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.
nitpick: A .
(dot) is missing here.
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.
As in, referring to the current directory? Will add.
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.
Or did you mean a full stop/period at the end of the sentence?
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 think he means punctuation.
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.
yes, I meant punctuation.
- `string` | ||
- `bool` | ||
- `bytes[]` | ||
- `byte[]` |
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.
If there is a byte[]
type should there be a byte
type too?
The current version of the idl article mentions byte
as a candidate for removal (see http://design.ros2.org/articles/interface_definition.html#primitive-field-types). I don't think that is reasonable but I just wanted mentioned it here.
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.
Interesting. I would argue that having byte[]
is a nice feature, which would necessitate that we keep byte
. I guess we could use the int64[]
parameter type to load arrays of bytes, just as we might use int64[]
to load parameters that are meant to be stored internally as int32[]
.
This raises another question: do we need to explicitly support arrays of every numerical primitive, or should we limit it to the 64-bit versions, and force users to cast them after the parameters are loaded?
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.
With parameters serializing to and from yaml we can't easily support numbers of different depths. So I'd advocate only supporting only the 64bit numeric types.
Sending byte arrays through parameters is pretty unportable. It requires both sides to implement their own serialization and deserialization without any container or metadata. Technically we support anything that can be transported as an XmlRpcValue however in practice we only really support strings, integers, booleans and doubles for parameters. I'd suggest that we not support byte or byte arrays as parameters. In addition to requiring serialization. It's something that non of our toolchain for interacting with parameters can easily support, such as rendering, diffing, or inputting for a gui like dynamic_reconfigure_gui.
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.
We only support 64-bit ints and floats for parameters right? So I don't think we need 32-bit arrays of them. The bytes[]
type is specifically for binary data. Personally I don't think we need a byte
type, because you can just use an int64 for decimal values and a length 1 string for a single character.
Parameters are, in my opinion, about conveying values for configuration not wire efficiency or disk storage efficiency, so not having 32-bit values and/or a byte type is ok.
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.
Maybe it should just be left as bytes
so people are not confused as to where the byte
type is.
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.
So I agree completely. I'm happy to support the 64-bit types and let users worry about how to interpret the parameters.
What's the verdict on whether or not bytes[]
lives?
articles/055_ros_parameter_design.md
Outdated
|
||
The datatypes are chosen as non-complex datatypes, as defined in the [interface definitions article](articles/interface_definition.html) | ||
The datatypes are chosen as non-complex datatypes, as defined in the [interface definitions article](interface_definition.html) |
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.
nitpick: A .
(dot) is missing here.
articles/055_ros_parameter_design.md
Outdated
- `string[]` can be used to express groups of names, such as a set of robots in a multi-robot context. | ||
|
||
While the use of array parameters increases the complexity of the API, their omission would necessitate complex naming schemes for parameters like matrices, which are common in robotics. | ||
They should not be abused, however; users should rely on namespacing and explicit variable names wherever possible. |
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.
Should it still be possible to query single elements from array parameters?
let's say in yaml:
robot:
joints:
- joint1
- joint2
- joint3
Should we have one parameter robot/joints
which will return the three values? If so, how would nested arrays look like?
joint_map:
-
- joint1
- joint2
-
- my_joint1
- my_joint2
I am not saying we necessarily support this - you could get around all this by using maps instead of nested arrays - but it's maybe worth mentioning it.
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 actually feel strongly one way or another about this. Anyone else?
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.
@Karsten1987 are you asking whether you could get a subtree as a "parameter"? If so no. You wouldn't get 3 values.
If you render your first yaml into parameters it would be:
robot/joints/joint1: value1
robot/joints/joint2: value2
robot/joints/joint3: value3
If you ask for parameter robot/joints
you'll get a response no such parameter. Though you could ask for a listing of parameters in the namespace robot/joints
to get the list of the three above.
Edit: This was assuming that you were leaving off the values in the display, not that joint1 joint2 and joint3 were the values since I was expecting. More like:
robot:
joints:
- joint1: value1
- joint2: value2
- joint3: value3
Something weird did happen. I think I commented on several posts inline not in a review. And clearly @Karsten1987 saw some of them. But now looking at it I see all my comments are in a pending review. Not sure how that happened. I'm posting them all now.
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.
Actually @Karsten1987 if you wanted to do that I would recommend using new keys:
joint_map:
keys:
- joint1
- joint2
values:
- my_joint1
- my_joint2
Which would become parameters like joint_map/keys
-> [joint1, joint2]
. Or you could do something like this:
joint_map:
joint1: my_joint1
joint2: my_joint2
Which would become parameters like joint_map/joint1
-> my_joint1
, etc...
I think a more general use for this would be a matrix, e.g. a 3 by 3:
my_matrix: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Essentially should there be lists of lists.
I feel like this is a critical feature, but I could be convinced otherwise I think.
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 actually think my first yaml example should be rendered as one parameter with a collection of three values. https://symfony.com/doc/current/components/yaml/yaml_format.html#collections
There is no direct key-value pair, but rather a list of three values. So the parameter I'd expect would be robot/joints
--> [joint1
, joint2
, joint3
]
@wjwwood I also would recommend using maps/key-value pairs instead, I solely wanted to point out that yaml supports such a syntax and we should mention how we would render it.
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.
Also why did you @tfoote? I'm confused.
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.
Hmm, must be something weird with github. I also see your comment twice here in that thread. I thought there was a comment prior to mine.
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 didn't see @tfoote's comment until just now... weird I explicitly looked for it before...
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.
So for ROS 1, I've been interpreting arrays as matrices by just reshaping them. It puts the onus on the package authors to interpret the parameters correctly, but I don't personally see an issue with that. How much complexity are we adding by supporting lists of lists? Would we support arbitrary list depths (e.g., lists of lists of lists of lists)?
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.
It looks like ROS 1 only supports one dimensional lists as well as only supporting homogeneous lists (can someone confirm that in this document? with links to docs or code if possible).
That would be a hint that maybe supporting the same set of features is sufficient for ROS 2 as well. I'm interested to see what others think.
If we only support homogenous lists, then supporting indefinite dimensionality to the lists seems like a limited amount of overhead, but I could be wrong about that. It might require some prototyping and brainstorming to find the corner cases that bite.
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.
Thanks for starting on this, I think we need to figure out if we want lists of lists or not and then we'll be ready to start an implementation.
- `string` | ||
- `bool` | ||
- `bytes[]` | ||
- `byte[]` |
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.
We only support 64-bit ints and floats for parameters right? So I don't think we need 32-bit arrays of them. The bytes[]
type is specifically for binary data. Personally I don't think we need a byte
type, because you can just use an int64 for decimal values and a length 1 string for a single character.
Parameters are, in my opinion, about conveying values for configuration not wire efficiency or disk storage efficiency, so not having 32-bit values and/or a byte type is ok.
articles/055_ros_parameter_design.md
Outdated
|
||
The datatypes are chosen as non-complex datatypes, as defined in the [interface definitions article](articles/interface_definition.html) | ||
The datatypes are chosen as non-complex datatypes, as defined in the [interface definitions article](interface_definition.html) |
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 think he means punctuation.
- `string` | ||
- `bool` | ||
- `bytes[]` | ||
- `byte[]` |
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.
Maybe it should just be left as bytes
so people are not confused as to where the byte
type is.
articles/055_ros_parameter_design.md
Outdated
- `string[]` can be used to express groups of names, such as a set of robots in a multi-robot context. | ||
|
||
While the use of array parameters increases the complexity of the API, their omission would necessitate complex naming schemes for parameters like matrices, which are common in robotics. | ||
They should not be abused, however; users should rely on namespacing and explicit variable names wherever possible. |
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.
Actually @Karsten1987 if you wanted to do that I would recommend using new keys:
joint_map:
keys:
- joint1
- joint2
values:
- my_joint1
- my_joint2
Which would become parameters like joint_map/keys
-> [joint1, joint2]
. Or you could do something like this:
joint_map:
joint1: my_joint1
joint2: my_joint2
Which would become parameters like joint_map/joint1
-> my_joint1
, etc...
I think a more general use for this would be a matrix, e.g. a 3 by 3:
my_matrix: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Essentially should there be lists of lists.
I feel like this is a critical feature, but I could be convinced otherwise I think.
Any further thoughts on list dimensionality? |
Sorry github did weird things on that thread so I'll comment on verious part in a single monolithic comment.
I think that renaming bytes[] to byte[] in the design makes sense as it will be consistent with the types we define for our IDL and that we use to defin parameters values in code: I dont think there is a need for a
It looks like the ROS1 allows one dimensional heterogeneous lists:
The roscpp parameters tutorial defines that lists in parameters can be of any XmlRpcValue type where I think the lilsts are of type I am not convinced that heterogenity is a critical feature for parameters though and would be fine if we don't support it in ROS 2
Again I dont think there is much value here.
I can see 1 being convenient for users. But as @ayrton04 said
So I'm fine targeting only one-dimension lists of homogeous types. But supporting multidimensional lists is doable and I could be convinced it's good enough of a feature to justify the additional complexity. |
Sorry @ayrton04 as the previous comment didnt give you a clear path forward. Discussing it internally yesterday we decided to side with only one-dimensional homogeneous lists for now (due to the unnecessary complexity of the introspection needed to handle multidimensional and heterogeneity within a list). We can revisit in the future if this happens to be too much of a burden from at the application level. On the implementation side we will need to enforce that the lists are checked for homogeneity at parsing / loading time, as heterogeneous lists are valid yaml definitions and the type of the parameter is not explicitly stated in the yaml description, we cannot "guess" and convert the values to the right type. |
OK, thanks for the feedback! I'll update the documentation to suit, and then get moving on the code. In the internal discussion, was there a final decision on |
I think As a side point I think |
Agreed. OK, will update this document. |
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.
lgtm, thanks @ayrton04 for iterating on this
TY all for the feedback! |
I'll wait for someone else from @ros2/team to appprove before merging |
* add array parameter types ros2/design#152 * update ParameterValue msg accordingly * rename X_values to X_array_value
* Remove the dependency for xmlrpcpp package * Since ROS2 doesn't support map type parameters(see: ros2/design#152), use array to assign tag ID
This PR is intended to start a conversation about how we can (or perhaps whether we should) support array parameters in ROS2. It follows a request from @wjwwood in the rclcpp repo.
Please note that this PR does not address all of the points that were requested, but it meant to act as a starting point upon which we can iterate as I receive feedback.
I have proposed that we add support for the following array types:
bool[]
int64[]
float64[]
string[]
The use case for
string[]
feels a little weak to me, so I can understand if we want to remove that.I would also advocate that, when we start discussing the constant names in
rcl_interfaces
, we consider renamingPARAMETER_BYTES
toPARAMETER_BYTE_ARRAY
for consistency.