Compare commits

...

19 Commits

Author SHA1 Message Date
684f026f2a freeing arrays 2026-01-19 15:52:31 +01:00
a1f9a9deab moved functions to seperate file and query the 4 main table data (throttle, brake, speed and steering) 2026-01-19 13:53:30 +01:00
3ea5736fb6 querying the throttle position from the db 2026-01-14 20:10:48 +01:00
c6a870a462 converted the LapInfo struct to use the float_array implementation 2026-01-14 20:10:31 +01:00
c5c5f44ec4 converted the function that destroys lapinfo to the new spec 2026-01-14 20:10:02 +01:00
d4a21df8a8 added new float array function and function definition to the header 2026-01-14 20:09:33 +01:00
a948ca19fc new memory free strategy that relies on goto 2026-01-08 21:16:11 +01:00
ad85394014 header guard 2026-01-08 21:15:55 +01:00
6d8018f21b header guard 2026-01-08 21:15:46 +01:00
4864f01af3 added array definiitions with getter and setter for each type 2026-01-08 21:15:35 +01:00
70c15db109 Update README.md 2026-01-08 14:51:17 +01:00
6f0fb8cefd Merge pull request 'moving development to master for a while since there is no need for branching yet' (#8) from duckdb into master
Reviewed-on: #8
2026-01-08 14:48:09 +01:00
53a2194bde added all the new error codes for the exits currently in the code 2026-01-08 12:53:49 +01:00
25a9dfb349 added path checking for input file and exit codes 2026-01-08 12:34:05 +01:00
b380f203e3 added valgrind toggle 2026-01-08 12:33:39 +01:00
615d8c7f06 query lap timestamps 2026-01-06 22:19:08 +01:00
f52d081d04 getting laptime data to know how many lapinfo needs to be allocated 2026-01-03 20:44:21 +01:00
abe3a2dbb1 changed makefile run command to run with valgrind and default data file 2026-01-03 20:43:51 +01:00
92cf26fcf6 moved table names to separate file 2026-01-03 20:43:21 +01:00
11 changed files with 829 additions and 201 deletions

View File

@@ -5,6 +5,7 @@ VENDORDIR = vendor
target ?= linux
profile ?= debug
valgrind ?= false
ifeq ($(target), windows)
CC = x86_64-w64-mingw32-gcc
@@ -56,7 +57,13 @@ $(BUILDDIR)/%.o: $(SRCDIR)/%.c
clean:
rm -rf $(BUILDDIR)
ifeq ($(valgrind), true)
RUN_CMD = valgrind --leak-check=full ./$(BUILDDIR)/$(APPNAME)$(EXT)
else
RUN_CMD = ./$(BUILDDIR)/$(APPNAME)$(EXT)
endif
run: all
./$(BUILDDIR)/$(APPNAME)$(EXT)
$(RUN_CMD) ./data/Circuit.duckdb
.PHONY: all clean run

View File

@@ -8,6 +8,12 @@ A Le Mans Ultimate telemetry viewer with a hosted database.
`sudo pacman -S mariadb-libs`
### Valgrind
`sudo pacman -S valgrind`
## Running:
`make run` -> run a linux binary with a sample data
`make run valgrind=true` -> run the linux binary with valgrind
## Compiling:
@@ -27,4 +33,4 @@ A Le Mans Ultimate telemetry viewer with a hosted database.
#### Linux (Default):
`make target=linux`
`make target=linux` or just `make`

56
src/array_utils.c Normal file
View File

@@ -0,0 +1,56 @@
#include <duckdb.h>
#include <stdio.h>
#include "arrays.h"
void allocate_array_for_db_data(float_array *array, const char *table, duckdb_connection *conn) {
char query[100];
sprintf(query, "Select count(*) from \"%s\"", table);
duckdb_result result;
duckdb_query(*conn, query, &result);
duckdb_data_chunk chunk = duckdb_fetch_chunk(result);
if (!chunk) {
return;
}
duckdb_vector col1 = duckdb_data_chunk_get_vector(chunk, 0);
int32_t *col1_data = (int32_t *)duckdb_vector_get_data(col1);
uint64_t *col1_validity = duckdb_vector_get_validity(col1);
if (duckdb_validity_row_is_valid(col1_validity, 0)) {
printf("capycity of array: %d\n", col1_data[0]);
float_array_allocate(array, col1_data[0]);
}
duckdb_destroy_data_chunk(&chunk);
duckdb_destroy_result(&result);
}
void get_data_from_db(const char *query, duckdb_connection *conn, float_array *info) {
duckdb_result result;
duckdb_query(*conn, query, &result);
while (true) {
duckdb_data_chunk data_chunk = duckdb_fetch_chunk(result);
if (!data_chunk) {
break;
}
idx_t row_count = duckdb_data_chunk_get_size(data_chunk); // number of rows from the data chunk
// set column
duckdb_vector col1 = duckdb_data_chunk_get_vector(data_chunk, 0);
void *col1_data = duckdb_vector_get_data(col1);
uint64_t *col1_validity = duckdb_vector_get_validity(col1);
for (idx_t row = 0; row < row_count; row++) {
if (duckdb_validity_row_is_valid(col1_validity, row)) {
float_array_set(info, ((float *)col1_data)[row], -1);
}
}
duckdb_destroy_data_chunk(&data_chunk);
}
duckdb_destroy_result(&result);
}

6
src/array_utils.h Normal file
View File

@@ -0,0 +1,6 @@
#include <duckdb.h>
#include "arrays.h"
void allocate_array_for_db_data(float_array *array, const char *table, duckdb_connection *conn);
void get_data_from_db(const char *query, duckdb_connection *conn, float_array *info);

330
src/arrays.c Normal file
View File

@@ -0,0 +1,330 @@
#include "arrays.h"
#include <stdint.h>
#include <stdlib.h>
bool bool_array_get(const bool_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void bool_array_set(bool_array *array, const bool value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length && index <= 0 && index < array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
char char_array_get(const char_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void char_array_set(char_array *array, const char value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
int8_t int8_array_get(const int8_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void int8_array_set(int8_array *array, const int8_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
int16_t int16_array_get(const int16_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void int16_array_set(int16_array *array, const int16_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
int32_t int32_array_get(const int32_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void int32_array_set(int32_array *array, const int32_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
int64_t int64_array_get(const int64_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void int64_array_set(int64_array *array, const int64_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
uint8_t uint8_array_get(const uint8_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void uint8_array_set(uint8_array *array, const uint8_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
uint16_t uint16_array_get(const uint16_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void uint16_array_set(uint16_array *array, const uint16_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
uint32_t uint32_array_get(const uint32_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void uint32_array_set(uint32_array *array, const uint32_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
uint64_t uint64_array_get(const uint64_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void uint64_array_set(uint64_array *array, const uint64_t value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}
float float_array_get(const float_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void float_array_set(float_array *array, const float value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
array->length++;
return;
}
array->items[index] = value;
}
void float_array_allocate(float_array *array, int32_t capacity) {
array->items = calloc(capacity, sizeof(float));
array->capacity = capacity;
}
void float_array_init(float_array *array) {
array->capacity = 0;
array->length = 0;
}
void float_array_free(float_array *array) {
free(array->items);
float_array_init(array);
}
double double_array_get(const double_array *array, int32_t index) {
if (index >= 0 && index < array->length) {
return array->items[index];
}
return 0;
}
//@param index: set to -1 to put it at the end of the array
void double_array_set(double_array *array, const double value, int32_t index) {
if (!array) {
return;
}
if (array->capacity <= array->length) {
return;
}
if (index == -1) {
array->items[array->length - 1] = value;
return;
}
array->items[index] = value;
}

123
src/arrays.h Normal file
View File

@@ -0,0 +1,123 @@
#ifndef ARRAYS_H
#define ARRAYS_H
#include <stdbool.h>
#include <stdint.h>
// --- Boolean ---
typedef struct {
bool *items;
int32_t length;
int32_t capacity;
} bool_array;
bool bool_array_get(const bool_array *array, int32_t index);
void bool_array_set(bool_array *array, const bool value, int32_t index);
// --- Char (Strings/Bytes) ---
typedef struct {
char *items;
int32_t length;
int32_t capacity;
} char_array;
char char_array_get(const char_array *array, int32_t index);
void char_array_set(char_array *array, const char value, int32_t index);
// --- Signed Integers ---
typedef struct {
int8_t *items;
int32_t length;
int32_t capacity;
} int8_array;
int8_t int8_array_get(const int8_array *array, int32_t index);
void int8_array_set(int8_array *array, const int8_t value, int32_t index);
typedef struct {
int16_t *items;
int32_t length;
int32_t capacity;
} int16_array;
int16_t int16_array_get(const int16_array *array, int32_t index);
void int16_array_set(int16_array *array, const int16_t value, int32_t index);
typedef struct {
int32_t *items;
int32_t length;
int32_t capacity;
} int32_array;
int32_t int32_array_get(const int32_array *array, int32_t index);
void int32_array_set(int32_array *array, const int32_t value, int32_t index);
typedef struct {
int64_t *items;
int32_t length;
int32_t capacity;
} int64_array;
int64_t int64_array_get(const int64_array *array, int32_t index);
void int64_array_set(int64_array *array, const int64_t value, int32_t index);
// --- Unsigned Integers ---
typedef struct {
uint8_t *items;
int32_t length;
int32_t capacity;
} uint8_array;
uint8_t uint8_array_get(const uint8_array *array, int32_t index);
void uint8_array_set(uint8_array *array, const uint8_t value, int32_t index);
typedef struct {
uint16_t *items;
int32_t length;
int32_t capacity;
} uint16_array;
uint16_t uint16_array_get(const uint16_array *array, int32_t index);
void uint16_array_set(uint16_array *array, const uint16_t value, int32_t index);
typedef struct {
uint32_t *items;
int32_t length;
int32_t capacity;
} uint32_array;
uint32_t uint32_array_get(const uint32_array *array, int32_t index);
void uint32_array_set(uint32_array *array, const uint32_t value, int32_t index);
typedef struct {
uint64_t *items;
int32_t length;
int32_t capacity;
} uint64_array;
uint64_t uint64_array_get(const uint64_array *array, int32_t index);
void uint64_array_set(uint64_array *array, const uint64_t value, int32_t index);
// --- Floating Point ---
typedef struct {
float *items;
int32_t length;
int32_t capacity;
} float_array;
float float_array_get(const float_array *array, int32_t index);
void float_array_set(float_array *array, const float value, int32_t index);
void float_array_allocate(float_array *array, int32_t capacity);
void float_array_init(float_array *array);
void float_array_free(float_array *array);
typedef struct {
double *items;
int32_t length;
int32_t capacity;
} double_array;
double double_array_get(const double_array *array, int32_t index);
void double_array_set(double_array *array, const double value, int32_t index);
#endif

14
src/exit_code.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef EXIT_CODE_H
#define EXIT_CODE_H
typedef enum {
EXIT_OK = 0,
ERR_ARGUMENT = 1,
ERR_FILE = 2,
ERR_DATABASE = 3,
ERR_CONNECTION = 4,
ERR_MEMORY = 5,
ERR_QUERY = 6,
} exit_code;
#endif

View File

@@ -3,16 +3,10 @@
#include "lapinfo.h"
void free_telemetry_info(TelemetryInfo *t) {
free(t->data);
free(t->validity);
// free(t);
}
void destroyLapinfo(LapInfo *info) {
free_telemetry_info(&info->throttle_pos);
free_telemetry_info(&info->brake_pos);
free_telemetry_info(&info->steering_pos);
free_telemetry_info(&info->speed);
// free(info);
free(info->throttle_pos.items);
free(info->brake_pos.items);
free(info->steering_pos.items);
free(info->speed.items);
free(info);
}

View File

@@ -1,7 +1,10 @@
#pragma once
#ifndef LAPINFO_H
#define LAPINFO_H
#include <stdint.h>
#include "arrays.h"
typedef enum {
BOOL,
INT,
@@ -21,11 +24,13 @@ typedef struct {
typedef struct {
int lap_number;
double start_time;
TelemetryInfo throttle_pos; // freq: 50
TelemetryInfo brake_pos; // freq: 50
TelemetryInfo steering_pos; // freq: 100
TelemetryInfo speed;
float_array throttle_pos;
float_array brake_pos;
float_array steering_pos; // freq: 100
float_array speed;
} LapInfo;
void free_telemetry_info(TelemetryInfo *t);
void destroyLapinfo(LapInfo *info);
#endif

View File

@@ -2,218 +2,194 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "array_utils.h"
#include "arrays.h"
#include "exit_code.h"
#include "lapinfo.h"
void get_data_from_db(const char *query, duckdb_connection *conn, TelemetryInfo *info) {
duckdb_result result;
int32_t iterations = 0;
int32_t number_of_data_points = 0;
duckdb_query(*conn, query, &result);
while (true) {
iterations++;
duckdb_data_chunk data_chunk = duckdb_fetch_chunk(result);
if (!data_chunk) {
break;
}
idx_t row_count = duckdb_data_chunk_get_size(data_chunk); // number of rows from the data chunk
number_of_data_points += row_count;
// set column
duckdb_vector col1 = duckdb_data_chunk_get_vector(data_chunk, 0);
float *col1_data = (float *)duckdb_vector_get_data(col1);
uint64_t *col1_validity = duckdb_vector_get_validity(col1);
for (idx_t row = 0; row < row_count; row++) {
if (duckdb_validity_row_is_valid(col1_validity, row)) {
// put a switch here based on the info from the struct
((float *)info->data)[info->data_last_index] = col1_data[row];
info->data_last_index++;
// TODO: set info->data_size as capacity at struct creation
printf("%f, ", col1_data[row]);
} else {
printf("NULL");
}
}
duckdb_destroy_data_chunk(&data_chunk);
bool is_valid_path(const char *path) {
if (path == NULL) {
return false;
}
duckdb_destroy_result(&result);
printf("\nNumber of iterations: %d, number of data points: %d\n", iterations, number_of_data_points);
const char *dot = strrchr(path, '.'); // find the last dot which is for the extension
if (!dot || strcmp(dot, ".duckdb") != 0) {
return false;
}
struct stat path_stat;
if (stat(path, &path_stat) != 0) {
return false; // path does not exist
}
if (!S_ISREG(path_stat.st_mode)) {
return false; // checks if it is a regular file
}
return true;
}
int main(int argc, char **argv) {
printf("Hello from HardCompound!\n");
duckdb_database db;
duckdb_connection conn;
duckdb_result lap_count_res;
LapInfo *session_data = NULL;
double *lap_timestamps = NULL;
printf("\nHello from HardCompound!\n");
if (argc < 2) {
printf("You need to specify a duckdb file path! Terminating!\n");
exit(1);
goto cleanup;
}
if (!is_valid_path(argv[1])) {
printf("The file you gave is not valid. Exiting!");
goto cleanup;
}
printf("First argument: %s\n", argv[1]);
duckdb_database db;
if (duckdb_open(argv[1], &db) == DuckDBError) {
printf("Error opening duckdb file, terminating!\n");
exit(2);
goto cleanup;
}
duckdb_connection conn;
if (duckdb_connect(db, &conn) == DuckDBError) {
printf("Error connecting to the duckdb database! Terminating!\n");
exit(3);
goto cleanup;
}
const char *channel_tables[] = {"Ambient Temperature",
"Brake Pos",
"Brake Pos Unfiltered",
"Brake Thickness",
"Brakes Air Temp",
"Brakes Force",
"Brakes Temp",
"Clutch Pos",
"Clutch Pos Unfiltered",
"Clutch RPM",
"Drag",
"Engine Oil Temp",
"Engine RPM",
"Engine Water Temp",
"FFB Output",
"Front3rdDeflection",
"FrontDownForce",
"FrontRideHeight",
"FrontWingHeight",
"Fuel Level",
"G Force Lat",
"G Force Long",
"G Force Vert",
"GPS Latitude",
"GPS Longitude",
"GPS Speed",
"GPS Time",
"Ground Speed",
"Lap Dist",
"Lateral Acceleration",
"Longitudinal Acceleration",
"OverheatingState",
"Path Lateral",
"ReadDownForce",
"Rear3rdDeflection",
"RearRideHeight",
"Regen Rate",
"RideHeights",
"SoC",
"Steered Angle",
"Steering Pos",
"Steering Pos Unfiltered",
"Steering Shaft Torque",
"Susp Pos",
"Throttle Pos",
"Throttle Pos Unfiltered",
"Time Behind Next",
"Total Dist",
"Track Edge",
"Track Temperature",
"Turbo Boost Pressure",
"Tyres Wear",
"TyresCarcassTemp",
"TyresPressure",
"TyresRimTemp",
"TyresRubberTemp",
"TyresTempCentre",
"TyresTempLeft",
"TyresTempRight",
"Virtual Energy",
"Wheel Speed",
"Wind Heading",
"Wind Speed",
"Yaw Rate"};
// get how many laps is in the session and allocate that many LapInfo-s
int32_t lap_count = 0;
duckdb_query(conn, "Select count(value) from Lap\n", &lap_count_res);
const int channel_table_count = sizeof(channel_tables) / sizeof(channel_tables[0]);
duckdb_data_chunk data_chunk = duckdb_fetch_chunk(lap_count_res);
if (!data_chunk) {
printf("Error in retrieving laps");
goto cleanup;
}
const char *event_tables[] = {"ABS",
"ABSLevel",
"AntiStall Activated",
"Best LapTime",
"Best Sector1",
"Best Sector2",
"Brake Bias Rear",
"Brake Migration",
"CloudDarkness",
"Current LapTime",
"Current Sector",
"Current Sector1",
"Current Sector2",
"Engine Max RPM",
"Finish Status",
"FrontFlapActivated",
"FuelMixtureMap",
"Gear",
"Headlights State",
"In Pits",
"Lap",
"Lap Time",
"Last Sector1",
"Last Sector2",
"LastImpactMagnitude",
"LaunchControlActive",
"Minimum Path Wetness",
"OffpathWetness",
"RearFlapActivated",
"RearFlapLegalStatus",
"Sector1 Flag",
"Sector2 Flag",
"Sector3 Flag",
"Speed Limiter",
"SurfaceTypes",
"TC",
"TCCut",
"TCLevel",
"TCSlipAngle",
"TyresCompound",
"WheelsDetached",
"Yellow Flag State"};
// set column
duckdb_vector col1 = duckdb_data_chunk_get_vector(data_chunk, 0);
int32_t *col1_data = (int32_t *)duckdb_vector_get_data(col1);
uint64_t *col1_validity = duckdb_vector_get_validity(col1);
idx_t row_count = duckdb_data_chunk_get_size(data_chunk); // number of rows from the data chunk
const int event_table_count = sizeof(event_tables) / sizeof(event_tables[0]);
for (idx_t row = 0; row < row_count; row++) {
if (duckdb_validity_row_is_valid(col1_validity, 0)) {
lap_count = col1_data[0];
}
}
LapInfo info = {.lap_number = 0,
.start_time = 0,
.throttle_pos = {.data_last_index = 0,
.data_size = 75000,
.frequency = 50,
.type = FLOAT,
.validity = NULL,
.data = malloc(sizeof(float) * 75000)},
.brake_pos = {.data_last_index = 0,
.data_size = 75000,
.frequency = 50,
.type = FLOAT,
.validity = NULL,
.data = malloc(sizeof(float) * 75000)},
.steering_pos = {.data_last_index = 0,
.data_size = 75000,
.frequency = 50,
.type = FLOAT,
.validity = NULL,
.data = malloc(sizeof(float) * 75000)},
.speed = {.data_last_index = 0,
.data_size = 75000,
.frequency = 50,
.type = FLOAT,
.validity = NULL,
.data = malloc(sizeof(float) * 75000)}};
duckdb_destroy_data_chunk(&data_chunk);
duckdb_destroy_result(&lap_count_res);
get_data_from_db("Select * from \"Throttle Pos\"\n", &conn, &info.throttle_pos);
destroyLapinfo(&info);
printf("Lap count: %d\n", lap_count);
session_data = calloc(lap_count, sizeof(LapInfo));
lap_timestamps = calloc(lap_count, sizeof(double));
printf("Shutting down HardCompound!\n");
if (!session_data) {
printf("Session data failed to allocate!");
goto cleanup;
}
if (!lap_timestamps) {
printf("Lap timestaps array failed to init!");
goto cleanup;
}
duckdb_result lap_timestamps_res;
if (duckdb_query(conn, "Select ts as DOUBLE from Lap\n", &lap_timestamps_res) == DuckDBError) {
goto cleanup;
}
int current_index = 0;
while (true) {
duckdb_data_chunk data_chunk_2 = duckdb_fetch_chunk(lap_timestamps_res);
if (!data_chunk_2) {
break;
}
idx_t current_chunk_size = duckdb_data_chunk_get_size(data_chunk_2);
duckdb_vector col2 = duckdb_data_chunk_get_vector(data_chunk_2, 0);
double *ts_data = (double *)duckdb_vector_get_data(col2);
uint64_t *col2_validity = duckdb_vector_get_validity(col2);
for (idx_t row = 0; row < current_chunk_size; row++) {
if (!col2_validity || duckdb_validity_row_is_valid(col2_validity, row)) {
if (current_index < lap_count) {
lap_timestamps[current_index++] = ts_data[row];
}
}
}
duckdb_destroy_data_chunk(&data_chunk_2);
}
duckdb_destroy_result(&lap_timestamps_res);
for (int i = 0; i < lap_count; i++) {
printf("%f, ", lap_timestamps[i]);
}
printf("\n");
// throttle
float_array throttle_data_all;
float_array_init(&throttle_data_all);
allocate_array_for_db_data(&throttle_data_all, "Throttle Pos", &conn);
get_data_from_db("Select value as FLOAT from \"Throttle Pos\"\n", &conn, &throttle_data_all);
for (int32_t i = 0; i < throttle_data_all.length; ++i) {
// printf(" %f", float_array_get(&throttle_data_all, i));
}
// brake
float_array brake_data_all;
float_array_init(&brake_data_all);
allocate_array_for_db_data(&brake_data_all, "Brake Pos", &conn);
get_data_from_db("Select value as FLOAT from \"Brake Pos\"\n", &conn, &brake_data_all);
for (int32_t i = 0; i < brake_data_all.length; ++i) {
// printf(" %f", float_array_get(&brake_data_all, i));
}
// steering
float_array steering_data_all;
float_array_init(&steering_data_all);
allocate_array_for_db_data(&steering_data_all, "Steering Pos", &conn);
get_data_from_db("Select value as FLOAT from \"Steering Pos\"\n", &conn, &steering_data_all);
for (int32_t i = 0; i < steering_data_all.length; ++i) {
// printf(" %f", float_array_get(&steering_data_all, i));
}
// select avg(((value1+value2+value3+value4)/4)*3.6) as speed from "Wheel Speed"
// speed
float_array speed_data_all;
float_array_init(&speed_data_all);
allocate_array_for_db_data(&speed_data_all, "Wheel Speed", &conn);
get_data_from_db("select ((value1+value2+value3+value4)/4)*3.6 as speed from \"Wheel Speed\"", &conn,
&speed_data_all);
for (int32_t i = 0; i < speed_data_all.length; ++i) {
// printf(" %f", float_array_get(&speed_data_all, i));
}
printf("\nShutting down HardCompound!\n");
printf("Closing database and any connection.\n");
goto cleanup;
exit:
return EXIT_OK;
cleanup:
free(NULL);
free(session_data);
free(lap_timestamps);
float_array_free(&throttle_data_all);
float_array_free(&brake_data_all);
float_array_free(&steering_data_all);
float_array_free(&speed_data_all);
duckdb_disconnect(&conn);
duckdb_close(&db);
return 0;
goto exit;
}

111
src/tables.c Normal file
View File

@@ -0,0 +1,111 @@
const char *channel_tables[] = {"Ambient Temperature",
"Brake Pos",
"Brake Pos Unfiltered",
"Brake Thickness",
"Brakes Air Temp",
"Brakes Force",
"Brakes Temp",
"Clutch Pos",
"Clutch Pos Unfiltered",
"Clutch RPM",
"Drag",
"Engine Oil Temp",
"Engine RPM",
"Engine Water Temp",
"FFB Output",
"Front3rdDeflection",
"FrontDownForce",
"FrontRideHeight",
"FrontWingHeight",
"Fuel Level",
"G Force Lat",
"G Force Long",
"G Force Vert",
"GPS Latitude",
"GPS Longitude",
"GPS Speed",
"GPS Time",
"Ground Speed",
"Lap Dist",
"Lateral Acceleration",
"Longitudinal Acceleration",
"OverheatingState",
"Path Lateral",
"ReadDownForce",
"Rear3rdDeflection",
"RearRideHeight",
"Regen Rate",
"RideHeights",
"SoC",
"Steered Angle",
"Steering Pos",
"Steering Pos Unfiltered",
"Steering Shaft Torque",
"Susp Pos",
"Throttle Pos",
"Throttle Pos Unfiltered",
"Time Behind Next",
"Total Dist",
"Track Edge",
"Track Temperature",
"Turbo Boost Pressure",
"Tyres Wear",
"TyresCarcassTemp",
"TyresPressure",
"TyresRimTemp",
"TyresRubberTemp",
"TyresTempCentre",
"TyresTempLeft",
"TyresTempRight",
"Virtual Energy",
"Wheel Speed",
"Wind Heading",
"Wind Speed",
"Yaw Rate"};
const int channel_table_count = sizeof(channel_tables) / sizeof(channel_tables[0]);
const char *event_tables[] = {"ABS",
"ABSLevel",
"AntiStall Activated",
"Best LapTime",
"Best Sector1",
"Best Sector2",
"Brake Bias Rear",
"Brake Migration",
"CloudDarkness",
"Current LapTime",
"Current Sector",
"Current Sector1",
"Current Sector2",
"Engine Max RPM",
"Finish Status",
"FrontFlapActivated",
"FuelMixtureMap",
"Gear",
"Headlights State",
"In Pits",
"Lap",
"Lap Time",
"Last Sector1",
"Last Sector2",
"LastImpactMagnitude",
"LaunchControlActive",
"Minimum Path Wetness",
"OffpathWetness",
"RearFlapActivated",
"RearFlapLegalStatus",
"Sector1 Flag",
"Sector2 Flag",
"Sector3 Flag",
"Speed Limiter",
"SurfaceTypes",
"TC",
"TCCut",
"TCLevel",
"TCSlipAngle",
"TyresCompound",
"WheelsDetached",
"Yellow Flag State"};
const int event_table_count = sizeof(event_tables) / sizeof(event_tables[0]);