Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f7cf9ac
Update
Steffen-Braun Nov 29, 2024
f282b28
add some code improvments regarding execution speed
Steffen-Braun Dec 2, 2024
0f39ccd
fix little mistakes
Steffen-Braun Dec 2, 2024
9b4f603
fix mistakes and adjust code
Steffen-Braun Dec 9, 2024
cfa1415
Update carTelemetry_feeder.py
Steffen-Braun Dec 11, 2024
e41133b
Update carTelemetry_feeder.ini
Steffen-Braun Dec 11, 2024
4a53cff
Update carTelemetry_feeder.py
Steffen-Braun Dec 11, 2024
40d13df
Update carTelemetry_feeder.py
Steffen-Braun Dec 11, 2024
7bd741c
Update README.md
Steffen-Braun Dec 11, 2024
349b758
Update README.md
Steffen-Braun Dec 11, 2024
cd7dc0e
Update README.md
Steffen-Braun Dec 11, 2024
b9b6063
adjust update algorithm
Jan 15, 2025
a7a4382
¨update¨
Steffen-Braun Jan 15, 2025
c776d5e
accept merge
Steffen-Braun Jan 15, 2025
252d8fb
adjust update algorithm
Jan 15, 2025
3bb16bc
Merge branch 'main' of https://github.com/Steffen-Braun/kuksa-incubation
Steffen-Braun Jan 15, 2025
94af12d
Merge branch 'eclipse-kuksa:main' into main
Steffen-Braun Jan 29, 2025
cfc8c3a
remove blank lines
Steffen-Braun Jan 29, 2025
b9a9bad
Merge branch 'main' of github.com:Steffen-Braun/kuksa-incubation
Steffen-Braun Jan 29, 2025
b2c0b4c
Remove blank lines
Steffen-Braun Jan 29, 2025
75db9c0
remove test scripts
Steffen-Braun Jan 29, 2025
50378ff
fix little mistakes
Steffen-Braun Jan 29, 2025
7d87cde
fix little mistakes
Steffen-Braun Jan 29, 2025
e6c7c56
fix little mistakes
Steffen-Braun Jan 29, 2025
052fef6
fix little mistakes
Steffen-Braun Jan 29, 2025
b62fdd0
Code change according to the PR error messages
Steffen-Braun Feb 10, 2025
af798d1
Merge branch 'main' into main
Steffen-Braun Feb 10, 2025
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
18 changes: 5 additions & 13 deletions fone2val/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The [`carTelemetry_feeder.ini`](./config/carTelemetry_feeder.ini) contains `kuk

Before starting the [F1 feeder](./carTelemetry_feeder.py), you need to start the `kuksa.val databroker` docker container by running the following command in the main project folder:
```
docker run -it -v ./VSS:/VSS --rm --net=host -p 127.0.0.1:8090:8090 -e LOG_LEVEL=ALL ghcr.io/eclipse/kuksa.val/databroker:master --insecure --vss /VSS/vss.json
docker run -it -v ./VSS:/VSS --rm --net=host -p 127.0.0.1:8090:8090 -e LOG_LEVEL=ALL ghcr.io/eclipse/kuksa.val/databroker:0.4.3 --insecure --vss /VSS/vss.json
```
This VSS folder, contains a custom vss.json file for this particular game.
## Install dependencies and execution
Expand All @@ -23,22 +23,14 @@ General Information: This Project was run on an Ubuntu VM and created in coopera
```
a. The F1 telemetry port/IP number for communication has to be updated in the ./config/carTelemetry_feeder.ini file.

> IP address of the Host/VM for example 192.168.178.154
> Same with the Port: fore example 20778
> IP address of the Host/VM for example 192.168.178.154 [listenerIPAddr] host
> Same with the Port: fore example 20778 [PS5_UDPort] port

b. The listenerIPAddr of the host/VM a also needs to be updated in the ./config/carTelemetry_feeder.ini file.

> It has to match with the given IP in step a.

c. The PS5_UDPPort of the host/VM a also needs to be updated in the ./config/carTelemetry_feeder.ini file.

> It has to match with the given Port in step a.

d. kuksa.val IP for the VSSClient has to be updated in the ./config/carTelemetry_feeder.ini file.
b. kuksa.val IP for the VSSClient has to be updated in the ./config/carTelemetry_feeder.ini file.

> Normally set to 127.0.0.1.

e. kuksa.val port for the VSSClient has to be updated in the ./config/carTelemetry_feeder.ini file.
c. kuksa.val port for the VSSClient has to be updated in the ./config/carTelemetry_feeder.ini file.

