PDA

View Full Version : [HowTo] Companion App - UDP Streaming



Pages : 1 2 3 4 5 [6]

pjrblue
30-04-2016, 11:37
I think the problem is Wireless vs Cable, but don't know why.

The first day I tested using the PS4, yesterday tested on X1 and today tested first with the X1 and then PS4.

I have both consoles cable connected to the internet router, X1 game is digital, PS4 game is physical.
My PC desktop and Laptop are both running windows 10 x64 and office 2010 x32, desktop cable connected to the internet router and the laptop connected wireless to the same router.
Using the laptop I could get the data and using the desktop I think (not sure) I got one in more than an hour of test.

Using the X1 I got an error:


Run-time error '6': Overflow
line 211 in Function UTF8_Decode(ByVal sStr As String) on X1, I think the X1 is not using the UTF-8 code (see post: http://forum.projectcarsgame.com/showthread.php?40113-HowTo-Companion-App-UDP-Streaming&p=1224757&viewfull=1#post1224757).


I'm testing right now, but I'm not receiving the packet 2, only packet 1 ... but is better than none ;)

Chawabax
30-04-2016, 12:46
I think the problem is Wireless vs Cable, but don't know why.

yes, can be.... but don't know why too :D :D :D


I think the X1 is not using the UTF-8 code

thanks! was not aware of this because I was not planning to make something usable by everyone but.... I will find a solution even for this


I'm testing right now, but I'm not receiving the packet 2, only packet 1 ... but is better than none ;)

absolutely yes!!!!!
Console players need only 16 drivers data, no more because of online limitations
PC players have already some alternative solution for time monitor or race overlay... only sad console players does not :cool:

pjrblue
30-04-2016, 18:38
Problem solved, but you will need some work.

I updated the DLL with another function and variables.

