Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design document for syncing GUI ECM with server ECM #8

Merged
merged 5 commits into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions gui_server_ecm_sync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Synchronization Between the GUI and Server ECM

## Goal
When creating, deleting, or modifying entities/components in the GUI _while paused_,
GUI changes should be reflected in the server once simulation is resumed, or stepped while paused.

## Approach
adlarkin marked this conversation as resolved.
Show resolved Hide resolved
If a user performs actions that modify/create/remove entities while simulation is paused, the ECM on the GUI side is updated directly to reflect these actions.
The server's ECM does not reflect these user actions yet, but will be notified of the changes that took place once simulation is resumed or stepped while paused.
When the server ECM is notified of these changes, it will be updated to have any changes made to the GUI ECM (unless the GUI and server are run in the same process, which will be discussed below).
Once the server ECM is updated, simulation will be carried out as normal.

The image below depicts how changes to the GUI's ECM are propogated to the server's ECM.
The GUI and server interaction can be done through an event (green arrows), or through a service (red arrow).
chapulina marked this conversation as resolved.
Show resolved Hide resolved
If GUI and server interaction is done through a service, then there's no way to propogate GUI ECM changes to the server.
chapulina marked this conversation as resolved.
Show resolved Hide resolved
The black arrows in the image are things that occur in both the event and service approach.

![gui_server_ecm_design](images/gui_server_ECM_sync_design.png)
chapulina marked this conversation as resolved.
Show resolved Hide resolved

## Notes/Things to Consider
adlarkin marked this conversation as resolved.
Show resolved Hide resolved

### How is the ECM shared and processed between the GUI and server?
The GUI will call [EntityComponentManager::State](https://ignitionrobotics.org/api/gazebo/6.0/classignition_1_1gazebo_1_1EntityComponentManager.html#a8dbc9cf1c9eb4af335aebc178b6cb6f7) to serialize its ECM into a `msgs::SerializedState`, and then share this serialized ECM with the server.
Once the server receives this `msgs::SerializedState`, the server will call [EntityComponentManager::SetState](https://ignitionrobotics.org/api/gazebo/6.0/classignition_1_1gazebo_1_1EntityComponentManager.html#a573b9551891a135bce602344e73a2a36) to apply changes in the GUI's ECM to the server's ECM.

### Server/Client Same Process
When running the server and client in the same process, the server and GUI share the same ECM.
In this scenario, the GUI (`gazebo::GuiRunner`) does not need to share its ECM with the server (`gazebo::SimulationRunner`), but the server still needs to make sure that server plugins are updated according to any changes made to the ECM while paused.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjcarroll , do you think this is reasonable for same-process? Or do we need a mechanism to bundle the GUI-only changes and sync them with the server on play? My concern is that every little change to the GUI ECM will be immediately processed by the server separately unless we bundle them. I think we also need to take the Recreate component into account somewhere in here.


### Updating server plugins
While calling `EntityComponentManager::SetState` will help ensure that server ECM is updated according to changes in the GUI's ECM, system plugins will also need to be updated based on the changes
that took place while simulation was paused.
Here are a few scenarios that will need to be considered:
* Is the physics system ready to handle new links being added to a model?
* Does the sensors system correctly handle a geometry change on a visual?
* What happens to the diff-drive plugin if a joint suddenly dissapears?

While the `ign-gazebo` API gives plugins a way to check what entities are new or removed, it does not provide a way to check what entities have recently changed components.
To get around this, when GUI plugins update an entity in the ECM, a component should be attached to the entity that flags it as an entity that was modified while simulation was paused.
adlarkin marked this conversation as resolved.
Show resolved Hide resolved
When the `gazebo::SimulationRunner` processes changes made to the GUI's ECM, it should also search for entities with this component, and then delete/re-create these entities.
That way, server plugins can listen for newly created entities and operate on them accordingly.

### Undo/Redo
The implementation depicted above does not support undo/redo.
However, looking forward, undo/redo should only be supported while paused since it would be difficult to undo/redo physics.
adlarkin marked this conversation as resolved.
Show resolved Hide resolved
If undo/redo is only supported while paused, the `gazebo::GuiRunner` can keep track of every action that changed the GUI's ECM while paused through a list of `msgs::SerializedState`.
That way, if a user wanted to undo/redo an action that took place while paused, the `gazebo::GuiRunner` could reset the ECM to the appropriate `msgs::SerializedState`.

### Component Serialization
In order to share new, removed, and/or modified entities and components between the server and GUI, the components will need to be serializable.
There are some gazebo components that currently are not serializable.
We should not rely on components that can't be trivially serialized, such as `components::ModelSdf`.

### Component Inspector (GUI)
By modifying the GUI’s ECM directly whenever a user performs a GUI action while simulation is paused,
the component inspector will be updated appropriately since the component inspector uses the GUI’s ECM.
adlarkin marked this conversation as resolved.
Show resolved Hide resolved
Binary file added images/gui_server_ECM_sync_design.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.