DEV Community

Cover image for Carla Simulator 2 : Welcome to the Ride, Brian Cooper Here! 🚗🏍️
Mitansh Gor
Mitansh Gor

Posted on

Carla Simulator 2 : Welcome to the Ride, Brian Cooper Here! 🚗🏍️

check Blog 1 of Carla Simulator.

Check Video

Hey, family! It’s Brian here — yes, the Brian O’Conner, the gearhead who always has your back on the road or in a high-speed chase. Dom handed me the keys to this blog, saying it’s time to dive deep into some next-gen simulator tech that fuels the autonomous revolution. Thanks, Dom, for trusting me. I’ll try not to wreck it (not that I ever wreck anything, right? 😉).

Dom mentioned how the CARLA simulator lets us test and train autonomous vehicles in a realistic, open-source environment. It’s got the kind of details that make even Letty go, "Damn, that’s sharp." Our mission here? To break it down for you like we would a turbocharged engine. You’ll know everything about CARLA’s actors, vehicles, and how to control them with the finesse of a perfectly-timed NOS burst. And if you stick with me, we’ll even set up a Flask API to bring this simulation to life. Let’s ride! 🏍️

Image description

The Plan for This Blog

  • Actors and Blueprints 101: Understand the essentials of what makes CARLA tick, from vehicles to walkers and how blueprints play a role.
  • Dive into Vehicle and Walker Management: Learn how actors are spawned, manipulated, and destroyed — think of it like choosing the perfect car for a street race and knowing when to swap gears.
  • Flask API Integration: Build Flask APIs step-by-step to control CARLA’s simulation programmatically. By the end, you’ll be setting up car chases, random pedestrians, and traffic with just a few lines of code.
  • Hands-on Examples: Showcase how to populate the simulation with vehicles and walkers using our Flask API endpoints.

Ready to start? Let’s shift into gear! 🏎️

Actors and Blueprints 101 🎨

In CARLA, actors are the dynamic elements that breathe life into the simulation. This includes:

  • Vehicles: Cars, trucks, bikes — the heart of the simulation.
  • Walkers: Pedestrians who roam the environment.
  • Traffic Entities: Traffic lights and stop signs.
  • Sensors: Cameras, LiDAR, radar, and GPS for data collection.
  • Blueprints: The DNA of Actors

Think of blueprints as pre-configured settings for creating actors. CARLA’s blueprint library includes attributes like:

  • Vehicle Colors
  • Engine Power
  • Walker Speed
  • Sensor Ranges

Each blueprint is customizable, letting you tweak the simulation to match real-world scenarios. It’s like choosing a Skyline’s body kit and tuning it for maximum horsepower.

Managing Actors: Spawning, Interacting, and Destroying

In CARLA:

  • Spawning: Use the spawn_actor API to bring vehicles and walkers into the world.
  • Interacting: Control the physics, speed, and direction of actors.
  • Destroying: Remove actors once their role in the simulation is done.

Vehicle Physics 🏎️⚡

  • Vehicles in CARLA come equipped with:
  • Dynamic Control: Accelerate, brake, and steer.
  • Collision Response: Simulates crashes and obstacle impacts.
  • Environmental Response: Handles weather and road conditions.

Walker Dynamics 🚶‍♂️
Walkers can:

  • Follow predefined paths.
  • React dynamically to traffic.
  • Walk at various speeds and animations.

Flask API Integration: Building the Engine 🚒

Now that we’ve got the basics, it’s time to build a Flask API to interact with CARLA. Here’s how:

Flask API Endpoints

  • Spawn Vehicles
@app.route('/spawn_vehicle', methods=['POST'])
def spawn_vehicle():
    data = request.get_json()
    model = data.get('model', 'vehicle.tesla.model3')

    blueprint_library = world.get_blueprint_library()
    vehicle_bp = blueprint_library.filter(model)[0]

    spawn_points = world.get_map().get_spawn_points()
    if not spawn_points:
        return jsonify({'error': 'No spawn points available'}), 400

    spawn_point = random.choice(spawn_points)
    vehicle = world.spawn_actor(vehicle_bp, spawn_point)

    return jsonify({'message': 'Vehicle spawned', 'id': vehicle.id})
Enter fullscreen mode Exit fullscreen mode
  • ✨📸 Setting Up the Sensor Cameras

To capture images from a vehicle's top view and front view, two cameras are mounted on the car. Here's the setup:

The code retrieves camera blueprints (sensor.camera.rgb) from CARLA's blueprint library. Resolution settings (800x600) are defined for the cameras to ensure clear visuals. 📷

Top Camera: Positioned directly above the car to capture a bird's-eye view.