DLL


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace ClassTest4Excel
{
public class Class1
{
private const int listenPort = 5606;

public string returnDateTime()
{
//only for DLL test
DateTime dt = DateTime.Now;

return
dt.Year.ToString() + "/" +
dt.Month.ToString() + "/" +
dt.Day.ToString() + " - " +
dt.Hour.ToString() + ":" +
dt.Minute.ToString();
}

public byte[] returnByte()
{
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);

try
{
byte[] bytes = listener.Receive(ref groupEP);
listener.Close();
return bytes;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
listener.Close();
}
return null;
}

Thread thread;
public byte[] bytes;
public bool started = false;
public bool byteHaveData = false;
public void startUDP()
{
thread = new Thread(threadUDP); // Kick off a new thread
thread.Start();
started = true;
}
public void stopUDP()
{
thread.Abort();
started = false;
byteHaveData = false;
}

private void threadUDP()
{
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);

while (true)
{
try
{
bytes = listener.Receive(ref groupEP);
byteHaveData = true;
Thread.Sleep(25);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
}


But with this method you will need to do some modifications to the VBA code. Also you have an error in the packet 2, it will fail the UTF8 (I edited the line so I could run the code: Drvs_ListAdd.sName(I) = "NONE")

What modification I made to run:


...
'start UDP
Dim bool As Boolean
bool = objImport.startUDP()
started = True

Do While ReadUDP_Endless

'Read data from UDP
If objImport.byteHaveData = False Then GoTo FastLoop
bytes = objImport.bytes
...

You can download the DLL/TLB from this link: https://dl.dropboxusercontent.com/u/3713969/ClassTest4Excel_v2.zip

The DLL is a new one, done in a different VS Studio. You will need to copy all the data to a new Excel file so you can use it.

public byte[] bytes; <- what you need :)
public bool started = false; <- to know if startUDP is running
public bool byteHaveData = false; <- to know if bytes have information
public void startUDP() <- to start the thread
public void stopUDP() <- to stop the thread

Edit: Also the stop function will stop, but you start again the excel will crash.
This will need more work to do a functional start ... stop.

I'm doing some tests, I will update you with the results.

https://dl.dropboxusercontent.com/u/3713969/print_excel.jpg

Chawabax
30-04-2016, 19:17
You can download the DLL/TLB from this link: https://dl.dropboxusercontent.com/u/3713969/ClassTest4Excel_v2.zip

Thanks a lot, really !

I downloaded the ZIP file but I found inside the .PDB file and not the .TLB

pjrblue
30-04-2016, 19:26
Thanks a lot, really !

I downloaded the ZIP file but I found inside the .PDB file and not the .TLB

Updated: https://www.dropbox.com/s/6tgy14hwxasnsxh/ClassTest4Excel_v2.zip?dl=1, sorry :(

What I made to make your code work with this modification:


Global objImport As ClassTest4Excel.Class1
Global started As Boolean
Global bytes() As Byte
Global IN_maxbytes As Integer
Global IN_byte As Integer
Global IN_value As Integer
Global I, J As Integer
Global Driver_Name As String
Global Driver_FastLap As Single
Global Drvs_List(32) As sParticipantInfo
Global Drvs_FLap As sParticipantInfoStrings
Global Drvs_ListAdd As sParticipantInfoStringsAdditional
Global Drvs_AggrSorted(32) As xParticipantInfo
Global DrvsNames_Found As Boolean
Global Packets As Long

Private Sub Workbook_Open()
started = False
End Sub

Sub Stop_ReadUDP_Cont()

If Not (started) Then Exit Sub

'Dim bool As Boolean
'bool = objImport.stopUDP()
ReadUDP_Endless = False
Worksheets("RACE").Cells(9, 14).Value = "STOPPED" 'only for visual info
DoEvents
End Sub




Sub ReadUDP_Cont()
'Read data from UDP, endless
Dim bool As Boolean

If Not (started) Then
Set objImport = New ClassTest4Excel.Class1

DrvsNames_Found = False
Packets = 0

'Clear data on screen
Range("A2:M33").Select
Selection.ClearContents
Range("A1").Select
End If

'start UDP
bool = objImport.startUDP()
started = True

Do While ReadUDP_Endless
... / ...
Loop

End Sub


There is still an error I couldn't correct, when we stop for the first time and (re)start the sub, it gives me an error. I select debug and then run the code using the play button, and it runs. After this we can stop and start the required times and it don't fails again.

Chawabax
30-04-2016, 19:33
Updated: https://dl.dropboxusercontent.com/u/3713969/ClassTest4Excel_v2.zip, sorry :(

grazie !

I want to show you what I was able to show yesterday to our youtube viewers, during a live coverage, with your big big help !!

http://i64.tinypic.com/4470p.jpg

as soon as this "packet 1" problem will be solved, I will share this excel file

pjrblue
30-04-2016, 19:51
I discovered a strange behavior in your code, if you replace the 12 lines that have <= ""> with <= " ">, the code runs a lot faster.

Edit: the lines <Driver_Name = ""> keep the same.

Chawabax
02-05-2016, 14:37
This is for the game software developers.

Is it possible to have a byte, in the UDP streaming, saying which driver is pointed in the spectator view?

This would help automatic data overlay during live coverage

oscarolim
02-05-2016, 20:12
Doesn't the sViewedParticipantIndex get updated with that information?

Chawabax
03-05-2016, 07:32
Doesn't the sViewedParticipantIndex get updated with that information?

Thanks, I will check... I was giving a different meaning to this parameter (index of the player sending UDP data)

EDIT: it works!! spasibo :victorious:


(NOTE) valide at least for my PS4.
Just to take care about this: sViewedParticipantIndex is not exactly the same index used in drivers info like ParticipantInfo, you must add "1".

ParticipantInfo(sViewedParticipantIndex+1) ---> infos about the driver viewed

mr_belowski
05-05-2016, 12:35
(NOTE) valide at least for my PS4.
Just to take care about this: sViewedParticipantIndex is not exactly the same index used in drivers info like ParticipantInfo, you must add "1".

ParticipantInfo(sViewedParticipantIndex+1) ---> infos about the driver viewed


Really? That's really really weird and sounds like a particularly nasty bug

cjorgens79
05-05-2016, 12:49
Just to take care about this: sViewedParticipantIndex is not exactly the same index used in drivers info like ParticipantInfo, you must add "1".

ParticipantInfo(sViewedParticipantIndex+1) ---> infos about the driver viewed

That's a misleading statement. Your probably just needing to add 1 because the language you are using to process the participant array probably has array indexes starting at 1 and not 0. In C/C++ arrays start at index 0, the participant index is relative to 0 being the first, in some other languages (Lua for example) arrays start at index 1 so you would need to do +1 to the participant index if you are then using it to access the array element in that language.

mr_belowski
05-05-2016, 12:50
Hope you're right there cjorgens :)

pjrblue
05-05-2016, 13:27
That's a misleading statement. Your probably just needing to add 1 because the language you are using to process the participant array probably has array indexes starting at 1 and not 0. In C/C++ arrays start at index 0, the participant index is relative to 0 being the first, in some other languages (Lua for example) arrays start at index 1 so you would need to do +1 to the participant index if you are then using it to access the array element in that language.

He is using VBA. The cycle starts with 1 so your information is correct, no problem with the index.


For I = 1 To 32

mr_belowski
05-05-2016, 13:49
phew :)

Chawabax
06-05-2016, 07:28
He is using VBA. The cycle starts with 1 so your information is correct, no problem with the index.


For I = 1 To 32


HI HI, yes... I was the "nusty bug" here :D

It is not a question of using VBA. I'm storing infos about drivers starting from 1, as pjrblue correctly stated, because I'm used to do in this way.
But driver index starts from "0" so I have do "add 1"
Even VBA has arrays with index starting from "0".... my mind not :D

I apologize for the false info

Chawabax
18-05-2016, 12:04
When a driver is in the pits?

I use sCurrentLapDistance parameter, checking if it changes or not, but sSector doesn't help me so much to choose if the driver is in the pits or not (sometimes I have s=1, sometimes s=3).
Maybe better to use sWorldPosition to avoid false positives, since the distance is rounded to [m], but still if a driver is really not moving outside of the pits in sector 1, I'm not able to say where exactly he is.

Yes, of course, knowing the map of the circuit I can tell where he is, but.... no other trick or solution?

mr_belowski
18-05-2016, 12:11
I use world position to trigger pit entry / exit logic. I collected up the postions manually but you're welcome to use my data - its in my github repo

Seubi42
23-05-2016, 12:08
Hi Guys,

I'm working on a OBS plugin for qualifications overlays.

Do you know if someone shared a C# implementation of am UDP server which parse binary data to a clean structure or class ? (Like MikeyTT for shared memory version).
I did not find something like that un forums but maybe i'm wrong... If it can help i will share my work when I be ready.


Thanks,

mr_belowski
23-05-2016, 12:12
The crew chief code is open source. I use this: https://github.com/mrbelowski/CrewChiefV4/blob/master/CrewChiefV4/PCars/PCarsUDPreader.cs to map the UDP stream to this struct: https://github.com/mrbelowski/CrewChiefV4/blob/master/CrewChiefV4/PCars/PCarsUDPTelemetryDataStruct.cs

Seubi42
23-05-2016, 12:24
The crew chief code is open source. I use this: https://github.com/mrbelowski/CrewChiefV4/blob/master/CrewChiefV4/PCars/PCarsUDPreader.cs to map the UDP stream to this struct: https://github.com/mrbelowski/CrewChiefV4/blob/master/CrewChiefV4/PCars/PCarsUDPTelemetryDataStruct.cs

Nice ! Good news ! Thanks for this info :)

MisterO
23-05-2016, 18:34
I guess so far no one has tried to receive and do something usefull with the data in Javascript?

bvillersjr
24-05-2016, 08:18
Suspension travel and velocity do not appear to be in the MMF version. What are the units for these please?

Chawabax
01-06-2016, 16:29
I found a strange behaviour of parameter "sTrackLocation" and I'm not able to find an explanation

If I play in Barcelona, sTrackLocation="Circuit of Barcelona...." OK
If I play in Sakitto after Barcelona, sTrackLocation="Sakitto of Barcelona..." :confused:
same if I play in Sakitto after Spa, sTrackLocation="Sakitto of Francorchamps..." or something similar :confused:

never "Sakitto"

It seems like I'm missing a separator char after Sakitto, or sTrackLocation=Name+Specification where "Specification" doesn't change, doesn't erase to "none"

oscarolim
01-06-2016, 16:32
You need to look for the NULL character and truncate the string there. After the NULL is 'garbage' from previous broadcasts.
Same for any other string in the packets.

mr_belowski
04-06-2016, 20:28
Guys, anyone been able to use the

f32 sLastSectorTime;

slot of the participant info? Was looking at it today and it's always the same 4 bytes (0, 0, 192, 246 or something - converted to float it's always -123 for each participant all the time)

Am I being thick? I frequently am :)

cjorgens79
05-06-2016, 04:36
Guys, anyone been able to use the

f32 sLastSectorTime;

slot of the participant info? Was looking at it today and it's always the same 4 bytes (0, 0, 192, 246 or something - converted to float it's always -123 for each participant all the time)

Am I being thick? I frequently am :)

Yeah I use it heavily, my entire F1 style live timing screen runs completely off it, so it definitely works.

From memory it is -123 when there is no value for it yet. So just ignore it until its > 0

Zalex
05-06-2016, 05:37
Great job!
I'm also learning programming from scratch, but I started with Python 3. Here's the code I wrote to get info from the game.


#!/usr/bin/env python3

from socket import *

s=socket(AF_INET,SOCK_DGRAM)
s.bind((' ',5606))
msg=s.recvfrom(2048)
print(msg[0])




Stop teasing me, where is the other part of the code ?!? :)

Is it only for PC over a client/server app or it could work grabing info from game on a tablet from a console ???

Also want to do a usefull app and have no clue on how to start coding it. lol
I'm a HW guy, just did a few scripts about 13 years ago, so i'm quite lost. :)

mr_belowski
05-06-2016, 08:33
Thanks cjorgens. I spotted my mistake - I wasnt skipping bytes 12 and 13 (which are always zero)

mr_belowski
05-06-2016, 14:11
gah, that's complete nonsense isn't it. I think I'm looking in the right place - bytes 12, 13, 14 and 15 (zero indexed) of the participant should be a float which is the lastSectorTime. But it's *always* -123 for me - the bytes always being 0, 0, 246 and 194

mr_belowski
05-06-2016, 15:05
Doh, it *does* start showing 'proper' data, but only on the second lap :) Phew, had me worried for a bit there :)

Chawabax
14-06-2016, 09:40
QUESTION: if I play Project CARS on PC, what about UDP data streaming? Is the same PC able to read UDP streaming?

cjorgens79
14-06-2016, 09:45
QUESTION: if I play Project CARS on PC, what about UDP data streaming? Is the same PC able to read UDP streaming?

