ROS2 Humble: Shutdown causes RCLError: publisher's context is invalid
I built some ROS2 Python nodes modeled after the ROS2 Humble demonodespy/talker.py
When I run and kill a single node in my package, I get:
rclpy._rclpy_pybind11.RCLError: Failed to publish: publisher's context is invalid, at ./src/rcl/publisher.c:389
I did not have this issue running the code in ROS 2 Foxy.
The full traceback:
Traceback (most recent call last):
File "/home/ubuntu/ros2ws/install/ros2_gopigo3_node/lib/ros2_gopigo3_node/distance_sensor", line 33, in <module>
sys.exit(load_entry_point('ros2-gopigo3-node==0.0.0', 'console_scripts', 'distance_sensor')())
File "/home/ubuntu/ros2ws/install/ros2_gopigo3_node/lib/python3.10/site-packages/ros2_gopigo3_node/distance_sensor.py", line 53, in main
rclpy.spin(ds_node)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/__init__.py", line 222, in spin
executor.spin_once()
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 712, in spin_once
raise handler.exception()
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/task.py", line 239, in __call__
self._handler.send(None)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 418, in handler
await call_coroutine(entity, arg)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 332, in _execute_timer
await await_or_execute(tmr.callback)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 107, in await_or_execute
return callback(*args)
File "/home/ubuntu/ros2ws/install/ros2_gopigo3_node/lib/python3.10/site-packages/ros2_gopigo3_node/distance_sensor.py", line 45, in timer_callback
self.pub.publish(self.msg_range)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/publisher.py", line 70, in publish
self.__publisher.publish(msg)
rclpy._rclpy_pybind11.RCLError: Failed to publish: publisher's context is invalid, at ./src/rcl/publisher.c:389
[ros2run]: Process exited with failure 1
```
It seems the only way to get rid of the error is to put a try/except pass
around the publisher statement, but the demo app exits cleanly without this. Why is this happening?
Here is the code for my node:
#!/usr/bin/env python3
# File: distance_sensor.py
# Basic ROS2 Node to publish distance sensor readings
import rclpy
from rclpy.executors import ExternalShutdownException
from rclpy.node import Node
# from angles import from_degrees
from sensor_msgs.msg import Range
from di_sensors.easy_distance_sensor import EasyDistanceSensor
import math
class DistanceSensorNode(Node):
def __init__(self):
super().__init__('distance_sensor')
self.ds = EasyDistanceSensor(use_mutex=True)
self.msg_range = Range()
self.msg_range.header.frame_id = "distance_sensor"
self.msg_range.radiation_type = Range.INFRARED # LASER is closer to INFRARED than ULTRASOUND
self.msg_range.min_range = 0.0200 # 2 cm / 20 mm
self.msg_range.max_range = 3.000 # 3 m / 300 cm / 3000 mm
self.msg_range.field_of_view = math.radians(25.0) # +/- 12.5 degree FOV (~60cm at max range)
self.pub = self.create_publisher(Range, '~/distance', qos_profile=10)
timer_period = 0.1 # 0.1 second = 10 Hz
self.timer = self.create_timer(timer_period, self.timer_callback)
self.get_logger().info('Created distance_sensor node at {:.0f} hz'.format(1.0/timer_period))
def timer_callback(self):
self.reading_mm = self.ds.read_mm()
self.msg_range.range = self.reading_mm/1000.0
self.msg_range.header.stamp = self.get_clock().now().to_msg()
try:
self.pub.publish(self.msg_range)
except Exception: # <<<<<----- Have to catch RCLError on shutdown -- WHY?
pass
def main(args=None):
rclpy.init(args=args)
ds_node = DistanceSensorNode()
try:
rclpy.spin(ds_node)
except KeyboardInterrupt:
pass
except ExternalShutdownException:
sys.exit(1)
finally:
ds_node.destroy_node()
rclpy.try_shutdown()
if __name__ == '__main__':
main()
```
Asked by RobotDreams on 2022-11-02 22:47:08 UTC
Answers
The tutorials and Humble have been updated, so the SIGINT handling in C++ is no longer an issue.
Asked by RobotDreams on 2022-12-24 18:47:01 UTC
Comments
It would be helpful to many if you explain what was added/changed to avoid the stack trace.
Asked by Mike Scheutzow on 2022-12-26 09:44:46 UTC
@mike-scheutzow The question included what I did to avoid the stack trace, and it appears that is still needed in Python. The C++ tutorial code and the ROS2 Humble did change and thus no longer causes the error in C++ code. I have no idea about what changed in the C++, only that people that are teaching ROS2 Humble using the older C++ talker/listener tutorial code, still result in the node shutdown attempted to be called after a SIGINT caused the node context to be invalid.
I could find no where on the Internet anyone was seeing this issue in Python or C++. In almost two months no one upvoted my question, and no one answered either affirming or rejecting my issue with the Humble tutorial code.
I have overestimated how many folks are beginners at the same point in my ROS2 Humble adventure. Perhaps beginners should stick with Foxy or Galactic. I have run into several other "gotcha"s with Humble that make me question the Humble regression testing.
Asked by RobotDreams on 2022-12-26 12:48:00 UTC
Comments