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

Crash on empty point_cloud2 #85

Open
tim-fan opened this issue Aug 25, 2021 · 1 comment
Open

Crash on empty point_cloud2 #85

tim-fan opened this issue Aug 25, 2021 · 1 comment

Comments

@tim-fan
Copy link

tim-fan commented Aug 25, 2021

Hi there, thanks for the great visualisation package!

I'm trying to visualise a point_cloud2 topic which occasionally contains no points (it is the output of a filtering operation, and sometimes all points are removed by the filter).

When rosboard receives the empty message it crashes with the error:

Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/tmp/colcon_ws/build/rosboard/rosboard/rospy2/__init__.py", line 82, in _thread_spin_target
    rclpy.spin(_node)
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/__init__.py", line 191, in spin
    executor.spin_once()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 711, in spin_once
    raise handler.exception()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/task.py", line 239, in __call__
    self._handler.send(None)
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 426, in handler                                               await call_coroutine(entity, arg)
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 351, in _execute_subscription
    await await_or_execute(sub.callback, msg)                                                                                           File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 118, in await_or_execute
    return callback(*args)
  File "/tmp/colcon_ws/build/rosboard/rosboard/rospy2/__init__.py", line 245, in _ros2_callback                                           self.callback(msg, self.callback_args)
  File "/tmp/colcon_ws/build/rosboard/rosboard/rosboard.py", line 324, in on_ros_msg
    ros_msg_dict = ros2dict(msg)                                                                                                        File "/tmp/colcon_ws/build/rosboard/rosboard/serialization.py", line 66, in ros2dict
    rosboard.compression.compress_point_cloud2(msg, output)
  File "/tmp/colcon_ws/build/rosboard/rosboard/compression.py", line 278, in compress_point_cloud2
    xmax = np.max(xpoints)                                                                                                              File "<__array_function__ internals>", line 5, in amax
  File "/tmp/colcon_ws/venv/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 2733, in amax
    return _wrapreduction(a, np.maximum, 'max', axis, None, out,                                                                        File "/tmp/colcon_ws/venv/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 87, in _wrapreduction
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
ValueError: zero-size array to reduction operation maximum which has no identity

Looks like the issue is with calling np.max on an empty array.

My workaround was as follows, I confirmed this works for my case:

$ git rev-parse HEAD
7ac609d8ab321cddf098bbf503ec3dee12324f1e
$ git diff
diff --git a/rosboard/compression.py b/rosboard/compression.py
index 3f36590..a6cdbd5 100644
--- a/rosboard/compression.py
+++ b/rosboard/compression.py
@@ -273,6 +273,10 @@ def compress_point_cloud2(msg, output):
         idx = np.random.randint(points.size, size=65536)
         points = points[idx]

+    if points.size == 0:
+        output["_warn"] = "Received empty PointCloud2 - ignoring"
+        return
+
     xpoints = points['x'].astype(np.float32)
     xmax = np.max(xpoints)
     xmin = np.min(xpoints)

If you're OK with that change I can put it in a pull request. Otherwise I'm not sure what the best fix would be,

@dheera
Copy link
Owner

dheera commented Aug 27, 2021

Hi @tim-fan Thanks for bringing this up!

Your fix looks like it would work in your cause. But I'm thinking that for general users, perhaps a better solution would be to actually send an empty cloud to the client for visualization (instead of throwing an exception of course).

The reason I say this is that in many systems, sporadic empty point clouds could actually be a bug, and one of the purposes of a visualization tool should be to see those blips so you know they are happening. Like for example if it is because one day suddenly my LIDAR is failing, I want to be able to see that problem in a visualization tool.

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

No branches or pull requests

2 participants