yes

Chawabax
14-06-2016, 10:07
yes

spasibo :o

oscarolim
14-06-2016, 21:26
yes

Isn't that dependent on the network hardware? I've seen several people having issues with getting the UDP packets on the same machine as the game is run.

cjorgens79
15-06-2016, 11:42
Isn't that dependent on the network hardware? I've seen several people having issues with getting the UDP packets on the same machine as the game is run.

i guess its possible with certain hardware or settings, but I've not had a single person using my app on PC have an issue. It might be quite rare.

Chawabax
18-06-2016, 11:43
Today I tried to use my Excel app with a replay and was not working.

Only drivers ranking was quite good (sometimes giving funny positions, then going back to the right ones after a while) but no data about lap number and timings... no sector times, no best lap
Have to say that this is coherent with what I see during the replay: no data at all on video

Before starting deeper investigating... is this something related to the replay? or to this particulare replay?

oscarolim
19-06-2016, 07:37
i guess its possible with certain hardware or settings, but I've not had a single person using my app on PC have an issue. It might be quite rare.

It seems is a UWP limitation after all (as I am using DatagramSocket: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/DatagramSocket)

Note Network communications using an IP loopback address cannot normally be used for interprocess communication between a Universal Windows Platform (UWP) app and a different process (a different UWP app or a desktop app) because this is restricted by network isolation. Network communication using an IP loopback address is allowed within the same process for communication purposes in a UWP app. For more information, see How to set network capabilities

I wonder if anyone has come across this issue in UWP and found an alternative (not necessarily with PCars) that could be used.

cjorgens79
19-06-2016, 11:34
It seems is a UWP limitation after all (as I am using DatagramSocket: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/DatagramSocket)


I wonder if anyone has come across this issue in UWP and found an alternative (not necessarily with PCars) that could be used.

ah fair enough, i had heard of that limitation when i looked into UWP myself a while ago.

oscarolim
20-06-2016, 09:00
I need to install redstone on a VM and see if the limitation still exists. I know they are refining quite a lot, so hopefully they will remove this limitation as well.

SenorPez
04-07-2016, 18:02
So this is going to sound like a ridiculous question, given that I've already committed thousands of lines of code to the Project CARS Replay Enhancer, but here we go.

Is there a way to determine the amount of time, in race, that has elapsed between two given UDP packets?

Let me elaborate:

