naoki-mizuno / ds4_driver

DualShock 4 driver for both ROS1 and ROS2
http://wiki.ros.org/ds4_driver
85 stars 53 forks source link

[foxy-devel] unhandled exceptions on controller disconnection #25

Closed geoporus1 closed 2 years ago

geoporus1 commented 2 years ago

Hello!

In the last couple of weeks I have seen these things happening over multiple development and testing sessions with the foxy branch of the ds4_driver. Basically what happens is that if we try to send any command to the controller after it has disconnected or died due to low battery, then some OSError exceptions are raised which are not properly caught in the current version. I have stack traces for 2 of them:

[ds4_driver_node.py-18] Exception in thread Thread-2:
[ds4_driver_node.py-18] Traceback (most recent call last):
[ds4_driver_node.py-18]   File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
[ds4_driver_node.py-18]     self.run()
[ds4_driver_node.py-18]   File "/usr/lib/python3.8/threading.py", line 870, in run
[ds4_driver_node.py-18]     self._target(*self._args, **self._kwargs)
[ds4_driver_node.py-18]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/__init__.py", line 191, in spin
[ds4_driver_node.py-18]     executor.spin_once()
[ds4_driver_node.py-18]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 714, in spin_once
[ds4_driver_node.py-18]     raise handler.exception()
[ds4_driver_node.py-18]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/task.py", line 239, in __call__
[ds4_driver_node.py-18]     self._handler.send(None)
[ds4_driver_node.py-18]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 429, in handler
[ds4_driver_node.py-18]     await call_coroutine(entity, arg)
[ds4_driver_node.py-18]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 354, in _execute_subscription
[ds4_driver_node.py-18]     await await_or_execute(sub.callback, msg)
[ds4_driver_node.py-18]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 118, in await_or_execute
[ds4_driver_node.py-18]     return callback(*args)
[ds4_driver_node.py-18]   File "/karelics_workspace/karelics_brain/package_ws/install/ds4_driver/lib/python3.8/site-packages/ds4_driver/controller_ros.py", line 108, in cb_feedback
[ds4_driver_node.py-18]     self.control(
[ds4_driver_node.py-18]   File "/karelics_workspace/karelics_brain/package_ws/install/ds4_driver/lib/python3.8/site-packages/ds4_driver/controller.py", line 89, in control
[ds4_driver_node.py-18]     self._control()
[ds4_driver_node.py-18]   File "/karelics_workspace/karelics_brain/package_ws/install/ds4_driver/lib/python3.8/site-packages/ds4_driver/controller.py", line 95, in _control
[ds4_driver_node.py-18]     self.device.control(led_red=self._led[0],
[ds4_driver_node.py-18]   File "/usr/local/lib/python3.8/dist-packages/ds4drv-0.5.1-py3.8.egg/ds4drv/device.py", line 160, in control
[ds4_driver_node.py-18]   File "/usr/local/lib/python3.8/dist-packages/ds4drv-0.5.1-py3.8.egg/ds4drv/backends/hidraw.py", line 67, in write_report
[ds4_driver_node.py-18] OSError: [Errno 5] Input/output error
[ds4_driver_node.py-23] Exception in thread Thread-2:
[ds4_driver_node.py-23] Traceback (most recent call last):
[ds4_driver_node.py-23]   File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
[ds4_driver_node.py-23]     self.run()
[ds4_driver_node.py-23]   File "/usr/lib/python3.8/threading.py", line 870, in run
[ds4_driver_node.py-23]     self._target(*self._args, **self._kwargs)
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/rclpy/lib/python3.8/site-packages/rclpy/__init__.py", line 191, in spin
[ds4_driver_node.py-23]     executor.spin_once()
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/rclpy/lib/python3.8/site-packages/rclpy/executors.py", line 714, in spin_once
[ds4_driver_node.py-23]     raise handler.exception()
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/rclpy/lib/python3.8/site-packages/rclpy/task.py", line 239, in __call__
[ds4_driver_node.py-23]     self._handler.send(None)
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/rclpy/lib/python3.8/site-packages/rclpy/executors.py", line 429, in handler
[ds4_driver_node.py-23]     await call_coroutine(entity, arg)
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/rclpy/lib/python3.8/site-packages/rclpy/executors.py", line 343, in _execute_timer
[ds4_driver_node.py-23]     await await_or_execute(tmr.callback)
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/rclpy/lib/python3.8/site-packages/rclpy/executors.py", line 118, in await_or_execute
[ds4_driver_node.py-23]     return callback(*args)
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/ds4_driver/lib/python3.8/site-packages/ds4_driver/controller_ros.py", line 127, in cb_stop_rumble
[ds4_driver_node.py-23]     self.control(rumble_small=0, rumble_big=0)
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/ds4_driver/lib/python3.8/site-packages/ds4_driver/controller.py", line 89, in control
[ds4_driver_node.py-23]     self._control()
[ds4_driver_node.py-23]   File "/karelics_workspace/karelics_brain/package_ws/install/ds4_driver/lib/python3.8/site-packages/ds4_driver/controller.py", line 95, in _control
[ds4_driver_node.py-23]     self.device.control(led_red=self._led[0],
[ds4_driver_node.py-23]   File "/usr/local/lib/python3.8/dist-packages/ds4drv-0.5.1-py3.8.egg/ds4drv/device.py", line 160, in control
[ds4_driver_node.py-23]   File "/usr/local/lib/python3.8/dist-packages/ds4drv-0.5.1-py3.8.egg/ds4drv/backends/hidraw.py", line 67, in write_report
[ds4_driver_node.py-23] OSError: [Errno 71] Protocol error

There are times when OSError: [Errno 108] Cannot send after transport endpoint shutdown is also thrown in those situations. I believe that these should be properly handled because someone might want to send some commands to the controller right before or after it disconnects and that situation is quite hard to properly detect sometimes. I will submit a pull request in which these are properly handled. Hope you will accept it! :)

geoporus1 commented 2 years ago

PR addressing this issue has now been merged. Closing this issue!