循环生成multibody plants遇X服务器连接错误,求渲染器清理方案
你的报错Maximum number of clients reached bad X server connection vtkXOpenGLRenderWindow本质是VTK渲染器创建的X窗口实例没有被正确销毁,导致X服务器的客户端连接数达到上限——每次循环调用scene_graph.AddRenderer都会新建一个VTK渲染器实例,而这些实例的资源没有被释放,最终撑爆连接数。
下面是具体的解决思路:
显式移除并释放渲染器资源
在每次循环结束、不再使用当前Multibody Plant和SceneGraph实例前,调用scene_graph.RemoveRenderer(renderer_name),让SceneGraph解除对该渲染器的引用。这样RenderEngineVtk实例会被正确析构,其内部的VTK窗口资源(包括X连接)也会被释放。确保在循环的收尾步骤执行这个操作,不要遗漏。复用渲染器实例,避免重复创建
如果你的循环只是需要更新Multibody Plant的内容而非完全重建场景,完全可以把渲染器的创建逻辑移到循环外部。只初始化一次RenderEngineVtk,循环内复用同一个渲染器,这样就不会不断产生新的X客户端连接,从根源上避免资源泄漏。关闭可视化窗口(非可视化场景)
如果循环过程不需要实时显示可视化界面,只是后台计算,可以修改RenderEngineVtkParams,禁用窗口显示:RenderEngineVtkParams params; params.show_window = false; scene_graph.AddRenderer(renderer_name, MakeRenderEngineVtk(params));这种情况下VTK不会创建X窗口,自然也就不会占用X服务器的客户端连接。
手动强制VTK清理底层资源
如果上述方法仍有残留资源,可以尝试手动触发VTK的资源回收。通过RenderEngineVtk的接口获取内部的vtkXOpenGLRenderWindow实例,调用其Finalize()或Delete()方法(注意要确保Drake的内存管理允许这样操作,避免悬空指针):auto render_engine = dynamic_cast<RenderEngineVtk*>(scene_graph.GetRenderer(renderer_name)); if (render_engine) { render_engine->render_window()->Finalize(); render_engine->render_window()->Delete(); }执行完后再调用
scene_graph.RemoveRenderer(renderer_name)完成清理。
内容的提问来源于stack exchange,提问作者Sarvesh Thakur

