Implementation:CARLA simulator Carla Command DestroyActor
| Knowledge Sources | |
|---|---|
| Domains | Simulation Resource Management, Actor Lifecycle |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
Concrete tool for batch-destroying simulation actors and properly stopping walker AI controllers during traffic cleanup, provided by the CARLA simulator.
Description
The carla.command.DestroyActor class creates a command object that, when executed via Client.apply_batch(), removes an actor from the simulation server. Combined with WalkerAIController.stop(), these form the standard cleanup pattern for traffic generation scripts.
DestroyActor accepts either an actor object or an actor ID (integer) and instructs the server to:
- Remove the actor from the simulation world
- Free all associated server-side resources (physics body, mesh, transform data)
- Unregister the actor from any subsystems that track it (Traffic Manager, sensors, etc.)
WalkerAIController.stop() must be called before destroying walker controllers and their associated walkers. This method unregisters the walker from the Detour crowd simulation system, preventing dangling agent references.
The batch destroy pattern uses apply_batch (asynchronous, no return values) rather than apply_batch_sync for cleanup, since checking individual destroy results is typically unnecessary during shutdown.
Usage
Use these APIs at the end of a traffic generation script or in a finally block to clean up all spawned actors. Always stop walker AI controllers before destroying them.
Code Reference
Source Location
- Repository: CARLA
- File:
PythonAPI/carla/src/Commands.cpp - Lines: L89-93
- Walker Stop:
LibCarla/source/carla/client/WalkerAIController.cpp, L69-81
Signature
# Destroy command for batch execution
carla.command.DestroyActor(actor: Union[carla.Actor, int]) -> DestroyActor
# Batch execution (asynchronous)
Client.apply_batch(commands: list[Command]) -> None
# Walker AI controller stop (must be called before destroy)
WalkerAIController.stop() -> None
Import
import carla
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| actor | carla.Actor or int | Yes | The actor to destroy. Can be an Actor object or an integer actor ID. The actor is removed from the server on execution. |
| commands (apply_batch) | list | Yes | A list of command objects (typically DestroyActor commands) to execute in a single server round-trip. |
Outputs
| Name | Type | Description |
|---|---|---|
| return (apply_batch) | None | Asynchronous execution; no return values. The server processes all destroy commands but does not report individual results. |
| return (stop) | None | No return value. The walker is unregistered from the crowd simulation system. |
Usage Examples
Basic Example
import carla
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
# Assume vehicle_ids is a list of actor IDs from earlier spawning
vehicle_ids = [101, 102, 103, 104, 105]
# Batch-destroy all vehicles
destroy_commands = [carla.command.DestroyActor(vid) for vid in vehicle_ids]
client.apply_batch(destroy_commands)
print(f"Destroyed {len(vehicle_ids)} vehicles")
Complete Traffic Cleanup
import carla
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()
# Lists populated during traffic spawning
vehicles_list = [] # List of vehicle actor IDs
walkers_list = [] # List of walker actor IDs
controllers_list = [] # List of WalkerAIController actor IDs
all_actors = [] # Combined list for final cleanup
# ... (traffic spawning code populates these lists) ...
# Step 1: Stop all walker AI controllers
all_actors_obj = world.get_actors(controllers_list)
for controller in all_actors_obj:
controller.stop()
# Step 2: Batch-destroy controllers, then walkers, then vehicles
destroy_commands = []
# Destroy AI controllers first
for controller_id in controllers_list:
destroy_commands.append(carla.command.DestroyActor(controller_id))
# Destroy walker bodies
for walker_id in walkers_list:
destroy_commands.append(carla.command.DestroyActor(walker_id))
# Destroy vehicles
for vehicle_id in vehicles_list:
destroy_commands.append(carla.command.DestroyActor(vehicle_id))
client.apply_batch(destroy_commands)
print(f"Cleanup complete: {len(vehicles_list)} vehicles, "
f"{len(walkers_list)} walkers, {len(controllers_list)} controllers")
Robust Cleanup with Try/Finally
import carla
import random
import time
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
world = client.get_world()
# Save original settings for restoration
original_settings = world.get_settings()
settings = world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = 0.05
world.apply_settings(settings)
traffic_manager = client.get_trafficmanager(8000)
traffic_manager.set_synchronous_mode(True)
tm_port = traffic_manager.get_port()
vehicle_ids = []
walker_ids = []
controller_ids = []
try:
# Spawn vehicles
blueprints = world.get_blueprint_library().filter('vehicle.*')
spawn_points = world.get_map().get_spawn_points()
random.shuffle(spawn_points)
batch = []
for i in range(min(30, len(spawn_points))):
bp = random.choice(blueprints)
batch.append(
carla.command.SpawnActor(bp, spawn_points[i])
.then(carla.command.SetAutopilot(
carla.command.FutureActor, True, tm_port))
)
results = client.apply_batch_sync(batch, do_tick=True)
vehicle_ids = [r.actor_id for r in results if not r.error]
# Spawn walkers with controllers
walker_bps = world.get_blueprint_library().filter('walker.pedestrian.*')
controller_bp = world.get_blueprint_library().find('controller.ai.walker')
walker_batch = []
for _ in range(20):
loc = world.get_random_location_from_navigation()
if loc:
walker_batch.append(
carla.command.SpawnActor(random.choice(walker_bps),
carla.Transform(loc)))
results = client.apply_batch_sync(walker_batch, do_tick=True)
walker_ids = [r.actor_id for r in results if not r.error]
ctrl_batch = [carla.command.SpawnActor(controller_bp, carla.Transform(), wid)
for wid in walker_ids]
results = client.apply_batch_sync(ctrl_batch, do_tick=True)
controller_ids = [r.actor_id for r in results if not r.error]
# Start controllers
world.tick()
for ctrl in world.get_actors(controller_ids):
ctrl.start()
dest = world.get_random_location_from_navigation()
if dest:
ctrl.go_to_location(dest)
ctrl.set_max_speed(1.4)
# Run simulation
for _ in range(500):
world.tick()
finally:
# GUARANTEED CLEANUP
# 1. Stop all walker controllers
for ctrl in world.get_actors(controller_ids):
ctrl.stop()
# 2. Batch-destroy all actors
destroy_cmds = []
destroy_cmds.extend([carla.command.DestroyActor(x) for x in controller_ids])
destroy_cmds.extend([carla.command.DestroyActor(x) for x in walker_ids])
destroy_cmds.extend([carla.command.DestroyActor(x) for x in vehicle_ids])
if destroy_cmds:
client.apply_batch(destroy_cmds)
# 3. Restore original world settings
world.apply_settings(original_settings)
print("Cleanup complete, world settings restored")