From ac6458362d35a48e43efdefa7cb059181d4103f1 Mon Sep 17 00:00:00 2001 From: Jan Hanca Date: Fri, 7 Mar 2025 18:23:31 +0100 Subject: [PATCH 1/4] Code review changes up to GetNamedPoses Signed-off-by: Jan Hanca --- rfcs/RFC Simulation Interfaces.md | 407 +++++++----------------------- 1 file changed, 86 insertions(+), 321 deletions(-) diff --git a/rfcs/RFC Simulation Interfaces.md b/rfcs/RFC Simulation Interfaces.md index 7e01dfc..88a6cba 100644 --- a/rfcs/RFC Simulation Interfaces.md +++ b/rfcs/RFC Simulation Interfaces.md @@ -14,7 +14,7 @@ As a rule of thumb, receiving encouraging feedback from long-standing project de ### Summary: -This RFC is a follow-up to an effort at [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1) to standardize simulation interfaces existing robotics simulators in [ROS 2](https://docs.ros.org/en/jazzy/index.html). Current implementation of similar interfaces is limited to ROS 2 Spawner Component, that utilizes gazebo messages for ROS 2 communication. Proposed approach includes three new Components that will fulfill the design presented at [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1), and that are planned to be developed alongside updates to simulation interfaces. Backward compatibility will be ensured for ROS2SpawnerComponent and ROS2ContactSensor - they will be available through CMake configuration. +This RFC is a follow-up to an effort at [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1) to standardize simulation interfaces existing robotics simulators in [ROS 2](https://docs.ros.org/en/jazzy/index.html). Current implementation of similar interfaces is limited to `ROS2SpawnerComponent`, that utilizes *Gazebo* messages for ROS 2 communication. The messages were marked deprecated in the latest ROS 2 release and should be superseded. Proposed approach includes three new *Components* that will fulfill the design presented in [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1), and that are planned to be developed alongside updates to simulation interfaces. Backward compatibility will be ensured for `ROS2SpawnerComponent` and `ROS2ContactSensor` through CMake configuration with the deprecation information. ### What is the relevance of this feature? @@ -33,15 +33,15 @@ Standardization would improve user experience when using their validation, testi The feature is an API for handling number of ROS 2 [services](https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Services/Understanding-ROS2-Services.html) and [actions](https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Actions/Understanding-ROS2-Actions.html). -There is a terminology that was created in [RFC-410](https://github.com/ros-infrastructure/rep/issues/410) in [ros-infrastructure/rep](https://github.com/ros-infrastructure/rep): +The following terminology that was created in [RFC-410](https://github.com/ros-infrastructure/rep/issues/410) in [ros-infrastructure/rep](https://github.com/ros-infrastructure/rep): -|Term | Description | -|-----------------|-----------------------------------------------------------------------------------------------------| -|Spawnable | Robot or other object that can be spawned in simulation runtime. -|Entity | Spawned spawnable, it has a unique name. -|Bound | A region that is defined by an axis-aligned box shape, convex hull, or a sphere. -|NamedPose | SE3 (translation and rotation) transform with a unique name -|Tag | A string that allows filtering entities and named poses +| Term | Description | +| --------- | -------------------------------------------------------------------------------- | +| Spawnable | Robot or other object that can be spawned in simulation runtime. | +| Entity | Spawned spawnable, it has a unique name. | +| Bound | A region that is defined by an axis-aligned box shape, convex hull, or a sphere. | +| NamedPose | SE3 (translation and rotation) transform with a unique name | +| Tag | A string that allows filtering entities and named poses | The implementation will be split into three (or more) system components: @@ -53,10 +53,10 @@ The implementation will be split into three (or more) system components: It will be responsible for modifying the global state of the simulation (e.g., pausing, reloading). We will decouple the implementation of those features from their ROS 2 interfaces. -Every manager will need to expose public methods that: +Every manager will expose public methods that: - will be callable from C++, - will be handled through dedicated ROS 2 interface and exposed as service. -The purpose of that approach is to enable testability without the need for a ROS domain. +The purpose of that approach is to enable testability without the need for a ROS framework. # ROS 2 API This section presents the detailed plan for implementation, including potential limitation. @@ -66,7 +66,7 @@ This section presents the detailed plan for implementation, including potential The simulator needs to advertise supported features via the ROS 2 service [GetSimulatorFeatures.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetSimulatorFeatures.srv) That service in its response provides the caller with a list of features [SimulatorFeatures.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/SimulatorFeatures.msg) -In the RFC we are proposing to support the following features: +The following features are the subject of this RFC: - SPAWNING - DELETING - NAMED_POSES @@ -83,85 +83,31 @@ In the RFC we are proposing to support the following features: - SIMULATION_PAUSE -We do not plan to support the moment: - - STEP_SIMULATION_SINGLE - - STEP_SIMULATION_MULTIPLE - - STEP_SIMULATION_ACTION +The features ` SIMULATION_RESET_STATE, STEP_SIMULATION_SINGLE, STEP_SIMULATION_MULTIPLE, STEP_SIMULATION_ACTION` will be introduced in the next RFC since they require multiple changes in the *PhysX Gem* and *AzPhysics API*. Action [SimulateSteps.action](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/action/SimulateSteps.action) will not be supported. -Following formats will be supported for spawning (field `spawn_formats` of [SimulatorFeatures.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/SimulatorFeatures.msg)): -``` -[`.spawnable`] -``` - -**Note** Other formats e.g. `URDF` and `SDF` are supported by ROS 2 Gem, but only in Editor. -Those tools are not available in the game mode, so spawning `SDF` and `URDF` would require: - - handling mesh importing in Game Launcher and preparing it to use with Mesh Feature processor, +Only `[.spawnable]` format will be supported for spawning (field `spawn_formats` of [SimulatorFeatures.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/SimulatorFeatures.msg)). Other formats, such as `URDF` and `SDF`, are supported only in the Editor mode in ROS 2 Gem. Spawning `SDF` and `URDF` would require support for the Game mode: + - handling mesh importing in game mode and preparing it to use with the *Mesh Feature Processor*, - creating materials and texture assets in runtime, - PhysX (or other Physics engine) collider mesh cooking with decomposition. Such a feature would be useful, but it is out of the scope of this RFC. -The features ` SIMULATION_RESET_STATE, STEP_SIMULATION_SINGLE, STEP_SIMULATION_MULTIPLE, STEP_SIMULATION_ACTION` will be introduced in the next RFC since they require multiple changes in the PhysX gem and AzPhysics API. -Action [SimulateSteps.action](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/action/SimulateSteps.action) will not be supported. - ## GetSpawnables service -This service allows users to find simulated spawnables to spawn (place) in the simulation. - -Service definition : [GetSpawnables](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetSpawnables.srv) -``` -# Return a list of resources which are valid as SpawnEntity uri fields (e.g. visible to or registered in simulator). -# This interface is an optional extension and might not be implemented by your simulator, check the result_code. - -string[] sources # Optional field for additional sources (local or remote) to search. - # By default, each simulator has visibility of spawnables through - # some mechanisms, e.g. a set of paths, registered assets etc. - # Since the simulator cannot possibly look everywhere, - # this field allows the user to specify additional sources. - # Unrecognized values are listed as such in the result.error_message, - # but do not hinder success of the response. - # Sources may include subcategories and be simulator-specific. - ---- - -Result result -Spawnable[] spawnables # Spawnable objects with URI and additional information. -``` -Definition of individual spawnables [Spawnable.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/Spawnable.msg): -``` -# Robot or other object which can be spawned in simulation runtime. - -string uri # URI which will be accepted by SpawnEntity service. -string description # Optional description for the user, e.g. "robot X with sensors A,B,C". -Bounds spawn_bounds # Optional spawn area bounds which fully encompass this object. -``` +This service allows users to find simulated *spawnables* to spawn (place) in the simulation. \ +Service definition: [GetSpawnables](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetSpawnables.srv) \ +Individual *spawnables* definition: [Spawnable.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/Spawnable.msg) -This service advertises available spawnables that can be used in simulation. -We will utilize the asset catalog to find those spawnables. -There is a useful API in the Engine to get product assets from the asset catalog: -```cpp -AZ::Data::AssetCatalogRequests::EnumerateAssets -``` -The asset catalog contains product assets (such as `.spawnable`, `.azmodel`, `.azbuffer`). -We will introduce another product asset called `.simulationinfo`. -This asset will contain necessary data about Prefab that can be spawned or adjusted by Simulation Interfaces. +We will utilize the asset catalog to find the available *spawnables*. The asset catalog contains product assets (such as `.spawnable`, `.azmodel`, `.azbuffer`). We will introduce another product asset called `.simulationinfo`. It will contain necessary data about *prefab* that can be spawned or adjusted by Simulation Interfaces. The Engine's API will be used to get product assets, namely `AZ::Data::AssetCatalogRequests::EnumerateAssets`. The `.simulationinfo` product asset will be an XML / JSON file (similar to other product assets like `.physxmaterial`) and will contain at least the following information: +- a description (as a string), +- bounds (as a variant of the chosen bound region), +- list of tags, +- category, +- Asset ID of the corresponding prefab. - - a description (as a string), - - bounds (as a variant of the chosen bound region), - - list of tags, - - category, - - Asset ID of the corresponding prefab. - - -The `.simulationinfo` will be created by the asset builder that will be registered by ROS 2 Gem. -This asset builder will consume source assets called `SimulationInfo` and eventually corresponding prefabs. -It will create a `SimulationInfo` product asset in the `Cache` directory. - -The `SimulationInfo` source asset will be a sidecar (a file with the same filename) to a prefab. -It will contain: - +The `.simulationinfo` will be created by the asset builder (registered by ROS 2 Gem) based on the `SimulationInfo` source assets and, eventually, the corresponding prefabs. The `SimulationInfo` source asset will be a sidecar (a file with the same filename) to a prefab. It will contain: - a description (as a string), - bounds (as a variant of the chosen bound region), - list of tags, @@ -170,205 +116,68 @@ It will contain: A simulation expert who wants to create a robot (or other simulation-ready asset) needs: - design a new prefab using standard O3DE workflow, using all available components, - save the prefab with a name e.g., `Robots/FooRobot.prefab` -- create and fill the `SimulationInfo` file as `Robots/FooRobot.SimulationInfo` using a text editor or some tooling in O3DE: - * fill description, - * fill tags, - * fill category, - * and hand-fill bounds (e.g., sphere radius), +- create and fill the `SimulationInfo` sidecar file as `Robots/FooRobot.SimulationInfo` using a text editor or the O3DE tooling - export simulation with the export script and [bundle assets](https://docs.o3de.org/docs/user-guide/packaging/asset-bundler/) -A simulation interfaces user who calls the `GetSpawnables` service against GameLauncher will trigger the following sequence: -- a call to the asset catalog to find all product assets of the type `.simulationinfo`. -- The `ROS 2 Entity manager` will aggregate found assets and will prepare a response that will contain: +A simulation interfaces user who calls the `GetSpawnables` service against GameLauncher will call the asset catalog to find all product assets of the type `.simulationinfo`. The `ROS 2 Entity manager` will aggregate found assets and will prepare a response that will contain: * `uri` as `spawnable://@cache@/robot/foorobot.spawnable` * the description copied from `Robots/FooRobot.SimulationInfo`, * the bound information copied from `Robots/FooRobot.SimulationInfo`, * tag list copied from `Robots/FooRobot.SimulationInfo`, * category copied from `Robots/FooRobot.SimulationInfo`. -- Prepared response will be returned to the ROS 2 user. +Prepared response will be returned to the ROS 2 user. ## SpawnEntity service -Service allows to spawn entities found previously with `GetSpawnables` service. +Service allows spawning entities previously found with `GetSpawnables` service. \ +Service definition: [SpawnEntity](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/SpawnEntity.srv) -Service definition [SpawnEntity](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/SpawnEntity.srv): +The ROS 2 user who wants to spawn a new object in their simulation has to have a valid URI e.g.,`spawnable://@cache@/robot/foorobot.spawnable`. `ROS 2 Entities Manager` will find respective Asset ID based on the URI. -``` -# Spawn an entity (a robot, other object) by name or URI - -string name # A name to give to the spawned entity. - # If empty, a name field in the uri file or resource_string will be used, - # if supported and not empty (e.g. "name" field in SDFormat, URDF). - # If the name is still empty or not unique (as determined by the simulator), - # the service returns a generated name in the entity_name response field if the - # allow_renaming field is set to true. Otherwise, the service call fails and an - # error is returned. -bool allow_renaming # Determines whether the spawning succeeds with a non-unique name. - # If it is set to true, the user should always check entity_name response field - # and use it for any further interactions. -string uri # Resource such as SDFormat, URDF, USD or MJCF file, a native prefab, etc. - # Valid URIs can be determined by calling GetSpawnables first, and you can check - # the simulator format support by reading SimulatorFeatures spawn_formats field. - # If uri field is empty, resource_string must not be empty. -string resource_string # An entity definition file passed as a string. - # Simulators may support spawning from a file generated on the fly (e.g. XACRO). - # Check whether it is supported by your simulator through GetSimulatorFeatures. - # If uri field is not empty, resource_string field will be ignored. -string entity_namespace # Spawn the entity with all its interfaces under this namespace. -geometry_msgs/PoseStamped initial_pose # Initial entity pose. - # The header contains a reference frame, which defaults to global "world" frame. - # This frame must be known to the simulator, e.g. of an object spawned earlier. - # The timestamp field in the header is ignored. - ---- - -# Additional result.result_code values for this service. Check result.error_message for further details. -uint8 NAME_NOT_UNIQUE = 101 # Given name is already taken by entity and allow_renaming is false. -uint8 NAME_INVALID = 102 # Given name is invalid in the simulator (e.g. does not meet naming - # requirements such as allowed characters). This is also returned if name is - # empty and allow_renaming is false. -uint8 UNSUPPORTED_FORMAT = 103 # Format for uri or resource string is unsupported. Check supported formats - # through GetSimulatorFeatures service, in spawn_formats field. -uint8 NO_RESOURCE = 104 # Both uri and resource string are empty. -uint8 NAMESPACE_INVALID = 105 # Namespace does not meet namespace naming standards. -uint8 RESOURCE_PARSE_ERROR = 106 # Resource file or string failed to parse. -uint8 MISSING_ASSETS = 107 # At least one of resource assets (such as meshes) was not found. -uint8 UNSUPPORTED_ASSETS = 108 # At least one of resource assets (such as meshes) is not supported. -uint8 INVALID_POSE = 109 # initial_pose is invalid, such as when the quaternion is invalid or position - # exceeds simulator world bounds. - -Result result -string entity_name # Spawned entity full name, guaranteed to be unique in the simulation. - # If allow_renaming is true, it may differ from the request name field. -``` - -The ROS 2 user who wants to spawn a new object in their simulation has to have a valid URI e.g.,`spawnable://@cache@/robot/foorobot.spawnable`. - -**Note !** -Spawning assets from the file system e.g., `spawnable://home/michalpelka/robots/FooRobot.spawnables` will not be supported. - -With that URI `ROS 2 Entity Manager` will find respective Asset Id. Next, the [SpawnableEntitiesDefinition](https://github.com/o3de/o3de/blob/152bc0a1851d881fe735adf54ec93e1ad7875b11/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h#L334-L333) interface will be utilized to create a spawn ticket and spawn entity. -During spawning the spawned O3DE entities will be modified: -- change the name of the root entity to that given by the `name` field, -- [Transform Component](https://docs.o3de.org/docs/user-guide/components/reference/transform/) of the root entity will modified to reflect the value of the `initial_pose` field, -- [ROS2 Frame](https://www.docs.o3de.org/docs/user-guide/components/reference/ros2/core/ros2-frame/) to set correct namespace. -- A component called `SimulationInfoComponent` will be created and attached to the root entity. - That component will be used to cache information from `simulationinfo` to be easily accessible in the future. -- [TagComponent](https://www.docs.o3de.org/docs/user-guide/components/reference/gameplay/tag/) from LmbrCentral gem at root entity will be created (if not present in prefab). -- TagComponent will be updated with a list of tags from 'simulationinfo'. +**Note !** Spawning assets from the file system e.g., `spawnable://home/username/robots/FooRobot.spawnables` will not be supported. +During spawning, the spawned O3DE entities will be modified as follows: +- The name of the root entity will reflect the name given by the `name` field, +- The [TransformComponent](https://docs.o3de.org/docs/user-guide/components/reference/transform/) of the root entity will reflect the value of the `initial_pose` field, +- The [ROS2FrameComponent](https://www.docs.o3de.org/docs/user-guide/components/reference/ros2/core/ros2-frame/) will reflect the namespace the value of the `entity_namespace` field. +- A component called `SimulationInfoComponent` will be created and attached to the root entity to cache the information from `simulationinfo` and to make it easily accessible in the future. +- [TagComponent](https://www.docs.o3de.org/docs/user-guide/components/reference/gameplay/tag/) from LmbrCentral Gem will be created at root entity (if not present) and updated with a list of tags from the `simulationinfo` sidecar. `SimulationInfoComponent` will be handling a `SimulationInfoComponentRequestBus`. `SimulationInfoComponentRequestBus` will have a unique string key that will come from the name of spawned entity. -This approach will result in a centralized aggregation of entities information, and will provide an API to i.a. find all spawned entities get their states. +This approach will result in a centralized aggregation of entities' information, and will provide an API to find all spawned entities and get their states. ## GetEntities service -This service provides an access to a list of all spawned entities. -Service definition : [GetEntities](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntities.srv ) +This service provides access to a list of all spawned entities. \ +Service definition: [GetEntities](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntities.srv ) -``` -# Get objects in the scene which can be interacted with, e.g. with using SetEntityState. -# You can get further information about entities through GetEntityInfo and GetEntityState services. -# There is also a GetEntitiesStates service if you would like to get state for each entity. - -EntityFilters filters # Optional filters for the query, including name, category, tags, - # and overlap filters. - ---- - -Result result -Entity[] entities # All entities matching the filters. -``` - -where [Entity](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/Entity.msg) is defined: -``` -# Entity identified by its unique name. Entities are objects in the simulation such as models and links. -# Each simulator might define what an entity is in a (slightly) different way. - -string name # Entity unique name. -``` - -We will serve this by calling `SimulationInfoComponentRequestBus` with `AZ::EBusAggregateResults`. -With that, we will obtain a 'AZStd::Vector' of 'AZ::EntityId', that can be converted to a list of entity names. +We will serve this by calling `SimulationInfoComponentRequestBus` with `AZ::EBusAggregateResults` to obtain a list of `AZ::EntityId`, that can be converted to a list of entity names. ## GetEntitiesStates service -This service allows users to get the state (speed, location, acceleration) of chosen entities. +This service allows users to get the state (speed, location, acceleration) of chosen entities. \ +Service definition: [GetEntitiesStates.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntitiesStates.srv) +Individual entity state definition: [EntityState](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/EntityState.msg) -Service definition : [GetEntitiesStates.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntitiesStates.srv) -``` -# Get objects in the scene which can be interacted, e.g. with using SetEntityState. -# Use GetEntities service instead if EntityState information for all entities is not needed. +The service handling will be similar to [GetEntities](#GetEntities). Additional calls will be required to fill the state information: + - [RigidBodyRequestBus](https://github.com/o3de/o3de/blob/79e1df3990c5554c454d68798a0f3ef94c8ae317/Code/Framework/AzFramework/AzFramework/Physics/RigidBodyBus.h) will be used to find the current twist, + - [TransformComponentRequests](https://github.com/o3de/o3de/blob/42d375dd99b972400f9f26bfec7e3444088f3398/Code/Framework/AzCore/AzCore/Component/TransformBus.h) will be used to find the current pose, + - [ROS2FrameBus.h](https://github.com/o3de/o3de-extras/blob/development/Gems/ROS2/Code/Include/ROS2/Frame/ROS2FrameBus.h) will be used to find the frame ID. -EntityFilters filters # Optional filters for the query, including name, category, tags, - # and overlap filters. - ---- - -Result result -Entity[] entities # All entities matching the filters. -EntityState[] states # States for these entities. -``` - -where [EntityState](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/EntityState.msg) is: -``` -# Entity current pose, twist and acceleration - -std_msgs/Header header # Frame and timestamp for pose and twist. Empty frame defaults to world. -geometry_msgs/Pose pose # Pose in reference frame, ground truth. -geometry_msgs/Twist twist # Ground truth linear and angular velocities - # observed in the frame specified by header.frame_id - # See https://github.com/ros2/common_interfaces/pull/240 for conventions. -geometry_msgs/Accel acceleration # Linear and angular acceleration ground truth, following the same convention. -``` - -The service handling will be similar to [GetEntities](#GetEntities). -There will be more calls to : - - [RigidBodyRequestBus](https://github.com/o3de/o3de/blob/79e1df3990c5554c454d68798a0f3ef94c8ae317/Code/Framework/AzFramework/AzFramework/Physics/RigidBodyBus.h) to find current twist, - - [TransformComponentRequests](https://github.com/o3de/o3de/blob/42d375dd99b972400f9f26bfec7e3444088f3398/Code/Framework/AzCore/AzCore/Component/TransformBus.h) to find current pose, - - [ROS2FrameBus.h](https://github.com/o3de/o3de-extras/blob/development/Gems/ROS2/Code/Include/ROS2/Frame/ROS2FrameBus.h) to find frame id. - -**Note !** Acceleration is will not be filled, and will not be supported. +**Note !** Acceleration will not be filled, and will not be supported. ## SetEntityState service -This service allows modifying the state of the chosen entity. +This service allows modifying the state of the chosen entity. \ +Service definition: [SetEntityState.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/SetEntityState.srv) -Service definition [SetEntityState.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/SetEntityState.srv) -``` -# Set a state of an object, which will result in an instant change in its pose and/or twist. - -Entity entity # Entity identified by its unique name as returned by GetEntities / SpawnEntity. -EntityState state # New state to set immediately. The timestamp in header is ignored. - # Note that the acceleration field may be ignored by simulators. - ---- - -Result `result`: -``` -where [EntityState](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/EntityState.msg) is: -``` -# Entity current pose, twist and acceleration - -std_msgs/Header header # Frame and timestamp for pose and twist. Empty frame defaults to world. -geometry_msgs/Pose pose # Pose in reference frame, ground truth. -geometry_msgs/Twist twist # Ground truth linear and angular velocities - # observed in the frame specified by header.frame_id - # See https://github.com/ros2/common_interfaces/pull/240 for conventions. -geometry_msgs/Accel acceleration # Linear and angular acceleration ground truth, following the same convention. -``` - -The O3DE EntityId will be discovered by calling `SimulationInfoComponentRequestBus` with the entity name provided in the service request. -Next, having the EntityId the corresponding API will be called to adjust the state: - - [TransformComponentRequests](https://github.com/o3de/o3de/blob/42d375dd99b972400f9f26bfec7e3444088f3398/Code/Framework/AzCore/AzCore/Component/TransformBus.h) or - [RigidBodyRequestBus](https://github.com/o3de/o3de/blob/79e1df3990c5554c454d68798a0f3ef94c8ae317/Code/Framework/AzFramework/AzFramework/Physics/RigidBodyBus.h) to - adjust the position of the simulated entity. - - [ROS2FrameBus.h](https://github.com/o3de/o3de-extras/blob/development/Gems/ROS2/Code/Include/ROS2/Frame/ROS2FrameBus.h) to eventually change frame id, - - [RigidBodyRequestBus](https://github.com/o3de/o3de/blob/79e1df3990c5554c454d68798a0f3ef94c8ae317/Code/Framework/AzFramework/AzFramework/Physics/RigidBodyBus.h) to - adjust speed or acceleration. +The `AZ::EntityId` will be discovered by calling `SimulationInfoComponentRequestBus` with the name provided in the request. Next, the corresponding API will be called to adjust the state of the entity: + - [TransformComponentRequests](https://github.com/o3de/o3de/blob/42d375dd99b972400f9f26bfec7e3444088f3398/Code/Framework/AzCore/AzCore/Component/TransformBus.h) or [RigidBodyRequestBus](https://github.com/o3de/o3de/blob/79e1df3990c5554c454d68798a0f3ef94c8ae317/Code/Framework/AzFramework/AzFramework/Physics/RigidBodyBus.h) to adjust the position of the simulated entity. + - [ROS2FrameBus.h](https://github.com/o3de/o3de-extras/blob/development/Gems/ROS2/Code/Include/ROS2/Frame/ROS2FrameBus.h) to eventually change the frame ID, + - [RigidBodyRequestBus](https://github.com/o3de/o3de/blob/79e1df3990c5554c454d68798a0f3ef94c8ae317/Code/Framework/AzFramework/AzFramework/Physics/RigidBodyBus.h) to adjust the speed or the acceleration. Note that serving this service is a bit tricky in O3DE. Due to the modularity of O3DE, the entities can be moved around in several ways: @@ -382,15 +191,15 @@ Due to the modularity of O3DE, the entities can be moved around in several ways: - Potential 3rd physics engine. Some of those methods respect calls to `TranformComponentRequests`, but some of them need to call directly methods in the PhysX gem. -| Method | TransformComponentRequests API| RigidBodyRequestBus API | Custom API | -|----------------------------------------|--------------------------------|--------------------------|------------| -|Simulated PhysX Rigid Body | | supports | | -|Kinematic PhysX Rigid Body | supports | | | -|TransformComponent due to parent-child | supports | | | -|TransformComponent (custom calls) | | | | -|PhysX character component | | | ? | -|PhysX ragdoll | | | ? | -|PhysX articulations | | | supports | +| Method | TransformComponentRequests API | RigidBodyRequestBus API | Custom API | +| --------------------------------------- | ------------------------------ | ----------------------- | ---------- | +| Simulated PhysX Rigid Body | | supports | | +| Kinematic PhysX Rigid Body | supports | | | +| TransformComponent due to parent-child | supports | | | +| TransformComponent (custom calls) | | | | +| PhysX character component | | | ? | +| PhysX ragdoll | | | ? | +| PhysX articulations | | | supports | The correct API needs to be chosen to get the expected outcome it can be quite tricky. Let us investigate moving a `Simulated PhysX Rigid Body'. @@ -419,82 +228,38 @@ The alternative, approach would be to cycle through: - Use `TransformBus::Events::SetWorldTM` to change location, - enable simulation of [simulated body](https://docs.o3de.org/docs/user-guide/interactivity/physics/nvidia-physx/simulated-bodies/). -The velocity (twist) can be applied using `RigidBodyRequestBus::SetLinearVelocity` and `RigidBodyRequestBus::SetAngularVelocity`. -It will be effective against Simulated PhysX Rigid Body and Kinematic PhysX Rigid Body and should give a warning if it called against -unsupported type. - +The velocity (twist) can be applied using `RigidBodyRequestBus::SetLinearVelocity` and `RigidBodyRequestBus::SetAngularVelocity`. +It will be effective against Simulated PhysX Rigid Body and Kinematic PhysX Rigid Body and should give a warning if it called against unsupported type. The acceleration can be applied using `RigidBodyRequestBus::ApplyLinearImpulse` w.r.t object's mass. It will be effective against Simulated PhysX Rigid Body and should give a warning if it is called against unsupported type. -**Important :** Currently ROS2 Gem is heavily dependant on PhysX5 (due to SDF importer). The decoupling of those needs to be done in the future. +**Important :** Currently ROS2 Gem is heavily dependent on PhysX5 (due to SDF importer). The decoupling of those needs to be done in the future. ## DeleteEntity service - -Despawn previously spawned entity - -Service definition [DeleteEntity.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/DeleteEntity.srv) -``` -# Remove an entity (a robot, other object) from the simulation - -Entity entity # Entity identified by its unique name with a namespace, - # as returned by SpawnEntity or GetEntities. ---- - -Result result -``` +This service allows despawning the previously spawned entities. \ +Service definition: [DeleteEntity.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/DeleteEntity.srv) -The O3DE entity ID and their spawn ticket ID will be discovered by `SimulationInfoComponentRequestBus`. -Next the component `ROS 2 Entity manager` will be asked to despawn and remove the corresponding spawn ticket. +The `AZ::EntityId` will be discovered by calling `SimulationInfoComponentRequestBus` with the name provided in the request. Next, the corresponding API will be called to despawn and remove the corresponding spawn ticket. -**Important:** This mechanism will now allow to delete of entities that are part of the level prefab (e.g., prefab instantiated in Editor). +**Important:** This mechanism will allow to delete the entities that are part of the level prefab (e.g., prefab instantiated in Editor). ## GetEntityBounds service -Returns bounds of the spawned entity. - -Service definition [GetEntityBounds.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntityBounds.srv) -``` -# Get geometrical bounds for entity. This feature is available if GetSimulatorFeatures includes ENTITY_BOUNDS feature. - -Entity entity # Entity identified by its unique name as returned by GetEntities / SpawnEntity. - ---- - -Result result -Bounds bounds -``` +This service allows to get the bounds of the previously spawned entities. \ +Service definition: [GetEntityBounds.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntityBounds.srv) -The bounds for particular entities will be obtained by calling `SimulationInfoComponentRequestBus`. +The bound for the particular entity will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. ## GetEntityInfo service -Returns category, description and tags for spawned entity. - -Service definition [GetEntityInfo.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntityInfo.srv): -``` -# Get type and other information about an entity. - -Entity entity # Entity identified by its unique name as returned by GetEntities / SpawnEntity. - ---- - -Result result -EntityInfo info # Only valid if result.result_code is OK. -``` -where [EntityInfo.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/EntityInfo.msg): -``` -# Entity type and additional information - -uint8 category # Major category for the entity. Extra entity type distinction can be made through tags. - # See EntityCategories for defined category values. -string description # optional: verbose, human-readable description of the entity. -string[] tags # optional: tags which are useful for filtering and categorizing entities further. -``` +This service allows to get the category, description and tags for the given entity. \ +Service definition: [GetEntityInfo.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntityInfo.srv) \ +Particular entity info definition: [EntityInfo.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/EntityInfo.msg) -This information will be obtained from `SimulationInfoComponentRequestBus`. +This information the particular entity will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. ## GetNamedPoses service @@ -583,12 +348,12 @@ Result result This service will need to use multiple APIs to give results. -|Scope | Planned API and usage | -|----------------|-------------------- -|SCOPE_ALL | ConsoleRequestBus and `LoadLevel` command. -|SCOPE_SPAWNED | Internal gem API to destroy all spawn tickets in ROS 2 Entities manager. -|SCOPE_STATE | Move all spawned entities to initial poses cached in ROS 2 Entities manager. -|SCOPE_TIME | New ROS2Bus call +| Scope | Planned API and usage | +| ------------- | ---------------------------------------------------------------------------- | +| SCOPE_ALL | ConsoleRequestBus and `LoadLevel` command. | +| SCOPE_SPAWNED | Internal gem API to destroy all spawn tickets in ROS 2 Entities manager. | +| SCOPE_STATE | Move all spawned entities to initial poses cached in ROS 2 Entities manager. | +| SCOPE_TIME | New ROS2Bus call | ## SetSimulationState service @@ -738,4 +503,4 @@ The effort needs to be taken to adjust the existing code to the deprecation of G - Handling integration of physics engine. - Timing of implementation and release. -- Avoid coupling ROS2 Gem with PhysX5 Gem. \ No newline at end of file +- Avoid coupling ROS2 Gem with PhysX5 Gem. From 69d9e15f9f4aaf4fb5f72467c99288784639a12c Mon Sep 17 00:00:00 2001 From: Jan Hanca Date: Mon, 10 Mar 2025 19:29:50 +0100 Subject: [PATCH 2/4] Code review changes after GetNamedPoses Signed-off-by: Jan Hanca --- rfcs/RFC Simulation Interfaces.md | 251 +++++++++--------------------- 1 file changed, 74 insertions(+), 177 deletions(-) diff --git a/rfcs/RFC Simulation Interfaces.md b/rfcs/RFC Simulation Interfaces.md index 88a6cba..72eda90 100644 --- a/rfcs/RFC Simulation Interfaces.md +++ b/rfcs/RFC Simulation Interfaces.md @@ -45,18 +45,14 @@ The following terminology that was created in [RFC-410](https://github.com/ros-i The implementation will be split into three (or more) system components: -- ROS 2 Entities manager \ - It will be responsible for the lifetime of spawned objects, it will cache initial positions. -- ROS 2 Named poses manager \ - It will be responsible for aggregating information in the Named Pose Game Component. -- ROS 2 Simulator manager \ - It will be responsible for modifying the global state of the simulation (e.g., pausing, reloading). - -We will decouple the implementation of those features from their ROS 2 interfaces. -Every manager will expose public methods that: +- `ROS 2 Entities manager`: responsible for the lifetime of spawned objects, it will cache initial positions. +- `ROS 2 Named poses manager`: responsible for aggregating information in the Named Pose Game Component. +- `ROS 2 Simulator manager`: responsible for modifying the global state of the simulation (e.g., pausing, reloading). + +We will decouple the implementation of those features from their ROS 2 interfaces. Every manager will expose public methods that: - will be callable from C++, - will be handled through dedicated ROS 2 interface and exposed as service. -The purpose of that approach is to enable testability without the need for a ROS framework. +The purpose of that approach is to enable testability without the need for a ROS framework and ensure the whole system can be used with any middleware in the future. # ROS 2 API This section presents the detailed plan for implementation, including potential limitation. @@ -83,7 +79,7 @@ The following features are the subject of this RFC: - SIMULATION_PAUSE -The features ` SIMULATION_RESET_STATE, STEP_SIMULATION_SINGLE, STEP_SIMULATION_MULTIPLE, STEP_SIMULATION_ACTION` will be introduced in the next RFC since they require multiple changes in the *PhysX Gem* and *AzPhysics API*. Action [SimulateSteps.action](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/action/SimulateSteps.action) will not be supported. +The features *SIMULATION_RESET_STATE*, *STEP_SIMULATION_SINGLE*, *STEP_SIMULATION_MULTIPLE*, *STEP_SIMULATION_ACTION* will be introduced in the next RFC since they require multiple changes in the *PhysX Gem* and *AzPhysics API*. Action [SimulateSteps.action](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/action/SimulateSteps.action) will not be supported. Only `[.spawnable]` format will be supported for spawning (field `spawn_formats` of [SimulatorFeatures.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/SimulatorFeatures.msg)). Other formats, such as `URDF` and `SDF`, are supported only in the Editor mode in ROS 2 Gem. Spawning `SDF` and `URDF` would require support for the Game mode: - handling mesh importing in game mode and preparing it to use with the *Mesh Feature Processor*, @@ -136,7 +132,7 @@ The ROS 2 user who wants to spawn a new object in their simulation has to have a Next, the [SpawnableEntitiesDefinition](https://github.com/o3de/o3de/blob/152bc0a1851d881fe735adf54ec93e1ad7875b11/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h#L334-L333) interface will be utilized to create a spawn ticket and spawn entity. -**Note !** Spawning assets from the file system e.g., `spawnable://home/username/robots/FooRobot.spawnables` will not be supported. +**Note:** Spawning assets from the file system e.g., `spawnable://home/username/robots/FooRobot.spawnables` will not be supported. During spawning, the spawned O3DE entities will be modified as follows: - The name of the root entity will reflect the name given by the `name` field, @@ -167,7 +163,7 @@ The service handling will be similar to [GetEntities](#GetEntities). Additional - [TransformComponentRequests](https://github.com/o3de/o3de/blob/42d375dd99b972400f9f26bfec7e3444088f3398/Code/Framework/AzCore/AzCore/Component/TransformBus.h) will be used to find the current pose, - [ROS2FrameBus.h](https://github.com/o3de/o3de-extras/blob/development/Gems/ROS2/Code/Include/ROS2/Frame/ROS2FrameBus.h) will be used to find the frame ID. -**Note !** Acceleration will not be filled, and will not be supported. +**Note:** Acceleration will not be filled, and will not be supported. ## SetEntityState service @@ -235,7 +231,7 @@ The acceleration can be applied using `RigidBodyRequestBus::ApplyLinearImpulse` It will be effective against Simulated PhysX Rigid Body and should give a warning if it is called against unsupported type. -**Important :** Currently ROS2 Gem is heavily dependent on PhysX5 (due to SDF importer). The decoupling of those needs to be done in the future. +**Note:** Currently ROS2 Gem is heavily dependent on PhysX5 (due to SDF importer). The decoupling of those needs to be done in the future. ## DeleteEntity service @@ -244,14 +240,14 @@ Service definition: [DeleteEntity.srv](https://github.com/adamdbrw/simulation_in The `AZ::EntityId` will be discovered by calling `SimulationInfoComponentRequestBus` with the name provided in the request. Next, the corresponding API will be called to despawn and remove the corresponding spawn ticket. -**Important:** This mechanism will allow to delete the entities that are part of the level prefab (e.g., prefab instantiated in Editor). +**Note:** This mechanism will allow to delete the entities that are part of the level prefab (e.g., prefab instantiated in Editor). ## GetEntityBounds service This service allows to get the bounds of the previously spawned entities. \ Service definition: [GetEntityBounds.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntityBounds.srv) -The bound for the particular entity will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. +The bound for the particular entity will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. The information about entity's bounds will be stored within the `.simulationinfo` product asset, and it will be generated based on the source asset data provided by the simulation engineer. ## GetEntityInfo service @@ -259,148 +255,53 @@ This service allows to get the category, description and tags for the given enti Service definition: [GetEntityInfo.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntityInfo.srv) \ Particular entity info definition: [EntityInfo.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/EntityInfo.msg) -This information the particular entity will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. +This information will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. The information will be stored within the `.simulationinfo` product asset, and it will be generated based on the source asset data provided by the simulation engineer. ## GetNamedPoses service -Simulation expert using O3DE Editor can add entity with component from ROS2 gem called `Named Pose Editor Component`. -This component will require `TransformService` and dependent services `BoxShapeService` and `SphereShapeService` -The `Named Pose Component` will contain two configurable fields called `description` and `tags`. -During creation of game component (`CreateGameEntity`) the TagComponent from LmbrCentral gem will be created and fed with list of tags. -Creating the TagComponent is useful to make this feature compatible with O3DE's tag system. -The box or sphere shape component allows to definition of optional boundaries around the named pose. - -**Important** Convex hull bound shape will not be supported yet. - -Calling service `GetNamedPose` will discover those components and return their configuration. - -Service definition [GetNamedPoses.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetNamedPoses.srv): -``` -# Get predefined poses which are convenient to for spawning, navigation goals etc. - -TagsFilter tags # Tags filter to apply. Only named poses with matching tags field - # will be returned. Can be empty (see TagsFilter). +This service allows to get the list of the predefined poses which are convenient to for spawning, navigation goals, etc. \ +Service definition: [GetNamedPoses.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetNamedPoses.srv) \ +Individual named pose definition: [NamedPose.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/NamedPose.msg) ---- +This information will be obtained by calling a respective bus of `ROS 2 Named poses manager`. Additionally, the aggregation will be filtered based on the parameters of the call. The poses will be predefined by a simulation expert using O3DE Editor. In particular, each entity with `NamedPoseComponent` from ROS 2 Gem will be registered in the poses manager. The `NamedPoseComponent` will contain two configurable fields called `description` and `tags`. During creation of game component (`CreateGameEntity`) the `TagComponent` from `LmbrCentral` Gem will be created and fed with the list of tags. -Result result -NamedPose[] poses # A list of predefined poses, which may be empty. -``` -where: [TagsFilter.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/TagsFilter.msg), -[NamedPose.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/NamedPose.msg): -``` -# A named pose defined in the simulation for certain purposes such as spawning. - -string name # Unique name. -string description # Description for the user, e.g. "near the charging station". -string[] tags # Optional tags which can be used to determine the named pose - # purpose, for example: "spawn", "parking", "navigation_goal", - # as well as fitting entity types e.g. "drone", "turtlebot3". -geometry_msgs/Pose pose # Pose relative to world, which can be used with SpawnEntity.srv. -``` - -During simulation entities with `Named Pose Component` will be discovered (e.g., using designated request bus or o3de tag system), -the aggregation will be filtered and returned to the caller. - -**Important** Since O3DE does not require those names to be unique, the ROS 2 gem needs to skip or extend the names of duplicates. +**Note:** `ROS 2 Named poses manager` will ensure the names are unique (O3DE does not check for the name's uniqueness). ## GetNamedPoseBounds service -Service allows to get boundaries defined in Named Pose. +This service allows to get the boundaries defined in the predefined pose object. \ +Service definition [GetNamedPoseBounds.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetNamedPoseBounds.srv) -Service definition [GetNamedPoseBounds.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetNamedPoseBounds.srv): -``` -# Get bounds for the named pose. This feature is available if GetSimulatorFeatures includes POSE_BOUNDS feature. +The information about the boundaries will be obtained by calling a respective bus of `ROS 2 Named poses manager`. Additionally, the aggregation will be filtered based on the parameters of the call. The boundaries of the pose will be predefined by a simulation expert using O3DE Editor by adding `TransformService` and dependent services `BoxShapeService` and `SphereShapeService` alongside with the `NamedPoseComponent`. -string name # unique names (as returned from GetNamedPoses). - ---- - -Result result -Bounds bounds # bounds for the named pose. -``` - -It will expose data in the Named Pose Game Component and corresponding Shape Components. +**Note:** Convex hull bound shape will not be supported in this implementation. This subject will be cover by another RFC when necessary. ## Reset Simulation service -Allows ROS 2 user to reset the simulation. - -Service definition [ResetSimulation.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/ResetSimulation.srv) -``` -# Reset the simulation to the start, including the entire scene and the simulation time. -# Objects that were dynamically spawned are de-spawned. - -uint8 SCOPE_DEFAULT = 0 # same as ALL. -uint8 SCOPE_TIME = 1 # Reset simulation time to start. -uint8 SCOPE_STATE = 2 # Reset state such as poses and velocities. This may include state randomization - # if such feature is available and turned on. -uint8 SCOPE_SPAWNED = 4 # De-spawns all spawned entities. -uint8 SCOPE_ALL = 255 # Fully resets simulation to the start, as if it was closed and launched again. - -uint8 scope # Scope of the reset. Note that simulators might only support some scopes. - # This is a bit field which may be checked for each scope e.g. scope & TIME. - ---- - -Result result -``` +This service allows to reset the simulation via ROS 2 interface. \ +Service definition: [ResetSimulation.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/ResetSimulation.srv) -This service will need to use multiple APIs to give results. +This service will be handled by `ROS 2 Simulator manager`. It will use multiple APIs to give results. -| Scope | Planned API and usage | -| ------------- | ---------------------------------------------------------------------------- | -| SCOPE_ALL | ConsoleRequestBus and `LoadLevel` command. | -| SCOPE_SPAWNED | Internal gem API to destroy all spawn tickets in ROS 2 Entities manager. | -| SCOPE_STATE | Move all spawned entities to initial poses cached in ROS 2 Entities manager. | -| SCOPE_TIME | New ROS2Bus call | +| Scope | Planned API and usage | +| ------------- | ------------------------------------------------------------------------------ | +| SCOPE_ALL | `ConsoleRequestBus` and `LoadLevel` command. | +| SCOPE_SPAWNED | Internal API to destroy all spawn tickets using `ROS 2 Entities manager`. | +| SCOPE_STATE | Move all spawned entities to initial poses cached in `ROS 2 Entities manager`. | +| SCOPE_TIME | New call using `ROS2Bus` | ## SetSimulationState service -Allows ROS 2 user to set the state of the simulation (STOPPED, PAUSED, PLAYING, QUITTING) +This service allows to set the state of the simulation (*STOPPED*, *PAUSED*, *PLAYING*, *QUITTING*). \ +Service definition: [SimulationState](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/SimulationState.msg) -``` -# Change the simulation state - - -SimulationState state # Target state to set for the simulation. +This service will be handled by `ROS 2 Simulator manager`. ---- +The transition from *PLAYING* or *PAUSED* to *STOPPED* will trigger level reloading. -uint8 ALREADY_IN_TARGET_STATE = 101 # Additional result type for this call, which means simulation was already - # in the target state (e.g. was already stopped when STOP was requested). -uint8 STATE_TRANSITION_ERROR = 102 # The simulator failed to transition to the target state. This might happen - # especially with the transition to PLAYING from STOPPED. - # See result.error_message for details. -uint8 INCORRECT_TRANSITION = 103 # Incorrect transition (pausing when in stopped state). +The transition from *PLAYING* to *PAUSED* will ask the default physics scene to be disabled. It will stop movement of all PhysX articulations, rigid bodies (both kinematic and simulated), and characters, but some animations will be played. The transition from *PAUSED* to *PLAYING* will do the opposite. -Result result - -``` -where [SimulationState](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/SimulationState.msg) is defined as: -``` -# Simulation states used in SetSimulationState and returned in GetSimulationState - -uint8 STOPPED = 0 # Simulation is stopped, which is equivalent to pausing and resetting with ALL. - # This is typically the default state when simulator is launched. - # Stopped simulation can be played. It can also be paused, which means - # starting simulation in a paused state immediately, - # without any time steps for physics or simulated clock ticks. -uint8 PLAYING = 1 # Simulation is playing, can be either paused or stopped. -uint8 PAUSED = 2 # Simulation is paused, can be either stopped (which will reset it) or played. -uint8 QUITTING = 3 # Closing the simulator application. Switching from PLAYING or PAUSED states - # is expected to stop the simulation first, and then exit. - # Simulation interfaces will become unavailable after quitting. - # Running simulation application is outside of the simulation interfaces as - # there is no service to handle the call when the simulator is not up. - -uint8 state -``` - -The transition from PLAYING to STOPPED will trigger level reloading. That will take a while to complete. \ -The transition from PLAYING to PAUSED will ask the default physics scene to be disabled. -It will stop movement of all PhysX articulations, rigid bodies (both kinematic and simulated), and characters, but some animations will be played. -The transition from PLAYING to QUITTING will simply call: +The transition from *PLAYING*, *PAUSED*, or *STOPPED* to *QUITTING* will call: ```cpp int* ptr = nullptr; *ptr= 99; @@ -415,48 +316,44 @@ The ROS 2 Simulator manager will contain the state of the simulation and perform ## GetSimulationState service -Allows ROS 2 user to get the current state of the simulation. +This service allows to get the current state of the simulation. \ +Service definition: [GetSimulationState.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetSimulationState.srv) -Service definition [GetSimulationState.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetSimulationState.srv) +This service will be handled by `ROS 2 Simulator manager`. If transition is in progress (e.g. reloading level or despawning), the old state will be returned. -``` -# Gets the simulation state (paused, playing, stopped) +# Deprecated components in ROS 2 Gem ---- +During this effort some components will be retired, and some moved outside of scope of supported and canonical repos. This is primarily caused by ROS 2 community retiring `gazebo_msgs`. -SimulationState state # Current state of the simulation. +### ROS2SpawnerComponent -Result result -``` -The ROS 2 Simulator manager will return current state. -If transition is in progress (e.g. reloading level or despawning), the old state will be returned. +The `ROS2SpawnerComponent` can co-exist with managers for *Simulation Interfaces* proposed in this RFC, but ROS 2 dependencies (namely `gazebo_msgs`) will be removed from upcoming ROS 2 distribution (`Kilted Kaiju`). The component will be marked deprecated (instead of completely removed from the codebase) to make the transition to Simulation Interfaces an easier experience. The component will be hidden away from users with the *CMake variable*. This variable will be first set to *enabled* by default, and toggled to *disabled* after the deprecation period into the retirement period. Finally, the component will be completely removed from ROS 2 Gem. +**Note:** Additional message during the *configure* step will be shown to the user if `gazebo_msgs` package is not detected, but the *variable* is set *true*. +Users of `Kilted Kaiju` (and newer) ROS 2 releases will be able to use the deprecated component by building the package manually in their custom ROS 2 workspace. This involves: +- cloning and building the latest [gazebo_ros_pkgs/gazebo_msgs](https://github.com/ros-simulation/gazebo_ros_pkgs/tree/3.9.0/gazebo_msgs) +- sourcing custom workspace +- setting CMake flag +- building ROS2 gem from source. -## Deprecated components in ROS 2 Gem +The deprecation period and the retirement period of the component are yet to be decided. -During this effort some components will be retired, and some moved outside of scope of supported and canonical repos. +### ROS2ContactSensorComponent -### ROS2SpawnerComponent +The `ROS2ContactSensorComponent` is independent of *Simulation Interfaces* proposed in this RFC, but ROS 2 dependencies (namely `gazebo_msgs`) will be removed from upcoming ROS 2 distribution (`Kilted Kaiju`). In particular, this component uses [`ContactState` message](https://github.com/ros-simulation/gazebo_ros_pkgs/blob/3.9.0/gazebo_msgs/msg/ContactState.msg). The component will be hidden away from users with the *CMake variable*. This variable will be first set to *enabled* by default, and toggled to *disabled* after the deprecation period into the retirement period. Finally, the component will be completely removed from ROS 2 Gem. -The ROS2Spawner component will be retired and hidden away from users with the CMake variable. -This component can co-exist with managers for Simulation Interfaces, but ROS 2 package that the ROS2Spawner requires will be removed from upcoming ROS 2 distribution (Kilted Kaiju). -The said package (`gazebo_msgs`) will be replaced by `simulation_interfaces`. -The component will be retired (instead of completely removed from the codebase) to make the transition to Simulation interfaces an easier experience. -However, using ROS2Spawner component will require a few extra steps (after the EOL of the `gazebo_msgs` package): +**Note:** Additional message during the *configure* step will be shown to the user if `gazebo_msgs` package is not detected, but the *variable* is set *true*. + +Users of `Kilted Kaiju` (and newer) ROS 2 releases will be able to use the deprecated component by building the package manually in their custom ROS 2 workspace. This involves: - cloning and building the latest [gazebo_ros_pkgs/gazebo_msgs](https://github.com/ros-simulation/gazebo_ros_pkgs/tree/3.9.0/gazebo_msgs) - sourcing custom workspace - setting CMake flag - building ROS2 gem from source. -### ROS2ContactSensorComponent - -This component's code also depends on [`gazebo_msgs`](https://github.com/ros-simulation/gazebo_ros_pkgs/blob/3.9.0/gazebo_msgs/msg/ContactState.msg). -Since there is no equivalent message in simulation_interfaces component will be retired and hidden from Users with CMakeVariable. -The steps to use this component will be the same as those in the ROS2SpawnerComponent. - -Note that the ROS 2 community probably propose suitable replacement messages in the future. +The deprecation period and the retirement period of the component are yet to be decided. +# Conclusions - -### What are the advantages of the feature? +## What are the advantages of the feature? - - Leading standardization of simulation in the robotics domain, - - easier usage of O3DE in robotics and ML pipelines, - - improve the testability of the ROS 2 features, - - adjustments to EOL of `gazebo_msgs` +- Adoption of the simulation standard in the robotics domain in O3DE. +- Improving the user experience of robotics and ML pipelines in O3DE. +- Improvement of the ROS 2 features' testability. +- Adjustments to the end-of-life of `gazebo_msgs`. -### What are the disadvantages of the feature? +## What are the disadvantages of the feature? -Significant increase in code base size for ROS2 Gem. +Significant increase in the code base size for ROS 2 Gem. ### How will this be implemented or integrated into the O3DE environment? -It was explained in great detail in the section [ROS 2 API](#ros-2-api). +The *Simulation Interfaces* feature will build over the ROS 2 Gem. In particular, three separate tools for managing the *spawnables*, the simulation and the named poses will be implemented as O3DE *System Components*. The tools will be callable using O3DE bus system and via ROS 2 middleware. The latter will be decoupled from the *Simulation Interfaces* implementation to ensure the system can be used with different frameworks in the future. More details about the design are given in section [ROS 2 API](#ros-2-api). ### Are there any alternatives to this feature? -The effort needs to be taken to adjust the existing code to the deprecation of Gazebo Classic and `gazebo_msgs`. +The effort needs to be taken to adjust the existing code to the deprecation of Gazebo Classic and `gazebo_msgs`. *ROS 2 Simulation Interfaces* are the upcoming simulation standard that was primarily designed by O3DE *sig-simulation* developers. It will be integrated into all simulation engines and, therefore, it makes no sense to ### How will users learn this feature? @@ -495,12 +391,13 @@ The effort needs to be taken to adjust the existing code to the deprecation of G - Explain how it would be taught to new and existing O3DE users. - Include any significant impacts to documentation such as; Required official video updates, required product screenshot updates (i.e. Editor UX changes), new documentation site sections. --> -- Posts by OpenRobotics and Robotec.AI in their social media -- documentation in [o3de.org](o3de.org) and [docs.ros.org](https://docs.ros.org/en/jazzy/Tutorials/Advanced/Simulators/Simulation-Main.html) -- tutorials, conferences +- Documentation in [o3de.org](o3de.org) and [docs.ros.org](https://docs.ros.org/en/jazzy/Tutorials/Advanced/Simulators/Simulation-Main.html). +- Discord social platform of O3DE. +- Posts by OpenRobotics and Robotec.ai in their social media. +- Tutorials, conferences. ### Are there any open questions? -- Handling integration of physics engine. -- Timing of implementation and release. -- Avoid coupling ROS2 Gem with PhysX5 Gem. +- Handling integration with the physics engine. +- Timing of the implementation and the release. +- Avoid coupling ROS 2 Gem with PhysX5 Gem. From 958bedd616d5bda3a198ab0227a9b63d09b296a3 Mon Sep 17 00:00:00 2001 From: Jan Hanca Date: Mon, 17 Mar 2025 15:25:18 +0100 Subject: [PATCH 3/4] External code review changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan Hanca Co-authored-by: Michał Pełka Co-authored-by: Paweł Liberadzki Signed-off-by: Jan Hanca --- rfcs/RFC Simulation Interfaces.md | 39 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/rfcs/RFC Simulation Interfaces.md b/rfcs/RFC Simulation Interfaces.md index 72eda90..2588056 100644 --- a/rfcs/RFC Simulation Interfaces.md +++ b/rfcs/RFC Simulation Interfaces.md @@ -14,7 +14,7 @@ As a rule of thumb, receiving encouraging feedback from long-standing project de ### Summary: -This RFC is a follow-up to an effort at [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1) to standardize simulation interfaces existing robotics simulators in [ROS 2](https://docs.ros.org/en/jazzy/index.html). Current implementation of similar interfaces is limited to `ROS2SpawnerComponent`, that utilizes *Gazebo* messages for ROS 2 communication. The messages were marked deprecated in the latest ROS 2 release and should be superseded. Proposed approach includes three new *Components* that will fulfill the design presented in [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1), and that are planned to be developed alongside updates to simulation interfaces. Backward compatibility will be ensured for `ROS2SpawnerComponent` and `ROS2ContactSensor` through CMake configuration with the deprecation information. +This RFC is a follow-up to an effort at [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1) to standardize [ROS 2](https://docs.ros.org/en/jazzy/index.html) simulation interfaces for robotics simulators. Current implementation of similar interfaces is limited to `ROS2SpawnerComponent`, that utilizes *Gazebo* messages for ROS 2 communication. The messages were marked deprecated in the latest ROS 2 release and should be superseded. Proposed approach includes three new *Components* that will fulfill the design presented in [ros-simulation/simulation_interfaces](https://github.com/ros-simulation/simulation_interfaces/pull/1), and that are planned to be developed alongside updates to simulation interfaces. Backward compatibility will be ensured for `ROS2SpawnerComponent` and `ROS2ContactSensor` through CMake configuration with the deprecation information. ### What is the relevance of this feature? @@ -39,7 +39,7 @@ The following terminology that was created in [RFC-410](https://github.com/ros-i | --------- | -------------------------------------------------------------------------------- | | Spawnable | Robot or other object that can be spawned in simulation runtime. | | Entity | Spawned spawnable, it has a unique name. | -| Bound | A region that is defined by an axis-aligned box shape, convex hull, or a sphere. | +| Bounds | A volume that is defined by an axis-aligned box shape, convex hull, or a sphere. | | NamedPose | SE3 (translation and rotation) transform with a unique name | | Tag | A string that allows filtering entities and named poses | @@ -52,6 +52,7 @@ The implementation will be split into three (or more) system components: We will decouple the implementation of those features from their ROS 2 interfaces. Every manager will expose public methods that: - will be callable from C++, - will be handled through dedicated ROS 2 interface and exposed as service. + The purpose of that approach is to enable testability without the need for a ROS framework and ensure the whole system can be used with any middleware in the future. # ROS 2 API @@ -68,6 +69,7 @@ The following features are the subject of this RFC: - NAMED_POSES - POSE_BOUNDS - ENTITY_BOUNDS + - ENTITY_TAGS - ENTITY_STATE_LISTING - ENTITY_STATE_SETTING @@ -75,11 +77,9 @@ The following features are the subject of this RFC: - SIMULATION_RESET - SIMULATION_RESET_TIME - SIMULATION_RESET_SPAWNED - - SIMULATION_RESET_STATE - - SIMULATION_PAUSE -The features *SIMULATION_RESET_STATE*, *STEP_SIMULATION_SINGLE*, *STEP_SIMULATION_MULTIPLE*, *STEP_SIMULATION_ACTION* will be introduced in the next RFC since they require multiple changes in the *PhysX Gem* and *AzPhysics API*. Action [SimulateSteps.action](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/action/SimulateSteps.action) will not be supported. +The features *STEP_SIMULATION_SINGLE*, *STEP_SIMULATION_MULTIPLE*, and *STEP_SIMULATION_ACTION* will be introduced in the next RFC since they require multiple changes in the *PhysX Gem* and *AzPhysics API*. Action [SimulateSteps.action](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/action/SimulateSteps.action) will not be supported. Only `[.spawnable]` format will be supported for spawning (field `spawn_formats` of [SimulatorFeatures.msg](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/msg/SimulatorFeatures.msg)). Other formats, such as `URDF` and `SDF`, are supported only in the Editor mode in ROS 2 Gem. Spawning `SDF` and `URDF` would require support for the Game mode: - handling mesh importing in game mode and preparing it to use with the *Mesh Feature Processor*, @@ -121,6 +121,7 @@ A simulation interfaces user who calls the `GetSpawnables` service against GameL * the bound information copied from `Robots/FooRobot.SimulationInfo`, * tag list copied from `Robots/FooRobot.SimulationInfo`, * category copied from `Robots/FooRobot.SimulationInfo`. + Prepared response will be returned to the ROS 2 user. ## SpawnEntity service @@ -193,8 +194,8 @@ Some of those methods respect calls to `TranformComponentRequests`, but some of | Kinematic PhysX Rigid Body | supports | | | | TransformComponent due to parent-child | supports | | | | TransformComponent (custom calls) | | | | -| PhysX character component | | | ? | -| PhysX ragdoll | | | ? | +| PhysX character component | | | TBD | +| PhysX ragdoll | | | TBD | | PhysX articulations | | | supports | The correct API needs to be chosen to get the expected outcome it can be quite tricky. @@ -240,14 +241,16 @@ Service definition: [DeleteEntity.srv](https://github.com/adamdbrw/simulation_in The `AZ::EntityId` will be discovered by calling `SimulationInfoComponentRequestBus` with the name provided in the request. Next, the corresponding API will be called to despawn and remove the corresponding spawn ticket. -**Note:** This mechanism will allow to delete the entities that are part of the level prefab (e.g., prefab instantiated in Editor). +**Note:** This mechanism will **not** allow to delete the entities that are the part of the level prefab (e.g., prefab instantiated in Editor). ## GetEntityBounds service This service allows to get the bounds of the previously spawned entities. \ Service definition: [GetEntityBounds.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetEntityBounds.srv) -The bound for the particular entity will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. The information about entity's bounds will be stored within the `.simulationinfo` product asset, and it will be generated based on the source asset data provided by the simulation engineer. +The bounds for the particular entity will be obtained by calling `SimulationInfoComponentRequestBus` with the name of the entity provided in the request. The information about entity's bounds will be stored within the `.simulationinfo` product asset, and it will be generated based on the source asset data provided by the simulation engineer. + +**Note:** Convex hull bounds shape will not be supported in this implementation. This subject will be cover by another RFC when necessary. ## GetEntityInfo service @@ -269,12 +272,12 @@ This information will be obtained by calling a respective bus of `ROS 2 Named po ## GetNamedPoseBounds service -This service allows to get the boundaries defined in the predefined pose object. \ +This service allows to get the bounds defined in the predefined pose object. \ Service definition [GetNamedPoseBounds.srv](https://github.com/adamdbrw/simulation_interfaces/blob/simulation_interfaces/srv/GetNamedPoseBounds.srv) -The information about the boundaries will be obtained by calling a respective bus of `ROS 2 Named poses manager`. Additionally, the aggregation will be filtered based on the parameters of the call. The boundaries of the pose will be predefined by a simulation expert using O3DE Editor by adding `TransformService` and dependent services `BoxShapeService` and `SphereShapeService` alongside with the `NamedPoseComponent`. +The information about the bounds will be obtained by calling a respective bus of `ROS 2 Named poses manager`. Additionally, the aggregation will be filtered based on the parameters of the call. The bounds of the pose will be predefined by a simulation expert using O3DE Editor by adding `TransformService` and dependent services `BoxShapeService` and `SphereShapeService` alongside with the `NamedPoseComponent`. -**Note:** Convex hull bound shape will not be supported in this implementation. This subject will be cover by another RFC when necessary. +**Note:** Convex hull bounds shape will not be supported in this implementation. This subject will be cover by another RFC when necessary. ## Reset Simulation service @@ -329,12 +332,12 @@ During this effort some components will be retired, and some moved outside of sc The `ROS2SpawnerComponent` can co-exist with managers for *Simulation Interfaces* proposed in this RFC, but ROS 2 dependencies (namely `gazebo_msgs`) will be removed from upcoming ROS 2 distribution (`Kilted Kaiju`). The component will be marked deprecated (instead of completely removed from the codebase) to make the transition to Simulation Interfaces an easier experience. The component will be hidden away from users with the *CMake variable*. This variable will be first set to *enabled* by default, and toggled to *disabled* after the deprecation period into the retirement period. Finally, the component will be completely removed from ROS 2 Gem. -**Note:** Additional message during the *configure* step will be shown to the user if `gazebo_msgs` package is not detected, but the *variable* is set *true*. +**Note:** Additional message during the *configure* step will be shown to the user if `gazebo_msgs` package is not detected, but the *variable* is set *enabled*. Users of `Kilted Kaiju` (and newer) ROS 2 releases will be able to use the deprecated component by building the package manually in their custom ROS 2 workspace. This involves: - cloning and building the latest [gazebo_ros_pkgs/gazebo_msgs](https://github.com/ros-simulation/gazebo_ros_pkgs/tree/3.9.0/gazebo_msgs) - sourcing custom workspace -- setting CMake flag +- setting *CMake variable* (after deprecation period) - building ROS2 gem from source. The deprecation period and the retirement period of the component are yet to be decided. @@ -343,12 +346,12 @@ The deprecation period and the retirement period of the component are yet to be The `ROS2ContactSensorComponent` is independent of *Simulation Interfaces* proposed in this RFC, but ROS 2 dependencies (namely `gazebo_msgs`) will be removed from upcoming ROS 2 distribution (`Kilted Kaiju`). In particular, this component uses [`ContactState` message](https://github.com/ros-simulation/gazebo_ros_pkgs/blob/3.9.0/gazebo_msgs/msg/ContactState.msg). The component will be hidden away from users with the *CMake variable*. This variable will be first set to *enabled* by default, and toggled to *disabled* after the deprecation period into the retirement period. Finally, the component will be completely removed from ROS 2 Gem. -**Note:** Additional message during the *configure* step will be shown to the user if `gazebo_msgs` package is not detected, but the *variable* is set *true*. +**Note:** Additional message during the *configure* step will be shown to the user if `gazebo_msgs` package is not detected, but the *variable* is set to *enabled*. Users of `Kilted Kaiju` (and newer) ROS 2 releases will be able to use the deprecated component by building the package manually in their custom ROS 2 workspace. This involves: - cloning and building the latest [gazebo_ros_pkgs/gazebo_msgs](https://github.com/ros-simulation/gazebo_ros_pkgs/tree/3.9.0/gazebo_msgs) - sourcing custom workspace -- setting CMake flag +- setting *CMake variable* (after deprecation period) - building ROS2 gem from source. The deprecation period and the retirement period of the component are yet to be decided. @@ -382,7 +385,9 @@ The *Simulation Interfaces* feature will build over the ROS 2 Gem. In particular ### Are there any alternatives to this feature? -The effort needs to be taken to adjust the existing code to the deprecation of Gazebo Classic and `gazebo_msgs`. *ROS 2 Simulation Interfaces* are the upcoming simulation standard that was primarily designed by O3DE *sig-simulation* developers. It will be integrated into all simulation engines and, therefore, it makes no sense to +The effort needs to be taken to adjust the existing code to the deprecation of Gazebo Classic and `gazebo_msgs`. *ROS 2 Simulation Interfaces* are the upcoming simulation standard that was primarily designed by O3DE *sig-simulation* developers. It will be integrated into all major simulation engines and, therefore, should be integrated into O3DE. + +The proposed approach allows for a smooth transition from the previous implementation to the standard. We are open for suggestions on the architecture of the O3DE integration. ### How will users learn this feature? From a370a165e09028d6e27eec52c8988d9799130251 Mon Sep 17 00:00:00 2001 From: Jan Hanca Date: Mon, 17 Mar 2025 15:32:11 +0100 Subject: [PATCH 4/4] Rename RFC file to keep consistent Signed-off-by: Jan Hanca --- ...faces.md => RFC Feature - Simulation Interfaces Integration.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename rfcs/RFC Simulation Interfaces.md => RFC Feature - Simulation Interfaces Integration.md (100%) diff --git a/rfcs/RFC Simulation Interfaces.md b/RFC Feature - Simulation Interfaces Integration.md similarity index 100% rename from rfcs/RFC Simulation Interfaces.md rename to RFC Feature - Simulation Interfaces Integration.md