关于ROS2的坑(galactic)
2023-12-16 本文已影响0人
AntiGravity
安装的坑已发表。
使用的坑
- 当自定义节点
class MyNode(Node)
后,通常会跟main()
函数指定name=name0
。
但若使用launch
文件启动多个MyNode
,并分别指定name=name1, name2, ...
后,self.name=name0
,而self.get_name()=name1, name2, ...
两者居然是不同的。 - 在不同的
namespace
中,通信无法传递。需要用remap: from ... to ...
使得指定Node能获取其他命名空间的通信。 - 局域网内的两台计算机之间可能会出现互相无法接受topic的情况,即便他们可以通过
ros2 multicast send
和ros2 multicast receive
联通,其原因通常是因为一台电脑有额外的网络连接导致。对于我而言,这根网线是为了接受其他设备的数据,不能拔掉。
在小鱼论坛上的所谓集中式服务的办法先放在下面:
ip1=192.168.3.96 # PC1
ip2=192.168.3.123 # PC2 has an extra web connection to receive device data
# command on PC2 terminal1
export ROS_DISCOVERY_SERVER="192.168.3.123:11815"
fastdds discovery --server-id 0 --ip-address 192.168.3.123 --port 11815
# command on PC2 terminal2
export ROS_DISCOVERY_SERVER="192.168.3.123:11815"
ros2 run demo_nodes_cpp listener
# command on PC1 terminal1
export ROS_DISCOVERY_SERVER="192.168.3.123:11815"
ros2 run demo_nodes_cpp talker
此方法在测试中仅适用于两台电脑都没有其他网络连接时有用,不知为何还是无效。目前找到的一个凑合用的解决办法:
- PC1的网线先断开
- PC1上运行一个中间人(inbetween)节点,即一边subscribe设备数据的publish,一边发布数据
- PC2上运行接受节点。因为此时PC1的网线还没连上,所以收发通道稳定,只不过收到的都是空数据。
- 连接PC1的网线。此时inbtween开始接受设备数据,并用之前的通道将数据传到另一台电脑。
中间人节点的代码如下:
from ros2_interfaces.msg import RobotPose, RobotTwist2D
import rclpy
from rclpy.node import Node
class Inbetween(Node):
def __init__(self,name):
super().__init__(name)
self.pose_pub=self.create_publisher(RobotPose,"robot_pose", 10)
self.pose_sub=self.create_subscription(RobotPose, 'robot_pose', self.sub_callback, 10)
self.timer=self.create_timer(1, self.timer_callback)
self.get=False
self.msg=RobotPose()
def timer_callback(self):
self.pose_pub.publish(self.msg)
def sub_callback(self, msg=None):
if msg==None:
self.get_logger().error('msg is none')
else:
self.get=True
self.msg=msg
def main(args=None):
rclpy.init(args=args) # 初始化rclpy
node = Inbetween("inbetween") # 新建一个节点
rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
rclpy.shutdown() # 关闭rclpy