Skip to content

Proposal to add support for managing simulation worlds #4

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

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

ayushgnv
Copy link

@ayushgnv ayushgnv commented Apr 1, 2025

Proposal for World Management Services for Simulation Interfaces Standard

These interfaces provide standardized world management across simulation_interfaces.

The proposed API introduces functionality to dynamically load and unload worlds, enabling automated testing across diverse simulation environments without restarting the simulator. This would allow for workflows where users can load a world file, spawn entities, and run SIL testing facilitating continuous operation on remote systems (sometimes in headless mode).

For Isaac Sim and O3DE (@adamdbrw), these services would likely be useful as these platforms support loading worlds dynamically.

Unlike Entities only one world should be loaded at a time. Attempting to load a world when a world already exists should result in automatically unloading the previously loaded world before loading the current one.

Change Summary:

  • New message: WorldResource
  • New services: LoadWorld, UnloadWorld, GetCurrentWorld, GetAvailableWorlds
  • Added corresponding feature flags (40-44) to SimulatorFeatures.msg
  • Added world_formats field to track supported world file formats

@ayushgnv ayushgnv changed the title Proposal to add support for modifying simulation worlds Proposal to add support for managing simulation worlds Apr 1, 2025
@pijaro
Copy link

pijaro commented Apr 8, 2025

I think it's a good idea.

However, I'm missing an additional simulator state. Setting up a new world will take time, and we should consider that. I suggest adding something like this to SimulationState.msg:

uint8 STATE_INITIALIZING = 4  # Simulation resources are being loaded; the simulation is not running and cannot be started, stopped, or paused.

@adamdbrw
Copy link
Contributor

adamdbrw commented Apr 9, 2025

Good PR, I would love to follow up and propose changes soon, will submit as a PR targeting this one.

@ayushgnv
Copy link
Author

I think it's a good idea.

However, I'm missing an additional simulator state. Setting up a new world will take time, and we should consider that. I suggest adding something like this to SimulationState.msg:

uint8 STATE_INITIALIZING = 4  # Simulation resources are being loaded; the simulation is not running and cannot be started, stopped, or paused.

@pijaro Thanks, great idea! Added STATE_INITIALIZING to SimulationState.msg

@adamdbrw
Copy link
Contributor

ayushgnv#1 - there's the PR

@adamdbrw
Copy link
Contributor

@mjcarroll @peci1 @DLu could you take a look at this one?

Copy link
Contributor

@peci1 peci1 left a comment

Choose a reason for hiding this comment

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

I went through this and left a few comments.

@ayushgnv ayushgnv requested a review from peci1 May 6, 2025 10:59
@mjcarroll
Copy link
Collaborator

@peci1 any more feedback here or are we good?

Copy link
Contributor

@DLu DLu left a comment

Choose a reason for hiding this comment

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

Apologies for the late review.

The thing that confuses me is what actually goes in the URI. I imagined them as unique ids, but LoadWorld.srv specifies them as having a specific format, like SDF.

Comment on lines 16 to 17
uint8 STATE_NO_WORLD = 4 # Simulation world is currently unloaded and a new world has not finished loading yet.
# The simulation is inactive and cannot be started, stopped, or paused.
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like NO_WORLD is a little too specific in this context and STATE_TRANSITIONAL would be better.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
uint8 STATE_NO_WORLD = 4 # Simulation world is currently unloaded and a new world has not finished loading yet.
# The simulation is inactive and cannot be started, stopped, or paused.
uint8 STATE_NO_WORLD = 4 # Simulation world is currently unloaded, and/or a new world has not finished loading yet.
# The simulation is inactive and cannot be started, stopped, or paused.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not 100% sure with my English here. Would TRANSITIONAL also semantically cover the instant where no world is loaded and no world is commanded to be loading?

Copy link
Author

Choose a reason for hiding this comment

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

@peci1 I think STATE_TRANSITIONAL should work as it indicates that simulation is not ready.

I think simulation should not be running anyway if a world is not present. Therefore STATE_TRANSITIONAL does indicate that simulator is not ready.

Alternatively we could switch to STATE_WORLD_UNLOADED. @peci1 @DLu what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I still have a problem with the word transitional. It evokes that a transition is happening. But sometimes, the simulation can just have no world and no transition to execute.

Copy link
Author

Choose a reason for hiding this comment

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

@peci1 I see your point. However I think we are trying to enforce the idea that having no world being loaded means simulation cannot be run and simulation should be in limbo until a new world is loaded.

In my mind an empty void is simply an "empty world" thats been loaded. Which is why I think its ok to call it TRANSITIONAL? This would be a state on its own, and not combined with PLAY, PAUSE, STOP, QUITTING.

Would STATE_LOADING_WORLD work instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see "no world" equal to "empty world". A world is not only a collection of spawnables. It is also something that defines the gravitational field, magnetic field, mapping between world and spherical coordinates, wind, atmospheric pressure, time reference and many other things.

So you cannot spawn entities in "no world".

