ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 150
Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 110
Abonament PDF

Simularea conducerii autonome folosind CARLA

Ovidiu Mățan
Fondator @ Today Software Magazine



PROGRAMARE


Cu toți suntem fascinați de mașinile autonome. Cu siguranță, unii dintre noi chiar visează să-și construiască una. Din păcate avem de-a face cu costuri mari pentru realizarea unui astfel de proiect, riscuri și autorizări în ceea ce privește testarea lor. Simulatorul CARLA rezolvă toate aceste probleme prin oferirea unei soluții virtuale unde vă veți putea testa algoritmii, folosi și testa camere video, senzori lidar sau de detecție a obstacolelor. În rândurile care urmează, veți descoperi moduri de instalare a simulatorului și de încărcare a anumitor hărți, precum și principiile de bază ale controlului automobilului. La final, va fi prezentat un exemplu complet în care se va implementa frânarea de urgență.

Instalare

Descărcați ultima versiune a simulatorului și lansați CarlaUE4. În cazul în care folosiți Windows instalați python 3.7 pentru rularea exemplelor. De asemenea, va trebui să instalați câteva pachete folosind utilitarul pip. Verificați și versiunea pip pe care o aveți instalată. Menționăm că ar fi bine să vă faceți un update înainte de a porni tot procesul de setup.

Tips & Tricks: Pentru rularea tuturor exemplelor pe window s-ar putea să fie nevoie să înlocuiți localhost cu 127.0.0.1 în sursele python ale acestora.

Arhitectura sistemului

Avem de a face cu o arhitectură server - client. Serverul afișează harta 3D folosind engine-ul Unreal. Aplicațiile client se conectează la acesta pe portul 2000 și transmit comenzile. Rulăm un prim exemplu din folderul /Carla/PythonAPI/examples:

python3 client_bounding_boxes.py

Principalele elemente

A. Hărțile

Vom începe cu un exemplu în care vom încărca o hartă specifică:

import carla
def main():
 client = carla.Client('localhost',2000);
   print ("Available maps:");
    print(client.get_available_maps());
    world=client.load_world('Town02');   
if __name__ == '__main__':
    main()

Creăm un obiect client prin conectarea la server pe portul 2000. Se afișează hărțile disponibile și încărcăm harta Town02. În cazul în care se dorește revenirea la harta inițială, se va încărca Town10HD.

B. Actorii

Odată încărcată o hartă, putem să adăugăm obiecte, în cazul nostru va fi vorba, bineînțeles, de câteva mașini. Acestea sunt obținute din librăria globală în felul următor: world.get_blueprint_library(). În funcție de modelul de care avem nevoie o putem interoga astfel: blueprint_lib.filter('vehicle.tesla.model3').

Următorul pas este să stabilim exact locul în care va fi adăugată mașina pe hartă. Un mod rapid este să obținem un punct aleatoriu astfel:

random.choice(world.get_map().get_spawn_points())

Alternativa este să definim exact locul în care aceasta va apărea așa cum se va putea vedea în exemplul următor.

Modelul mașinii împreună cu locul în care va apărea aceasta ne permite să adăugăm mașina pe hartă cu ajutorul metodei world.spawn_actor(car, transform).

world.spawn_actor(car, transform).

def main():
    client = carla.Client('localhost',2000);
    world=client.load_world('Town04');
    world=client.get_world();
    blueprint_lib=world.get_blueprint_library();    
    tesla3_bp=blueprint_lib.filter(
    'vehicle.tesla.model3');

    spawn_car(world, tesla3_bp[0],
    carla.Transform(carla.Location(
    x=-60.149902, y=33.856983, z=10.458009), 
    carla.Rotation(pitch=0.972154, yaw=0.076826, 
    roll=0.000000)));

    spawn_car(world, tesla3_bp[0], 
    carla.Transform(carla.Location(x=-60.149902,   
    y=29.756983, z=10.458009), 
    carla.Rotation(pitch=0.972154, yaw=0.076826, 
    roll=0.000000)));

    spawn_car(world, tesla3_bp[0], 
    carla.Transform(carla.Location(x=-60.149902, 
    y=37.356983, z=10.458009), 
    carla.Rotation(pitch=0.972154, yaw=0.076826, 
    roll=0.000000)));

    spawn_car(world, tesla3_bp[0], 
    carla.Transform(carla.Location(x=-60.149902,  
    y=26.256983, z=10.458009), 
    carla.Rotation(pitch=0.972154, yaw=0.076826, 
    roll=0.000000)));

    client.set_timeout(20.0);

