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

Allow integers in conversion to float array messages #777

Merged
merged 3 commits into from
Aug 16, 2022

Conversation

jtbandes
Copy link
Member

Public API Changes
None

Description
Fixes #764 by using ndarray/array assignment operations that accept ints as well as floats, rather than directly assigning the incoming list value, which failed at the msg/idl generated python code's validation step.

Before this change, the newly added tests would fail with this error for dynamic-length arrays:

2: ___________________ TestMessageConversion.test_float32array ____________________
2: 
2: self = <test.internal.test_message_conversion.TestMessageConversion testMethod=test_float32array>
2: 
2:     def test_float32array(self):
2:         def test_float32_msg(rostype, data):
2:             msg = {"data": data}
2:             inst = ros_loader.get_message_instance(rostype)
2:             c.populate_instance(msg, inst)
2:             self.validate_instance(inst)
2:             return inst.data
2:     
2:         for msgtype in ["TestFloat32Array"]:
2:             rostype = "rosbridge_test_msgs/" + msgtype
2:     
2:             # From List[float]
2:             floats = list(map(float, range(0, 256)))
2:             ret = test_float32_msg(rostype, floats)
2:             np.testing.assert_array_equal(ret, np.array(floats))
2:     
2:             # From List[int]
2:             ints = list(map(int, range(0, 256)))
2: >           ret = test_float32_msg(rostype, ints)
2: 
2: ../../rosbridge_library/test/internal/test_message_conversion.py:304: 
2: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
2: ../../rosbridge_library/test/internal/test_message_conversion.py:290: in test_float32_msg
2:     c.populate_instance(msg, inst)
2: ../../install/rosbridge_library/lib/python3.8/site-packages/rosbridge_library/internal/message_conversion.py:177: in populate_instance
2:     return _to_inst(msg, inst_type, inst_type, inst)
2: ../../install/rosbridge_library/lib/python3.8/site-packages/rosbridge_library/internal/message_conversion.py:294: in _to_inst
2:     return _to_object_inst(msg, rostype, roottype, inst, stack)
2: ../../install/rosbridge_library/lib/python3.8/site-packages/rosbridge_library/internal/message_conversion.py:403: in _to_object_inst
2:     setattr(inst, field_name, field_value)
2: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
2: 
2: self = rosbridge_test_msgs.msg.TestFloat32Array(data=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13....239.0, 240.0, 241.0, 242.0, 243.0, 244.0, 245.0, 246.0, 247.0, 248.0, 249.0, 250.0, 251.0, 252.0, 253.0, 254.0, 255.0])
2: value = [0, 1, 2, 3, 4, 5, ...]
2: 
2:     @data.setter
2:     def data(self, value):
2:         if isinstance(value, array.array):
2:             assert value.typecode == 'f', \
2:                 "The 'data' array.array() must have the type code of 'f'"
2:             self._data = value
2:             return
2:         if __debug__:
2:             from collections.abc import Sequence
2:             from collections.abc import Set
2:             from collections import UserList
2:             from collections import UserString
2: >           assert \
2:                 ((isinstance(value, Sequence) or
2:                   isinstance(value, Set) or
2:                   isinstance(value, UserList)) and
2:                  not isinstance(value, str) and
2:                  not isinstance(value, UserString) and
2:                  all(isinstance(v, float) for v in value) and
2:                  True), \
2:                 "The 'data' field must be a set or sequence and each value of type 'float'"
2: E           AssertionError: The 'data' field must be a set or sequence and each value of type 'float'
2: 
2: ../../install/rosbridge_test_msgs/lib/python3.8/site-packages/rosbridge_test_msgs/msg/_test_float32_array.py:131: AssertionError

And this error for fixed-length arrays:

2: self = rosbridge_test_msgs.msg.TestFloat32BoundedArray(data=array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.,
2:        13., 14., 15.], dtype=float32))
2: value = [0, 1, 2, 3, 4, 5, ...]
2: 
2:     @data.setter
2:     def data(self, value):
2:         if isinstance(value, numpy.ndarray):
2:             assert value.dtype == numpy.float32, \
2:                 "The 'data' numpy.ndarray() must have the dtype of 'numpy.float32'"
2:             assert value.size == 16, \
2:                 "The 'data' numpy.ndarray() must have a size of 16"
2:             self._data = value
2:             return
2:         if __debug__:
2:             from collections.abc import Sequence
2:             from collections.abc import Set
2:             from collections import UserList
2:             from collections import UserString
2: >           assert \
2:                 ((isinstance(value, Sequence) or
2:                   isinstance(value, Set) or
2:                   isinstance(value, UserList)) and
2:                  not isinstance(value, str) and
2:                  not isinstance(value, UserString) and
2:                  len(value) == 16 and
2:                  all(isinstance(v, float) for v in value) and
2:                  True), \
2:                 "The 'data' field must be a set or sequence with length 16 and each value of type 'float'"
2: E           AssertionError: The 'data' field must be a set or sequence with length 16 and each value of type 'float'

@jtbandes jtbandes merged commit 4de99bc into ros2 Aug 16, 2022
@jtbandes jtbandes deleted the jacob/fix-int-in-float-array branch August 16, 2022 18:51
jihoonl pushed a commit to floatic-unicorn/rosbridge_suite that referenced this pull request Oct 6, 2022
Fixes RobotWebTools#764 by using `ndarray`/`array` assignment operations that accept ints as well as floats, rather than directly assigning the incoming list value, which failed at the msg/idl generated python code's validation step.
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.

Message conversion fails to convert list of integers to float32[]
2 participants