RobotLocomotion / drake

Model-based design and verification for robotics.
https://drake.mit.edu
Other
3.32k stars 1.26k forks source link

Firefox doesn't play well with MeshcatVisualizer when the number of objects is large #16265

Closed xuchenhan-tri closed 7 months ago

xuchenhan-tri commented 2 years ago

In the review of #16248, @jwnimmer-tri discovered that when trying to visualize the mass spring example (with 400 spheres by default) with Firefox is excruciatingly slow and usually ends up crashing the browser. Chrome, on the other hand, doesn't suffer as much.

Admittedly, visualizing the cloth with hundreds of spheres is not ideal. In this branch, I experimented with sending a single triangle mesh instead of hundreds of spheres in the message and it seems to alleviate the problem. Nevertheless, the difference between Firefox and Chrome is probably still worth exploring. Posting this as a Drake issue for now, but I'm not sure if this issue should belong in the upstream repo.

In addition, MeshCatVisualizer doesn't seem to provide an API to visualize triangle meshes even though the underlying MeshCat class does support it. This API should come in handy when we visualize hydro contact surfaces as a part of #15738.

CC @RussTedrake

RussTedrake commented 2 years ago

Just to be clear, MeshcatVisualizer would not provide API support for triangle meshes; it is simply a system that publishes using the Meshcat API with the contents of the SceneGraph. Internally, if the SceneGraph has geometry that should be rendered with triangle meshes, then it would call that appropriate Meshcat API.

RussTedrake commented 2 years ago

Another thought: There is a mechanism in uWebsockets, which I haven't used yet, to do "corking". Perhaps this example is a case that merits it, or something similar. If the problem here is that we are killing the socket by sending a ton of small messages (with the RigidTransform for all of the spheres), we might want to cork and uncork to transmit one blob of messages instead. But I have not tried it yet.

xuchenhan-tri commented 2 years ago

I don't really know anything about Websockets so I can't meaningfully comment on that. But the fact that the visualizer can take a single message of the entire mesh just fine seems to indicate that the problem here is caused by a ton of small messages.

RussTedrake commented 2 years ago

I reproduced the terrible performance with firefox. yuck.

FTR -- sending an animation works well (since it sends all of the poses at once). To try it, just use:

  auto& visualizer = geometry::MeshcatVisualizerd::AddToBuilder(
      &builder, *scene_graph, std::make_shared<geometry::Meshcat>());
  auto diagram = builder.Build();
  auto context = diagram->CreateDefaultContext();
  auto simulator =
      systems::MakeSimulatorFromGflags(*diagram, std::move(context));
  visualizer.StartRecording();
  simulator->AdvanceTo(10.0);
  visualizer.PublishRecording();
  std::cout << "[Press RETURN to continue]." << std::endl;
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

I also looked quickly at the corking support in uWebSockets. I don't think it's going to accomplish our goal. So I might recommend two resolutions: 1) add an option to MeshcatVisualizer to disable the nominal display while recording. (the code above runs the at the slow rate while generating the simulation, then the animation at the end plays beautifully). 2) add a mechanism at the meshcat layer to publish a list of commands in a single message. This will require a little plumbing on the meshcat javascript side, too. But it should be easy enough.

sherm1 commented 2 years ago

Assigned to @xuchenhan-tri for now -- please reassign if appropriate.

xuchenhan-tri commented 7 months ago

I can't reproduce this issue any more. Not sure if this is caused by changes in Firefox versions or recent changes to meshcat. Closing the issue anyway.