Command#

class genesis_forge.managers.command.CommandManager(env: GenesisEnv, range: Tuple[float, float] | dict[str, Tuple[float, float]], resample_time_sec: float = 5.0)[source]#

Bases: BaseManager

Generates a command from uniform distribution of values. You can use this to regularly sample a commands for each environment, such as a height command, a target destination, or a specific pose.

Parameters:
  • env – The environment to control

  • range – The number range, or dict of ranges, to generate target command(s) for

  • resample_time_sec – The time interval between changing the command

Example:

class MyEnv(GenesisEnv):
    def config(self):
        # Create a height command
        self.height_command = CommandManager(self, range=(0.1, 0.2))

        # Rewards
        RewardManager(
            self,
            logging_enabled=True,
            cfg={
                "base_height_target": {
                    "weight": -50.0,
                    "fn": rewards.base_height,
                    "params": {
                        "height_command": self.height_command,
                    },
                },
                # ... other rewards ...
            },
        )

        # Observations
        ObservationManager(
            self,
            cfg={
                "height_cmd": {"fn": self.height_command.observation},
                # ... other observations ...
            },
        )
build()#

Called when the scene is built

get_command(range_key: str) torch.Tensor[source]#

If the range is a dict, get the command values for the given key.

get_command_idx(key: str) int[source]#

If the range is a dict, get the command index for the given key.

observation(env: GenesisEnv) torch.Tensor[source]#

Function that returns the current command for each environment.

resample_command(env_ids: list[int])[source]#

Create a new command for the given environment ids.

reset(env_ids: list[int] | None = None)[source]#

One or more environments have been reset

set_command(range_key: str, value: torch.Tensor, envs_idx: list[int] | None = None)[source]#

Update a command value for selected environments.

step()[source]#

Resample the command if necessary

use_external_controller(controller: Callable[[int], Tuple[float, float] | dict[str, Tuple[float, float]]])[source]#

Bypass the internal command controller, and generate the command values with an external control function. This can be used to connect a gamepad, joystick, or other external controller to the command manager.

Parameters:

controller – A function that takes the step index and returns a tensor of command values with the shape (num_envs, num_ranges).

Example:

N_ENVS = 1
MIN_HEIGHT = 0.1
MAX_HEIGHT = 0.2

# Create environment
class MyEnv(GenesisEnv):
    def config(self):
        self.height_command = CommandManager(self, range=(MIN_HEIGHT, MAX_HEIGHT))
    # ...

# Setup gamepad
gamepad = Gamepad(GAMEPAD_PRODUCT)
cmd_buffer = torch.zeros((N_ENVS, 1), device=gs.device)
def gamepad_controller(_step):
    a_pressed = "A" in gamepad.state.buttons
    cmd_buffer[:, 0] = MAX_HEIGHT if a_pressed else MIN_HEIGHT
    return cmd_buffer

# Create environment & connect gamepad
env = MyEnv(num_envs=N_ENVS)
env.build()
env.command_manager.use_external_controller(gamepad_controller)
use_gamepad(gamepad: Gamepad, range_axis: int | dict[str, int])[source]#

A wrapper around use_external_controller that converts a gamepad joystick axis to a command value.

Parameters:
  • gamepad – The gamepad to use.

  • range_axis – The axis or dict of axes to use for the command value. This should match the range init param.

Example:

# Create environment
class MyEnv(GenesisEnv):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.height_command = CommandManager(self, range=(0.1, 0.2))
    # ...

# Connect gamepad
gamepad = Gamepad(GAMEPAD_PRODUCT)

# Create environment & connect gamepad
env = MyEnv(num_envs=1)
env.build()

# Connect joystick axis 3 to the height command
env.height_command.use_gamepad(gamepad_controller, range_axis=3)

Example with multiple ranges:

# Create environment
class MyEnv(GenesisEnv):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.height_command = CommandManager(
            self,
            range={
                "cmd1": (-2.0, 2.0),
                "cmd2": (1.0, 5.0),
            }
        )
    # ...

# Connect gamepad
gamepad = Gamepad(GAMEPAD_PRODUCT)

# Create environment & connect gamepad
env = MyEnv(num_envs=1)
env.build()

# Connect joystick axis 2 and 3 to to the indvidual ranges
env.height_command.use_gamepad(
    gamepad_controller,
    range_axis={
        "cmd1": 2,
        "cmd2": 3,
    })
property command: torch.Tensor#

The desired command value. Shape is (num_envs, num_ranges).

property range: Tuple[float, float] | dict[str, Tuple[float, float]]#

The range of values to generate target command(s) for.

property resample_time_sec: float#

The time interval (in seconds) between changing the command for each environment.