Image description

Front Camera: Placed at the front of the car for a forward-facing perspective

Image description

camera_spawn_pointTop = carla.Transform(
    carla.Location(x=0.0, y=0.0, z=5.0),  # 5 meters above the car
    carla.Rotation(pitch=-90.0)  # Looking straight down
)
cameraTop = world.spawn_actor(camera_bp1, camera_spawn_pointTop, attach_to=vehicle)

camera_spawn_pointFront = carla.Transform(
    carla.Location(x=-5.0, y=0.0, z=3.0),  # 5 meters in front and 3 meters high
    carla.Rotation(pitch=-15.0)  # Slight downward tilt
)
cameraFront = world.spawn_actor(camera_bp2, camera_spawn_pointFront, attach_to=vehicle)
Enter fullscreen mode Exit fullscreen mode

Each camera is set up with a callback function (e.g., camera_callback1) to process the captured images. These images are saved as files and encoded in Base64 for easy transfer and storage.

def camera_callback1(image, id, vehicleId, pos):
    array = image.raw_data
    img = Image.frombytes("RGBA", (image.width, image.height), bytes(array))
    img = img.convert("RGB")
    img.save(f"./images/{id}_{vehicleId}_{pos}.png", format="PNG")

Enter fullscreen mode Exit fullscreen mode
  • 🎥 Spectator Camera: Follow the Car To make the simulation more immersive, a spectator camera is configured to follow the vehicle dynamically.

A spectator camera is moved relative to the car's position using the set_transform method.
It stays a few meters behind and slightly above the car, aligned with its orientation.

Image description

def setup_spectator_camera(world, vehicle):
    vehicle_transform = vehicle.get_transform()  # Get the car's position and rotation
    spectator = world.get_spectator()  # Access the spectator camera

    spectator_transform = carla.Transform(
        vehicle_transform.location + carla.Location(x=-6, y=0, z=2),  # Offset behind and above the car
        vehicle_transform.rotation  # Match the car's orientation
    )
    spectator.set_transform(spectator_transform)  # Update the spectator's position

Enter fullscreen mode Exit fullscreen mode

The spectator camera is continually updated in a loop, ensuring it tracks the car as it moves. This creates a realistic following effect.

  • Spawn Walkers
@app.route('/spawn_walker', methods=['POST'])
def spawn_walker():
    data = request.get_json()
    walker_count = data.get('count', 1)

    walker_blueprints = world.get_blueprint_library().filter('walker.pedestrian.*')
    spawn_points = [random.choice(world.get_map().get_spawn_points()) for _ in range(walker_count)]

    walkers = []
    for spawn_point in spawn_points:
        walker_bp = random.choice(walker_blueprints)
        walker = world.spawn_actor(walker_bp, spawn_point)
        walkers.append(walker)

    return jsonify({'message': f'{walker_count} walkers spawned', 'ids': [w.id for w in walkers]})

Enter fullscreen mode Exit fullscreen mode
  • Destroy All Actors
@app.route('/destroy_actors', methods=['POST'])
def destroy_actors():
    actors = world.get_actors()
    actors_to_destroy = [actor for actor in actors if actor.type_id.startswith('vehicle') or actor.type_id.startswith('walker')]

    for actor in actors_to_destroy:
        actor.destroy()

    return jsonify({'message': 'All actors destroyed'})
Enter fullscreen mode Exit fullscreen mode
  • Add Random Vehicles and Walkers

Image description

@app.route('/populate_simulation', methods=['POST'])
def populate_simulation():
    data = request.get_json()
    vehicle_count = data.get('vehicles', 10)
    walker_count = data.get('walkers', 10)

    # Spawn Vehicles
    for _ in range(vehicle_count):
        vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.*'))
        spawn_point = random.choice(world.get_map().get_spawn_points())
        world.spawn_actor(vehicle_bp, spawn_point)

    # Spawn Walkers
    for _ in range(walker_count):
        walker_bp = random.choice(world.get_blueprint_library().filter('walker.pedestrian.*'))
        spawn_point = random.choice(world.get_map().get_spawn_points())
        world.spawn_actor(walker_bp, spawn_point)

    return jsonify({'message': f'{vehicle_count} vehicles and {walker_count} walkers added'})
Enter fullscreen mode Exit fullscreen mode

Wrapping Up 🏎️

And that’s how you take control of CARLA with Flask! Whether you’re simulating a high-speed chase or a casual Sunday drive, these tools let you shape your virtual world. Stay tuned for more deep dives and, as always, drive safe — or at least make it look cool while you’re not. 🚗🚨

Top comments (0)