rosboard
rosboard copied to clipboard
Crash on empty point_cloud2
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,
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.