I'm assuming (and looking at the data descriptors, am probably right?) that there's no timing information included in mCount. I typically use that only to ensure the packets are read in the correct order (since UDP doesn't guarantee in-order delivery).
During the race, I use sCurrentTime to calculate the total elapsed time in the race.
However, the problem I'm finding is that once the "viewed car," (usually mine) finishes the race, sCurrentTime stops incrementing; it's frozen. In single-player, this is actually not a big deal, since the replay ends when the player's car finishes. For multiplayer, however, it means data stops being useful after the viewed car. Additionally, I've kind of gone... way too far... down a rabbit hole in my 0.4 development: I want to process and render the enhanced replay on a packet-stream, instead of loading the entire telemetry collection into memory (which makes doing anything like a 24-hour race impossible), but am finding that having a viewport of 2-3 packets instead of 2000-3000 packets makes things difficult!


I'm thinking the answer is no, and if this is the case, has anyone good strategies to work around it?

Zalex
30-07-2016, 16:32
I will try this later.

My android app: 4Sim Racing 2nd Screen, is currently on google play in open beta.
If anyone would like to try it and give feedback I appreciated.

link for the beta version: https://play.google.com/apps/testing/com.project.projectcars_secondscreen

video for config file: https://www.youtube.com/watch?v=CYxKiNpAJSY

Hi pjrblue,

nice app, but tablet version seem to be ported from cell version as is, no scaling to fit biger/higher resolution screens, so it look a bit silly.

Cell version is really nice tought, do you plan to make a version to fit tablet screens anytime soon ?
i'dd be happy to beta test it. :)

I dont have an android cell, so i'll pass if there is no tablet version coming.

pjrblue
01-08-2016, 07:39
Hi pjrblue,

nice app, but tablet version seem to be ported from cell version as is, no scaling to fit biger/higher resolution screens, so it look a bit silly.

Cell version is really nice tought, do you plan to make a version to fit tablet screens anytime soon ?
i'dd be happy to beta test it. :)

I dont have an android cell, so i'll pass if there is no tablet version coming.

Thanks.

Perhaps in my vacations (almost there) I get some time to upgrade that version and release it.

slow_burn
19-10-2016, 08:21
Dear all, I'm after some help. I'm writing a basic UDP reader in VS2015 and c#. I've managed to figure out whether a particular sector is ahead of your pb, but I'm searching for a property that shows the instant lap delta against your pb. The only things that look likely are mSplitTimeAhead, mSplitTimeBehind and mSplitTime but these just read -1,-1,0 when you're in Time Trial Mode. I'm positive it can be done because it looks like VRHive and Z Dash show it.

Any help greatly appreciated.
Thanks

oscarolim
19-10-2016, 13:57
You need to calculate that value. You have the current lap time and the personal best, as well as the track position. So with all this you can interpolate what is the current live delta.

slow_burn
19-10-2016, 15:28
Wow, I'm not sure how that's possible to do with any accuracy without having pre-stored a full list of the fastest lap's track position and times, and even then you'd have to take into account different driving lines, but obviously better men than me have done it.

oscarolim
19-10-2016, 20:19
No, you don't use the world position, but the track position.
It gives you how many meters into the lap you are. So as a basic example::
0 meters - 0 seconds
1 meter - 0.1 seconds
2 meters - 0.2 seconds
Etc.
Now that you have the two way map of lap position - time for the fastest lap, you check the current lap time and position against that map of values and get the live diference.

jimmyb_84
11-11-2016, 16:19
Problem solved, but you will need some work.

I updated the DLL with another function and variables.

DLL


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace ClassTest4Excel
{
public class Class1
{
private const int listenPort = 5606;

public string returnDateTime()
{
//only for DLL test
DateTime dt = DateTime.Now;

return
dt.Year.ToString() + "/" +
dt.Month.ToString() + "/" +
dt.Day.ToString() + " - " +
dt.Hour.ToString() + ":" +
dt.Minute.ToString();
}

public byte[] returnByte()
{
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);

try
{
byte[] bytes = listener.Receive(ref groupEP);
listener.Close();
return bytes;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
listener.Close();
}
return null;
}

Thread thread;
public byte[] bytes;
public bool started = false;
public bool byteHaveData = false;
public void startUDP()
{
thread = new Thread(threadUDP); // Kick off a new thread
thread.Start();
started = true;
}
public void stopUDP()
{
thread.Abort();
started = false;
byteHaveData = false;
}

private void threadUDP()
{
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);

while (true)
{
try
{
bytes = listener.Receive(ref groupEP);
byteHaveData = true;
Thread.Sleep(25);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
}


But with this method you will need to do some modifications to the VBA code. Also you have an error in the packet 2, it will fail the UTF8 (I edited the line so I could run the code: Drvs_ListAdd.sName(I) = "NONE")

What modification I made to run:


...
'start UDP
Dim bool As Boolean
bool = objImport.startUDP()
started = True

Do While ReadUDP_Endless

'Read data from UDP
If objImport.byteHaveData = False Then GoTo FastLoop
bytes = objImport.bytes
...

You can download the DLL/TLB from this link: https://dl.dropboxusercontent.com/u/3713969/ClassTest4Excel_v2.zip

The DLL is a new one, done in a different VS Studio. You will need to copy all the data to a new Excel file so you can use it.

public byte[] bytes; <- what you need :)
public bool started = false; <- to know if startUDP is running
public bool byteHaveData = false; <- to know if bytes have information
public void startUDP() <- to start the thread
public void stopUDP() <- to stop the thread

Edit: Also the stop function will stop, but you start again the excel will crash.
This will need more work to do a functional start ... stop.

I'm doing some tests, I will update you with the results.

https://dl.dropboxusercontent.com/u/3713969/print_excel.jpg

This is amazing stuff, I may try and get the data into my Strategy calculator (link in dig) for live strategy updates, the possibilities are endless.

I've also re-started work on my ios app with the same goal unfortunately apple have decided to change swift versions and some of my code no longer works :(

androidslide
23-12-2016, 16:29
Took a couple of days to get this going - I think the original docs need to explain more about how to split some of the bytes.
e.g. no: gears vs current gear - did I miss something in the docs or do you need to read high and low bytes etc.

shdwprince
24-12-2016, 01:40
I have a problem - UDP interval issues on PS4:

If I select UDP 9 packets come in expected 1000ms interval:
Got packet in 1.019075047969818 sock wait 1.018985998630524
where sock wait is the time recvfrom took to get the packet.

UDP 8 works as expected too:
Got packet in 0.204603016376495 sock wait 0.203256011009216

However, starting with UDP 7 time start to behave strangely:
Got packet in 0.0118889808654785 sock wait 0.0117020010948181
We can see that recvfrom only took 11ms to receive packet, instead of expected 100ms.

It seems that 11ms is absolute minimum latency in my network, because changing UDP to anything lower results in exact same numbers. Needless to say that data comes with ever-increasing delay.

Am I doing something wrong? Code is fairly simple, and works flawlessly with Codemasters games.

Update: it's something with my network. If I connect a device directly to PS4 packets being sent as expected.

StryderIT
02-01-2017, 19:45
I have noticed something like you describe too, but on the PC.
I'm using a Fritzbox, and the PC is connected with a LAN cable. The data delay increases (I saw 30 seconds and more, you can verify that when you check the laps counter in the telemetry data after you passed the start / finish line).
When the pc and the second device is connected through an android mobile hotspot I have absolutely no delay. So it seems, that in my case the Fritzbox is causing the delay. Maybe some flood protection or just a slow packet handling.

tiago.vt
03-01-2017, 16:26
How I convert char sName[16][64]; Using java ?

I got convert :// Car state
s16 sOilTempCelsius; // 100
u16 sOilPressureKPa; // 102
s16 sWaterTempCelsius; // 104
u16 sWaterPressureKpa; // 106
u16 sFuelPressureKpa; // 108
u8 sCarFlags; // 110
u8 sFuelCapacity; // 111
u8 sBrake; // 112
u8 sThrottle; // 113
u8 sClutch; // 114
s8 sSteering; // 115
f32 sFuelLevel; // 116
f32 sSpeed; // 120
u16 sRpm; // 124
u16 sMaxRpm; // 126
u8 sGearNumGears; // 128

But I don't convert struct sParticipantInfoStrings, sParticipantInfoStringsAdditional.

onaromv
19-01-2017, 01:54
Hello all good day. I'm trying to write a program for PC using C++. I'm using ADDR_ANY, 5606 when binding. I'm having problems when receiving the data. The size I'm receiving is 1367, should be right. But the data is all rubbish. I've set the UDP setting to 4. Am I'm missing something?

pjrblue
20-01-2017, 11:04
Hello all good day. I'm trying to write a program for PC using C++. I'm using ADDR_ANY, 5606 when binding. I'm having problems when receiving the data. The size I'm receiving is 1367, should be right. But the data is all rubbish. I've set the UDP setting to 4. Am I'm missing something?

The data you receive contains a lot of data in a sequence form (byte[] array), rubbish like you write.
You need to use the info from the first post to interpret the data, see "The data structure is as follows".

Chawabax
08-06-2017, 12:28
Does anyone know UDP specs for Project CARS 2?

vince34750
11-10-2017, 19:46
Now we have UDP available on PS4, which has also legacy PC1 format, could we get some info on the new UDP format ? Maybe I missed it, but it is not discussed a lot. I do not see the point of providing a new format if no one can use it.
Cheers,
Vincent

cjorgens79
12-10-2017, 09:50
Now we have UDP available on PS4, which has also legacy PC1 format, could we get some info on the new UDP format ? Maybe I missed it, but it is not discussed a lot. I do not see the point of providing a new format if no one can use it.
Cheers,
Vincent

The PCARS2 UDP protocol is unfinished which is why there are no officially released specs.

anma
01-01-2018, 18:23
Hi,
does anybody know how to get pitch, roll, yaw and surge, sway, heave acceleration and traction loss from UDP streaming? Does a reference implementation exist?

BR

leroythelegend
31-01-2018, 12:32
Hi,
does anybody know how to get pitch, roll, yaw and surge, sway, heave acceleration and traction loss from UDP streaming? Does a reference implementation exist?

BR

I created a cpp set of classes to work with project cars udp format 1, only recently uploaded to GitHub so still work in progress.
https://github.com/leroythelegend/rough_idea_project_cars

Killg0re NL
27-12-2018, 20:40
i am working on an Arduino ESP32 (WiFi) Solution for the PS4.

i got ABS, TCS, ESP, Light, Track/Ambient/Engine-Temperature, Fuel Capacity and Gear working, but i can't seem to get grip on the fuelLevel, RPM and Speed.

Are there any other players still working on Arduino and dashboard options?
especially on a completer WiFi solution. (so NOT feeded through an Windows application)

cjorgens79
28-12-2018, 00:28
i am working on an Arduino ESP32 (WiFi) Solution for the PS4.

i got ABS, TCS, ESP, Light, Track/Ambient/Engine-Temperature, Fuel Capacity and Gear working, but i can't seem to get grip on the fuelLevel, RPM and Speed.

Are there any other players still working on Arduino and dashboard options?
especially on a completer WiFi solution. (so NOT feeded through an Windows application)

Fuel level is the ratio (0 - 1) fill of the tank, so just multiply with total fuel capacity.
Speed is in meters per sec, so just multiply it out to km/h or mph
RPM is just rpm, nothing to change with that. If you are getting weird values then check that you have all the prior fields mapped correctly and that your structure padding is correct.

Killg0re NL
28-12-2018, 13:58
Fuel level is the ratio (0 - 1) fill of the tank, so just multiply with total fuel capacity.
i'll start with this one...


If you are getting weird values then check that you have all the prior fields mapped correctly and that your structure padding is correct.
But this seems to be the main problem, cause, i get 89L as a capacity, (packetbuffer 111)


float FuelLevel; // 13 // 116

The amount of fuel should be in packetbuffer 116, so displaying this should get me a value ranging from 0 to 1 so:
But i get value's from 0 to 220


FuelLevel = (bitRead(packetBuffer[116], 0)) * (FuelCapacity); should have gotten me the actual fuel Level.

But it seems my knowledge stops here....

And whats with the different FuelLevels? such as:



packetBuffer[116]; // FuelLevel 1st
packetBuffer[117]; // FuelLevel 2nd
packetBuffer[118]; // FuelLevel 3rd
packetBuffer[119]; // FuelLevel 4th

cjorgens79
29-12-2018, 00:38
But this seems to be the main problem, cause, i get 89L as a capacity, (packetbuffer 111)

The amount of fuel should be in packetbuffer 116, so displaying this should get me a value ranging from 0 to 1 so:
But i get value's from 0 to 220

should have gotten me the actual fuel Level.

But it seems my knowledge stops here....

And whats with the different FuelLevels? such as:

89L sounds right, that is an 8 bit value so you cant really go wrong reading that one.
Fuel level is a FLOAT (which is 32 bit, hence 4 bytes), so you need to actually read it as a float. Your language should have a function to read as float and that will give you the value you expect. You will get a floating point value between 0 and 1 and everything in between (eg 0.3345) would be a valid result.

Killg0re NL
01-01-2019, 20:40
FuelLevel = (bitRead(packetBuffer[116], 0) << 24 | bitRead(packetBuffer[117], 0) & 0xff << 16 | bitRead(packetBuffer[118], 0) & 0xff << 8 | bitRead(packetBuffer[119], 0) & 0xff << 0);
Serial.print("Fuel level : "); Serial.print(FuelLevel); Serial.print(" / "); Serial.print(FuelCapacity); Serial.println(" L "); Serial.println(" ");


Still stuck at this... grrr any one got a clue what i am missing here?
Thought when i get one float, setting working, it opens the road to other data, but the road remains closed for now...

ps, with this code i am expecting a value ranging from 0 to 1. (so not multiplied by the fuelcapacity yet)

Is there a way i can check if the packetbuffers are ok?

ie. when i put in 10 Litres of fuel what should i expect on the 1, 2, 3 and 4th fuel Byte? :


Serial.print("Packetbuffer 116: "); Serial.println(packetBuffer[116]);
Serial.print("Packetbuffer 117: "); Serial.println(packetBuffer[117]);
Serial.print("Packetbuffer 118: "); Serial.println(packetBuffer[118]);
Serial.print("Packetbuffer 119: "); Serial.println(packetBuffer[119]);

cjorgens79
02-01-2019, 01:14
Still stuck at this... grrr any one got a clue what i am missing here?
Thought when i get one float, setting working, it opens the road to other data, but the road remains closed for now...

ps, with this code i am expecting a value ranging from 0 to 1. (so not multiplied by the fuelcapacity yet)

Is there a way i can check if the packetbuffers are ok?

ie. when i put in 10 Litres of fuel what should i expect on the 1, 2, 3 and 4th fuel Byte? :

Your issue is that you still aren't reading it as a float. What you have shown in your example is reading it as an int32 which is not the same as a float (which is also 32 bit). If the language you are using does not have specific readers for float values (or sometimes called Single), then it is possible to extract out each byte (like you have attempted) and convert it to a float. The 32 bits contain a sign, exponent and mantissa that need to be decoded into the resulting float value. https://blog.penjee.com/binary-numbers-floating-point-conversion/

Most languages will have the ability to directly read data from a byte stream/buffer as a float, int32, etc as required, so its possibly there is an easy way for you to do it if you use the right functions in whatever language it is you are using.

Killg0re NL
10-01-2019, 19:25
Sorted in the mean time:

I got the Corvette C7R as a car
FuelCapacity is 89L, and i got 40L in the tuning setup.
After starting the practise session i turned the engine of. (the ingame fuellevel is 40L)

This is what i get from serial printing the next:


Fuel level (FL) : 111110111001100001011001010110
Fuel level : 40.00
119 : 111110
118 : 11100110
117 : 10110
116 : 1010110



This is the used code for reading the packets 119, 118, 117 and 116:

uint32_t FL=0;
for (uint8_t i=119; i>115; i--) {
FL=FL<<8;
FL=FL+packetBuffer[i];
}
FuelLevel = FL;
memcpy(&FuelLevel, &FL, 4);
FuelLevel = FuelLevel * FuelCapacity;

The FuelLevel is declared as:


float FuelLevel; // 13 // 116

cjorgens79
11-01-2019, 00:13
Sorted in the mean time:

I got the Corvette C7R as a car
FuelCapacity is 89L, and i got 40L in the tuning setup.
After starting the practise session i turned the engine of. (the ingame fuellevel is 40L)

This is what i get from serial printing the next:


Fuel level (FL) : 111110111001100001011001010110
Fuel level : 40.00
119 : 111110
118 : 11100110
117 : 10110
116 : 1010110



This is the used code for reading the packets 119, 118, 117 and 116:

uint32_t FL=0;
for (uint8_t i=119; i>115; i--) {
FL=FL<<8;
FL=FL+packetBuffer[i];
}
FuelLevel = FL;
memcpy(&FuelLevel, &FL, 4);
FuelLevel = FuelLevel * FuelCapacity;

The FuelLevel is declared as:


float FuelLevel; // 13 // 116


That is certainly a novel way of converting to a float. Glad to hear you got it sorted.

Maskmagog
22-01-2019, 16:01
I'm trying to get my console leaderboard project (see signature) to use UDP v1 as well as UDP 2.
I'm getting almost every data I need, except for sTrackLength. I need sTrackLength to tell a few tracks apart, because of bugs in the UDP (same in v2).

It seems TrackLength was moved around during development, and it's hard to know what the correct place for it is. Right now, my code looks like this, at the end of Telemetry packet:



AmbientTemperature = binaryReader.ReadSByte();
TrackTemperature = binaryReader.ReadSByte();
RainDensity = binaryReader.ReadByte();
WindSpeed = binaryReader.ReadSByte();
WindDirectionX = binaryReader.ReadSByte();
WindDirectionY = binaryReader.ReadSByte();

for (int i = 0; i < 16; i++)
{
ParticipantInfo[i, 0] = Convert.ToDouble(binaryReader.ReadInt16()); //WorldPosition
ParticipantInfo[i, 1] = Convert.ToDouble(binaryReader.ReadInt16()); //WorldPosition
ParticipantInfo[i, 2] = Convert.ToDouble(binaryReader.ReadInt16()); //WorldPosition
ParticipantInfo[i, 3] = Convert.ToDouble(binaryReader.ReadUInt16()); //sCurrentLapDistance
ParticipantInfo[i, 4] = Convert.ToDouble(binaryReader.ReadByte()) - 128; //sRacePosition
ParticipantInfo[i, 5] = Convert.ToDouble(binaryReader.ReadByte()); //sLapsCompleted
ParticipantInfo[i, 6] = Convert.ToDouble(binaryReader.ReadByte()); //sCurrentLap
byte Sector_ALL = binaryReader.ReadByte();
var Sector_Extracted = Sector_ALL & 7;
ParticipantInfo[i, 7] = Convert.ToDouble(Sector_Extracted); //sSector
ParticipantInfo[i, 8] = Convert.ToDouble(binaryReader.ReadSingle()); //sLastSectorTime
}


TrackLength = binaryReader.ReadSingle();
//Console.WriteLine("Tracklength from PCarsUDP: " + TrackLength);
Wings[0] = binaryReader.ReadByte();
Wings[1] = binaryReader.ReadByte();
DPad = binaryReader.ReadByte();


I haven't tried all data, but for example sAmbientTemperature, sSector and sLastSectorTime works. At least for player index = 0, which is all I use.
Getting crazy, so any help is much appreciated!


EDIT: I'm using it to read data from Xbox, if that matters.

Maskmagog
22-01-2019, 16:40
Finally seem to have figured it out. Should use 56 instead of 16 in the for-loop above.

Killg0re NL
18-03-2019, 19:50
This is the used code for reading the packets 119, 118, 117 and 116:

uint32_t FL=0;
for (uint8_t i=119; i>115; i--) {
FL=FL<<8;
FL=FL+packetBuffer[i];
}
FuelLevel = FL;
memcpy(&FuelLevel, &FL, 4);
FuelLevel = FuelLevel * FuelCapacity;

The FuelLevel is declared as:


float FuelLevel; // 13 // 116


Any idea why this only works when the protocol is on Project Cars 1, on the UPD protocol Project Cars 2, it doesn't work

for the record, i got the packet who is used in PC2 32-35 (instead off 115-118)

uint32_t FL=0;
for (uint8_t i=36; i>32; i--) {
FL=FL<<8;
FL=FL+packetBuffer[i];
}
FuelLevel = FL;
memcpy(&FuelLevel, &FL, 4);
FuelLevel = FuelLevel * FuelCapacity;


And 2nd question, i use carFlags awell:


// (Type#9) Car Flags (to be used with 'mCarFlags')
enum
{
CAR_HEADLIGHT = (1<<0),
CAR_ENGINE_ACTIVE = (1<<1),
CAR_ENGINE_WARNING = (1<<2),
CAR_SPEED_LIMITER = (1<<3),
CAR_ABS = (1<<4),
CAR_HANDBRAKE = (1<<5),
CAR_STABILITY = (1<<6),
CAR_TRACTION_CONTROL = (1<<7),
};


But with UDP on project Cars 2, TCS (Bit 7) isn't working either ?? what am i missing here???

mr_belowski
18-03-2019, 19:52
There are loads of unfinished and buggy data when using pcars2 UDP protocol. I gave up with it

Fer2707
22-05-2021, 10:33
Beste heer
Ik ben sinds gisteren op dit Forum ,omdat ik sinds kort projeckt cars heb ,en er niet uitg kwam om de instellingen te veranderen , maar heb het gevond
U maakt zeer mooie dingen
Kunt u me daar meer over vertellen
Ik wil binnenkort een Playseat incl Rs3000 stuur incl pedalen kopen ,heeft u misschien wat advies
Hoor het graag
Met vriendelijke groet Fer v Asten te Valkenswaard the Nederlands