Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/NVlabs/alpasim/llms.txt

Use this file to discover all available pages before exploring further.

Overview

AlpaSim’s microservice architecture allows you to customize or replace any component. This guide covers:
  • Making code changes during development
  • Building custom container images
  • Understanding service interfaces via protocol buffers

Code Changes

During development, code changes in the repository are automatically mounted into docker containers at runtime.

Quick Iteration Workflow

1

Edit source code

Make changes to any file in src/:
# Example: add logging to driver
vim src/driver/src/alpasim_driver/inference.py
2

Rerun the wizard

No rebuild needed - changes are live:
alpasim_wizard +deploy=local wizard.log_dir=$PWD/test_run
3

Check output

Your changes will be reflected immediately in the next run
Dependency Changes Require RebuildCode changes that rely on new dependencies will require rebuilding the container image, as the virtual environment is not synced at runtime.

Example: Adding Debug Logging

Try adding logging statements to the driver:
import logging

logger = logging.getLogger(__name__)

def run_inference(frames, metadata):
    logger.info(f"Running inference on {len(frames)} frames")
    logger.debug(f"Metadata: {metadata}")
    # ... existing code ...
Rerun the wizard and check driver/ logs to see your output.

Custom Container Images

The simulation is split into multiple microservices, each running in its own docker container:
  • sensorsim - Neural rendering engine for camera images
  • driver - Driving policy (VaVAM, Alpamayo-R1, etc.)
  • controller - Trajectory tracking and pose estimation
  • physics - Physics simulation and collision detection
  • runtime - Orchestration and scenario execution
  • trafficsim - Background traffic simulation

Service Interface Requirements

The primary requirement for a custom container image is that it exposes a gRPC endpoint compatible with the expected service interface.

Overriding Default Images

Default images are specified in stable_manifest/oss.yaml. Override them using:
alpasim_wizard +deploy=local \
  wizard.log_dir=$PWD/custom_run \
  services.<service>.image=<your-registry>/<your-image>:<tag> \
  services.<service>.command="your-custom-command"

Example: Custom Driver Image

Replace the default driver with a custom image:
alpasim_wizard +deploy=local \
  wizard.log_dir=$PWD/custom_driver_run \
  services.driver.image=myregistry/custom-driver:v1.0 \
  services.driver.command="python -m my_driver.server --port=6789"
Your custom driver must implement the gRPC interface defined in src/grpc/alpasim_grpc/v0/egodriver.proto.

Example: Custom Model Weights

Mount a custom model directory for the VaVAM driver:
alpasim_wizard +deploy=local \
  wizard.log_dir=$PWD/custom_model_run \
  defines.vavam_driver=/path/to/custom/vavam-driver
Default location: data/vavam-driver/ (in repository root) The wizard mounts defines.vavam_driver as /mnt/vavam_driver in the container.

Protocol Buffer Definitions

All microservice APIs are defined using Protocol Buffers in src/grpc/alpasim_grpc/v0/.

Available Service Interfaces

ServiceProto FileDescription
Sensorsimsensorsim.protoNeural rendering for camera images
Driveregodriver.protoDriving policy interface
Controllercontroller.protoTrajectory tracking and pose
Physicsphysics.protoPhysics simulation
Runtimeruntime.protoOrchestration (internal)
Traffictraffic.protoBackground traffic
Commoncommon.protoShared types (poses, trajectories)
Logginglogging.protoASL log format

Using gRPC APIs

After compiling protos with uv run compile-protos from src/grpc/:
import grpc
from alpasim_grpc.v0.sensorsim_pb2 import RenderRequest, RenderReturn
from alpasim_grpc.v0.sensorsim_pb2_grpc import SensorsimServiceStub

with grpc.insecure_channel('host:port') as channel:
    service = SensorsimServiceStub(channel)
    render_request = RenderRequest(
        scene_id="clipgt-026d6a39-bd8f...",
        camera_config=camera_config,
        timestamp_us=1234567890,
    )
    response: RenderReturn = service.render(render_request)
    print(f"Rendered {len(response.images)} images")

Compiling Protocol Buffers

1

Navigate to grpc directory

cd src/grpc
2

Compile protos

uv run compile-protos
This generates *_pb2.py and *_pb2_grpc.py files.
3

Clean generated files (optional)

uv run clean-protos
Protobuf definitions are not automatically compiled when installing the gRPC package. You must run uv run compile-protos manually after changes.

Coordinate Frame Conventions

When implementing custom services, follow AlpaSim’s coordinate frame conventions:
Format: {quantity}_{source_frame}_to_{target_frame}Examples:
  • pose_local_to_rig - Pose from local to rig frame
  • velocity_vehicle_in_local - Velocity in local frame
  • transform_camera_to_vehicle - Transform from camera to vehicle
  • global - World coordinate system
  • local - Scene-local coordinates
  • vehicle - Ego vehicle body frame
  • camera - Camera sensor frame
  • rig - Sensor rig mounting frame
Refer to CONTRIBUTING.md for detailed conventions shared across the runtime and gRPC APIs.

Building Custom Images

Example Dockerfile

FROM python:3.12-slim

# Install dependencies
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy service code
COPY my_service/ ./my_service/

# Expose gRPC port
EXPOSE 6789

# Start service
CMD ["python", "-m", "my_service.server", "--port=6789"]

Multi-Replica Services

If your service will run with multiple replicas (for scaling), ensure:
  1. Thread-safe state management - Each replica handles concurrent requests
  2. GPU assignment - Configure services.<service>.gpus if using GPUs
  3. Port allocation - Docker compose auto-assigns ports per replica
See Performance Tuning for replica configuration.

Testing Custom Components

1

Unit test your service

Test gRPC interface implementation:
pytest tests/test_my_service.py
2

Integration test with wizard

Run a minimal simulation:
alpasim_wizard +deploy=local \
  wizard.log_dir=$PWD/test \
  scenes.scene_ids='["clipgt-026d6a39..."]' \
  services.driver.image=myregistry/my-service:dev
3

Check outputs

Verify simulation completes and check results:
ls test/rollouts/  # Should contain rollout data
cat test/txt-logs/driver-0.log  # Check service logs