Velocity#

class genesis_forge.managers.command.VelocityCommandManager(env: GenesisEnv, range: VelocityCommandRange, resample_time_sec: float = 5.0, standing_probability: float = 0.0, debug_visualizer: bool = False, debug_visualizer_cfg: VelocityDebugVisualizerConfig = {'actual_color': (0.0, 0.0, 0.5, 1.0), 'arrow_max_length': 0.15, 'arrow_offset': 0.03, 'arrow_radius': 0.02, 'commanded_color': (0.0, 0.5, 0.0, 1.0), 'envs_idx': None})[source]#

Bases: CommandManager

Generates a velocity command from uniform distribution. The command comprises of a linear velocity in x and y direction and an angular velocity around the z-axis.

IMPORTANT: The velocity commands are interpreted as robot-relative coordinates: - X-axis: Forward/backward relative to robot’s current orientation - Y-axis: Left/right relative to robot’s current orientation - Z-axis: Yaw rotation around robot’s vertical axis

:::{admonition} Debug Visualization

If you set debug_visualizer to True, arrows will be rendered above your robot showing the commanded velocity vs the actual velocity.

Arrow meanings:

  • GREEN: Commanded velocity (robot-relative, transformed to world coordinates for visualization) When joystick is “forward”, this arrow points in the robot’s forward direction

  • BLUE: Actual robot velocity in world coordinates

Parameters:
  • env – The environment to control

  • range – The ranges of linear & angular velocities

  • standing_probability – The probability of all velocities being zero for an environment (0.0 = never, 1.0 = always)

  • resample_time_sec – The time interval between changing the command

  • debug_visualizer – Enable the debug arrow visualization

  • debug_visualizer_cfg – The configuration for the debug visualizer

Example:

class MyEnv(GenesisEnv):
    def config(self):
        # Create a velocity command manager
        self.command_manager = VelocityCommandManager(
            self,
            visualize=True,
            range = {
                "lin_vel_x_range": (-1.0, 1.0),
                "lin_vel_y_range": (-1.0, 1.0),
                "ang_vel_z_range": (-0.5, 0.5),
            }
        )

        RewardManager(
            self,
            logging_enabled=True,
            cfg={
                "tracking_lin_vel": {
                    "weight": 1.0,
                    "fn": rewards.command_tracking_lin_vel,
                    "params": {
                        "vel_cmd_manager": self.velocity_command,
                    },
                },
                "tracking_ang_vel": {
                    "weight": 1.0,
                    "fn": rewards.command_tracking_ang_vel,
                    "params": {
                        "vel_cmd_manager": self.velocity_command,
                    },
                },
                # ... other rewards ...
            },
        )

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

Called when the scene is built

get_command(range_key: str) torch.Tensor#

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

get_command_idx(key: str) int#

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

observation(env: GenesisEnv) torch.Tensor#

Function that returns the current command for each environment.

resample_command(env_ids: list[int])#

Create a new command for the given environment ids.

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

One or more environments have been reset

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

Update a command value for selected environments.

step()[source]#

Render the command arrows

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

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, lin_vel_y_axis: int = 0, lin_vel_x_axis: int = 1, ang_vel_z_axis: int = 2)[source]#

Use a connected gamepad to control the command.

Parameters:
  • gamepad – The gamepad to use.

  • lin_vel_x_axis – Map this gamepad axis index to the linear velocity in the x-direction.

  • lin_vel_y_axis – Map this gamepad axis index to the linear velocity in the y-direction.

  • ang_vel_z_axis – Map this gamepad axis index to the angular velocity in the z-direction.

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.