我有用 python 编写的 ROS2 包(使用
rclpy
)和 ROS2 节点。在这个节点内,我想使用节点记录器,可以用以下方式表示:
def __init__(self):
self.get_logger().info("Starting my node!")
self.get_logger().warn("My node has already started!")
这与标准 python 构建完美配合,但是当我想使用 Cython 构建它时(因为代码即将投入生产)我遇到错误:
Logger severity cannot be changed between calls.
这是由于实施CallerId
造成的:
class CallerId(
namedtuple('CallerId', ['function_name', 'file_path', 'line_number', 'last_index'])):
def __new__(cls, frame=None):
if not frame:
frame = _find_caller(inspect.currentframe())
return super(CallerId, cls).__new__(
cls,
function_name=frame.f_code.co_name,
file_path=os.path.abspath(inspect.getframeinfo(frame).filename),
line_number=frame.f_lineno,
last_index=frame.f_lasti, # To distinguish between two callers on the same line
)
在文件
rcutils_logger.py
中。我完全理解,在文件“cythonization”之后,我的检查模块将不再工作(因为每次调用检查函数都会返回相同的行/文件),但我无法修复它。有没有人遇到过类似的问题?
我正在使用一种解决方法,它远非完美的解决方案,但它可能会帮助您/其他人:
import cython
def _cython_workaround(log_function):
"""Workaround for cythonized log functions."""
if cython.compiled:
def wrapper(msg, *args, **kwargs):
try:
log_function(msg, *args, **kwargs)
except Exception:
# catch without re-raise
# TODO finer control of the exceptions to catch; fix altogether
msg = log_function.__name__.upper() + ": " + msg
logger.info(msg, *args, **kwargs)
return wrapper
else:
return log_function
我在鸭子类型我的复合材料的函数中使用它:
composite.debug = _cython_workaround(logger.debug)
composite.info = _cython_workaround(logger.info)
...