def spawn_car(world, car, transform):
    print('transform=',transform);
    tesla3_auto=world.spawn_actor(car, transform);

Se observă apelarea metodei set_timeout() care definește în secunde durata de existență a clientului.

Un exemplu complet

Vom prezenta acum un exemplu complet pornind de la informațiile prezentate până acum. Este vorba de implementarea unui algoritm de frânare în două etape, în funcție de distanța detectată până la obstacol:

Vor fi pornite patru mașini. Precizăm că în fața uneia dintre ele va fi un obstacol reprezentat de un automobil aflat în staționare.

import carla
import random;
import time;
sensor=[];
cars=[];
def main():
    client = carla.Client('localhost',2000);
    world=client.load_world('Town04');
    world=client.get_world();
    blueprint_lib=world.get_blueprint_library();
    tesla3_bp=blueprint_lib.filter(
    'vehicle.tesla.model3');

    for x in range(4):
      cars.append(spawn_car(world, tesla3_bp[0], x));
      sensor.append(set_sensor(world,cars[x]));
      print('car=',cars[x]);      

    #add obstacle car
    transform=carla.Transform(
    carla.Location(x=300.149902, y=26.756983, 
    z=10.458009), carla.Rotation(pitch=0.972154, 
    yaw=0.076826, roll=0.000000))

    stoped_car=world.spawn_actor(tesla3_bp[0], 
    transform);

    for x in range(4):    
      cars[x].apply_control(
      carla.VehicleControl(throttle=1.0, steer=0.0)) 

    while True:
        time.sleep(60);

    client.set_timeout(20.0);

def process_sensor(data, car):
    lidar_data=data;
    print("distance:",data.distance);
    if (data.distance<40):  
        print("Stop !!!!");
        car.apply_control(
        carla.VehicleControl(hand_brake=True))

    else:
        if (data.distance<80):
            print("Stop accelrating !!!!");
            car.apply_control(
            carla.VehicleControl(throttle=0.0, 
            brake=1.0))

def set_sensor(world, car):
    blueprint_obstacle = 
    world.get_blueprint_library().
    find("sensor.other.obstacle");

    print('obstacle=',blueprint_obstacle);
    blueprint_obstacle.
    set_attribute('distance','100');  

    transform = carla.Transform(carla.Location(x=1.0, 
    z=1.8));

    sens= world.spawn_actor(blueprint_obstacle, 
    transform, attach_to=car);

    sens.listen(lambda data: process_sensor(data, 
    car));

   return sens;

  def spawn_car(world, car, index):
    transform=carla.Transform(
    carla.Location(x=-60.149902, 
    y=(26.256983+3.5*index), z=10.458009), 
    carla.Rotation(pitch=0.972154, yaw=0.076826, 
    roll=0.000000))

    print('transform=',transform);
    tesla3_auto=world.spawn_actor(car, transform);

    return tesla3_auto;

if __name__ == '__main__':
    main()

Fiecare mașină are atașat un senzor de detecție a obstacolelor obținut din librăria CARLA: sensor.other.obstacle. Acestuia îi este stabilită distanța de detecție începând cu 100 m, fiind generat prin atașarea la fiecare automobil. Datele procesate de acesta sunt trimise printr-un callback la metoda process_data împreună cu obiectul car la care este atașat.

sens.listen(lambda data: process_sensor(data, car));

Controlul mașinilor este realizat prin metoda apply_control care poate primi o listă de parametri cu valori între 0.0 și 1.0: trotthle, steer, brake și hand_brake, de tip boolean.

Concluzii

Sperăm ca prin acest articol v-am deschis apetitul pentru simularea conducerii unui automobil. Putem ajunge chiar la un algoritm de autonomous driving și - de ce nu ?- să îl folosim ulterior pentru testare pe o mașină reală.

NUMĂRUL 149 - Development with AI

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects