Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
tests/setsimdata
simd/build

.cache/
tests/view_telemetry
simmapper_mixed.c
simmapper_old.c
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.9)
project(simapi VERSION 1.0.1 DESCRIPTION "Telemetry Mapping Library for Racing Sims")
include(GNUInstallDirs)
add_library(simapi SHARED simapi/simmapper.c simapi/getpid.c simapi/mapping/acmapper.c simapi/mapping/pcars2mapper.c simapi/mapping/rf2mapper.c simapi/mapping/scs2mapper.c simapi/mapping/outgaugemapper.c)
add_library(simapi SHARED simapi/simmapper.c simapi/getpid.c simapi/mapping/acmapper.c simapi/mapping/pcars2mapper.c simapi/mapping/rf2mapper.c simapi/mapping/scs2mapper.c simapi/mapping/outgaugemapper.c simapi/mapping/dirt2mapper.c)

set(SIMAPI_PUBLIC_HEADERS
"simapi/simmapper.h"
Expand All @@ -20,3 +20,6 @@ install(TARGETS simapi
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${CMAKE_BINARY_DIR}/simapi.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)

add_executable(view_telemetry tests/view_telemetry.c)
target_link_libraries(view_telemetry simapi m)
46 changes: 46 additions & 0 deletions docs/UDP_SUPPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# UDP Telemetry Support in SimAPI

SimAPI supports simulators that output telemetry data over UDP. This document explains the architecture and how to implement support for new UDP-based simulators.

## Architecture Overview

The UDP support is integrated into the `simd` daemon and the `simapi` library.

### 1. Reception (simd)

The `simd` daemon handles the UDP socket lifecycle:
- **Initialization**: `startudp(port)` initializes a `uv_udp_t` socket using `libuv`.
- **Callback**: `on_udp_recv` is triggered whenever a packet arrives.
- **Data Flow**: The raw buffer is passed to `simdatamap` with the `udp` flag set to `true`.

```mermaid
graph TD
A[Simulator] -->|UDP Packet| B[simd: on_udp_recv]
B --> C[simapi: simdatamap]
C --> D[simapi: map_xxx_data]
D --> E[Shared Memory: SimData]
```

### 2. Mapping (simapi)

The mapping logic resides in `simapi/mapping/`. For UDP simulators, the `base` parameter in `map_xxx_data` points to the raw packet buffer.

- **DiRT Rally 2.0**: Uses `map_dirt_rally_2_data` to process the "extradata=3" packet.
- **Inputs**: Raw fields like throttle/brake are mapped directly to `SimData`.
- **Calculations**: Some values (like Lateral G-force or Euler angles) are derived from world vectors and velocities.

## Implementing New UDP Simulators

To add support for a new UDP-based simulator:

1. **Define Packet Structure**: Create a header in `include/` (e.g., `mynewsimdata.h`) with the packed struct representing the UDP packet.
2. **Add Mapper**: Create `simapi/mapping/mynewsimmapper.c` and implement the mapping function.
3. **Update simmapper.c**:
- Add the new simulator to `SimulatorEXE` and `SimulatorAPI` enums.
- Update `getSim` to detect the running process and call `setup_udp(port)`.
- Update `simdatamap` to call your new mapper.
4. **Update simmap.h**: Add a struct for the new simulator to the `SimMap` union to persist state (if needed, e.g., for acceleration calculations).

## Configuration

UDP support usually requires zero-configuration in `simapi` as it automatically detects the simulator and binds to the correct port. However, ensured the simulator itself is configured to send data to `127.0.0.1` on the expected port (e.g., `20777` for DiRT Rally 2.0).
103 changes: 103 additions & 0 deletions include/dirt2data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#ifndef _DIRT2DATA_H
#define _DIRT2DATA_H

#include <stdint.h>

#pragma pack(push, 1)

// DiRT Rally 2.0 UDP packet structure (extradata=3)
// 66 floats (264 bytes)
/**
* @struct DR2_UDP_ExtraData3
* @brief DiRT Rally 2.0 UDP packet structure for "extradata=3".
*
* This structure contains 66 floating point values (264 bytes total).
* Data is sent in little-endian format.
*/
typedef struct {
float runTime; /**< Total time the session has been running
(seconds) */
float lapTime; /**< Current lap time (seconds) */
float distance; /**< [UNVERIFIED] Total distance travelled in the session
(meters) */
float progress; /**< Current lap progress (0.0 to 1.0, accumulative for each
lap) */
float posX; /**< World position X (East/West) */
float posY; /**< World position Y (Up/Down) */
float posZ; /**< World position Z (North/South) */
float speed; /**< Speed (m/s) */
float velX; /**< Velocity in world X direction */
float velY; /**< Velocity in world Y direction */
float velZ; /**< Velocity in world Z direction */
float rightX; /**< Local right vector X component */
float rightY; /**< Local right vector Y component */
float rightZ; /**< Local right vector Z component */
float forwardX; /**< Local forward vector X component */
float forwardY; /**< Local forward vector Y component */
float forwardZ; /**< Local forward vector Z component */
float suspRL; /**< Suspension position Rear Left */
float suspRR; /**< Suspension position Rear Right */
float suspFL; /**< Suspension position Front Left */
float suspFR; /**< Suspension position Front Right */
float suspVelRL; /**< Suspension velocity Rear Left */
float suspVelRR; /**< Suspension velocity Rear Right */
float suspVelFL; /**< Suspension velocity Front Left */
float suspVelFR; /**< Suspension velocity Front Right */
float wheelSpeedRL; /**< Wheel speed Rear Left (m/s) */
float wheelSpeedRR; /**< Wheel speed Rear Right (m/s) */
float wheelSpeedFL; /**< Wheel speed Front Left (m/s) */
float wheelSpeedFR; /**< Wheel speed Front Right (m/s) */
float throttle; /**< Throttle input (0.0 to 1.0) */
float steering; /**< Steering input (-1.0 to 1.0) */
float brake; /**< Brake input (0.0 to 1.0) */
float clutch; /**< Clutch input (0.0 to 1.0) */
float gear; /**< Current gear (0=neutral, 1-10=gears, -1=reverse) */
float gForceLat; /**< Lateral G-Force (Field 34) */
float gForceLon; /**< Longitudinal G-Force (Field 35) */
float lap; /**< Current lap number */
float engineRPM; /**< Engine RPM (raw value is RPM / 10) */
float sliProSupport; /**< [UNVERIFIED] Sli-Pro support data */
float racePos; /**< Current race position */
float kersLevel; /**< [UNVERIFIED] KERS level (likely unused in DR2) */
float kersMaxLevel; /**< [UNVERIFIED] KERS max level (likely unused in DR2) */
float drs; /**< [UNVERIFIED] DRS status (likely unused in DR2) */
float tractionControl; /**< [UNVERIFIED] Traction control setting/activity */
float antiLockBrakes; /**< [UNVERIFIED] ABS setting/activity */
float fuelInTank; /**< Current fuel in tank (liters) (always 0.0) */
float fuelCapacity; /**< Fuel tank capacity (liters) (always 0.0) */
float inPit; /**< [UNVERIFIED] Pit lane status (0=on track, 1=in pit) */
float sector; /**< Current sector index */
float sector1Time; /**< Time for sector 1 (seconds) */
float sector2Time; /**< Time for sector 2 (seconds) */
float brakesTempRL; /**< Brake temperature Rear Left (Celsius) */
float brakesTempRR; /**< Brake temperature Rear Right (Celsius) */
float brakesTempFL; /**< Brake temperature Front Left (Celsius) */
float brakesTempFR; /**< Brake temperature Front Right (Celsius) */
float tyrePressureRL; /**< Tyre pressure Rear Left (always 0.0) */
float tyrePressureRR; /**< Tyre pressure Rear Right (always 0.0) */
float tyrePressureFL; /**< Tyre pressure Front Left (always 0.0) */
float tyrePressureFR; /**< Tyre pressure Front Right (always 0.0) */
float lapsCompleted; /**< Number of laps completed */
float totalLaps; /**< Total laps in session */
float trackLength; /**< Track length (meters) */
float lastLapTime; /**< Duration of the last completed lap (seconds) */
float maxRPM; /**< Maximum engine RPM (raw value is RPM / 10) */
float idleRPM; /**< Idle engine RPM (raw value is RPM / 10) */
float maxGears; /**< Maximum number of gears */
} DR2_UDP_ExtraData3;

// Main packet structure using a union for both named field access and array
// access
struct dirt2_udp_packet {
union {
float data[66];
DR2_UDP_ExtraData3 fields;
};
};

#pragma pack(pop)

// Note: This structure is based on DiRT Rally 2.0 extradata=3 specification.
// Gear mapping: 0=neutral, 1-10=gears, -1=reverse.

#endif
22 changes: 22 additions & 0 deletions simapi/dirt2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef _DIRT2_H
#define _DIRT2_H

#include <stdbool.h>
#include "../include/dirt2data.h"

#define DIRT_RALLY_2_EXE "dirtrally2.exe"

typedef struct
{
bool has_telemetry;
struct dirt2_udp_packet dirt2_telemetry;
float last_velX;
float last_velY;
float last_velZ;
float last_runTime;
bool has_last_vel;
}
Dirt2Map;

#endif

Loading