> Normaly set to 55555.
```
Expand Down
200 changes: 135 additions & 65 deletions fone2val/carTelemetry_feeder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,67 @@
from kuksa_client.grpc import VSSClient
from kuksa_client.grpc import Datapoint
from telemetry_f1_2021.listener import TelemetryListener
from threading import Lock

scriptDir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(scriptDir, "../../"))

# telemetry packet ids
TelemetryPacketID_Engine = 6
TelemetryPacketID_CarStatus = 7
TelemetryPacketID_CarDamage = 10
TelemetryPacketID_LapTime = 2


class Kuksa_Client():
# Constructor
def __init__(self, config):
print("Init kuksa client...")
self.config = config
if "kuksa_val" not in config:
print("kuksa_val section missing from configuration, exiting")
sys.exit(-1)
kuksaConfig = config['kuksa_val']
self.host = kuksaConfig.get('host')
self.port = kuksaConfig.getint('port')

def shutdown(self):
self.client.stop()

# Christophers approach on sending Data to Kuksa Server
def setTelemetryData(self, teleData):
dataDictionary = {}

kuksaConfig = config['kuksa_val']
with VSSClient(kuksaConfig.get('host'), kuksaConfig.getint('port')) as client:
for x, y in teleData.items():
dataDictionary.update({
str(x): Datapoint(y)
})
client.set_current_values(dataDictionary)
# Christophers approach on sending Data to Kuksa Server
def setTelemetryData(self, telemetryData):
with VSSClient(self.host, self.port) as client:
client.set_current_values(telemetryData)


class carTelemetry_Client():

def __init__(self, config, consumer):
print("Init carTelemetry client...")
self.consumer = consumer
if "listenerIPAddr" not in config:
print("listenerIPAddr section missing from configuration, exiting")
sys.exit(-1)
if "PS5_UDPPort" not in config:
print("PS5_UDPPort section missing from configuration, exiting")
sys.exit(-1)
# init thread variables
self.datastructure_lock = Lock()
self.list_for_Ids = []
self.id_To_LastPacket = {}
self.id_To_ProcessingFunction = {}
self.id_To_ProcessingFunction[TelemetryPacketID_Engine] = (
self.processTelemetryPacket_Engine
)
self.id_To_ProcessingFunction[TelemetryPacketID_CarDamage] = (
self.processTelemetryPacket_CarDamage
)
self.id_To_ProcessingFunction[TelemetryPacketID_CarStatus] = (
self.processTelemetryPacket_CarStatus
)
self.id_To_ProcessingFunction[TelemetryPacketID_LapTime] = (
self.processTelemetryPacket_LapTime
)
# extract carTelemetry Data
print("Connecting to extract CarTelemetry Data")

Expand All @@ -67,73 +89,121 @@ def __init__(self, config, consumer):
self.thread = threading.Thread(target=self.loop, args=())
self.thread.start()

def get_next_packet(self):
print("start next packet thread")
while self.running:
try:
# listen to the data via UDP channel
packet = self.listener.get()
packetID = packet.m_header.m_packet_id
if packetID in [
TelemetryPacketID_Engine,
TelemetryPacketID_CarDamage,
TelemetryPacketID_CarStatus,
TelemetryPacketID_LapTime,
]:
with self.datastructure_lock:
if packetID not in self.list_for_Ids:
self.list_for_Ids.append(packetID)
self.id_To_LastPacket[packetID] = packet
except Exception:
continue

def loop(self):
print("Car Telemetry data loop started")

# extract config
config_ipAddr = config['listenerIPAddr']
config_UDPport = config['PS5_UDPPort']

listener_ip = config_ipAddr['host']
udp_port = config_UDPport['port']

print(f"listener_ip:{listener_ip}")
print(f"udp_port:{udp_port}")

listener = TelemetryListener(port=int(udp_port), host=listener_ip)

# init threads to process telemetry data
self.listener = TelemetryListener(port=int(udp_port), host=listener_ip)
thread_get_next_packet = threading.Thread(target=self.get_next_packet)
thread_initPacketProcessing = threading.Thread(target=self.initPacketProcessing)
thread_get_next_packet.start()
thread_initPacketProcessing.start()
thread_get_next_packet.join()
thread_initPacketProcessing.join()

def processTelemetryPacket_Engine(self, telemetryPacket):
# Get data
carIndex = telemetryPacket.m_header.m_player_car_index
Speed = telemetryPacket.m_car_telemetry_data[carIndex].m_speed
EngineRPM = telemetryPacket.m_car_telemetry_data[carIndex].m_engine_rpm
# Store data
carTelemetry = {}
carTelemetry['Vehicle.Speed'] = Datapoint(Speed)
carTelemetry['Vehicle.RPM'] = Datapoint(EngineRPM)
return carTelemetry

def processTelemetryPacket_CarDamage(self, telemetryPacket):
# Get data
carIndex = telemetryPacket.m_header.m_player_car_index
leftWingDamage = telemetryPacket.m_car_damage_data[carIndex].m_front_left_wing_damage
rightWingDamage = telemetryPacket.m_car_damage_data[carIndex].m_front_right_wing_damage
# Extract nested data
tyreWear_1 = telemetryPacket.m_car_damage_data[carIndex].m_tyres_wear[0]
tyreWear_2 = telemetryPacket.m_car_damage_data[carIndex].m_tyres_wear[1]
tyreWear_3 = telemetryPacket.m_car_damage_data[carIndex].m_tyres_wear[2]
tyreWear_4 = telemetryPacket.m_car_damage_data[carIndex].m_tyres_wear[3]
# Store data
carTelemetry = {}
carTelemetry['Vehicle.FrontLeftWingDamage'] = Datapoint(leftWingDamage)
carTelemetry['Vehicle.FrontRightWingDamage'] = Datapoint(rightWingDamage)
carTelemetry['Vehicle.Tire.RearLeftWear'] = Datapoint(tyreWear_1)
carTelemetry['Vehicle.Tire.RearRightWear'] = Datapoint(tyreWear_2)
carTelemetry['Vehicle.Tire.FrontLeftWear'] = Datapoint(tyreWear_3)
carTelemetry['Vehicle.Tire.FrontRightWear'] = Datapoint(tyreWear_4)
return carTelemetry

def processTelemetryPacket_LapTime(self, telemetryPacket):
# Get data
carIndex = telemetryPacket.m_header.m_player_car_index
lastLapTime_in_ms = telemetryPacket.m_lap_data[carIndex].m_last_lap_time_in_ms
# Preprocessing
lastLapTime_in_s = lastLapTime_in_ms / 1000
# Store data
carTelemetry = {}
carTelemetry['Vehicle.LastLapTime'] = Datapoint(lastLapTime_in_s)
return carTelemetry

def processTelemetryPacket_CarStatus(self, telemetryPacket):
# Get data
carIndex = telemetryPacket.m_header.m_player_car_index
fuelInTank = telemetryPacket.m_car_status_data[carIndex].m_fuel_in_tank
fuelCapacity = telemetryPacket.m_car_status_data[carIndex].m_fuel_capacity
# Preprocessing
fuelInPercent = int((fuelInTank / fuelCapacity) * 100)
# Store data
carTelemetry = {}
carTelemetry['Vehicle.FuelLevel'] = Datapoint(fuelInPercent)
return carTelemetry

def initPacketProcessing(self):
while self.running:
try:
# listen to the data via UDP channel
packet = listener.get()

# Update packet ID
packetID = packet.m_header.m_packet_id
# player carIndex
carIndex = packet.m_header.m_player_car_index
# Check for telemetry data - packet ID 6.
if (packetID == 6):

EngineRPM = packet.m_car_telemetry_data[carIndex].m_engine_rpm
Speed = packet.m_car_telemetry_data[carIndex].m_speed

self.carTelemetry['Vehicle.Speed'] = Speed
self.carTelemetry['Vehicle.RPM'] = EngineRPM

# Set the data to the KUKSA_VAL
self.consumer.setTelemetryData(self.carTelemetry)

if (packetID == 7): # car status data packet
fuelInTank = packet.m_car_status_data[carIndex].m_fuel_in_tank
fuelCapacity = packet.m_car_status_data[carIndex].m_fuel_capacity
fuelInPercent = fuelInTank/fuelCapacity

self.carTelemetry['Vehicle.FuelLevel'] = int(fuelInPercent*100)
self.consumer.setTelemetryData(self.carTelemetry)

if (packetID == 10): # car dmg packet

leftWingDamage = packet.m_car_damage_data[carIndex].m_front_left_wing_damage
rightWingDamage = packet.m_car_damage_data[carIndex].m_front_right_wing_damage

tyreWear_1 = packet.m_car_damage_data[carIndex].m_tyres_wear[0]
tyreWear_2 = packet.m_car_damage_data[carIndex].m_tyres_wear[1]
tyreWear_3 = packet.m_car_damage_data[carIndex].m_tyres_wear[2]
tyreWear_4 = packet.m_car_damage_data[carIndex].m_tyres_wear[3]

self.carTelemetry['Vehicle.FrontLeftWingDamage'] = leftWingDamage
self.carTelemetry['Vehicle.FrontRightWingDamage'] = rightWingDamage
self.carTelemetry['Vehicle.Tire.RearLeftWear'] = tyreWear_1
self.carTelemetry['Vehicle.Tire.RearRightWear'] = tyreWear_2
self.carTelemetry['Vehicle.Tire.FrontLeftWear'] = tyreWear_3
self.carTelemetry['Vehicle.Tire.FrontRightWear'] = tyreWear_4

self.consumer.setTelemetryData(self.carTelemetry)
if (packetID == 2):
lastLapTime = packet.m_lap_data[carIndex].m_last_lap_time_in_ms

self.carTelemetry['Vehicle.LastLapTime'] = lastLapTime/1000

self.consumer.setTelemetryData(self.carTelemetry)
# Initializing variables
packetID = None
packet = None
# Lock datastructures
with self.datastructure_lock:
# Update packet ID and get dependend packet
if len(self.list_for_Ids) > 0:
packetID = self.list_for_Ids.pop()
packet = self.id_To_LastPacket[packetID]
else:
packetID = None
packet = None
if packet is not None:
# Process telemetry packet
carTelemetry = self.id_To_ProcessingFunction[packetID](packet)
# Forward data to KUKSA_VAL
self.consumer.setTelemetryData(carTelemetry)
except Exception:
continue

Expand Down
Loading