pcars icon indicating copy to clipboard operation
pcars copied to clipboard

Info

Open ThunderPaul opened this issue 7 years ago • 12 comments

Hello, I'm trying to figure out the operation of reading data between ProjectCars and UDP, I saw your library, and I wanted to ask you in what format the data is returned and in case you can recognize them (tires, engine speeds, etc) Thank you

ThunderPaul avatar Jun 29 '17 15:06 ThunderPaul

Hi,

To use this library, you'll need to create a pcars.stream.PCarsStreamListener in your code, and pass an object with a handlePacket method to its addListener method. Once you call start() on the PCarsStreamListener, your object's handlePacket method will be called for each packet from the game that is received.

The structure of these packets is as described in pcars.packet - there are several different packet types with different fields in. You can access the data by name as if it were a dict e.g. packet['speed'], packet['tyres'][0]['tyreTemp'] from a TelemetryPacket (check against PACKET_TYPES).

Hope that's helpful?

jamesremuscat avatar Jun 30 '17 14:06 jamesremuscat

Thank you, virtually UDP packets are read from PS4 via the IP of the PS4 and a specific port and then the data is parsed. Do the HD data read through UDP where they are transformed into various packages of speeds, tires and more? Or where can I find a UDP model template that sends project cars? I'm starting to work on an application to be used in live if not knowing python I should rewrite all the main structure from scratch.

2017-06-30 16:03 GMT+02:00 James Muscat [email protected]:

Hi,

To use this library, you'll need to create a pcars.stream. PCarsStreamListener in your code, and pass an object with a handlePacket method to its addListener method. Once you call start() on the PCarsStreamListener, your object's handlePacket method will be called for each packet from the game that is received.

The structure of these packets is as described in pcars.packet - there are several different packet types with different fields in. You can access the data by name as if it were a dict e.g. packet['speed'], packet['tyres'][0]['tyreTemp'] from a TelemetryPacket (check against PACKET_TYPES`).

Hope that's helpful?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jamesremuscat/pcars/issues/6#issuecomment-312275605, or mute the thread https://github.com/notifications/unsubscribe-auth/AE1pYIOLvtxEssIHbR7jvST1gBbFWzxaks5sJQAngaJpZM4OJbvE .

-- Paolo Cavicchia Web Developer cell: 329 - 97.79.429

ThunderPaul avatar Jun 30 '17 14:06 ThunderPaul

I'm sorry, I'm not entirely sure what you're trying to ask.

The game will broadcast data packets via UDP multicast - there is no need to know the IP address of your PS4.

The data structures are all documented on the Project CARS forums at http://forum.projectcarsgame.com/showthread.php?40113-HowTo-Companion-App-UDP-Streaming (as well as in the pcars.packet module here).

jamesremuscat avatar Jul 03 '17 11:07 jamesremuscat

So do not I have to create a socket that reads data from the PSP's IP on a given port and then transforms all the single bytes read in strings?

2017-07-03 13:39 GMT+02:00 James Muscat [email protected]:

I'm sorry, I'm not entirely sure what you're trying to ask.

The game will broadcast data packets via UDP multicast - there is no need to know the IP address of your PS4.

The data structures are all documented on the Project CARS forums at http://forum.projectcarsgame.com/showthread.php?40113- HowTo-Companion-App-UDP-Streaming (as well as in the pcars.packet module here).

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jamesremuscat/pcars/issues/6#issuecomment-312623567, or mute the thread https://github.com/notifications/unsubscribe-auth/AE1pYNY7Tc3r-y3edPqWRXgUZhUzvZ1Cks5sKNL8gaJpZM4OJbvE .

-- Paolo Cavicchia Web Developer cell: 329 - 97.79.429

ThunderPaul avatar Jul 03 '17 12:07 ThunderPaul

Can I have a little example for the PCarsStreamListener? Thank you

2017-07-03 14:11 GMT+02:00 Paolo Cavicchia [email protected]:

So do not I have to create a socket that reads data from the PSP's IP on a given port and then transforms all the single bytes read in strings?

2017-07-03 13:39 GMT+02:00 James Muscat [email protected]:

I'm sorry, I'm not entirely sure what you're trying to ask.

The game will broadcast data packets via UDP multicast - there is no need to know the IP address of your PS4.

The data structures are all documented on the Project CARS forums at http://forum.projectcarsgame.com/showthread.php?40113-HowTo- Companion-App-UDP-Streaming (as well as in the pcars.packet module here).

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jamesremuscat/pcars/issues/6#issuecomment-312623567, or mute the thread https://github.com/notifications/unsubscribe-auth/AE1pYNY7Tc3r-y3edPqWRXgUZhUzvZ1Cks5sKNL8gaJpZM4OJbvE .

-- Paolo Cavicchia Web Developer cell: 329 - 97.79.429

-- Paolo Cavicchia Web Developer cell: 329 - 97.79.429

ThunderPaul avatar Jul 03 '17 12:07 ThunderPaul

Hi,

I have followed the steps in your quickstart example. (copying and pasting).

I run the python script on my RaspberryPi, and the script just exits with no output.

I'm assuming if I print data, it will print the whole data packet? Or do I need to explicitly ask for a data type?

Thanks in advance.

colugav avatar Apr 24 '18 20:04 colugav

@colugav:

The reason nothing happens is, that you terminate your Python code before the first packet is received.

So, in a quick and dirty way, add:

while True:
  continue 

after stream.start() at the end of your quickstart.py, or however you named it.

A more elegant way would be:

from time import sleep
.
.
.
while True:
  sleep(1)

which does not unnecessarily stress the CPU.

I might carry owls to Athens :grinning:.

You should then get something like this:

python3 quickstart.py 
<pcars.packet.TelemetryPacket object at 0x7f0f9497eb38>
<pcars.packet.TelemetryPacket object at 0x7f0f949f96d8>
<pcars.packet.TelemetryPacket object at 0x7f0f9497eb38>
<pcars.packet.TelemetryPacket object at 0x7f0f949f96d8>

ghost avatar Apr 25 '18 09:04 ghost

Hi I know its an old post, but im hoping you can help me. Im very new to python could I ask if you could just place one piece of example code to demonstrate the syntax within the handlepacket method? Ive tried to call upon other class/method examples from google but for some reason I cant seem to get it right. I understand I can call the relevant data just like a dict method, but I dont understand how i can call the required field example ['speed'].

Meganoodle avatar May 12 '20 23:05 Meganoodle

Hi I know its an old post, but im hoping you can help me. Im very new to python could I ask if you could just place one piece of example code to demonstrate the syntax within the handlepacket method? Ive tried to call upon other class/method examples from google but for some reason I cant seem to get it right. I understand I can call the relevant data just like a dict method, but I dont understand how i can call the required field example ['speed'].

Iam away from my computer now, but I'm almost sure that you can see the separate fields in packet.py. There, the code run to assign different values to the dictionary-like object can be seen so, essentially, look carefully and you'll see that all relevant keys are there.

AlexandrePiccini avatar May 13 '20 10:05 AlexandrePiccini

I understand where to get the id tags from but what I need to know is how to apply that within the code. I have a fair knowledge of programming in other languages, but im very new to python and havent got to grips with the object /class system.

The example shows where to put the code but there is no example for the line to retrieve the data.

I thats what I need , I believe thats what the op for this post was looking for originally. I just need one sample so I can apply that syntax for the rest of the information i need.

Meganoodle avatar May 13 '20 12:05 Meganoodle

@Meganoodle I get what you mean. Well, this is a very simple example I did when I had some free time a while ago, but it's very poorly written and very silly. It should only copy the vehicle speed into a separate variable and print at the console that it received data. Bear in mind also I'm copying pasting bits of code that were together with a work-in-progress GUI application, so there might be a hiccup here and there, but all in all, you should be able to run it just fine.

from pcars.stream import PCarsStreamReceiver
import time
import math
import sys
from enum import Enum


class PacketTypeID(Enum):
	eCarPhysics = 0
	eRaceDefinition = 1
	eParticipants = 2
	eTimings = 3
	eGameState = 4
	eWeatherState = 5
	eVehicleNames = 6 #//not sent at the moment
	eTimeStats = 7
	eParticipantVehicleNames = 8

class MyPCarsListener(object):
    
    def __init__(self):
        self.packcount = 0
    
    
    def handlePacket(self, data):
        self.data = data
        self.packcount += 1
        
        if data.packetType == PacketTypeID.eCarPhysics.value:
            # Prints speed
            s = self.data['speed']
            
            # Timestamp
            now = time.time()
            nowgm = time.gmtime(now)
            msecs = (now - math.floor(now))
            secs = round(nowgm.tm_sec + msecs, 5)
            srt2print = f'[{nowgm.tm_hour}:{nowgm.tm_min}:{secs}] Packet = {self.packcount} // Speed =  {s}'
            print(str2print)
            
        # Termination condition
        if self.packcount > 100:
            sys.exit(app.exec_())



listener = MyPCarsListener()
stream = PCarsStreamReceiver()
stream.addListener(listener)
print(f'[SETUP] Listener active.')
stream.run()

AlexandrePiccini avatar May 13 '20 22:05 AlexandrePiccini

runfile('C:/Users/LEE/Desktop/pc2telemetry/pcars test.py', wdir='C:/Users/LEE/Desktop/pc2telemetry') [SETUP] Listener active. ValueError: 6 is not a valid GameState

Thanks for the information but still seem to have problems with it. Im getting similar errors to what I was getting before , but I assumed it was my lack of understanding of the library.I tried your code and this is what i got.(see above)

Ive kind of found a raw and dirty method of plucking the info from the stream , Im gonn try that for now to see how that works.

Thanks again, Ill keep my eyes open on this project incase theres any further developement .

Meganoodle avatar May 14 '20 16:05 Meganoodle