A fost odata ca niciodata, in lumea Formula 1, o echipa legendara numita Ferrari. Aceasta echipa italiana si-a inceput calatoria in lumea curselelor in anul 1950 si de atunci a devenit una dintre cele mai recunoscute si respectate echipe din istoria sportului cu motor. Povestea Ferrari in lumea Formula 1 este una plina de momente de sacrificiu si durere. Cu toate acestea, pasiunea lor pentru motorsport ramane la fel de puternica ca intotdeauna si continuă sa inspire si sa impresioneze fanii din intreaga lume. Inginerii de la Ferrari au nevoie de ajutorul tau pentu a reusi sa castige curse in acest sezon. Au realizat ca una dintre probelmele masinii lor este cauzata de niste senzori defecti (cumparati de pe AliExpress) care transmit date gresite catre echipa de ingineri. Ajutati echipa sa identifice si sa elimine datele eronate pentru a castiga curse.
Implementarea va consta crearea unui vector de tip Sensor* ce va contine doua tipuri de senzori: Tire Sensor si Power Management Unit Sensor (vezi mai jos structurile). O structura de tip Sensor va contine pe langa datele sensorului asociat si un vector cu indicii operatiilor ce vor trebui efectuate pe date sensorului. Sunt un numar total de 8 operatii sub forma de functii care trebuie apelate pe datele sensorului. Implementarea acestora se gaseste in fisierul operations.c din schelet, avand urmatoarele antete:
static void tire_pressure_status(void* data); static void tire_temperature_status(void* data); static void tire_wear_level_status(void* data); static void tire_performance_score(void* data); static void pmu_compute_power(void* data); static void pmu_regenerate_energy(void* data); static void pmu_get_energy_usage(void* data); static void pmu_is_battery_healthy(void* data);
Pentru a usura utilizarea acestora, va punem la dispozitie urmatoarea functie (tot in operations.c) ce va alcatui un vector de operatii:
void get_operations(void** operations)
Fiecare senzor va primi ca input un vector de indecsi ai operatiilor ce vor trebui apelate din vectorul obtinut dupa apelarea functiei de mai sus. Functiile trebuie apelate prin intermediul vectorului, NU aveti voie sa apelati functiile explicit.
Exemplu:
Pentru un senzor de tipul Tire Sensor se primeste ca input urmatorul vector:
3 1 0 2
Se vor apela, in ordine, urmatoarele functii:
tire_performance_score(); tire_temperature_status(); tire_pressure_status(); tire_wear_level_status();
Prioritati
Valorile primite de la senzorii de tip Power Management Unit sunt mai importante decat cele primite de la senzorii de tip Tire Sensor. Astfel, vom dorii care senzorii Power Management Unit sa se afle primii in vectorul de senzori.
Exemplu:
Primim ca input urmatorii senzori:
Tire_1 Tire_2 PMU_1 PMU_2 Tire_3 PMU_3 Tire_4 Tire_5 PMU_4
Vectorul va contine senzorii in urmatoarea ordine:
PMU_1 PMU_2 PMU_3 PMU_4 Tire_1 Tire_2 Tire_3 Tire_4 Tire_5
Structuri
Mai jos aveti implementarea structurilor:
enum sensor_type { TIRE, PMU }; typedef struct { enum sensor_type sensor_type; // 0/1 void *sensor_data; // TireSensor/PowerManagementUnit int nr_operations; int *operations_idxs; } Sensor; typedef struct __attribute__((__packed__)) { float voltage; // voltage level of the battery; 10-20 volts float current; // current draw from the battery; -100 to 100 amps; negative values indicate energy regeneration during braking float power_consumption; // power consumption of the car; 0 to 1000 kilowatts int energy_regen; // energy regenerated during braking; between 0-100% int energy_storage; // amount of energy stored in the battery; between 0-100% } PowerManagementUnit; typedef struct __attribute__((__packed__)) { float pressure; // 19-26 psi float temperature; // between 0-120C int wear_level; // interval between 0-100%;. 0% wear means new tire. int performace_score; // between 1-10; 1 low performance; 10 high performance } TireSensor;
Schelet
In schelet se aflat 4 fisiere:
Programul va citi comenzi de la tastatura pana la primirea comenzii exit, in urma careia programul va elibera memoria si va iesi.
Comenzile primite vor veni in urmatorul format:
Se va face printarea vectorului de senzori, aplicandu-se urmatorul format:
Pentru Tire Sensor:
Tire Sensor Pressure: <pressure> Temperature: <temperature> Wear Level: <wear_level> Performance Score: <computed score>/Performance Score: Not Calculated
Pentru Power Management Unit Sensor:
Power Management Unit Voltage: <voltage> Current: <current> Power Consumption: <power_consumption> Energy Regen: <energy_regen> Energy Storage: <energy_storage>
Printarea variabilelor de tip float se va face cu o precizie de 2 zecimale.
Se va face printarea vectorului de senzori in acelasi format prezentat mai sus, tinandu-se cont de prioritatile acestora.
Se vor efectua toate operatiile senzorului dat ca argument, in ordine in care au fost date.
Se vor sterge din vector, senzorii care contin valori eronate. Un senzor este considerat invalid daca NU respecta cel putin una din urmatoarele conditii:
Tire Sensor: pressure: between 19 and 28 psi temperature: between 0°C and 120°C wear_level: between 0% and 100%
Power Management Unit Sensor: voltage: between 10V and 20V current: between -100A and 100A power_consumption: between 0kW and 1000kW energy_regen: between 0% and 100% energy_storage: between 0% and 100%
La primirea acestei comenzi memoria este dezalocata si programul se opreste.
O alta parte foarte importanta a temei este intelegerea si lucrul cu memoria. Pentru asta, acest task va consta din doua parti:
1) Alocarea corecta de memorie: memoria va fi alocata dinamic pentru toate structurile folosite.
2) Dezalocarea corecta a memoriei: memoria va fi dezalocata corect si complet. Pentru testare, vom folosi valgrind si ca punct de referinta, programul nu trebuie sa afiseze niciun read invalid sau orice leak de memorie.(erori de REDIR nu o sa fie depunctate).
valgrind –leak-check=full –show-leak-kinds=all –track-origins=yes ./main
.
Ca sa nu va chinuiti aveti deja la dispozitie o astfel de rulare prin comanda make check
.
Se acorda 10p pentru coding style si comentarii. README-ul este optional. Daca doriti sa adaugati un README, este de preferat sa fie de tipul Markdown.
Fisierele de input sunt sub forma binara.
Exemplu fisier input:
2 1 12.3 -50 500 30 70 4 4 5 6 7 0 23.5 80 20 0 4 0 1 2 3
Explicatia fisierului:
2 // numar de senzori 1 // senzor de tip PMU 12.3 -50 500 30 70 // datele senzorului PMU 4 // numarul de operatii ce vor fi aplicate pe datelor senzorului PMU 4 5 6 7 // operatiile ce vor fi aplicate 0 // senzor de tip Tire 23.5 80 20 0 // datele senzorului Tire 4 // numarul de operatii ce vor fi aplicate pe datelor senzorului Tire 0 1 2 3 // operatiile ce vor fi aplicate
Tema valoreaza un punct (1p) din nota finala.
Cele 100 de puncte ale temei sunt impartite astfel:
Temele vor trebui încărcate pe platforma TODO.
teme/tema-1/
.