You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webots多E-puck机器人项目报错:仅允许创建一个Robot类实例

Webots多机器人项目错误排查:Robot实例重复创建问题

问题背景

开发Webots项目时,使用四个E-puck机器人推送箱子至目标位置,代码采用Environment类、Robot类加主控制循环的结构。运行时出现错误:Only one instance of the Robot class should be created,同时收到警告:'Supervisor' controller exited with status: -1。相关代码片段如下:

_robot_instance = None
_supervisor_instance = None
def __init__(self, use_supervisor=False):
    self.use_supervisor = use_supervisor
    self.TIME_STEP = 32
    self.receiver = None
    self.webots_supervisor = None
    if use_supervisor:
        if Environment._supervisor_instance is None:
            Environment._supervisor_instance = Supervisor()
        self.webots_supervisor = Environment._supervisor_instance
        self.robot = self.webots_supervisor.getFromDef("agent1")
    else:
        if Environment._robot_instance is None:
            Environment._robot_instance = Robot()
        self.robot = Environment._robot_instance
def reset(self):
    print(f"Supervisor: {self.webots_supervisor}")
    # Release existing Robot/Supervisor instance if it exists
    if self.use_supervisor:
        if Environment._supervisor_instance is not None:
            self.webots_supervisor = None
            self.robot = None
            del Environment._supervisor_instance
    else:
        if Environment._robot_instance is not None:
            self.robot = None
    # Create a new Robot/Supervisor instance
    if use_supervisor:
        Environment._supervisor_instance = Supervisor()
        self.webots_supervisor = Environment._supervisor_instance
        self.robot = self.webots_supervisor.getFromDef("agent1")
    else:
        if Environment._robot_instance is None:
            Environment._robot_instance = Robot()
        self.robot = Environment._robot_instance
    try:
        # Ensure that Supervisor instance is used when appropriate
        root = (
            self.webots_supervisor.getRoot()
            if self.use_supervisor
            else self. robot.getRoot()
        )
        self.print_node_names(root)
    except AttributeError as e:
        print(f"Error getting nodes: {e}")

错误原因分析

  1. Robot实例重复创建:reset方法的非Supervisor分支中,删除旧实例后未置空类变量_robot_instance,导致下次创建时if Environment._robot_instance is None判断失效,实际旧实例已被销毁,重新赋值时会创建新的Robot实例,违反Webots一个控制器只能有一个Robot实例的规则。
  2. Supervisor分支逻辑漏洞:reset方法创建新Supervisor实例时未检查类变量是否已存在,直接赋值可能导致重复创建;删除实例后也未置空_supervisor_instance类变量。
  3. 拼写错误:self. robot.getRoot()中多了空格,会触发AttributeError,进而导致控制器异常退出。

修复方案

修复后的代码片段

_robot_instance = None
_supervisor_instance = None
def __init__(self, use_supervisor=False):
    self.use_supervisor = use_supervisor
    self.TIME_STEP = 32
    self.receiver = None
    self.webots_supervisor = None
    if use_supervisor:
        if Environment._supervisor_instance is None:
            Environment._supervisor_instance = Supervisor()
        self.webots_supervisor = Environment._supervisor_instance
        self.robot = self.webots_supervisor.getFromDef("agent1")
    else:
        if Environment._robot_instance is None:
            Environment._robot_instance = Robot()
        self.robot = Environment._robot_instance

def reset(self):
    print(f"Supervisor: {self.webots_supervisor}")
    # Release existing Robot/Supervisor instance if it exists
    if self.use_supervisor:
        if Environment._supervisor_instance is not None:
            self.webots_supervisor = None
            self.robot = None
            del Environment._supervisor_instance
            Environment._supervisor_instance = None  # 置空类变量
    else:
        if Environment._robot_instance is not None:
            self.robot = None
            del Environment._robot_instance
            Environment._robot_instance = None  # 置空类变量
    # Create a new Robot/Supervisor instance
    if self.use_supervisor:
        if Environment._supervisor_instance is None:  # 增加存在性检查
            Environment._supervisor_instance = Supervisor()
        self.webots_supervisor = Environment._supervisor_instance
        self.robot = self.webots_supervisor.getFromDef("agent1")
    else:
        if Environment._robot_instance is None:
            Environment._robot_instance = Robot()
        self.robot = Environment._robot_instance
    try:
        # 修复空格拼写错误
        root = (
            self.webots_supervisor.getRoot()
            if self.use_supervisor
            else self.robot.getRoot()
        )
        self.print_node_names(root)
    except AttributeError as e:
        print(f"Error getting nodes: {e}")

关键修复点

  • 置空类变量:删除实例后必须将_robot_instance和_supervisor_instance置为None,确保下次创建时的判断逻辑正确。
  • 增加实例存在性检查:Supervisor分支创建新实例前先检查类变量是否为空,避免重复创建。
  • 修复拼写错误:去掉self. robot中的空格,改为self.robot,防止AttributeError导致控制器异常退出。

额外注意事项

  • Webots中每个控制器进程只能创建一个Robot/Supervisor实例,多机器人场景下每个机器人对应独立的控制器进程,不要在同一个控制器里尝试创建多个Robot实例。
  • 若使用Supervisor控制多机器人,确保通过getFromDef或getFromId正确获取各个机器人节点,而非重复创建Supervisor实例。

内容的提问来源于stack exchange,提问作者Kazmi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:20:37