Gazebo is written in a way that (at least theoretically) allows having a running gz-server without a loaded world, or with multiple worlds loaded at once, or with multiple worlds loaded sequentially.

So the running server with no loaded world would have the state NO_WORLD.

I see the value of both NO_WORLD and LOADING_WORLD states.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think there is harm in having both NO_WORLD and LOADING_WORLD states. I think it is easy enough to set on the simulator side. Maybe that would be a good patch?

Copy link
Author

@ayushgnv ayushgnv Jun 27, 2025

Choose a reason for hiding this comment

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

string uri

# Simulation world passed as a string. This field is used if the uri field is empty.
string resource_string
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make more sense to have two separate services.

  1. Add World, which takes in a resource_string and makes it available for use
  2. Load World, which only takes a uri

Copy link
Author

Choose a reason for hiding this comment

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

Would does "makes it available for use" entail for the simulator? Is there any pre-processing that needs to happen before loading a world in your case?

Copy link
Contributor

Choose a reason for hiding this comment

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

Does "adding" have a value from the perspective of external interface node / automation? I am of opinion that it is an implementation detail, some resources need to be downloaded and other will be available; I would expect the simulator to handle that.

Perhaps it would be useful to document that loading can take a bit and make things clearer through error codes, suggesting async service call etc, what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

So from an abstract perspective, here's what I imagine.

As an external client, I call GetAvailableWorlds.srv and get a list of unique world uri.

worlds: [
  - {uri: 'factory1'}
  - {uri: 'competition_2'}
  - {uri: 'moon}
]

I could then call LoadWorld.srv with uri: 'moon'. However, if instead I wanted to load in some other world that is not specified yet, I could call AddWorld.srv with the resource_string (which I assume would be SDF or similar), and then that new world be listed in the available worlds.

The core issue here is that I think it is semantically cleaner to run separate Add/Load calls than it is to have the single Load call with different behavior if the uri field is empty or not. Also, what happens when uri is nonempty and resource_string is nonempty?

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems to me it could be beneficial to create a Resource message like this:

string uri
string resource_string  # only used if uri is empty

This could then be used in Spawnable, WorldResource and here.

The proposal with AddWorld/LoadWorld seems too complicated to me.

Copy link
Author

@ayushgnv ayushgnv Jun 27, 2025

Choose a reason for hiding this comment

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

@ayushgnv
Copy link
Author

ayushgnv commented May 13, 2025

Apologies for the late review.

The thing that confuses me is what actually goes in the URI. I imagined them as unique ids, but LoadWorld.srv specifies them as having a specific format, like SDF.

@DLu At least from an Isaac Sim perspective we would load USD files by accessing the filepaths in the URI field. Happy to update the LoadWorld.srv message type or description to be something more permissive.

@DLu
Copy link
Contributor

DLu commented May 13, 2025

Apologies for the late review.
The thing that confuses me is what actually goes in the URI. I imagined them as unique ids, but LoadWorld.srv specifies them as having a specific format, like SDF.

@DLu At least from an Isaac Sim perspective we would load USD files by accessing the filepaths in the URI field. Happy to update the LoadWorld.srv message type or description to be something more permissive.

Might just be me, but I could benefit from a description of how you envision these services being used, similar to the "call this one, then this one" example I gave above.

Comment on lines 16 to 17
uint8 STATE_NO_WORLD = 4 # Simulation world is currently unloaded and a new world has not finished loading yet.
# The simulation is inactive and cannot be started, stopped, or paused.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not 100% sure with my English here. Would TRANSITIONAL also semantically cover the instant where no world is loaded and no world is commanded to be loading?

string uri

# Simulation world passed as a string. This field is used if the uri field is empty.
string resource_string
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems to me it could be beneficial to create a Resource message like this:

string uri
string resource_string  # only used if uri is empty

This could then be used in Spawnable, WorldResource and here.

The proposal with AddWorld/LoadWorld seems too complicated to me.

@ayushgnv ayushgnv requested review from peci1, adamdbrw and DLu June 27, 2025 06:31
@@ -0,0 +1,5 @@
# This message is used to specify a resource, either by a URI or by its string content.
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be applied to Spawnable, but not to SpawnEntity interface.
Both of these changes are breaking currently released interfaces. I am not opposed to having a quick version uptick for the package with Worlds feature in though.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for catching! Applied it to SpawnEntity as well.

Bumped the version to 2.0.0 due to the breaking changes

ayushgnv and others added 8 commits June 30, 2025 21:37
Signed-off-by: Adam Dąbrowski <adam.dabrowski@robotec.ai>
Signed-off-by: Adam Dąbrowski <adam.dabrowski@robotec.ai>
Co-authored-by: Martin Pecka <peci1@seznam.cz>
Co-authored-by: Martin Pecka <peci1@seznam.cz>
@ayushgnv ayushgnv force-pushed the simulation_world branch from 072d641 to e87f399 Compare July 1, 2025 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants