Skip to content

Composabl Sim API

Simulators are the core of the Composabl platform. They are the environments in which agents are trained. To create a simulator that works with the Composabl API, you have the choice to either:

  • Use the Composabl SDK
  • Implement the Composabl API with gRPC
  • Implement the Composabl API with HTTP

💡 The Composabl SDK will automatically take care of serializing and deserializing the different requests and responses

Composabl SDK

The Composabl SDK provides a simple way to create simulators that work with the Composabl platform. To create a simulator using the Composabl SDK, you have to implement the ServerComposabl class. This class provides the necessary methods to interact with the simulation environment.

python
from typing import Any, Dict, SupportsFloat, Tuple
import gymnasium as gym

from composabl_core.agent.scenario.scenario import Scenario
from composabl_core.networking.server_composabl import ServerComposabl

from your_env.sim import YourEnv as Sim


class ServerImpl(ServerComposabl):
    """
    Define the way how Composabl (ServerComposabl) can interact with the simulation environment (SimEnv)
    """
    def __init__(self, *args, **kwargs):
        self.env_init = kwargs.get("env_init", {})

    async def make(self, env_id: str, env_init: dict):
        self.env_id = env_id if env_id else self.env_id
        self.env_init = env_init if env_init else self.env_init

        print("Creating MockSim with env_init: ", self.env_init)
        self.env = Sim(self.env_init)

        return {
            "id": "my_simulator",
            "max_episode_steps": 1000
        }

    async def observation_space_info(self) -> gym.Space:
        return self.env.observation_space

    async def action_space_info(self) -> gym.Space:
        return self.env.action_space

    async def action_space_sample(self) -> Any:
        return self.env.action_space.sample()

    async def reset(self) -> Tuple[Any, Dict[str, Any]]:
        return self.env.reset()

    async def step(self, action) -> Tuple[Any, SupportsFloat, bool, bool, Dict[str, Any]]:
        return self.env.step(action)

    async def close(self):
        self.env.close()

    async def set_scenario(self, scenario):
        self.env.scenario = scenario

    async def get_scenario(self):
        if self.env.scenario is None:
            return Scenario({
                "dummy": 0
            })

        return self.env.scenario

    async def set_reward_func(self, reward_func):
        self.env.set_reward_func(reward_func)

    async def set_render_mode(self, render_mode):
        self.env.render_mode = render_mode

    async def get_render_mode(self):
        return self.env.render_mode

    async def get_render(self):
        self.env.render_mode = "rgb_array"
        return self.env.render()

gRPC

Under the hood, the Composabl SDK uses gRPC to communicate with the Composabl platform. If you want to implement the Composabl API with gRPC yourself, you have to implement the following gRPC methods:

To create a simulator that works with the Composabl API, you have to implement the following gRPC methods:

protobuf
service Composabl {
  // Creates the environment with specified configurations.
  // - MakeRequest: Contains parameters to configure the environment.
  // - MakeResponse: Returns an identifier for the created environment and possibly other initial setup information.
  rpc make(MakeRequest) returns (MakeResponse) {}

  // Advances the environment by one timestep using the action provided in the request.
  // - StepRequest: Includes the action to be taken in the current state of the environment.
  // - StepResponse: Returns the new state of the environment, reward received, and a flag indicating if the episode has ended.
  rpc step(StepRequest) returns (StepResponse) {}

  // Resets the state of the environment, returning it to its initial conditions.
  // - ResetRequest: May include parameters for resetting to specific scenarios.
  // - ResetResponse: Provides the initial observation of the reset environment.
  rpc reset(ResetRequest) returns (ResetResponse) {}

  // Performs any necessary cleanup before the environment is closed.
  // - CloseRequest: May be empty or include specific closing instructions.
  // - CloseResponse: Acknowledges the environment has been successfully closed.
  rpc close(CloseRequest) returns (CloseResponse) {}

  // Generates a sample action from the environment's action space.
  // - ActionSpaceSampleRequest: May be empty or specify particular sampling criteria.
  // - ActionSpaceSampleResponse: Provides a sample action from the action space.
  rpc action_space_sample(ActionSpaceSampleRequest) returns (ActionSpaceSampleResponse) {}

  // Retrieves information about the environment's action space.
  // - ActionSpaceInfoRequest: May be empty or include parameters for the information request.
  // - ActionSpaceInfoResponse: Returns detailed information about the action space.
  rpc action_space_info(ActionSpaceInfoRequest) returns (ActionSpaceInfoResponse) {}

  // Retrieves information about the environment's observation space.
  // - ObservationSpaceInfoRequest: May be empty or include parameters for the information request.
  // - ObservationSpaceInfoResponse: Returns detailed information about the observation space.
  rpc observation_space_info(ObservationSpaceInfoRequest) returns (ObservationSpaceInfoResponse) {}

  // Sets the current scenario for the environment.
  // - SetScenarioRequest: Includes parameters defining the scenario to set.
  // - SetScenarioResponse: Acknowledges the scenario has been set.
  rpc set_scenario(SetScenarioRequest) returns (SetScenarioResponse) {}

  // Retrieves the current scenario of the environment.
  // - GetScenarioRequest: May be empty if simply retrieving the current scenario.
  // - GetScenarioResponse: Returns details of the current scenario.
  rpc get_scenario(GetScenarioRequest) returns (GetScenarioResponse) {}

  // Sets the render mode of the environment.
  // - SetRenderModeRequest: Includes parameters for the desired render mode.
  // - SetRenderModeResponse: Confirms the render mode has been set.
  rpc set_render_mode(SetRenderModeRequest) returns (SetRenderModeResponse) {}

  // Retrieves the current render mode of the environment.
  // - GetRenderModeRequest: May be empty if simply querying the current mode.
  // - GetRenderModeResponse: Returns the current render mode.
  rpc get_render_mode(GetRenderModeRequest) returns (GetRenderModeResponse) {}

  // Retrieves the current render of the environment.
  // - GetRenderRequest: May include parameters specifying the render details.
  // - GetRenderResponse: Provides the current render of the environment.
  rpc get_render(GetRenderRequest) returns (GetRenderResponse) {}
}

HTTP

json
// Creates the environment with specified configurations.
// - MakeRequest: Contains parameters to configure the environment.
// - MakeResponse: Returns an identifier for the created environment and possibly other initial setup information.
POST '/make'

// Advances the environment by one timestep using the action provided in the request.
// - StepRequest: Includes the action to be taken in the current state of the environment.
// - StepResponse: Returns the new state of the environment, reward received, and a flag indicating if the episode has ended.
GET '/observation-space-info'

// Resets the state of the environment, returning it to its initial conditions.
// - ResetRequest: May include parameters for resetting to specific scenarios.
// - ResetResponse: Provides the initial observation of the reset environment.
GET '/action-space-info'

// Performs any necessary cleanup before the environment is closed.
// - CloseRequest: May be empty or include specific closing instructions.
// - CloseResponse: Acknowledges the environment has been successfully closed.
GET '/action-space-sample'

// Generates a sample action from the environment's action space.
// - ActionSpaceSampleRequest: May be empty or specify particular sampling criteria.
// - ActionSpaceSampleResponse: Provides a sample action from the action space.
POST '/reset'

// Retrieves information about the environment's action space.
// - ActionSpaceInfoRequest: May be empty or include parameters for the information request.
// - ActionSpaceInfoResponse: Returns detailed information about the action space.
POST '/step'

// Retrieves information about the environment's observation space.
// - ObservationSpaceInfoRequest: May be empty or include parameters for the information request.
// - ObservationSpaceInfoResponse: Returns detailed information about the observation space.
POST '/close'

// Sets the current scenario for the environment.
// - SetScenarioRequest: Includes parameters defining the scenario to set.
// - SetScenarioResponse: Acknowledges the scenario has been set.
POST '/scenario'

// Retrieves the current scenario of the environment.
// - GetScenarioRequest: May be empty if simply retrieving the current scenario.
// - GetScenarioResponse: Returns details of the current scenario.
GET '/scenario'

// Sets the render mode of the environment.
// - SetRenderModeRequest: Includes parameters for the desired render mode.
// - SetRenderModeResponse: Confirms the render mode has been set.
POST '/render-mode'

// Retrieves the current render mode of the environment.
// - GetRenderModeRequest: May be empty if simply querying the current mode.
// - GetRenderModeResponse: Returns the current render mode.
GET '/render-mode'

