DEV Community

Cover image for Carla Simulator 2 : Welcome to the Ride 🚗🏍️
Mitansh Gor
Mitansh Gor

Posted on • Edited on

Carla Simulator 2 : Welcome to the Ride 🚗🏍️

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. 🚗🚨

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay