ros-visualization / rqt_reconfigure

http://wiki.ros.org/rqt_reconfigure
Other
23 stars 50 forks source link

Clicking refresh freezes rqt #97

Closed Kaju-Bubanja closed 3 years ago

Kaju-Bubanja commented 4 years ago

Opening rqt and then opening parameter reconfigure and hitting Refresh freezes whole rqt and it needs to be force shutdown. Info: Ros2 Foxy, built by source. rqt_reconfigure dashing branch. Ubuntu 20.04.

xydesa commented 4 years ago

This is happening to me too, also in Ubuntu 20.04, ROS 2 Foxy. I'm using apt installed ros-foxy-rqt-reconfigure.

$ ros2 run rqt_reconfigure rqt_reconfigure 
^C[INFO] [1605727363.846724404] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
PluginHandler.save_settings() plugin "rqt_reconfigure/Param#0" raised an exception:
Traceback (most recent call last):
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui/plugin_handler.py", line 191, in save_settings
    self._save_settings(plugin_settings, instance_settings)
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui/plugin_handler_direct.py", line 114, in _save_settings
    self.emit_save_settings_completed()
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui/plugin_handler.py", line 207, in emit_save_settings_completed
    callback(self._instance_id)
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui/plugin_manager.py", line 459, in _close_application_save_callback
    self._close_application_shutdown_plugins()
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui/plugin_manager.py", line 466, in _close_application_shutdown_plugins
    self._shutdown_plugin(
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui/plugin_manager.py", line 353, in _shutdown_plugin
    handler.close_signal.disconnect(self.unload_plugin)
TypeError: disconnect() failed between 'close_signal' and 'unload_plugin'

^C[INFO] [1605727364.574836832] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
^C[INFO] [1605727365.030892332] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
^C[INFO] [1605727365.359810927] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
^C[INFO] [1605727368.262765530] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
^C[INFO] [1605727368.406749937] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
^C[INFO] [1605727368.542732863] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
^C[INFO] [1605727368.694778147] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)

I'm also seeing a different stack trace, along with the node actually closing. This started happening after I saw the freeze and need to force-close rqt. In both cases, the behavior was instigated by clicking "Refresh".