// Retrieves the current render of the environment.
// - GetRenderRequest: May include parameters specifying the render details.
// - GetRenderResponse: Provides the current render of the environment.
POST '/render'

Request / Response Objects

For performance reasons, Both HTTP and gRPC methods utilize Protobuf for serializing and deserializing the requests and responses to and from the Composabl platform.

protobuf
// Base request for all operations, can be extended for specific needs.
message BaseRequest {}

// Base response for all operations, can be extended with operation-specific data.
message BaseResponse {}

// Request to create a new environment instance.
// - runId: Unique identifier for the run.
// - envId: Identifier for the type of environment to create.
// - envInit: Initial configuration for the environment (optional).
// - seed: Seed for the environment's random number generator (optional).
message MakeRequest {
  string runId = 1;
  string envId = 2;
  optional DataType envInit = 3;
  optional int32 seed = 4;
}

// Response to MakeRequest containing the specifications of the created environment.
message MakeResponse {
  DataType spec = 1; // Environment specifications.
}

// Request to sample an action from the environment's action space.
message ActionSpaceSampleRequest {}

// Response to ActionSpaceSampleRequest with a sample action.
// - action: The sampled action, serialized as bytes.
message ActionSpaceSampleResponse {
  DataType action = 1;
}

// Request information about the environment's action space.
message ActionSpaceInfoRequest {}

// Response with details of the environment's action space.
// - result: The structure defining the action space.
message ActionSpaceInfoResponse {
  Space result = 1;
}

// Request information about the environment's observation space.
message ObservationSpaceInfoRequest {}

// Response with details of the environment's observation space.
// - result: The structure defining the observation space.
message ObservationSpaceInfoResponse {
  Space result = 1;
}

// Request to take an action in the environment.
// - action: The action to be taken, provided by the agent.
message StepRequest {
  DataType action = 1;
}

// Response to StepRequest with the outcome of the taken action.
// - observation: The observation following the action.
// - reward: The reward received after taking the action.
// - terminated: Whether the episode has ended.
// - truncated: Whether the episode was truncated before a natural conclusion.
// - info: Additional information about the step.
message StepResponse {
  DataType observation = 1;
  float reward = 2;
  bool terminated = 3;
  bool truncated = 4;
  DataType info = 5;
}

// Request to reset the environment to its initial state.
message ResetRequest {}

// Response to ResetRequest with the initial observation of the reset environment.
// - observation: The initial observation after resetting.
// - info: Additional information about the reset environment.
message ResetResponse {
  DataType observation = 1;
  DataType info = 2;
}

// Request to set the rendering mode of the environment.
// - mode: The desired rendering mode.
message SetRenderModeRequest {
  string mode = 1;
}

// Response to SetRenderModeRequest. Typically acknowledges the mode change.
message SetRenderModeResponse {}

// Request to get the current rendering mode of the environment.
message GetRenderModeRequest {}

// Response to GetRenderModeRequest with the current rendering mode.
// - mode: The current rendering mode.
message GetRenderModeResponse {
    string mode = 1;
}

// Request to get the current render of the environment.
message GetRenderRequest {}

// Response to GetRenderRequest with the current rendered image of the environment.
// - image: The rendered image, serialized as bytes.
message GetRenderResponse {
  DataType image = 1;
}

// Request to set the current scenario of the environment.
// - scenario: The scenario to be set.
message SetScenarioRequest {
  DataType scenario = 1;
}

// Response to SetScenarioRequest. Typically acknowledges the scenario change.
message SetScenarioResponse {}

// Request to get the current scenario of the environment.
message GetScenarioRequest {}

// Response to GetScenarioRequest with the current scenario.
// - scenario: The current scenario, if any.
message GetScenarioResponse {
  optional DataType scenario = 1;
}

// Request to close the environment, performing any necessary cleanup.
message CloseRequest {}

// Response to CloseRequest. Typically acknowledges the environment has been closed.
message CloseResponse {}

// Structure to encapsulate details of an exception or error.
// - errorType: The type of the error.
// - errorMessage: Human-readable error message.
// - stackTrace: Detailed stack trace of the error (optional).
message ExceptionDetails {
    string errorType = 1;
    string errorMessage = 2;
    google.protobuf.StringValue stackTrace = 3;
}