rosbridge_suite icon indicating copy to clipboard operation
rosbridge_suite copied to clipboard

Cbor conversion does not work for fixed length arrays

Open romainreignier opened this issue 1 year ago • 2 comments

Description When subscribing to a topic with cbor compression on a message with a fixed-length array, like the position_covariance (float64[9]) of the sensor_msgs/NavSatFix message, the rosbridge fails to encode the message and shows this error:

[-] [MultiSubscriber.callback]: Exception calling subscribe callback: 'float' object has no attribute '__slots__'
  • Library Version: 0.11.16
  • ROS Version: ROS 1 Noetic
  • Platform / OS: Ubuntu 20.04

Steps To Reproduce

  1. roslaunch rosbridge_server rosbridge_websocket.launchrosbridge_server rosbridge_websocket.launch
  2. rostopic pub -r 2 /nav sensor_msgs/NavSatFix "header: seq: 0 stamp: {secs: 0, nsecs: 0} frame_id: '' status: {status: 0, service: 0} latitude: 0.0 longitude: 0.0 altitude: 0.0 position_covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] position_covariance_type: 0"
  3. Run the Python script below as a WS client:
#!/usr/bin/env python
import json
import time
from twisted.internet import reactor
from autobahn.twisted.websocket import (WebSocketClientProtocol,
                                        WebSocketClientFactory)

if __name__ == '__main__':
    class TestClientProtocol(WebSocketClientProtocol):
        def onOpen(self):
            self.sendMessage(json.dumps({
                'op': 'subscribe',
                'type': 'sensor_msgs/NavSatFix',
                'topic': '/nav',
                'compression': 'cbor',
            }).encode('utf-8'))

        def onMessage(self, payload, is_binary):
            print(payload)

    url = 'ws://127.0.0.1:9090'
    factory = WebSocketClientFactory(url)
    factory.protocol = TestClientProtocol
    time.sleep(1.0)
    reactor.connectTCP('127.0.0.1', 9090, factory)

    reactor.run()

Expected Behavior The rosbridge server transmits the cbor encoded to the payload to the client.

Actual Behavior The rosbridge server fails wit the error:

[MultiSubscriber.callback]: Exception calling subscribe callback: 'float' object has no attribute '__slots__'

Note that the issue is the same on ros2 branch.

Origin In the cbor_conversion.py file, the slot_type is matched against the keys of the TAGGED_ARRAY_FORMATS dict:

https://github.com/RobotWebTools/rosbridge_suite/blob/b0d0d711931d8ab7a5f079f948ced8875b4dc5d9/rosbridge_library/src/rosbridge_library/internal/cbor_conversion.py#L86

And in that dict, the syntax supported is only for variable length arrays: https://github.com/RobotWebTools/rosbridge_suite/blob/b0d0d711931d8ab7a5f079f948ced8875b4dc5d9/rosbridge_library/src/rosbridge_library/internal/cbor_conversion.py#L33

While in this case, the variable slot_type has the value: float64[9]

So it would be nice to match on strings starting with float64[ for example.

romainreignier avatar Jun 30 '23 09:06 romainreignier