小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
使用launch启动两个node,但是只打印了一个node的日志
-
环境:
win11
ros2 humble第一个:
包名:pkg_cpp
node:node_cpp
文件内容:#include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" //导入订阅者的消息接口类型 #include "std_msgs/msg/u_int32.hpp" // class NodeCpp : public rclcpp::Node { public: NodeCpp(std::string nodeName):Node(nodeName) //用nodeName实例化一个父类Node的匿名对象 { RCLCPP_INFO(this->get_logger(), "Hello, this is %s.", nodeName); //实例化一个订阅者对象 m_subscriber = this->create_subscription<std_msgs::msg::String>("my_new_topic", 10, std::bind(&NodeCpp::sub_callback, this, std::placeholders::_1)); //实例化一个发布者对象 m_Publisher = this->create_publisher<std_msgs::msg::UInt32>("my_new_topic_money", 10); m_account.data = 10000; } private: //回调函数 void sub_callback(const std_msgs::msg::String::SharedPtr msg) { std_msgs::msg::UInt32 msg_temp; msg_temp.data = 10; m_account.data -= msg_temp.data; m_Publisher->publish(msg_temp); RCLCPP_INFO(this->get_logger(), "node_cpp:收到消息:%s. 支付 %d 元. 剩余 %d 元.", msg->data, msg_temp.data, m_account.data); //.c_str(); } //声明一个订阅者成员变量 rclcpp::Subscription<std_msgs::msg::String>::SharedPtr m_subscriber; //声明一个发布者成员变量 rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr m_Publisher; std_msgs::msg::UInt32 m_account; }; int main(int argc, char **argv) { // 初始化rclcpp rclcpp::init(argc, argv); // 产生一个名为node_cpp的节点 auto node = std::make_shared<NodeCpp>("node_cpp"); // 运行节点,并检测退出信号 Ctrl+C rclcpp::spin(node); // 停止运行 rclcpp::shutdown(); return 0; }
第二个:
包名:pkg_py
node:node_py
文件内容:import rclpy from rclpy.node import Node from std_msgs.msg import String,UInt32 class NodeWriter(Node): def __init__(self, name): super().__init__(name) #初始化基类name self.get_logger().info(f"Hello, this is {name}") self.msg_publisher = self.create_publisher(String, "my_new_topic", 10) #创建一个发布者 self.timer_period = 5.0 self.timer = self.create_timer(self.timer_period, self.pub_callback) # 创建订阅者 self.msg_subscribe_ = self.create_subscription(UInt32,"my_new_topic_money",self.func_callback,10) self.account = 100.0 self.count = 0 def pub_callback(self): ''' 回调函数 ''' msg = String() msg.data = f"msg:{self.count}" self.count += 1 self.msg_publisher.publish(msg) # 调用发布者的publish方法来发布消息 self.get_logger().info(f'发布了指令:{msg.data}') #打印发布的数据 def func_callback(self,money): self.account += money.data self.get_logger().info(f"node_py 收到 {money.data} 元,现在有 {self.account} 元。") def main(args=None): """ ros2运行该节点的入口函数 编写ROS2节点的一般步骤 1. 导入库文件 2. 初始化客户端库 3. 新建节点对象 4. spin循环节点 5. 关闭客户端库 """ rclpy.init(args=args) # 初始化rclpy node = NodeWriter("node_py") # 新建一个节点 # node.get_logger().info("Hello, this is writer_node_py.") rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C) rclpy.shutdown() # 关闭rclpy
launch文件放在pkg_py包下,
launch文件内容:# 导入库 from launch import LaunchDescription #用于对launch文件内容进行描述 from launch_ros.actions import Node #用于声明节点所在的位置 def generate_launch_description(): """launch内容描述函数,由ros2 launch 扫描调用""" node_cpp = Node( package="pkg_cpp", #包名 executable="node_cpp" #node名 ) node_py = Node( package="pkg_py", executable="node_py" ) # 创建LaunchDescription对象launch_description,用于描述launch文件 launch_description = LaunchDescription( [node_cpp, node_py]) # 返回让ROS2根据launch描述执行节点 return launch_description
pkg_py包的setup.py文件内容如下:
from setuptools import find_packages, setup from glob import glob import os package_name = 'pkg_py' setup( name=package_name, version='0.0.0', packages=find_packages(exclude=['test']), data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')), ], install_requires=['setuptools'], zip_safe=True, maintainer='jason', maintainer_email='jason.duan@innovention.cn', description='TODO: Package description', license='Apache-2.0', tests_require=['pytest'], entry_points={ 'console_scripts': [ "node_py = pkg_py.node_py:main" ], }, )
编译后可以正常通过launch命令打开这两个node,rqt_graph显示的逻辑也是对的
也有node_py这个节点的进程
但是没有node_py这个节点的日志输出,只要node_cpp的日志
这是为什么?哪位大神可以解答一下 -
在你的问题中,
node_py
节点没有输出日志,但node_cpp
节点有日志输出,这通常是由于几种可能的原因导致的。以下是一些可能的原因及解决方案:1. 日志级别问题
首先,确保
node_py
中的日志级别足够高以显示信息。ROS 2 默认的日志级别是INFO
,但如果你在某个地方(可能是代码或配置文件)改变了它,那么INFO
级别的日志可能就不会显示了。检查方法:
- 确认在
node_py
代码中是否修改了日志级别。 - 检查 ROS 2 的配置文件(如
config/settings.yaml
),看是否有针对整个系统的日志级别设置。
2. 节点没有运行或崩溃
如果节点没有正确运行或启动后立即崩溃,那么它不会输出任何日志。
检查方法:
- 使用
ros2 node list
确认node_py
是否在运行。 - 检查
node_py
的进程状态(使用如top
,ps
等命令)。 - 查看是否有相关的错误或崩溃信息输出到控制台或日志文件。
3. 节点启动顺序问题
在某些情况下,如果
node_py
依赖于node_cpp
的某些服务或话题,并且node_cpp
还没有准备好,那么node_py
可能会因为无法连接到所需的服务或话题而静默失败。然而,这通常会导致错误或警告日志。检查方法:
- 确保
node_py
和node_cpp
之间的依赖关系正确无误。 - 检查
node_py
的代码,看是否有任何处理依赖失败的逻辑,可能这些逻辑会静默处理错误。
4. 配置文件或环境问题
有时,特定的配置文件或环境设置可能会影响节点的行为。
检查方法:
- 检查
node_py
和node_cpp
的环境变量和配置文件是否一致。 - 尝试在不同的环境中运行节点,看是否有不同的行为。
5. 代码问题
最后,可能是
node_py
代码中的某个部分阻止了日志的正常输出。检查方法:
- 仔细检查
node_py
的代码,特别是与日志输出相关的部分。 - 尝试在
node_py
的不同位置添加日志输出,看是否能看到任何输出。
解决方案
- 确保所有节点的日志级别都设置为可见(例如,
INFO
或更低)。 - 检查节点的启动和运行状态,确保它们都在正常运行。
- 如果节点之间有依赖关系,请确保它们按正确的顺序启动。
- 仔细检查代码和环境配置,查找可能导致问题的任何不一致之处。
如果以上方法都不能解决问题,你可能需要更详细地检查
node_py
的代码和配置,或者尝试在更简单的环境中重现问题。
以上为生成回答,仅供参考~
- 确认在
-
@Jason_Duan
不使用launch,单独启动这俩node,node_py有日志输出
-
@Jason_Duan
将pkg_cpp这个包中的CMakeLists.txt结尾加入install(DIRECTORY launch DESTINATION share/${PROJECT_NAME} )
后,重新编译pkg_cpp包,再launch这个包的launch文件,也是同样的现象
-
@Jason_Duan
使用Ctrl + C终止运行后,最后才显示node_py节点打印的内容,但是仅有一行,图如下
打印的信息为:[node_cpp.EXE-1] [INFO] [1729671693.937304300] [node_cpp]: node_cpp:收到消息:27. 支付 10 元. 剩余 9720 元. [node_cpp.EXE-1] [INFO] [1729671698.941970600] [node_cpp]: node_cpp:收到消息:28. 支付 10 元. 剩余 9710 元. [WARNING] [launch]: user interrupted with ctrl-c (SIGINT) [INFO] [node_cpp.EXE-1]: process has finished cleanly [pid 8092] [ERROR] [node_py.EXE-2]: process has died [pid 32524, exit code 3221225786, cmd 'd:\Code\ros2project\project01\demo_proj\install\pkg_py\lib\pkg_py\node_py.EXE --ros-args']. [node_py.EXE-2] [INFO] [1729671553.926409700] [node_py]: Hello, this is node_py d:\Code\ros2project\project01\demo_proj>
-
@Jason_Duan
问题解决,但又没解决:
使用rqt的console能看到node_py的日志
由此确定:
肯定不是通信的问题,
可能是windows环境下ros2的问题,
更可能是微软的问题 -
@Jason_Duan windows 不好说欸