$ ros2 run rqt_reconfigure rqt_reconfigure
^C[INFO] [1605727622.828869366] - rclcpp:/tmp/binarydeb/ros-foxy-rclcpp-2.2.0/src/rclcpp/signal_handler.cpp:signal_handler:202: signal_handler(signal_value=2)
[ERROR] [1605727622.927742918] - rqt_reconfigure:/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py:_prune_nodetree_pernode:438: Reconfigure GUI cannot connect to master.
Traceback (most recent call last):
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 452, in _refresh_nodes
    self._prune_nodetree_pernode()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 439, in _prune_nodetree_pernode
    raise e  # TODO Make sure 'raise' here returns or finalizes func.
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 436, in _prune_nodetree_pernode
    nodes = find_nodes_with_params(self._context.node)
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 129, in find_nodes_with_params
    return list(
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 131, in <lambda>
    lambda node_name: _has_params(node, node_name),
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 122, in _has_params
    client.wait_for_service()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/client.py", line 164, in wait_for_service
    return self.service_is_ready()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/client.py", line 143, in service_is_ready
    with self.handle as capsule:
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/handle.py", line 124, in __enter__
    return self._get_capsule()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/handle.py", line 106, in _get_capsule
    raise InvalidHandle('Tried to use a handle that has been destroyed.')
rclpy.handle.InvalidHandle: Tried to use a handle that has been destroyed.
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 153, in apport_excepthook
    with os.fdopen(os.open(pr_filename,
FileNotFoundError: [Errno 2] No such file or directory: '/var/crash/_opt_ros_foxy_lib_rqt_reconfigure_rqt_reconfigure.1000.crash'

Original exception was:
Traceback (most recent call last):
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 452, in _refresh_nodes
    self._prune_nodetree_pernode()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 439, in _prune_nodetree_pernode
    raise e  # TODO Make sure 'raise' here returns or finalizes func.
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 436, in _prune_nodetree_pernode
    nodes = find_nodes_with_params(self._context.node)
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 129, in find_nodes_with_params
    return list(
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 131, in <lambda>
    lambda node_name: _has_params(node, node_name),
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 122, in _has_params
    client.wait_for_service()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/client.py", line 164, in wait_for_service
    return self.service_is_ready()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/client.py", line 143, in service_is_ready
    with self.handle as capsule:
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/handle.py", line 124, in __enter__
    return self._get_capsule()
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/handle.py", line 106, in _get_capsule
    raise InvalidHandle('Tried to use a handle that has been destroyed.')
rclpy.handle.InvalidHandle: Tried to use a handle that has been destroyed.
lenpuc commented 3 years ago

Same, though for me the trouble only appears when rviz2 is running in parallel. With a custom node using the parameters so far it does not crash and refreshes the list to include my node.

Once rviz2 is opened it freezes.

Am on Ubunutu 20.04 with a ros2 install by binaries.

and its consistent if I start it with rqtor with ros2 run rqt_reconfigure rqt_reconfigure

`

$ rqt
^C[INFO] [1607535108.410624788] [rclcpp]: signal_handler(signal_value=2) [ERROR] [1607535108.546704721] [rqt_reconfigure]: Reconfigure GUI cannot connect to master. Traceback (most recent call last): File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 452, in _refresh_nodes self._prune_nodetree_pernode() File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 439, in _prune_nodetree_pernode raise e # TODO Make sure 'raise' here returns or finalizes func. File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/node_selector_widget.py", line 436, in _prune_nodetree_pernode nodes = find_nodes_with_params(self._context.node) File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 129, in find_nodes_with_params return list( File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 131, in lambda node_name: _has_params(node, node_name), File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_reconfigure/param_api.py", line 122, in _has_params client.wait_for_service() File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/client.py", line 164, in wait_for_service return self.service_is_ready() File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/client.py", line 143, in service_is_ready with self.handle as capsule: File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/handle.py", line 124, in enter return self._get_capsule() File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/handle.py", line 106, in _get_capsule raise InvalidHandle('Tried to use a handle that has been destroyed.') rclpy.handle.InvalidHandle: Tried to use a handle that has been destroyed.

`

Which strikes me as weird is the prompt that no master can be contacted, which sounds a lot like ROS1.

mjeronimo commented 3 years ago

The root of the problem is that there are a couple incorrect assumptions in the code (specifically, the _has_params function in rqt_reconfigure's param_api.py module).

def _has_params(node, node_name):
    client = node.create_client(
        ListParameters,
        '{node_name}/list_parameters'.format_map(locals()))
    if not client.service_is_ready():
        client.wait_for_service()
    ret = len(client.call(ListParameters.Request()).result.names) > 0
    node.destroy_client(client)
    return ret

First, some background context: A node doesn't have to support the parameter services. It can set start_parameter_services in NodeOptions to false. Also, some nodes in the system may not be spinning and therefore don't processing incoming messages. These nodes might have the parameter services, but they won't respond to the incoming service request since they aren't processing messages.

However, _has_params is creating a service client for ListParameters, waiting for the service (and assuming a successful result), and is then doing a synchronous call, which blocks forever since the node isn't spinning to process the request, resulting in a hang.

This code needs to be updated to both ensure that the service is actually present and ready and then to an async call with a timeout in case the node doesn't respond to the request.

I've entered an issue on this here: #96

facontidavide commented 3 years ago

I am having the same issue. Any progress on this?

mjeronimo commented 3 years ago

Carved out some time to fix it: #98. Please give it a try and let me know how it goes. It will now timeout and print an appropriate message if a node doesn't respond to a parameters-related service request.