PDA

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



Pages : 1 [2] 3 4 5 6

Jussi Viljami Karjalainen
05-11-2015, 13:45
One thing that's also a possibility is running an Android emulator/virtual machine like AMIDuOS, which allows you to run any android app on a windows machine. At least AMIDuOS claims that they're running a virtual machine that's 100% native Android, so should work. There's also a 30 day free trial for it to try it out. I'm actually somewhat interested in this possibility myself. =)

TheReaper GT
05-11-2015, 14:07
One thing that's also a possibility is running an Android emulator/virtual machine like AMIDuOS, which allows you to run any android app on a windows machine. At least AMIDuOS claims that they're running a virtual machine that's 100% native Android, so should work. There's also a 30 day free trial for it to try it out. I'm actually somewhat interested in this possibility myself. =)

Sounds great. If they allow you to use your purchased content from Google play, it can be a good option. I play on xbox one but my laptop is aways around. Being able to run crew chief + vdash on a single device will be the best scenario.

Jussi Viljami Karjalainen
05-11-2015, 14:36
It should be 100% native android, just running on a virtual machine instead of a phone or a tablet. You can install google play store on it (it comes preloaded with the Amazon appstore, but they offer a link for Google's store as well), you can link it to your Google account like any normal Android device, etc.

I'm about to try out the free trial now, I'll report back.

TheReaper GT
05-11-2015, 14:45
It should be 100% native android, just running on a virtual machine instead of a phone or a tablet. You can install google play store on it (it comes preloaded with the Amazon appstore, but they offer a link for Google's store as well), you can link it to your Google account like any normal Android device, etc.

I'm about to try out the free trial now, I'll report back.

I'm testing right now and it is a very good experience... all good so far. Now is up to wait the UDP release and vDash update to test if it's gonna work...

Keithb23
05-11-2015, 15:21
Bluestacks is another good option for running an Android virtual machine. I use it to build my dashes for VDash. Much easier to edit on the big screen and it behaves exactly like the app on my tablet. You can sign in with your google account and all of your purchased apps are available.

Jussi Viljami Karjalainen
05-11-2015, 15:43
Bluestacks is another option, it was the second most common one to pop up when I searched, though from the reviews I read it seemed that AMIDuOS gets a lot better performance, has better compatibility and offers a fuller Android experience.

EDIT: Admittedly though I'm having significant amount of trouble getting the AMIDuOS running on my 2-in-1 Windows 10 machine (starts only every other time, often fails to load into android, etc.) while BlueStacks works fine. On my desktop both work fine.

Just too bad my desktop doesn't have Wi-Fi so I can't use my 2-in-1 as a dash...

TheReaper GT
05-11-2015, 15:53
I tried bluestacks before for another purpose but it's way too unstable on my laptop, keeps crashing every other minute...

diesel97
05-11-2015, 16:06
that is not cheap enough for "poorfags" like me T_T

I was looking at this:

http://www.ebay.it/itm/Tablet-Android-7-WiFi-Cobra-Wazird-TB-7-HD-Android-4-1-1-/151709541029?hash=item235297e2a5

On a second tought maybe a fire hd 7" from amazon would work well if the apps would be available as apk or on aptoide?

I would stay away from the Amazon fire line their Apps come from their store and dont play well with Google play store. Amazon has a closed system when it comes to their tablets

mjemec11
05-11-2015, 16:36
Any idea for a phone mount to put behind the wheel rim of my T300RS for MOTEC type apps? I'm planning on using my phone as a rev screen and my 10" Windows tablet for telemetry data. Maybe even run Crew Chief from my PC.

TheReaper GT
05-11-2015, 16:38
Any idea for a phone mount to put behind the wheel rim of my T300RS for MOTEC type apps? I'm planning on using my phone as a rev screen and my 10" Windows tablet for telemetry data. Maybe even run Crew Chief from my PC.

Those mounts used to secure the phone on the car windshield ?

Jussi Viljami Karjalainen
05-11-2015, 16:48
Those mounts used to secure the phone on the car windshield ?Those suction cup ones? I doubt there's enough flat space on there for one. =/

I've personally been thinking about velcro stickers.

mjemec11
05-11-2015, 17:35
Those mounts used to secure the phone on the car windshield ?

Thought about that, but I doubt the suction cup would grip on the plastic base of the T300.

ElectricBlues85
05-11-2015, 17:47
Thought about that, but I doubt the suction cup would grip on the plastic base of the T300.

I'm thinking about butchering a 'selfie stick' to mount the device I'm going to use as a MOTEC. You can also get those things similar to the car windscreen suction pads but with a clip on the end. A bit like this:

http://www.amazon.co.uk/High-grade-Construction-Hands-free-Windshield-Smartphone/dp/B00XJCLLKY/ref=sr_1_3?s=electronics&ie=UTF8&qid=1446745578&sr=1-3&keywords=phone+mount+with+clip

Edit: image for those that CBA to click the link

221478

TheReaper GT
05-11-2015, 17:49
I'm thinking about butchering a 'selfie stick' to mount the device I'm going to use as a MOTEC. You can also get those things similar to the car windscreen suction pads but with a clip on the end. A bit like this:

http://www.amazon.co.uk/High-grade-Construction-Hands-free-Windshield-Smartphone/dp/B00XJCLLKY/ref=sr_1_3?s=electronics&ie=UTF8&qid=1446745578&sr=1-3&keywords=phone+mount+with+clip

those flexible brakets must work very well. :D

diesel97
05-11-2015, 18:25
I'm thinking about butchering a 'selfie stick' to mount the device I'm going to use as a MOTEC. You can also get those things similar to the car windscreen suction pads but with a clip on the end. A bit like this:

http://www.amazon.co.uk/High-grade-Construction-Hands-free-Windshield-Smartphone/dp/B00XJCLLKY/ref=sr_1_3?s=electronics&ie=UTF8&qid=1446745578&sr=1-3&keywords=phone+mount+with+clip

Edit: image for those that CBA to click the link

221478

I have one of these a they work fine

azidahaka
05-11-2015, 18:34
I would stay away from the Amazon fire line their Apps come from their store and dont play well with Google play store. Amazon has a closed system when it comes to their tablets

Are knowledgeable in tablets? I thought of that one because they say you can easily install apk programs and it's very cheap.

Any cheap suggestion is welcome!

TheReaper GT
05-11-2015, 18:39
Are knowledgeable in tablets? I thought of that one because they say you can easily install apk programs and it's very cheap.

Any cheap suggestion is welcome!

A Samsung galaxy tab 7 or lg gpad 8 is more than enough and they are cheap...

azidahaka
05-11-2015, 19:35
A Samsung galaxy tab 7 or lg gpad 8 is more than enough and they are cheap...

Those are not cheap in my book!

the-D-
05-11-2015, 19:41
Those are not cheap in my book!

Get a different book?

KkDrummer
05-11-2015, 19:47
cheap windows 1o tablet? check this out, ridiculous! and the reviews are excellent. I am sure you can buy it in the US as well:

http://www.amazon.co.uk/Linx-1-83GHz-Quad-Core-Processor-storage/dp/B00O636WJU/ref=sr_1_12?s=computers&ie=UTF8&qid=1446752722&sr=1-12&keywords=windows+10+tablet

TheReaper GT
05-11-2015, 19:47
Those are not cheap in my book!

They are about the same price as the Amazon Fire HD, even cheaper if second hand..

Fil140
05-11-2015, 20:01
Where can i gat a copy of the book?

Fil140
05-11-2015, 20:02
Also,where can i buy thst flexi mount stick thing?

hdh
05-11-2015, 20:17
Also,where can i buy thst flexi mount stick thing?

Ebay is your friend ;)

http://pages.ebay.com/link/?nav=item.view&id=131547124057&alt=web

azidahaka
05-11-2015, 20:23
Get a different book?

Maybe a different pocket?

RomKnight
05-11-2015, 20:46
Ebay is your friend ;)

http://pages.ebay.com/link/?nav=item.view&id=131547124057&alt=web

Actually bought one of these. Mine looks just like that (from ebay too) and if this one is like mine it is tough

Tim Mann
05-11-2015, 21:58
Now, the good news or the bad news?

Bad news first. Due to me being extremely busy I was unable to get the GUI requirement (the menu option added and saving to profile) plus all the required testing stuff (Things like a doc to show QA how to use Wireshark for testing etc.) in, in time for the cut off day for additions on the next patch (which was around the same day as I got the UDP stream file working). As that file had a few errors in it (thanks to all those who tested it) I was unhappy about forcing it out without more testing (it had never yet been tested on a live network including MP, so had no idea of the impact). So it won't I'm afraid be in the November patch.....(this was my decision, so shout at me).

However....now the good news.

I prodded the physics guys the other day about 'ride height' and suspension data. They have given me a couple of values to poke at. I'm just looking at them now....looked at and added. There is 'WheelLocalPositionY(wheel)' (f32) and 'RideHeight(wheel)' (f32). These have now been added.....

Now, here's the deal, as a way of an apology. I'll give you a bit of a 'free for all' until Monday, where you can request any data you like....If I can find it and I can squeeze it into the packet somewhere then I'll add it. THIS WILL NOT EFFECT THE EXISTING SHARED MEMORY API. That will remain untouched. The main packet is currently 1093. I will add the extra precision bits encoded for the X/Y as well, so that will be 0.25M accuracy.

Once this has been done. I'll do the final packet structure and produce a new UDP.BIN (if anyone has anywhere where I can share it....) you can then test it. It will then go into QA and be enabled on the next patch.

SUBGTRACER
05-11-2015, 22:03
Thank you for update Tim and confirmation that patch 6.0 is done :) oh and that there will be a patch 7.0 also ........Keep up the good work bud we are all looking forward to this with great anticipation ....

That will give me time to get my mounting options prepped and ready for its release.

inthebagbud
05-11-2015, 22:04
Timm no apologies needed as you are providing extra to what we thought we would get and rather it be right than issued into the wild not working properly.

mjemec11
05-11-2015, 22:06
Thanks for keeping us up to date, Tim!

TheReaper GT
05-11-2015, 22:11
Tim the Mann :D

Jussi Viljami Karjalainen
05-11-2015, 22:12
Hopefully wheel local position is the same thing as travel. Ride height is nifty but unfortunately has the problem that the measurement points can be far away from the suspension so it can give you odd results (for example if front and rear compression is the same it might work perfectly, but if rear compression is larger the leverage resulting from the difference in measurement point between suspension and ride height could skew the results by several centimeters)...

Anyway, the data I'm most interested in:

-Travel, or more specifically spring and/or damper compression. The specific amount the springs/dampers compress and extend so that we can use that data to calculate suspension histograms etc. Sub-millimeter accuracy would be best, because I've already noticed that the in-game HUD's millimeter accuracy isn't really enough.
-Anything at all related to downforce & drag: Front DF, rear DF, underbody DF, total DF, downforce center of pressure, total drag, anything at all related to the aerodynamics as a whole and downforce specifically.

Data that would be great but I'm not really hopeful for because reasons:

-Car Center of Gravity height (mostly static, but changes from car to car)
-Front and rear roll center heights (dynamic as the suspension moves around)

Pappa_Stig
05-11-2015, 22:13
Now, the good news or the bad news?

Bad news first. Due to me being extremely busy I was unable to get the GUI requirement (the menu option added and saving to profile) plus all the required testing stuff (Things like a doc to show QA how to use Wireshark for testing etc.) in, in time for the cut off day for additions on the next patch (which was around the same day as I got the UDP stream file working). As that file had a few errors in it (thanks to all those who tested it) I was unhappy about forcing it out without more testing (it had never yet been tested on a live network including MP, so had no idea of the impact). So it won't I'm afraid be in the November patch.....(this was my decision, so shout at me).

However....now the good news.

I prodded the physics guys the other day about 'ride height' and suspension data. They have given me a couple of values to poke at. I'm just looking at them now....looked at and added. There is 'WheelLocalPositionY(wheel)' (f32) and 'RideHeight(wheel)' (f32). These have now been added.....

Now, here's the deal, as a way of an apology. I'll give you a bit of a 'free for all' until Monday, where you can request any data you like....If I can find it and I can squeeze it into the packet somewhere then I'll add it. THIS WILL NOT EFFECT THE EXISTING SHARED MEMORY API. That will remain untouched. The main packet is currently 1093. I will add the extra precision bits encoded for the X/Y as well, so that will be 0.25M accuracy.

Once this has been done. I'll do the final packet structure and produce a new UDP.BIN (if anyone has anywhere where I can share it....) you can then test it. It will then go into QA and be enabled on the next patch.

Thanks for the update mate, your regular updates and detailed info is hugely appreciated, and I feel confident everyone here shares this opinion with me. :)

Tim Mann
05-11-2015, 22:15
Added:

mTelemetryData.sParticipantInfo[i].sSector=((u8)pMemory->mParticipantInfo[i].mCurrentSector)|(x<<6)|(z<<4); // (enum 3 bits)+(x 2 bits, z 2 bits)->u8

Not sure who requested it now, but 0.25 precision if you decode it from there.

Tim Mann
05-11-2015, 22:22
Hopefully wheel local position is the same thing as travel. Ride height is nifty but unfortunately has the problem that the measurement points can be far away from the suspension so it can give you odd results (for example if front and rear compression is the same it might work perfectly, but if rear compression is larger the leverage resulting from the difference in measurement point between suspension and ride height could skew the results by several centimeters)...

Anyway, the data I'm most interested in:

-Travel, or more specifically spring and/or damper compression. The specific amount the springs/dampers compress and extend so that we can use that data to calculate suspension histograms etc. Sub-millimeter accuracy would be best, because I've already noticed that the in-game HUD's millimeter accuracy isn't really enough.
-Anything at all related to downforce & drag: Front DF, rear DF, underbody DF, total DF, downforce center of pressure, total drag, anything at all related to the aerodynamics as a whole and downforce specifically.

Data that would be great but I'm not really hopeful for because reasons:

-Car Center of Gravity height (mostly static, but changes from car to car)
-Front and rear roll center heights (dynamic as the suspension moves around)

I've found some things relating to some of those, I'll be nice to Steve tomorrow, he may tell me what some of them do....

Fil140
05-11-2015, 22:55
HERO!!

ElectricBlues85
05-11-2015, 22:58
Now, here's the deal, as a way of an apology. I'll give you a bit of a 'free for all' until Monday, where you can request any data you like....If I can find it and I can squeeze it into the packet somewhere then I'll add it. THIS WILL NOT EFFECT THE EXISTING SHARED MEMORY API. That will remain untouched. The main packet is currently 1093. I will add the extra precision bits encoded for the X/Y as well, so that will be 0.25M accuracy.


First of all - great work Tim, this all sounds fantastic.

I've looked through the file that is already being used and I can't see anything to do with weather forecast. I know it's not telemetry as such but would be great to see weather forecast info so I'm not having to check for pause screen.

If there is info about when weather is likely to change, what it might change to and how long for (or anything along these lines) it would great to see this in a dashboard app.

Apologies if this has already been covered and/or is already available. I've only been dipping in and out of this thread :)

Thanks again

RomKnight
05-11-2015, 23:00
The suspension stuff was what was lacking. I did hint a couple of pages ago. Finally good news today (renewed hope is more like it).

Do you need help with Steve? Because we can help :D

hdh
05-11-2015, 23:12
First of all - great work Tim, this all sounds fantastic.

I've looked through the file that is already being used and I can't see anything to do with weather forecast. I know it's not telemetry as such but would be great to see weather forecast info so I'm not having to check for pause screen.

If there is info about when weather is likely to change, what it might change to and how long for (or anything along these lines) it would great to see this in a dashboard app.

Apologies if this has already been covered and/or is already available. I've only been dipping in and out of this thread :)

Thanks again

Wouldn't it be even better to link weather info to a pit wall engineer-app? At least for realism and immersion purposes. It would also mean one less bit of visual data to keep track of while racing.

mr_belowski
05-11-2015, 23:13
ta for the extra position precision Tim :)

I'd really like to have (in order or priority...)

the currently fitted tyre compound for each car (or at the very least the player's car)
the car class of the player and the opponent cars
tyre pressures for the player (or at least 4 bits borrowed from somewhere which can be used as 'puncture' flags)
mandatory pitstop info - pit window open & close lap / time, and something about the required action (tyre type change, driver swap, or whatever it is)

ElectricBlues85
05-11-2015, 23:20
Wouldn't it be even better to link weather info to a pit wall engineer-app? At least for realism and immersion purposes. It would also mean one less bit of visual data to keep track of while racing.

Agreed but the key here is getting the info in the first place - I've no doubt the very kind and community centric app developers will give us plenty to chose from :)

pock1910
05-11-2015, 23:40
... I'll give you a bit of a 'free for all' until Monday, where you can request any data you like.... If I can find it and I can squeeze it into the packet somewhere then I'll add it. THIS WILL NOT EFFECT THE EXISTING SHARED MEMORY API. That will remain untouched.


It would be really great if ParticipantInfo can have additional data.

My favorites are: throttle, brake, speed, rpm, gear

Jussi Viljami Karjalainen
06-11-2015, 00:00
Oh oh, one thing popped up!

-Power
-Torque

These would be great because using any suitable telemetry program (pCARS Telemetry, pCARS Profiler for example) you could combine Power, Torque and RPM into a single graph and get instant power/torque curves!

Furthermore, if you could get power for each persona participating in the race, you would have an effective mechanism to check if people are adhering to engine restrictor settings. Series that run balancing for cars could check beforehand what the maximum power of a given car should be at any given restrictor setting, and during a race they could follow people who are supposed to run a restricted setup for balancing reasons and see if they're actually adhering to the rules.

RomKnight
06-11-2015, 00:05
Double like for the restrictor! could serve as "ballast" or "time penalty" in leagues ;)

transfix
06-11-2015, 01:39
Thanks for the update Tim. All the better we get a solid release for Holidays.

cjorgens79
06-11-2015, 02:01
A few requests that people have asked me to add to pCars Dash but we were lacking the info

1. Brake bias
2. Tyre Pressures
3. Aids (abs, tc, stability ctrl). We have abs already (car flag to say if its available on car), and mAntiLockActive for on/off, need same added for tc/sc
4. Kers / Drs, same as above available car flag, and on/off indicator
5. Tyre compounds front and rear (some other games api's do this as a string (ie name of compound), but if space is an issue a series of defines would also be fine)
6. Any aero data (eg F/R downforce)
7. Additional info on other participants
- bits could be added to existing field (eg sector) to indicate if particpant has abs/tc/sc available to them (1 bit per aid) to make it easier to tell who has what aids available
- timing for other participants would be fantastic to do F1 style timing screens, however i doubt there is enough space for this. There should be enough room for one f32 for timing field, it could be previous completed sector time for participant, you could then take note of each sector for a lap and calculate total lap time as we have current sector and lap already
- gap to next player would also be quite helpful, again probably not enough room, would be another f32 per participant

With regards to the participant info stucture taking up alot of space and having no room for additional fields, we could limit the structure to the actual max number of a players instead of 64. AFAIK 56 is the max at Lemans on PC, i figure consoles is probably actually lower than that.

cjorgens79
06-11-2015, 02:07
Oh one other thing that's a real pain in the arse for me is "Track Name" and "Track Variation". I use these to determine what map to display in pCars Dash, however these strings are not consistant between different languages (eg German, French etc) which means some of the maps don't work for certain language versions of Project Cars. I would either need to be given a list of all the name variations for each track for each language so i can try and deal with it, or ideally have a track ID number and track variation ID number which would obviously eliminate this issue completely as it would be consistant between all languages.

madmax2069
06-11-2015, 02:17
With regards to the participant info stucture taking up alot of space and having no room for additional fields, we could limit the structure to the actual max number of a players instead of 64. AFAIK 56 is the max at Lemans on PC, i figure consoles is probably actually lower than that.

I do know that in online races consoles are limited to 15 + 1 (#1 being you), so in online races it could open up the headroom for more data on each car (I could be wrong, unless thats already been thought of) then vs offline mode with the full max grid on console (which is less then the PC version, but more then the online Max car count on consoles).

odemode
06-11-2015, 06:20
Anyone got a suggestion for mounting an iPhone plus to a Thrustmaster Ferrari F1 add on wheel?

TheReaper GT
06-11-2015, 06:22
Anyone got a suggestion for mounting an iPhone plus to a Thrustmaster Ferrari F1 add on wheel?

Look one page back...

SUBGTRACER
06-11-2015, 06:29
Double sided tape will hold it there .

R74NN
06-11-2015, 06:52
THIS WILL NOT EFFECT THE EXISTING SHARED MEMORY API. That will remain untouched.

May I ask what is the reason for abandoning the Shared Memory API like this?

I could understand it is someone else's job to maintain it and it has nothing to do with you, Tim, but maybe you could shed a light on this issue, since no one else in SMS seems to be willing to talk about this matter.

Thanks.

azidahaka
06-11-2015, 06:59
Now, the good news or the bad news?

Bad news first. Due to me being extremely busy I was unable to get the GUI requirement (the menu option added and saving to profile) plus all the required testing stuff (Things like a doc to show QA how to use Wireshark for testing etc.) in, in time for the cut off day for additions on the next patch (which was around the same day as I got the UDP stream file working). As that file had a few errors in it (thanks to all those who tested it) I was unhappy about forcing it out without more testing (it had never yet been tested on a live network including MP, so had no idea of the impact). So it won't I'm afraid be in the November patch.....(this was my decision, so shout at me).

However....now the good news.

I prodded the physics guys the other day about 'ride height' and suspension data. They have given me a couple of values to poke at. I'm just looking at them now....looked at and added. There is 'WheelLocalPositionY(wheel)' (f32) and 'RideHeight(wheel)' (f32). These have now been added.....

Now, here's the deal, as a way of an apology. I'll give you a bit of a 'free for all' until Monday, where you can request any data you like....If I can find it and I can squeeze it into the packet somewhere then I'll add it. THIS WILL NOT EFFECT THE EXISTING SHARED MEMORY API. That will remain untouched. The main packet is currently 1093. I will add the extra precision bits encoded for the X/Y as well, so that will be 0.25M accuracy.

Once this has been done. I'll do the final packet structure and produce a new UDP.BIN (if anyone has anywhere where I can share it....) you can then test it. It will then go into QA and be enabled on the next patch.

YES! Ride height! i may finally be able to do some proper setup work! Or at least understand why i'm so bad at it lol

mr_belowski
06-11-2015, 08:36
Cjorgens - have you tried using the track length to identify tracks? Have a look at my code on github, there's a TrackData class with them all in

cjorgens79
06-11-2015, 11:15
Cjorgens - have you tried using the track length to identify tracks? Have a look at my code on github, there's a TrackData class with them all in

Great idea, I hadn't thought of that. Thanks for the pointer to your git hub repo, will save me the hassle of having to go work out each tracks length. :)

transfix
06-11-2015, 13:28
Didn't get the chance to check every page of the thread but will the api support track maps, live or static?

cjorgens79
06-11-2015, 13:47
Didn't get the chance to check every page of the thread but will the api support track maps, live or static?

No you cant get the maps from the api. You can however make your own map (which i did for my pcars dash app) and used the participant x/z positions to show where everyone is on track.

PTG Baby Cow
06-11-2015, 15:29
wow. I would like to say thanks to tim and all the 3rd party developers working hard to get something here. This is awesome work and is going be amazing to have this available on console. Thanks everyone for the hard work, cant wait. Now if only we could get ms/thrustmaster to allow me to map all the buttons seperately.

TheReaper GT
06-11-2015, 15:34
wow. I would like to say thanks to tim and all the 3rd party developers working hard to get something here. This is awesome work and is going be amazing to have this available on console. Thanks everyone for the hard work, cant wait. Now if only we could get ms/thrustmaster to allow me to map all the buttons seperately.

I wouldn't hold my breath waiting for that one, but maybe when the full keyboard support comes...

Tim Mann
06-11-2015, 21:32
Before I forget:

Shared memory enum has been updated (easier to do it here than elsewhere):

// (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),
};

Tim Mann
06-11-2015, 21:39
Okay then, I went back through the last few pages and noted everyone's requests. If the data was available in the various telemetry places, then it was added. If it wasn't then it hasn't been. Things like weather can't be easily got hold of as you end up with all sorts of threading issues accessing data. A lot of the requested physics data is buried quite deep so isn't accessible in various telemetry structures. Here's the new layout:

struct sParticipantInfo
{
s16 sWorldPosition[3]; // 0
u16 sCurrentLapDistance; // 6
u8 sRacePosition; // 8
u8 sLapsCompleted; // 9
u8 sCurrentLap; // 10
u8 sSector; // 11
u16 sLastSectorTime; // 12
// 14
};

struct sParticipantInfoStrings
{
static const u32 sPacketSize = 1347;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
char sCarName[64]; // 3
char sCarClassName[64]; // 131
char sTrackLocation[64]; // 195
char sTrackVariation[64]; // 259
char sName[16][64]; // 323
// 1347
};

struct sParticipantInfoStringsAdditional
{
static const u32 sPacketSize = 1028;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
u8 sOffset; // 3
char sName[16][64]; // 4
// 1028
};

struct sTelemetryData
{
static const u32 sPacketSize = 1270;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2

// Game states
u8 sGameSessionState; // 3

// Participant info
s8 sViewedParticipantIndex; // 4
s8 sNumParticipants; // 5

// Unfiltered input
u8 sUnfilteredThrottle; // 6
u8 sUnfilteredBrake; // 7
s8 sUnfilteredSteering; // 8
u8 sUnfilteredClutch; // 9
u8 sRaceStateFlags; // 10

// Event information
u8 sLapsInEvent; // 11

// Timings
f32 sBestLapTime; // 12
f32 sLastLapTime; // 16
f32 sCurrentTime; // 20
f32 sSplitTimeAhead; // 24
f32 sSplitTimeBehind; // 28
f32 sSplitTime; // 32
f32 sEventTimeRemaining; // 36
f32 sPersonalFastestLapTime; // 40
f32 sWorldFastestLapTime; // 44
f32 sCurrentSector1Time; // 48
f32 sCurrentSector2Time; // 52
f32 sCurrentSector3Time; // 56
f32 sFastestSector1Time; // 60
f32 sFastestSector2Time; // 64
f32 sFastestSector3Time; // 68
f32 sPersonalFastestSector1Time; // 72
f32 sPersonalFastestSector2Time; // 76
f32 sPersonalFastestSector3Time; // 80
f32 sWorldFastestSector1Time; // 84
f32 sWorldFastestSector2Time; // 88
f32 sWorldFastestSector3Time; // 92

u16 sTrackLength; // 96

// Flags
u8 sHighestFlag; // 98

// Pit info
u8 sPitModeSchedule; // 99

// 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
s8 sLastOpponentCollisionIndex; // 129

u8 sLastOpponentCollisionMagnitude; // 130
u8 sBoostAmount; // 131

f32 sOdometerKM; // 132
f32 sOrientation[3]; // 136
f32 sLocalVelocity[3]; // 148
f32 sWorldVelocity[3]; // 160
f32 sAngularVelocity[3]; // 172
f32 sLocalAcceleration[3]; // 184
f32 sWorldAcceleration[3]; // 196
f32 sExtentsCentre[3]; // 208

// Wheels / Tyres
u8 sTyreFlags[4]; // 220
u8 sTerrain[4]; // 224
f32 sTyreY[4]; // 228
f32 sTyreRPS[4]; // 244
f32 sTyreSlipSpeed[4]; // 260
u8 sTyreTemp[4]; // 276
u8 sTyreGrip[4]; // 280
f32 sTyreHeightAboveGround[4]; // 284
f32 sTyreLateralStiffness[4]; // 300
u8 sTyreWear[4]; // 316
u8 sBrakeDamage[4]; // 320
u8 sSuspensionDamage[4]; // 324
s16 sBrakeTempCelsius[4]; // 328
u16 sTyreTreadTemp[4]; // 336
u16 sTyreLayerTemp[4]; // 344
u16 sTyreCarcassTemp[4]; // 352
u16 sTyreRimTemp[4]; // 360
u16 sTyreInternalAirTemp[4]; // 368
f32 sWheelLocalPositionY[4]; // 376
f32 sRideHeight[4]; // 392
f32 sSuspensionTravel[4]; // 408
f32 sSuspensionVelocity[4]; // 424
f32 sAirPressure[4]; // 440

// Extras
f32 sEngineSpeed; // 456
f32 sEngineTorque; // 460
f32 sWings[2]; // 464
s8 sEnforcedPitStopLap; // 472

// Car damage
u8 sCrashState; // 473
u8 sAeroDamage; // 474
u8 sEngineDamage; // 475

// Weather
s8 sAmbientTemperature; // 476
s8 sTrackTemperature; // 477
u8 sRainDensity; // 478
s8 sWindSpeed; // 479
s8 sWindDirectionX; // 480
s8 sWindDirectionY; // 481
u8 sCloudBrightness; // 482

// Buttons
u8 sDPad; // 483
u16 sJoyPad; // 484


sParticipantInfo sParticipantInfo[56]; // 486
// 56*14=784
// 1272 struct is padded to
};


mBuildVersionNumber=mTelemetryData.sBuildVersionNumber=(u16)pMemory->mBuildVersionNumber; // u32->u16
mTelemetryData.sPacketType=0; // Unique

// Game state
mTelemetryData.sGameSessionState=((u8)pMemory->mGameState)|(((u8)pMemory->mSessionState)<<4); // (enum 3 bits/enum 3 bits)->u8
mTelemetryData.sRaceStateFlags=((u8)pMemory->mRaceState) | // (enum 3 bits)->u8
(pMemory->mLapInvalidated?8:0)|(pMemory->mAntiLockActive?16:0)|(pMemory->mBoostActive?32:0); // (bool/bool/bool)->u8

// Participant info
mTelemetryData.sViewedParticipantIndex=(s8)pMemory->mViewedParticipantIndex; // s32->s8
mTelemetryData.sNumParticipants=(s8)pMemory->mNumParticipants; // s32->s8

// Unfiltered input
mTelemetryData.sUnfilteredThrottle=(u8)(Clamp(pMemory->mUnfilteredThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredBrake=(u8)(Clamp(pMemory->mUnfilteredBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredSteering=(s8)(Clamp(pMemory->mUnfilteredSteering, -1.0f, 1.0f)*127.0f); // f32->s8
mTelemetryData.sUnfilteredClutch=(u8)(Clamp(pMemory->mUnfilteredClutch, 0.0f, 1.0f)*255.0f); // f32->u8

// Event information
mTelemetryData.sTrackLength=(u16)pMemory->mTrackLength; // f32->u16
mTelemetryData.sLapsInEvent=(u8)min(pMemory->mLapsInEvent,255); // u32->u8

// Timings
mTelemetryData.sBestLapTime=pMemory->mBestLapTime; // f32->f32
mTelemetryData.sLastLapTime=pMemory->mLastLapTime; // f32->f32
mTelemetryData.sCurrentTime=pMemory->mCurrentTime; // f32->f32
mTelemetryData.sSplitTimeAhead=pMemory->mSplitTimeAhead; // f32->f32
mTelemetryData.sSplitTimeBehind=pMemory->mSplitTimeBehind; // f32->f32
mTelemetryData.sSplitTime=pMemory->mSplitTime; // f32->f32
mTelemetryData.sEventTimeRemaining=pMemory->mEventTimeRemaining; // f32->f32
mTelemetryData.sPersonalFastestLapTime=pMemory->mPersonalFastestLapTime; // f32->f32
mTelemetryData.sWorldFastestLapTime=pMemory->mWorldFastestLapTime; // f32->f32
mTelemetryData.sCurrentSector1Time=pMemory->mCurrentSector1Time; // f32->f32
mTelemetryData.sCurrentSector2Time=pMemory->mCurrentSector2Time; // f32->f32
mTelemetryData.sCurrentSector3Time=pMemory->mCurrentSector3Time; // f32->f32
mTelemetryData.sFastestSector1Time=pMemory->mFastestSector1Time; // f32->f32
mTelemetryData.sFastestSector2Time=pMemory->mFastestSector2Time; // f32->f32
mTelemetryData.sFastestSector3Time=pMemory->mFastestSector3Time; // f32->f32
mTelemetryData.sPersonalFastestSector1Time=pMemory->mPersonalFastestSector1Time; // f32->f32
mTelemetryData.sPersonalFastestSector2Time=pMemory->mPersonalFastestSector2Time; // f32->f32
mTelemetryData.sPersonalFastestSector3Time=pMemory->mPersonalFastestSector3Time; // f32->f32
mTelemetryData.sWorldFastestSector1Time=pMemory->mWorldFastestSector1Time; // f32->f32
mTelemetryData.sWorldFastestSector2Time=pMemory->mWorldFastestSector2Time; // f32->f32
mTelemetryData.sWorldFastestSector3Time=pMemory->mWorldFastestSector3Time; // f32->f32

// Flags
mTelemetryData.sHighestFlag=((u8)pMemory->mHighestFlagColour) | (((u8)pMemory->mHighestFlagReason)<<4); // (enum 3 bits/enum 2 bits)

// Pit info
mTelemetryData.sPitModeSchedule=((u8)pMemory->mPitMode) | (((u8)pMemory->mPitSchedule)<<4); // (enum 3 bits/enum 2 bits)

// Car state
mTelemetryData.sCarFlags=(u8)pMemory->mCarFlags; // enum->u8
mTelemetryData.sOilTempCelsius=(s16)pMemory->mOilTempCelsius; // f32->s16
mTelemetryData.sOilPressureKPa=(u16)pMemory->mOilPressureKPa; // f32->u16
mTelemetryData.sWaterTempCelsius=(s16)pMemory->mWaterTempCelsius; // f32->s16
mTelemetryData.sWaterPressureKpa=(u16)pMemory->mWaterPressureKPa; // f32->u16
mTelemetryData.sFuelPressureKpa=(u16)pMemory->mFuelPressureKPa; // f32->u16
mTelemetryData.sFuelCapacity=(u8)pMemory->mFuelCapacity; // f32->u8
mTelemetryData.sBrake=(u8)(Clamp(pMemory->mBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sFuelLevel=pMemory->mFuelLevel; // f32->f32
mTelemetryData.sSpeed=pMemory->mSpeed; // f32->f32
mTelemetryData.sRpm=(u16)pMemory->mRpm; // f32->u16
mTelemetryData.sMaxRpm=(u16)pMemory->mMaxRPM; // f32->u16
mTelemetryData.sThrottle=(u8)(Clamp(pMemory->mThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sClutch=(u8)(Clamp(pMemory->mClutch, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSteering=(s8)(Clamp(pMemory->mSteering, -1.0f, 1.0f)*127.0f); // f32->s8
u8 gear=pMemory->mGear<0?0x0f:min((u8)(pMemory->mGear&0xff), 7);
u8 numGears=max((u8)(pMemory->mNumGears&0xff), 0);
mTelemetryData.sGearNumGears=(gear&0x0f)|((numGears&0x0f)<<4); // s32/s32->u8
mTelemetryData.sOdometerKM=pMemory->mOdometerKM; // f32->f32
mTelemetryData.sLastOpponentCollisionIndex=(s8)pMemory->mLastOpponentCollisionIndex; // s32->s8
mTelemetryData.sLastOpponentCollisionMagnitude=(u8)min(pMemory->mLastOpponentCollisionMagnitude, 255); // f32->u8
mTelemetryData.sBoostAmount=(u8)pMemory->mBoostAmount; // f32->u8
mTelemetryData.sOrientation[0]=pMemory->mOrientation[0]; // f32->f32
mTelemetryData.sOrientation[1]=pMemory->mOrientation[1]; // f32->f32
mTelemetryData.sOrientation[2]=pMemory->mOrientation[2]; // f32->f32
mTelemetryData.sLocalVelocity[0]=pMemory->mLocalVelocity[0]; // f32->f32
mTelemetryData.sLocalVelocity[1]=pMemory->mLocalVelocity[1]; // f32->f32
mTelemetryData.sLocalVelocity[2]=pMemory->mLocalVelocity[2]; // f32->f32
mTelemetryData.sWorldVelocity[0]=pMemory->mWorldVelocity[0]; // f32->f32
mTelemetryData.sWorldVelocity[1]=pMemory->mWorldVelocity[1]; // f32->f32
mTelemetryData.sWorldVelocity[2]=pMemory->mWorldVelocity[2]; // f32->f32
mTelemetryData.sAngularVelocity[0]=pMemory->mAngularVelocity[0]; // f32->f32
mTelemetryData.sAngularVelocity[1]=pMemory->mAngularVelocity[1]; // f32->f32
mTelemetryData.sAngularVelocity[2]=pMemory->mAngularVelocity[2]; // f32->f32
mTelemetryData.sLocalAcceleration[0]=pMemory->mLocalAcceleration[0]; // f32->f32
mTelemetryData.sLocalAcceleration[1]=pMemory->mLocalAcceleration[1]; // f32->f32
mTelemetryData.sLocalAcceleration[2]=pMemory->mLocalAcceleration[2]; // f32->f32
mTelemetryData.sWorldAcceleration[0]=pMemory->mWorldAcceleration[0]; // f32->f32
mTelemetryData.sWorldAcceleration[1]=pMemory->mWorldAcceleration[1]; // f32->f32
mTelemetryData.sWorldAcceleration[2]=pMemory->mWorldAcceleration[2]; // f32->f32
mTelemetryData.sExtentsCentre[0]=pMemory->mExtentsCentre[0]; // f32->f32
mTelemetryData.sExtentsCentre[1]=pMemory->mExtentsCentre[1]; // f32->f32
mTelemetryData.sExtentsCentre[2]=pMemory->mExtentsCentre[2]; // f32->f32

// Wheels / Tyres
u32 i;
for (i=0;i<4;i++)
{
mTelemetryData.sTyreFlags[i]=(u8)pMemory->mTyreFlags[i]; // (enum 3 bits)->u8
mTelemetryData.sTerrain[i]=(u8)pMemory->mTerrain[i]; // (enum 6 bits)->u8
mTelemetryData.sTyreY[i]=pMemory->mTyreY[i]; // f32->f32
mTelemetryData.sTyreRPS[i]=pMemory->mTyreRPS[i]; // f32->f32
mTelemetryData.sTyreSlipSpeed[i]=pMemory->mTyreSlipSpeed[i]; // f32->f32
mTelemetryData.sTyreTemp[i]=(u8)Clamp(pMemory->mTyreTemp[i], 0.0f, 255.0f); // f32->u8
mTelemetryData.sTyreGrip[i]=(u8)Clamp(pMemory->mTyreGrip[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sTyreHeightAboveGround[i]=pMemory->mTyreHeightAboveGround[i]; // f32->f32
mTelemetryData.sTyreLateralStiffness[i]=pMemory->mTyreLateralStiffness[i]; // f32->f32
mTelemetryData.sTyreWear[i]=(u8)(Clamp(pMemory->mTyreWear[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeDamage[i]=(u8)(Clamp(pMemory->mBrakeDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSuspensionDamage[i]=(u8)(Clamp(pMemory->mSuspensionDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeTempCelsius[i]=(s16)pMemory->mBrakeTempCelsius[i]; // f32->s16
mTelemetryData.sTyreTreadTemp[i]=(u16)pMemory->mTyreTreadTemp[i]; // f32->u16
mTelemetryData.sTyreLayerTemp[i]=(u16)pMemory->mTyreLayerTemp[i]; // f32->u16
mTelemetryData.sTyreCarcassTemp[i]=(u16)pMemory->mTyreCarcassTemp[i]; // f32->u16
mTelemetryData.sTyreRimTemp[i]=(u16)pMemory->mTyreRimTemp[i]; // f32->u16
mTelemetryData.sTyreInternalAirTemp[i]=(u16)pMemory->mTyreInternalAirTemp[i]; // f32->u16
mTelemetryData.sWheelLocalPositionY[i]=pMemoryExtras->mWheelLocalPositionY[i]; // f32->f32
mTelemetryData.sRideHeight[i]=pMemoryExtras->mRideHeight[i]; // f32->f32
mTelemetryData.sSuspensionTravel[i]=pMemoryExtras->mSuspensionTravel[i]; // f32->f32
mTelemetryData.sSuspensionVelocity[i]=pMemoryExtras->mSuspensionVelocity[i]; // f32->f32
mTelemetryData.sAirPressure[i]=pMemoryExtras->mAirPressure[i]; // f32->f32
}

// Extras
mTelemetryData.sEngineSpeed=pMemoryExtras->mEngineSpeed; // f32->f32
mTelemetryData.sEngineTorque=pMemoryExtras->mEngineTorque; // f32->f32
mTelemetryData.sWings[0]=pMemoryExtras->mWings[0]; // f32->f32
mTelemetryData.sWings[1]=pMemoryExtras->mWings[1]; // f32->f32
mTelemetryData.sEnforcedPitStopLap=(s8)pMemoryExtras->mEnforcedPitStopLap; // S32->s8

//Car damage
mTelemetryData.sCrashState=(u8)pMemory->mCrashState; // (enum 3 bits)->u8
mTelemetryData.sAeroDamage=(u8)(Clamp(pMemory->mAeroDamage, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sEngineDamage=(u8)(Clamp(pMemory->mEngineDamage, 0.0f, 1.0f)*255.0f); // f32->u8

// Weather
mTelemetryData.sAmbientTemperature=(s8)Clamp(pMemory->mAmbientTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sTrackTemperature=(s8)Clamp(pMemory->mTrackTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sRainDensity=(u8)(Clamp(pMemory->mRainDensity, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sWindSpeed=(u8)(Clamp(pMemory->mWindSpeed*0.5f, 0.0f, 255.0f)); // f32->u8
mTelemetryData.sWindDirectionX=(s8)Clamp(pMemory->mWindDirectionX*127.0f, -127.0f, 127.0f); // f32->s8
mTelemetryData.sWindDirectionY=(s8)Clamp(pMemory->mWindDirectionY*127.0f, -127.0f, 127.0f); // f32->s8
mTelemetryData.sCloudBrightness=(u8)Clamp(pMemory->mCloudBrightness, 0.0f, 255.0f); // f32->u8

for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 46);i++)
{
mTelemetryData.sParticipantInfo[i].sWorldPosition[0]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[0], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[1]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[1], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[2]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[2], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sCurrentLapDistance=(u16)min(pMemory->mParticipantInfo[i].mCurrentLapDistance, 65535.0f); // f32->u16
mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?127:0); // u32+bool->u8
mTelemetryData.sParticipantInfo[i].sLapsCompleted=(u8)min(pMemory->mParticipantInfo[i].mLapsCompleted, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sCurrentLap=(u8)min(pMemory->mParticipantInfo[i].mCurrentLap, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sSector=(u8)pMemory->mParticipantInfo[i].mCurrentSector; // (enum 3 bits)->u8
// Extra accuracy bits for x/z
u32 x=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[0]*4.0f))&3;
u32 z=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[2]*4.0f))&3;
mTelemetryData.sParticipantInfo[i].sSector=((u8)pMemory->mParticipantInfo[i].mCurrentSector)|((u8)x<<6)|((u8)z<<4); // (enum 3 bits)+(x 2 bits, z 2 bits)->u8

f32 sectorTime=pMemoryExtras->mLastSectorTime[i];
u32 seconds=(u32)Floor(sectorTime);
u32 subSeconds=(u32)Floor(sectorTime*128.0f)&127;
mTelemetryData.sParticipantInfo[i].sLastSectorTime=(u16)((seconds<<7)|subSeconds); // 9:7 (Seconds / Sub-seconds)
}

mTelemetryData.sJoyPad=(u16)JOYPAD BUTTON MASK
mTelemetryData.sDPad=(u8)JOYPAD DPAD MASK

// This packet below is sent less often
BStrcpy(mParticipantStrings.sCarName, 64, pMemory->mCarName);
BStrcpy(mParticipantStrings.sCarClassName, 64, pMemory->mCarClassName);
BStrcpy(mParticipantStrings.sTrackLocation, 64, pMemory->mTrackLocation);
BStrcpy(mParticipantStrings.sTrackVariation, 64, pMemory->mTrackVariation);
for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 16);i++)
{
BStrcpy(mParticipantStrings.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStrings.sBuildVersionNumber=mBuildVersionNumber;


// These extra packets are sent if participants>16
for (groups of 16)
{
BStrcpy(mParticipantStringsAdditional.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStringsAdditional.sOffset=(u8)OFFSET IN 16's, so 1st packet of this type offset will be 16, 2nd 32 etc
mParticipantStringsAdditional.sBuildVersionNumber=mBuildVersionNumber;

Please sanity check it for errors. There is a new UDP.BIN file, if you requested it last time and I still have your email I'll send it again now.

If there is anything I've missed and you still want (and haven't requested it over the past couple of days) shout now and I'll have a look. But this all needs to be locked down now over the next few days.

cjorgens79
07-11-2015, 01:48
Before I forget:

Shared memory enum has been updated (easier to do it here than elsewhere):

// (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),
};

Thanks Tim, can we please have TC (Traction control) as well in here as there are 3 different aids in game, ABS TC, and SC.

cjorgens79
07-11-2015, 01:49
There is a new UDP.BIN file, if you requested it last time and I still have your email I'll send it again now.

Could you please send me the bin file too, i didn't receive the latest one. Thanks

cjorgens79
07-11-2015, 02:00
@Tim, could we spare two more bytes and make
u16 sTrackLength;
into
f32 sTrackLength;

The reason being that mr_belowski and now myself use the track length to identify the track (so we dont have to worry about track names being different for different languages). The track length seems to be accurate to 3dps, so while we could use the rounded version, there is a possibility that multiple tracks could have the same rounded length. At the moment it looks ok, but there are already some tracks that are less than 1 meter difference in length, eg sonoma short and donington national are 3174.824m and 3175.802m in length. If we have float precision it should be pretty much enough to guarantee uniqueness.

cjorgens79
07-11-2015, 11:35
@Tim, re the participant sLastSectorTime, u16 is not enough accuracy. We need proper f32 accuracy as we will need to remember and add up sectors to get a final accurate lap times per participant, so f32 is really required. Lap times are the one thing that really needs precision. That will push the main struct up to 1400 bytes, but there are a few places space can be saved if required. Eg new new fields are

f32 sWheelLocalPositionY[4];// 376
f32 sRideHeight[4]; // 392
f32 sSuspensionTravel[4]; // 408
f32 sSuspensionVelocity[4]; // 424
f32 sAirPressure[4]; // 440

// Extras
f32 sEngineSpeed; // 456
f32 sEngineTorque; // 460
f32 sWings[2]; // 464

f32 is a bit overkill for some of those i would have thought.

Tim Mann
07-11-2015, 12:20
Lap time is accurate to 8/1000 of a second. Traction control is a bit of an odd one, internally I think it's actually called something different. Having a quick look it should be okay.

Tim Mann
07-11-2015, 12:21
Could you please send me the bin file too, i didn't receive the latest one. Thanks

You were on the list, I'll send it again now as I've got a couple more requests as well.

pock1910
07-11-2015, 13:04
Too bad that the fields throttle, brake, speed, rpm, gear are not available for ParticipantInfo structure.

For the App Race Trainer this extension would be a so-called game changer.

You could go up and race against the best racers in the time trial mode and you could use this extended trainer information (gas, brake, speed, gear, RPM) to learn from the best.

Unfortunately, the very good drivers do not use the Race Trainer currently (it's logical, because they can race already very well). Therefore the not so good racers have this potential training data not available. With the mentioned extension, each racer can measure with the best drivers and can see where he lose his time.

Perhaps this can be added at a later time to support the newcomers better. Hopefully the newcomers have the long breath to wait for that.
Nevertheless, many thanks for this awesome development.

cjorgens79
07-11-2015, 13:14
Lap time is accurate to 8/1000 of a second. Yeah i meant 8/1000 accuracy is not enough for lap timing, as lap times and fastest laps are counted to the 1000th of a second. A live qualifying leaderboard for example wouldnt work so well without proper 1000th accuracy as it could show players in the wrong positions, 0.024 seconds potential rounding loss over 3 sectors is alot in lap time terms.

Fil140
07-11-2015, 13:21
Too bad that the fields throttle, brake, speed, rpm, gear are not available for ParticipantInfo structure.

For the App Race Trainer this extension would be a so-called game changer.

You could go up and race against the best racers in the time trial mode and you could use this extended trainer information (gas, brake, speed, gear, RPM) to learn from the best.

Unfortunately, the very good drivers do not use the Race Trainer currently (it's logical, because they can race already very well). Therefore the not so good racers have this potential training data not available. With the mentioned extension, each racer can measure with the best drivers and can see where he lose his time.

Perhaps this can be added at a later time to support the newcomers better. Hopefully the newcomers have the long breath to wait for that.
Nevertheless, many thanks for this awesome development.
Sorry, off topic.Is English not your first language?,i suspect not.You have just posted one of the best explained and easily understandable comments ive ever read, some of us native english speakers need to take note.
I also agree with the Training idea as i know people who would benefit greatly.

Fil140
07-11-2015, 13:28
Just a thought and this may or may not be a silly question but is there any chance that we would now be able to run an anlogue speedo/tacho/rev counter?

TheReaper GT
07-11-2015, 13:30
Just a thought and this may or may not be a silly question but is there any chance that we would now be able to run an anlogue speedo/tacho/rev counter?

If the hardware has a software capable of reading the streamed data, yes

Fil140
07-11-2015, 13:47
http://youtu.be/u7aa5oNCsA0
Any chance of someone being able to get this to run on ps4 wit pcars?

Fil140
07-11-2015, 13:51
http://youtu.be/llH2LLJtSjc
This one explsins more details on software

Tim Mann
07-11-2015, 16:08
Too bad that the fields throttle, brake, speed, rpm, gear are not available for ParticipantInfo structure.

For the App Race Trainer this extension would be a so-called game changer.

You could go up and race against the best racers in the time trial mode and you could use this extended trainer information (gas, brake, speed, gear, RPM) to learn from the best.

Unfortunately, the very good drivers do not use the Race Trainer currently (it's logical, because they can race already very well). Therefore the not so good racers have this potential training data not available. With the mentioned extension, each racer can measure with the best drivers and can see where he lose his time.

Perhaps this can be added at a later time to support the newcomers better. Hopefully the newcomers have the long breath to wait for that.
Nevertheless, many thanks for this awesome development.

Hmm, data is available, it's just finding somewhere to stick it. It's only really useful for MP so that would limit it normally to 16 entries...

I'll let cjorgens play with the numbers, may be 16 participant info with extra data (be careful of alignment). Just for reference there is no point going above rpm(u16), throttle(u8), brake(u8).

Wings could move to a u8.

mr_belowski
07-11-2015, 16:13
Is sEnforcedPitStopLap the start or the end of the pit window? Is there ever mandatory pit stops in races held over a fixed time rather than number of laps?

Any chance of opponent car class and player tyre type?

If you're looking for more space in the packet, the collision data are unusable in the shared memory (the last collision participant index seems random and often refers to opponents who don't exist). The cloud brightness is also quite random and unusable, bearing no relationship to the actual brightness. Perhaps these could be dropped

Fil140
07-11-2015, 16:50
So tim,can we get an email address from you? We really want to paypal you a pint! Its the least we can do, we can easily pay or donate to the app guys.

Mr.60trim
07-11-2015, 19:14
So tim,can we get an email address from you? We really want to paypal you a pint! Its the least we can do, we can easily pay or donate to the app guys.
Yeah, I'm in for donating towards the cause.

Also, BIG BIG BIG thanks to everyone making a collaborative effort here. From everyone on the software development side, to all of the fellow members submitting great suggestions & ideas to be incorporated in this awesome feature.

I can't wait for this to go live! Keep up the good work!

Tim Mann
07-11-2015, 21:03
Is sEnforcedPitStopLap the start or the end of the pit window? Is there ever mandatory pit stops in races held over a fixed time rather than number of laps?

Any chance of opponent car class and player tyre type?

If you're looking for more space in the packet, the collision data are unusable in the shared memory (the last collision participant index seems random and often refers to opponents who don't exist). The cloud brightness is also quite random and unusable, bearing no relationship to the actual brightness. Perhaps these could be dropped

Apparently its the start window and is valid until the end of the race. Tyre's are not available (they are hidden several layers down). I don't really have anywhere to stick the opponents class. I'll remove the collision data if its useless.

Tim Mann
07-11-2015, 21:05
So tim,can we get an email address from you? We really want to paypal you a pint! Its the least we can do, we can easily pay or donate to the app guys.

Thank you for the offer!

But for professional reasons I will have to decline (which is a shame, you can never have too much wine). You bought the game, so in that sense, you've already donated, so thank you:)

Tim

Fil140
07-11-2015, 21:51
Then all we can do is say thankyou tim and tell you just how much we truly appreciate your effort and time,i will most certainly remain loyal to sms.

pock1910
08-11-2015, 00:32
Too bad that the fields throttle, brake, speed, rpm, gear are not available for ParticipantInfo structure.

For the App Race Trainer this extension would be a so-called game changer.

You could go up and race against the best racers in the time trial mode and you could use this extended trainer information (gas, brake, speed, gear, RPM) to learn from the best.

Unfortunately, the very good drivers do not use the Race Trainer currently (it's logical, because they can race already very well). Therefore the not so good racers have this potential training data not available. With the mentioned extension, each racer can measure with the best drivers and can see where he lose his time.

Perhaps this can be added at a later time to support the newcomers better. Hopefully the newcomers have the long breath to wait for that.
Nevertheless, many thanks for this awesome development.

Hmm, data is available, it's just finding somewhere to stick it. It's only really useful for MP so that would limit it normally to 16 entries...

I'll let cjorgens play with the numbers, may be 16 participant info with extra data (be careful of alignment). Just for reference there is no point going above rpm(u16), throttle(u8), brake(u8).

Wings could move to a u8.

A limit of 16 entries would be fine. I'd also appreciate the availability of this extension for Time Trial mode.

I'm looking forward to future changes.

Fil140
08-11-2015, 01:50
So what anout an anlogue tacho then??anyone?

TheReaper GT
08-11-2015, 01:58
So what anout an anlogue tacho then??anyone?

It must be fed by a device able to capture the udp data and translate it into analog signal.

Fil140
08-11-2015, 02:13
http://youtu.be/llH2LLJtSjc
So would this work or would it need to have a software programme written specifically for ps4,is it even possible at all?

TheReaper GT
08-11-2015, 02:26
http://youtu.be/llH2LLJtSjc
So would this work or would it need to have a software programme written specifically for ps4,is it even possible at all?

I think a simple pc or a arduino based board can catch the data and feed that unit. Plugin in on the PS4 ain't gonna work.

cjorgens79
08-11-2015, 04:32
Hmm, data is available, it's just finding somewhere to stick it. It's only really useful for MP so that would limit it normally to 16 entries...

I'll let cjorgens play with the numbers, may be 16 participant info with extra data (be careful of alignment). Just for reference there is no point going above rpm(u16), throttle(u8), brake(u8).

Wings could move to a u8.

Ive played with the numbers and have come up with a way to get all that extra stuff into the participants struct and get my 1000th accuracy timing :) Ill post the details up in a few hours when i get back. Also think i have a way to get car names and car class for all participants too.

rotorrian
08-11-2015, 07:49
I think the VBox could be reprogrammed for this. Its arduino based with PS4 drivers.

but it would need a wifi board to pickup the UDP then Vbox can be powered via PS4/USB or external power.



I think a simple pc or a arduino based board can catch the data and feed that unit. Plugin in on the PS4 ain't gonna work.

cjorgens79
08-11-2015, 08:15
So a revised participant info struct could look like this

struct sParticipantInfo
{
s16 sWorldPosition[2]; // 0 X,Z only
u8 sXZAdditional; // 4 X/Z additional precision (4 bits Z, 4 bits X)
u8 sCurrentLap; // 5
u16 sCurrentLapDistance; // 6
u16 sRPM // 8 RPM
u16 sSpeedGear // 10 12 bit speed (1dps), 4 bit gear
u32 sTiming // 12 1 bit in Garage, 1 bit Active, 1 bit Lap Invalid, 2 bit sector, 7 bit race position, 20 bit last sector time (17 minute max sector time)
u8 sThrottle // 16
u8 sBrake // 17
}; // 18

The main things to note here are
1. dropped Y from the sWorldPosition array to save 2 bytes, if anyone actually needs this please shout out, i dont see it as really being useful unless you were doing a 3d map
2. created seperate u8 for the x/z additional precision for mr belowski, 4 bits each (so 1/16th precision)
3. removed "sLapsCompleted" as we can calculate that from sCurrentLap - 1 i would assume?
4. added sRPM
5. added sSpeedGear which is 12 bits for speed (to 1 decimal place, so a range of 0-409.5 meters per sec) and 4 bits for gear
6. added u32 for sTiming which is a series of bits for timing status, sector, race pos and sector time.
- 1 bit inGarage (is the car on track or in the garage
- 1 bit isActive (that existing mIsActive flag, if this is effectively the same as inGarage then one can be dropped, i dont know what it actually refers to though)
- 1 bit LapInvalid (really need to be able to tell if a participants lap time is valid or not
- 2 bit current sector
- 7 bit for current race position
- 20 bit for last sector time (* 1000) which is a sector time range of 0 to 17:28.575ms
7. added sThrottle
8. added sBrake

So that results in an 18 byte participant struct * 56 max players = 1008 bytes. If we stuck with the rest of the existing shared memory struct, that would be an addition 486 bytes which would total 1494.. so right on the limit.

The existing shared memory structure has some room for improvement to free up some more space to give us back some head room. More to come on that.


@Tim, if there is a way to determine what aids each participant has, I will be able to find a couple of bits in here so we can see which players have abs/tc/sc which would be nice. If its possible to get that info ill tweak the struct further.

cjorgens79
08-11-2015, 08:31
A couple of options for sParticipantInfoStrings if we want to try and get car name and car class per participant

First if we want to use strings for all we need to reduce the max sizes for each. Only place we would see truncation is on the car name, and only 2 cars in the field i think would get truncated slightly.
struct sParticipantInfoStrings
{
static const u32 sPacketSize = 1347;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
char sTrackLocation[32]; // 3 // -- CHANGED to 32 chars, longest track name i could find was 30 chars
char sTrackVariation[32]; // 35 // -- CHANGED to 32 chars, longest track variation i could find was 29 chars
char sName[16][32]; // 67 // -- CHANGED to 32 chars max for player
char sCarName[16][32]; // 579 // -- CHANGED to 32 chars, biggest name i could find in car list was 40 chars
char sCarClassName[16][24]; // 1091 // -- CHANGED to 24 chars, longest class name is 20 chars
};// 1475

Alternatively if there is an enum somewhere for car class, then we can instead use the enum and therefore allocate more for car name so no truncation at all.
struct sParticipantInfoStrings
{
static const u32 sPacketSize = 1363;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
char sTrackLocation[32]; // 3 // -- CHANGED to 32 chars, longest track name i could find was 30 chars
char sTrackVariation[32]; // 35 // -- CHANGED to 32 chars, longest track variation i could find was 29 chars
char sName[16][32]; // 67 // -- CHANGED to 32 chars max for player
char sCarName[16][48]; // 579 // -- CHANGED to 48 chars, biggest name i could find in car list was 40 chars
u8 sCarClass[16]; // 1347 // -- CHANGED to 24 chars, longest class name is 20 chars
};// 1363

Same can be applied to the sParticipantInfoStringsAdditional struct.

This would mean we can have both car name and car class for every participant in the race, which would be awesome as we could make some great timing boards with that info.

cjorgens79
08-11-2015, 08:40
Now in terms of the main sTelemetryData struct, if we want to get back some head room, the following could be looked at

u8 sUnfilteredThrottle; // 6 // -- REMOVE, this field is now in ParticipantInfo struct
u8 sUnfilteredBrake; // 7 // -- REMOVE, this field is now in ParticipantInfo struct

u8 sBrake; // 112 // -- REMOVE, this field is now in ParticipantInfo struct
u8 sThrottle; // 113 // -- REMOVE, this field is now in ParticipantInfo struct

^^^^ not sure what the diff between these and the unfiltered version in the struct is. Personally i used the unfiltered one in my app, was figuring we would use that in the participant info struct as we would want to know as close as possible actual throttle/brake position, no filtering when comparing driving styles.

f32 sSpeed; // 120 // -- REMOVE, this field is now in ParticipantInfo struct
u16 sRpm; // 124 // -- REMOVE, this field is now in ParticipantInfo struct

s8 sLastOpponentCollisionIndex; // 129 // -- REMOVE, apparently doesn't work (random values)
u8 sLastOpponentCollisionMagnitude; // 130 // -- REMOVE, apparently doesn't work


f32 sOrientation[3]; // 136 // |
f32 sLocalVelocity[3]; // 148 // |
f32 sWorldVelocity[3]; // 160 // |
f32 sAngularVelocity[3]; // 172 // |
f32 sLocalAcceleration[3]; // 184 // |
f32 sWorldAcceleration[3]; // 196 // |
f32 sExtentsCentre[3]; // 208 // |
^^^^^^^^ are any of these useful, does anyone use them at all and if so, do they need to be f32?

f32 sTyreY[4]; // 228
and
f32 sWheelLocalPositionY[4];// 376
^^^^^ are these the same thing or different things?


f32 sRideHeight[4]; // 392 // -- QUESTION, can this be u8? in setup editor, range is usually well within 0-255mm
f32 sSuspensionTravel[4]; // 408 // -- QUESTION, can this be s16 (*1000) gives travel range of -32.765 to +32.765cm, not sure if suspension travel would exceed this. If it does, could do *100 instead, so -327.65 to +327.65 range instead
f32 sSuspensionVelocity[4];// 424 // -- QUESTION, dont know what ranges on this are, maybe suitable to go s16
f32 sAirPressure[4]; // 440 // -- QUESTION, this should be able to be u16, i presume its in KPa. Could do *100 to retain 2dps, would give range up to 95psi

// Extras
f32 sEngineSpeed; // 456 // -- QUESTION, could be u16? not sure what unit this is in
f32 sEngineTorque; // 460 // -- QUESTION, could be u16? not sure what unit this is in
f32 sWings[2]; // 464 // -- QUESTION, could be u8?


u8 sCloudBrightness; // 482 // REMOVE, apparently random and unusable

cjorgens79
08-11-2015, 09:19
oh and also,
u8 sBrakeBias
this would be really nice to have if its possible to read, would just be the percentage we see on setup screen. Very useful for tuning and tweaking during races

rotorrian
08-11-2015, 09:42
I totally agree as some cars like the Bentley GT3 especially need alot of fidding with the Brake Bias and Anti-Roll bars as the fuel load and tyres decrease.




oh and also,
u8 sBrakeBias
this would be really nice to have if its possible to read, would just be the percentage we see on setup screen. Very useful for tuning and tweaking during races

Jussi Viljami Karjalainen
08-11-2015, 19:20
Tim, you da man! Personally loving the suspension parameters (holy hell we have a direct suspension velocity, this will make histograms so easy!) and the fact that torque is accessible (and power, since (Newton meters * rpm) / 7120 = hp) with boost, great for keeping restrictor/boost cheaters in check. Fantastic additions all around. =)

Too bad the aerodynamics stuff (downforce etc.) couldn't be implemented, but I wasn't really that hopeful to begin with for those. The suspension data should be good enough to get decent approximations anyway. =)


f32 sOrientation[3]; // 136 // |
f32 sLocalVelocity[3]; // 148 // |
f32 sWorldVelocity[3]; // 160 // |
f32 sAngularVelocity[3]; // 172 // |
f32 sLocalAcceleration[3]; // 184 // |
f32 sWorldAcceleration[3]; // 196 // |
f32 sExtentsCentre[3]; // 208 // |
^^^^^^^^ are any of these useful, does anyone use them at all and if so, do they need to be f32?I'm not developing an app, but personally I do think that being able to get the velocities, orientations and accelerations of all cars could definitely have worthy use, partially for training purposes (comparing different cars/drivers), partially for rule keeping purposes ("How is this one car always managing higher accelerations through corners than the others? Running on forbidden tyres?").


ff32 sTyreY[4]; // 228
and
f32 sWheelLocalPositionY[4];// 376
^^^^^ are these the same thing or different things?Technically at least the tyre and wheel are separate, and the tyre can flex around, but whether it makes any actual difference in in-game terms...



f32 sRideHeight[4]; // 392 // -- QUESTION, can this be u8? in setup editor, range is usually well within 0-255mm
f32 sSuspensionTravel[4]; // 408 // -- QUESTION, can this be s16 (*1000) gives travel range of -32.765 to +32.765cm, not sure if suspension travel would exceed this. If it does, could do *100 instead, so -327.65 to +327.65 range instead
f32 sSuspensionVelocity[4];// 424 // -- QUESTION, dont know what ranges on this are, maybe suitable to go s16
f32 sAirPressure[4]; // 440 // -- QUESTION, this should be able to be u16, i presume its in KPa. Could do *100 to retain 2dps, would give range up to 95psiAs long as we retain sub-millimeter accuracy with the suspension measures, that's very important (for example a single mm of compression in downforce calculations can add up to nearly 100 kg of DF difference). Would be great to get confirmations, but I'm expecting the ride height and suspension travel to be in mm, and the suspension velocity to be in mm per second.


// Extras
f32 sEngineSpeed; // 456 // -- QUESTION, could be u16? not sure what unit this is in
f32 sEngineTorque; // 460 // -- QUESTION, could be u16? not sure what unit this is in
f32 sWings[2]; // 464 // -- QUESTION, could be u8?Engine speed is probably in RPM, and can go up to like 16 000+ rpm I think, for F1 cars. Engine torque is likely in Newton meters, will go over 1000 Nm on many cars. No idea about wings, wonder if it's wing position or something related to downforce...


u8 sCloudBrightness; // 482 // REMOVE, apparently random and unusable[/QUOTE]

JohnSchoonsBeard
08-11-2015, 23:08
Thank you for the offer!

But for professional reasons I will have to decline (which is a shame, you can never have too much wine). You bought the game, so in that sense, you've already donated, so thank you:)

Tim

Ah, we get the hint. So it's a case of Blue Nun for the whole team then.

TheReaper GT
08-11-2015, 23:46
Push to pass information from the Caterham SP300/R falls into KERS data?

Tim Mann
09-11-2015, 12:47
Last file attached

221678

mr_belowski
09-11-2015, 14:04
Awesome stuff :)

So is this the final format?

MikeyTT
09-11-2015, 14:44
Unfortunately I missed Tims post last week in the depths of dash discussions.

IMO there are a few we could/should drop as they are largely similar and only really useful for deep analysis, or are practically duplicates, which will free up some space. When pCars was in development I can see the logic, but there are more worthy variables we could replace these with now:

Keep the single tyre temp value:


u16 sTyreTreadTemp[4];

Drop the other tyre/rim temp related variables:


u16 sTyreLayerTemp[4];
u16 sTyreCarcassTemp[4];
u16 sTyreRimTemp[4];
u16 sTyreInternalAirTemp[4];

Drop the following (practically duplicates of Unfiltered variations):


u8 sBrake;
u8 sThrottle;
u8 sClutch;

Partly from the original list in WMD, and I've not included the stuff that cjorgens79 has previously discussed, I'd like to see the following implemented (apologies if I have my bit/byte stuff wrong, I'm rusty on this):



u8:
- Brake Bias (7 bits: 0-100)
- Session UID (1 bit: 0-1?) - New session/restart session flip-flops this value to indicate a new session

u8:
- Boost/KERS % available (7 bits: 0-100) - FA has a limited use per lap

u8:
- Tyre Type/Compound (3 bits?) - backed off to a new enum?
- 5 free bits for something else?

u8 Tyre Pressure[4]
u8 Tyre Load (Nm)[4]

u8:
- Start Light Status (3 bits: 0-session not started, 1-1 red light, 2-2 red lights, 3-3 red lights, 4-4 red lights, 8-green light session) Can be used for start light sequences. Possible to hook into and expend race state enum?
- Packet Sequential ID (4 bits: 0-16?) - sequential number as a new UDP packet is created, when we get to 16, restart at 0. Gives us some ordering capability for those apps that log data



Just by removing the temp duplicates (technically I know, not actual duplicates, but close enough in my book) that should give us more headroom.

Separate struct for car set-up data - Sent as changes in the garage are saved and once every second for a few seconds post this save (to make sure the packet wasn't lost).
Also sent a few times at the start of a session in a short burst. Here is the ref to the original request for this: (http://forum.wmdportal.com/showthread.php?13563-SDK-API-Feature-Request&p=804867&viewfull=1#post804867)

Tim: If you've not seen it there is a request thread on the old WMD side: http://forum.wmdportal.com/showthread.php?13563-SDK-API-Feature-Request. I appreciate that the MMF isn't your side of things, but I think the "community" would appreciate you raising this internally. It was 2013 that it was last looked at, and we've spent a lot of time putting together a request list that has seemingly been dropped/overlooked. Thanks.

Tim Mann
09-11-2015, 14:57
Awesome stuff :)

So is this the final format?

No that's just a copy of the previous file, I had several bounce messages so a few people didn't get it.

Tim

Tim Mann
09-11-2015, 15:02
Sequential ID isn't a bad idea. Most of the other stuff isn't available. I'm going to draw this to a close, so I'll implement the last lot of changes this week (based on crjorgens etc.), then that'll be in the next patch.

Incidentally I'm a bit adverse about removing the Y pos...is there any evidence of anyone actually using it?

mr_belowski
09-11-2015, 16:47
I don't use the y position but probably should to prevent spotter warnings at the sakkito cross over

mr_belowski
09-11-2015, 16:50
Oh, and a sequential id so we know to discard an out of date packet would be handy. But I'd actually prefer a time for this - perhaps a uint32 of milliseconds, starting at zero when the current session starts (or is joined by the current client). Raceroom has something similar and they call it "gameSimulationTime" - it's incredibly handy. This would provide the ordering data but it'd also be a massive help for me when timing opponent laps and stuff. And it'd give us something simple and reliable when it comes to detecting session restarts.

Brake bias seems like a pretty important one if it's available to be added. Are tyre compounds really not available here? It's such a fundamental piece of data.

Fil140
10-11-2015, 00:55
So when will the apps actually be available to us on console and do we know wich apps will or wont work?

TheReaper GT
10-11-2015, 00:59
So when will the apps actually be available to us on console and do we know wich apps will or wont work?

Timm said it will be in the next patch after the 6.0, so 7.0.
Mr Belowski already confirmed that Crew Chief (which is AWESOME) will be compatible. Pcars Dash dev confirmed too. I'm only waiting for confirmation from vDash dev...

Fil140
10-11-2015, 01:08
Great stuff!!!!

SUBGTRACER
10-11-2015, 01:16
Are you getting both reaper ? pcars dash and vdash ....

TheReaper GT
10-11-2015, 01:51
Are you getting both reaper ? pcars dash and vdash ....

Probably both yes. I like the customization on vDash (mostly because of the Cosworth Omega display (Ginetta, Clio and Bentley GT3) and that the Pcars Dash has a big telemetry section and it's dev is an active user in this forum.

SUBGTRACER
10-11-2015, 02:10
yeah that's how I was looking at it also . well done bud

cjorgens79
10-11-2015, 05:09
Sequential ID isn't a bad idea. Most of the other stuff isn't available. I'm going to draw this to a close, so I'll implement the last lot of changes this week (based on crjorgens etc.), then that'll be in the next patch.

Incidentally I'm a bit adverse about removing the Y pos...is there any evidence of anyone actually using it?

The only reason i removed Y was to make space for the extra stuff we added to participant info which will be useful to people. Y has limited uses as far as i can tell, 3d maps (which afaik no-one is doing) and the suzuka crossover detection for his spotter app that mr_belowski mentioned (although hes not using it yet). Having that Y value will add 112 bytes to the overall participant packet (s16 * 56) which is alot.

Rudolph523
10-11-2015, 15:51
Timm said it will be in the next patch after the 6.0, so 7.0.
Mr Belowski already confirmed that Crew Chief (which is AWESOME) will be compatible. Pcars Dash dev confirmed too. I'm only waiting for confirmation from vDash dev...

i have a question, where can i find the crew chief app?

TheReaper GT
10-11-2015, 15:53
i have a question, where can i find the crew chief app?

Right here my good man:

http://forum.projectcarsgame.com/showthread.php?38922-Crew-Chief-an-alternative-race-engineer-for-PC-users

You have to install it on your PC, but it will only work with the console version of pCars after the patch 7.0

Tim Mann
10-11-2015, 20:57
Some of the participant info isn't available in the telemetry, so I'm going to have to leave it pretty much as the last layout. Only real addition is the TC and the sequence number.

// (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),
};

Tim Mann
10-11-2015, 21:21
Here's the final layout:

struct sParticipantInfo
{
s16 sWorldPosition[3]; // 0
u16 sCurrentLapDistance; // 6
u8 sRacePosition; // 8
u8 sLapsCompleted; // 9
u8 sCurrentLap; // 10
u8 sSector; // 11
f32 sLastSectorTime; // 14
// 16
};

struct sParticipantInfoStrings
{
static const u32 sPacketSize = 1347;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
char sCarName[64]; // 3
char sCarClassName[64]; // 131
char sTrackLocation[64]; // 195
char sTrackVariation[64]; // 259
char sName[16][64]; // 323
// 1347
};

struct sParticipantInfoStringsAdditional
{
static const u32 sPacketSize = 1028;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
u8 sOffset; // 3
char sName[16][64]; // 4
// 1028
};

struct sTelemetryData
{
static const u32 sPacketSize = 1366;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2

// Game states
u8 sGameSessionState; // 3

// Participant info
s8 sViewedParticipantIndex; // 4
s8 sNumParticipants; // 5

// Unfiltered input
u8 sUnfilteredThrottle; // 6
u8 sUnfilteredBrake; // 7
s8 sUnfilteredSteering; // 8
u8 sUnfilteredClutch; // 9
u8 sRaceStateFlags; // 10

// Event information
u8 sLapsInEvent; // 11

// Timings
f32 sBestLapTime; // 12
f32 sLastLapTime; // 16
f32 sCurrentTime; // 20
f32 sSplitTimeAhead; // 24
f32 sSplitTimeBehind; // 28
f32 sSplitTime; // 32
f32 sEventTimeRemaining; // 36
f32 sPersonalFastestLapTime; // 40
f32 sWorldFastestLapTime; // 44
f32 sCurrentSector1Time; // 48
f32 sCurrentSector2Time; // 52
f32 sCurrentSector3Time; // 56
f32 sFastestSector1Time; // 60
f32 sFastestSector2Time; // 64
f32 sFastestSector3Time; // 68
f32 sPersonalFastestSector1Time; // 72
f32 sPersonalFastestSector2Time; // 76
f32 sPersonalFastestSector3Time; // 80
f32 sWorldFastestSector1Time; // 84
f32 sWorldFastestSector2Time; // 88
f32 sWorldFastestSector3Time; // 92

u16 sTrackLength; // 96

// Flags
u8 sHighestFlag; // 98

// Pit info
u8 sPitModeSchedule; // 99

// 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
u8 sBoostAmount; // 129
s8 sEnforcedPitStopLap; // 130
u8 sCrashState; // 131

f32 sOdometerKM; // 132
f32 sOrientation[3]; // 136
f32 sLocalVelocity[3]; // 148
f32 sWorldVelocity[3]; // 160
f32 sAngularVelocity[3]; // 172
f32 sLocalAcceleration[3]; // 184
f32 sWorldAcceleration[3]; // 196
f32 sExtentsCentre[3]; // 208

// Wheels / Tyres
u8 sTyreFlags[4]; // 220
u8 sTerrain[4]; // 224
f32 sTyreY[4]; // 228
f32 sTyreRPS[4]; // 244
f32 sTyreSlipSpeed[4]; // 260
u8 sTyreTemp[4]; // 276
u8 sTyreGrip[4]; // 280
f32 sTyreHeightAboveGround[4]; // 284
f32 sTyreLateralStiffness[4]; // 300
u8 sTyreWear[4]; // 316
u8 sBrakeDamage[4]; // 320
u8 sSuspensionDamage[4]; // 324
s16 sBrakeTempCelsius[4]; // 328
u16 sTyreTreadTemp[4]; // 336
u16 sTyreLayerTemp[4]; // 344
u16 sTyreCarcassTemp[4]; // 352
u16 sTyreRimTemp[4]; // 360
u16 sTyreInternalAirTemp[4]; // 368
f32 sWheelLocalPositionY[4]; // 376
f32 sRideHeight[4]; // 392
f32 sSuspensionTravel[4]; // 408
f32 sSuspensionVelocity[4]; // 424
u16 sAirPressure[4]; // 440

// Extras
f32 sEngineSpeed; // 448
f32 sEngineTorque; // 452
u8 sWings[2]; // 456

// Car damage
u8 sAeroDamage; // 458
u8 sEngineDamage; // 459

// Weather
s8 sAmbientTemperature; // 460
s8 sTrackTemperature; // 461
u8 sRainDensity; // 462
s8 sWindSpeed; // 463
s8 sWindDirectionX; // 464
s8 sWindDirectionY; // 465
u8 sCloudBrightness; // 466

// Buttons
u8 sDPad; // 467


sParticipantInfo sParticipantInfo[56]; // 468
// 56*16=896

u16 sJoyPad; // 1364
// 1368 struct is padded to
};


mBuildVersionNumber=mTelemetryData.sBuildVersionNumber=(u16)pMemory->mBuildVersionNumber; // u32->u16
mTelemetryData.sPacketType=0; // Unique (2 bits) Sequence (6 bits)

// Game state
mTelemetryData.sGameSessionState=((u8)pMemory->mGameState)|(((u8)pMemory->mSessionState)<<4); // (enum 3 bits/enum 3 bits)->u8
mTelemetryData.sRaceStateFlags=((u8)pMemory->mRaceState) | // (enum 3 bits)->u8
(pMemory->mLapInvalidated?8:0)|(pMemory->mAntiLockActive?16:0)|(pMemory->mBoostActive?32:0); // (bool/bool/bool)->u8

// Participant info
mTelemetryData.sViewedParticipantIndex=(s8)pMemory->mViewedParticipantIndex; // s32->s8
mTelemetryData.sNumParticipants=(s8)pMemory->mNumParticipants; // s32->s8

// Unfiltered input
mTelemetryData.sUnfilteredThrottle=(u8)(Clamp(pMemory->mUnfilteredThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredBrake=(u8)(Clamp(pMemory->mUnfilteredBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredSteering=(s8)(Clamp(pMemory->mUnfilteredSteering, -1.0f, 1.0f)*127.0f); // f32->s8
mTelemetryData.sUnfilteredClutch=(u8)(Clamp(pMemory->mUnfilteredClutch, 0.0f, 1.0f)*255.0f); // f32->u8

// Event information
mTelemetryData.sTrackLength=(u16)pMemory->mTrackLength; // f32->u16
mTelemetryData.sLapsInEvent=(u8)min(pMemory->mLapsInEvent,255); // u32->u8

// Timings
mTelemetryData.sBestLapTime=pMemory->mBestLapTime; // f32->f32
mTelemetryData.sLastLapTime=pMemory->mLastLapTime; // f32->f32
mTelemetryData.sCurrentTime=pMemory->mCurrentTime; // f32->f32
mTelemetryData.sSplitTimeAhead=pMemory->mSplitTimeAhead; // f32->f32
mTelemetryData.sSplitTimeBehind=pMemory->mSplitTimeBehind; // f32->f32
mTelemetryData.sSplitTime=pMemory->mSplitTime; // f32->f32
mTelemetryData.sEventTimeRemaining=pMemory->mEventTimeRemaining; // f32->f32
mTelemetryData.sPersonalFastestLapTime=pMemory->mPersonalFastestLapTime; // f32->f32
mTelemetryData.sWorldFastestLapTime=pMemory->mWorldFastestLapTime; // f32->f32
mTelemetryData.sCurrentSector1Time=pMemory->mCurrentSector1Time; // f32->f32
mTelemetryData.sCurrentSector2Time=pMemory->mCurrentSector2Time; // f32->f32
mTelemetryData.sCurrentSector3Time=pMemory->mCurrentSector3Time; // f32->f32
mTelemetryData.sFastestSector1Time=pMemory->mFastestSector1Time; // f32->f32
mTelemetryData.sFastestSector2Time=pMemory->mFastestSector2Time; // f32->f32
mTelemetryData.sFastestSector3Time=pMemory->mFastestSector3Time; // f32->f32
mTelemetryData.sPersonalFastestSector1Time=pMemory->mPersonalFastestSector1Time; // f32->f32
mTelemetryData.sPersonalFastestSector2Time=pMemory->mPersonalFastestSector2Time; // f32->f32
mTelemetryData.sPersonalFastestSector3Time=pMemory->mPersonalFastestSector3Time; // f32->f32
mTelemetryData.sWorldFastestSector1Time=pMemory->mWorldFastestSector1Time; // f32->f32
mTelemetryData.sWorldFastestSector2Time=pMemory->mWorldFastestSector2Time; // f32->f32
mTelemetryData.sWorldFastestSector3Time=pMemory->mWorldFastestSector3Time; // f32->f32

// Flags
mTelemetryData.sHighestFlag=((u8)pMemory->mHighestFlagColour) | (((u8)pMemory->mHighestFlagReason)<<4); // (enum 3 bits/enum 2 bits)

// Pit info
mTelemetryData.sPitModeSchedule=((u8)pMemory->mPitMode) | (((u8)pMemory->mPitSchedule)<<4); // (enum 3 bits/enum 2 bits)

// Car state
mTelemetryData.sCarFlags=(u8)pMemory->mCarFlags; // enum->u8
mTelemetryData.sOilTempCelsius=(s16)pMemory->mOilTempCelsius; // f32->s16
mTelemetryData.sOilPressureKPa=(u16)pMemory->mOilPressureKPa; // f32->u16
mTelemetryData.sWaterTempCelsius=(s16)pMemory->mWaterTempCelsius; // f32->s16
mTelemetryData.sWaterPressureKpa=(u16)pMemory->mWaterPressureKPa; // f32->u16
mTelemetryData.sFuelPressureKpa=(u16)pMemory->mFuelPressureKPa; // f32->u16
mTelemetryData.sFuelCapacity=(u8)pMemory->mFuelCapacity; // f32->u8
mTelemetryData.sBrake=(u8)(Clamp(pMemory->mBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sFuelLevel=pMemory->mFuelLevel; // f32->f32
mTelemetryData.sSpeed=pMemory->mSpeed; // f32->f32
mTelemetryData.sRpm=(u16)pMemory->mRpm; // f32->u16
mTelemetryData.sMaxRpm=(u16)pMemory->mMaxRPM; // f32->u16
mTelemetryData.sThrottle=(u8)(Clamp(pMemory->mThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sClutch=(u8)(Clamp(pMemory->mClutch, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSteering=(s8)(Clamp(pMemory->mSteering, -1.0f, 1.0f)*127.0f); // f32->s8
u8 gear=pMemory->mGear<0?0x0f:min((u8)(pMemory->mGear&0xff), 7);
u8 numGears=max((u8)(pMemory->mNumGears&0xff), 0);
mTelemetryData.sGearNumGears=(gear&0x0f)|((numGears&0x0f)<<4); // s32/s32->u8
mTelemetryData.sOdometerKM=pMemory->mOdometerKM; // f32->f32
mTelemetryData.sBoostAmount=(u8)pMemory->mBoostAmount; // f32->u8
mTelemetryData.sOrientation[0]=pMemory->mOrientation[0]; // f32->f32
mTelemetryData.sOrientation[1]=pMemory->mOrientation[1]; // f32->f32
mTelemetryData.sOrientation[2]=pMemory->mOrientation[2]; // f32->f32
mTelemetryData.sLocalVelocity[0]=pMemory->mLocalVelocity[0]; // f32->f32
mTelemetryData.sLocalVelocity[1]=pMemory->mLocalVelocity[1]; // f32->f32
mTelemetryData.sLocalVelocity[2]=pMemory->mLocalVelocity[2]; // f32->f32
mTelemetryData.sWorldVelocity[0]=pMemory->mWorldVelocity[0]; // f32->f32
mTelemetryData.sWorldVelocity[1]=pMemory->mWorldVelocity[1]; // f32->f32
mTelemetryData.sWorldVelocity[2]=pMemory->mWorldVelocity[2]; // f32->f32
mTelemetryData.sAngularVelocity[0]=pMemory->mAngularVelocity[0]; // f32->f32
mTelemetryData.sAngularVelocity[1]=pMemory->mAngularVelocity[1]; // f32->f32
mTelemetryData.sAngularVelocity[2]=pMemory->mAngularVelocity[2]; // f32->f32
mTelemetryData.sLocalAcceleration[0]=pMemory->mLocalAcceleration[0]; // f32->f32
mTelemetryData.sLocalAcceleration[1]=pMemory->mLocalAcceleration[1]; // f32->f32
mTelemetryData.sLocalAcceleration[2]=pMemory->mLocalAcceleration[2]; // f32->f32
mTelemetryData.sWorldAcceleration[0]=pMemory->mWorldAcceleration[0]; // f32->f32
mTelemetryData.sWorldAcceleration[1]=pMemory->mWorldAcceleration[1]; // f32->f32
mTelemetryData.sWorldAcceleration[2]=pMemory->mWorldAcceleration[2]; // f32->f32
mTelemetryData.sExtentsCentre[0]=pMemory->mExtentsCentre[0]; // f32->f32
mTelemetryData.sExtentsCentre[1]=pMemory->mExtentsCentre[1]; // f32->f32
mTelemetryData.sExtentsCentre[2]=pMemory->mExtentsCentre[2]; // f32->f32

// Wheels / Tyres
u32 i;
for (i=0;i<4;i++)
{
mTelemetryData.sTyreFlags[i]=(u8)pMemory->mTyreFlags[i]; // (enum 3 bits)->u8
mTelemetryData.sTerrain[i]=(u8)pMemory->mTerrain[i]; // (enum 6 bits)->u8
mTelemetryData.sTyreY[i]=pMemory->mTyreY[i]; // f32->f32
mTelemetryData.sTyreRPS[i]=pMemory->mTyreRPS[i]; // f32->f32
mTelemetryData.sTyreSlipSpeed[i]=pMemory->mTyreSlipSpeed[i]; // f32->f32
mTelemetryData.sTyreTemp[i]=(u8)Clamp(pMemory->mTyreTemp[i], 0.0f, 255.0f); // f32->u8
mTelemetryData.sTyreGrip[i]=(u8)Clamp(pMemory->mTyreGrip[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sTyreHeightAboveGround[i]=pMemory->mTyreHeightAboveGround[i]; // f32->f32
mTelemetryData.sTyreLateralStiffness[i]=pMemory->mTyreLateralStiffness[i]; // f32->f32
mTelemetryData.sTyreWear[i]=(u8)(Clamp(pMemory->mTyreWear[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeDamage[i]=(u8)(Clamp(pMemory->mBrakeDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSuspensionDamage[i]=(u8)(Clamp(pMemory->mSuspensionDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeTempCelsius[i]=(s16)pMemory->mBrakeTempCelsius[i]; // f32->s16
mTelemetryData.sTyreTreadTemp[i]=(u16)pMemory->mTyreTreadTemp[i]; // f32->u16
mTelemetryData.sTyreLayerTemp[i]=(u16)pMemory->mTyreLayerTemp[i]; // f32->u16
mTelemetryData.sTyreCarcassTemp[i]=(u16)pMemory->mTyreCarcassTemp[i]; // f32->u16
mTelemetryData.sTyreRimTemp[i]=(u16)pMemory->mTyreRimTemp[i]; // f32->u16
mTelemetryData.sTyreInternalAirTemp[i]=(u16)pMemory->mTyreInternalAirTemp[i]; // f32->u16
mTelemetryData.sWheelLocalPositionY[i]=pMemoryExtras->mWheelLocalPositionY[i]; // f32->f32
mTelemetryData.sRideHeight[i]=pMemoryExtras->mRideHeight[i]; // f32->f32
mTelemetryData.sSuspensionTravel[i]=pMemoryExtras->mSuspensionTravel[i]; // f32->f32
mTelemetryData.sSuspensionVelocity[i]=pMemoryExtras->mSuspensionVelocity[i]; // f32->f32
mTelemetryData.sAirPressure[i]=pMemoryExtras->mAirPressure[i]; // f32->u16
}

// Extras
mTelemetryData.sEngineSpeed=pMemoryExtras->mEngineSpeed; // f32->f32
mTelemetryData.sEngineTorque=pMemoryExtras->mEngineTorque; // f32->f32
mTelemetryData.sWings[0]=pMemoryExtras->mWings[0]; // f32->u8
mTelemetryData.sWings[1]=pMemoryExtras->mWings[1]; // f32->u8
mTelemetryData.sEnforcedPitStopLap=(s8)pMemoryExtras->mEnforcedPitStopLap; // S32->s8

//Car damage
mTelemetryData.sCrashState=(u8)pMemory->mCrashState; // (enum 3 bits)->u8
mTelemetryData.sAeroDamage=(u8)(Clamp(pMemory->mAeroDamage, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sEngineDamage=(u8)(Clamp(pMemory->mEngineDamage, 0.0f, 1.0f)*255.0f); // f32->u8

// Weather
mTelemetryData.sAmbientTemperature=(s8)Clamp(pMemory->mAmbientTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sTrackTemperature=(s8)Clamp(pMemory->mTrackTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sRainDensity=(u8)(Clamp(pMemory->mRainDensity, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sWindSpeed=(u8)(Clamp(pMemory->mWindSpeed*0.5f, 0.0f, 255.0f)); // f32->u8
mTelemetryData.sWindDirectionX=(s8)Clamp(pMemory->mWindDirectionX*127.0f, -127.0f, 127.0f); // f32->s8
mTelemetryData.sWindDirectionY=(s8)Clamp(pMemory->mWindDirectionY*127.0f, -127.0f, 127.0f); // f32->s8

for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 56);i++)
{
mTelemetryData.sParticipantInfo[i].sWorldPosition[0]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[0], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[1]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[1], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[2]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[2], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sCurrentLapDistance=(u16)min(pMemory->mParticipantInfo[i].mCurrentLapDistance, 65535.0f); // f32->u16
mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?127:0); // u32+bool->u8
mTelemetryData.sParticipantInfo[i].sLapsCompleted=(u8)min(pMemory->mParticipantInfo[i].mLapsCompleted, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sCurrentLap=(u8)min(pMemory->mParticipantInfo[i].mCurrentLap, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sSector=(u8)pMemory->mParticipantInfo[i].mCurrentSector; // (enum 3 bits)->u8
// Extra accuracy bits for x/z
u32 x=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[0]*4.0f))&3;
u32 z=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[2]*4.0f))&3;
mTelemetryData.sParticipantInfo[i].sSector=((u8)pMemory->mParticipantInfo[i].mCurrentSector)|((u8)x<<6)|((u8)z<<4); // (enum 3 bits)+(x 2 bits, z 2 bits)->u8
mTelemetryData.sParticipantInfo[i].sLastSectorTime=pMemoryExtras->mLastSectorTime[i]; // f32->f32
}

mTelemetryData.sJoyPad=(u16)JOYPAD BUTTON MASK
mTelemetryData.sDPad=(u8)JOYPAD DPAD MASK

// This packet below is sent less often
BStrcpy(mParticipantStrings.sCarName, 64, pMemory->mCarName);
BStrcpy(mParticipantStrings.sCarClassName, 64, pMemory->mCarClassName);
BStrcpy(mParticipantStrings.sTrackLocation, 64, pMemory->mTrackLocation);
BStrcpy(mParticipantStrings.sTrackVariation, 64, pMemory->mTrackVariation);
for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 16);i++)
{
BStrcpy(mParticipantStrings.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStrings.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStrings.sPacketType=1; // Unique (2 bits) Sequence (6 bits)


// These extra packets are sent if participants>16
for (groups of 16)
{
BStrcpy(mParticipantStringsAdditional.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStringsAdditional.sOffset=(u8)OFFSET IN 16's, so 1st packet of this type offset will be 16, 2nd 32 etc
mParticipantStringsAdditional.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStringsAdditional.sPacketType=2; // Unique (2 bits) Sequence (6 bits)


Thanks everyone for their input and suggestions. Please find a test UDP.BIN attached. If the above doesn't have any issues I'll move it to the first post and close the thread.

221772

TheReaper GT
10-11-2015, 21:25
1- May I suggest that after confirmation, a list of the compatible apps could be added to the first post?

2- is the push to pass count for the sp300r under the kers data?

SkyyJuice
10-11-2015, 22:39
Timmy my good sir when are we gearing to go with this app (sorry had to put that pun in there..lol) make it my xmas prezzie fella, and i'll get you a virtual drink bruv, hell everyone on this thread will get you your virtual drink :-)

SUBGTRACER
11-11-2015, 02:43
I'll put in for a real drink ... as I'm sure plenty would :)

Fil140
11-11-2015, 10:09
Already offered but tim said that for professional reasons he cant accept gifts or payments and that we are supporting him in purchasing the game.

mr_belowski
11-11-2015, 10:35
Smashing, do you have a .bin with data in this latest format?

mr_belowski
11-11-2015, 11:13
sorry, I see the .bin attached to the post.

What does

mTelemetryData.sParticipantInfo[i].sLastSectorTime=; // 9:7 (Seconds / Sub-seconds)

mean? Isn't this just a float32?

You have

u8 sCloudBrightness; // 466

// Buttons
u8 sDPad; // 467

in the telemetry packet description but sCloudBrightness doesn't appear to be populated - has this been removed from the packet?


Your participants loop looks like this:
for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 46);i++)

is 46 correct here?

Tim Mann
11-11-2015, 11:39
Amended. sCloudBrightness never ended up being removed.

mr_belowski
11-11-2015, 12:02
in that most recent UDP bin file, what's the first packet type?

The first 2 bytes are the version - 1112 as a ushort which is the same as the last version, but the next byte is 192 as a uint. I'm expecting 0, 1, or 2 here

Tim Mann
11-11-2015, 12:08
in that most recent UDP bin file, what's the first packet type?

The first 2 bytes are the version - 1112 as a ushort which is the same as the last version, but the next byte is 192 as a uint. I'm expecting 0, 1, or 2 here

And out the bottom 2 bits, the top six are the sequence number (count updated each time).

mr_belowski
11-11-2015, 12:09
Ah, sorry my bad - I completely forgot about that

cjorgens79
11-11-2015, 13:06
Is it possible for u16 sTrackLength to go back to f32 so it can be more accurately used for track identification by length? (as track lengths are to high precision)

cjorgens79
11-11-2015, 13:30
And out the bottom 2 bits, the top six are the sequence number (count updated each time).

@Tim, the sequence number in the udp.bin is not an indicating an incremental counter. The sequence values just repeat every 4 packets, 0xC0, 0x00, 0x40, 0x80, repeat

cjorgens79
11-11-2015, 13:42
Part of the udp.bin strings packets are incorrect. The sParticipantInfoStringsAdditional packet is being sent as packet type 1 (example at position 35516) instead of packet type 2. The sParticipantInfoStrings packet is being sent correctly as 1 (example at position 125672).

So the current file can't be processed for testing as 2 packets of different sizes have the same id so there is no way to know how many bytes to get to proceed through the file.

mr_belowski
11-11-2015, 13:46
Arrrggghhhh I've just wasted 2 hours of my day trying to get to the bottom of exactly the same weirdness. I'd assumed the packets were correct and I my brain was in some way broken :tongue-new:

RomKnight
11-11-2015, 13:49
just to let you guys know you rock. Great test/debug work

jimmyb_84
11-11-2015, 15:17
just to let you guys know you rock. Great test/debug work

What he said! I cannot wait for this to go live, I thank everyone for there efforts. Anyone who knows what I've done will know I love a good bit of data.

Tim Mann
11-11-2015, 20:26
Sorry chaps, my bad, last thing I did was put that sequence count in and promptly c&p'd it all over with the wrong packet ID's in. I've fixed that and changed track length, I'll post another struct and bin if I get a chance in a bit.

Tim Mann
11-11-2015, 21:11
Lets have another pop:

struct sParticipantInfo
{
s16 sWorldPosition[3]; // 0
u16 sCurrentLapDistance; // 6
u8 sRacePosition; // 8
u8 sLapsCompleted; // 9
u8 sCurrentLap; // 10
u8 sSector; // 11
f32 sLastSectorTime; // 14
// 16
};

struct sParticipantInfoStrings
{
static const u32 sPacketSize = 1347;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
char sCarName[64]; // 3
char sCarClassName[64]; // 131
char sTrackLocation[64]; // 195
char sTrackVariation[64]; // 259
char sName[16][64]; // 323
// 1347
};

struct sParticipantInfoStringsAdditional
{
static const u32 sPacketSize = 1028;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
u8 sOffset; // 3
char sName[16][64]; // 4
// 1028
};

struct sTelemetryData
{
static const u32 sPacketSize = 1367;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2

// Game states
u8 sGameSessionState; // 3

// Participant info
s8 sViewedParticipantIndex; // 4
s8 sNumParticipants; // 5

// Unfiltered input
u8 sUnfilteredThrottle; // 6
u8 sUnfilteredBrake; // 7
s8 sUnfilteredSteering; // 8
u8 sUnfilteredClutch; // 9
u8 sRaceStateFlags; // 10

// Event information
u8 sLapsInEvent; // 11

// Timings
f32 sBestLapTime; // 12
f32 sLastLapTime; // 16
f32 sCurrentTime; // 20
f32 sSplitTimeAhead; // 24
f32 sSplitTimeBehind; // 28
f32 sSplitTime; // 32
f32 sEventTimeRemaining; // 36
f32 sPersonalFastestLapTime; // 40
f32 sWorldFastestLapTime; // 44
f32 sCurrentSector1Time; // 48
f32 sCurrentSector2Time; // 52
f32 sCurrentSector3Time; // 56
f32 sFastestSector1Time; // 60
f32 sFastestSector2Time; // 64
f32 sFastestSector3Time; // 68
f32 sPersonalFastestSector1Time; // 72
f32 sPersonalFastestSector2Time; // 76
f32 sPersonalFastestSector3Time; // 80
f32 sWorldFastestSector1Time; // 84
f32 sWorldFastestSector2Time; // 88
f32 sWorldFastestSector3Time; // 92

u16 sJoyPad; // 96

// Flags
u8 sHighestFlag; // 98

// Pit info
u8 sPitModeSchedule; // 99

// 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
u8 sBoostAmount; // 129
s8 sEnforcedPitStopLap; // 130
u8 sCrashState; // 131

f32 sOdometerKM; // 132
f32 sOrientation[3]; // 136
f32 sLocalVelocity[3]; // 148
f32 sWorldVelocity[3]; // 160
f32 sAngularVelocity[3]; // 172
f32 sLocalAcceleration[3]; // 184
f32 sWorldAcceleration[3]; // 196
f32 sExtentsCentre[3]; // 208

// Wheels / Tyres
u8 sTyreFlags[4]; // 220
u8 sTerrain[4]; // 224
f32 sTyreY[4]; // 228
f32 sTyreRPS[4]; // 244
f32 sTyreSlipSpeed[4]; // 260
u8 sTyreTemp[4]; // 276
u8 sTyreGrip[4]; // 280
f32 sTyreHeightAboveGround[4]; // 284
f32 sTyreLateralStiffness[4]; // 300
u8 sTyreWear[4]; // 316
u8 sBrakeDamage[4]; // 320
u8 sSuspensionDamage[4]; // 324
s16 sBrakeTempCelsius[4]; // 328
u16 sTyreTreadTemp[4]; // 336
u16 sTyreLayerTemp[4]; // 344
u16 sTyreCarcassTemp[4]; // 352
u16 sTyreRimTemp[4]; // 360
u16 sTyreInternalAirTemp[4]; // 368
f32 sWheelLocalPositionY[4]; // 376
f32 sRideHeight[4]; // 392
f32 sSuspensionTravel[4]; // 408
f32 sSuspensionVelocity[4]; // 424
u16 sAirPressure[4]; // 440

// Extras
f32 sEngineSpeed; // 448
f32 sEngineTorque; // 452
u8 sWings[2]; // 456

// Car damage
u8 sAeroDamage; // 458
u8 sEngineDamage; // 459

// Weather
s8 sAmbientTemperature; // 460
s8 sTrackTemperature; // 461
u8 sRainDensity; // 462
s8 sWindSpeed; // 463
s8 sWindDirectionX; // 464
s8 sWindDirectionY; // 465

sParticipantInfo sParticipantInfo[56]; // 466
// 56*16=896
// Buttons
f32 sTrackLength; // 1362
u8 sDPad; // 1366
// 1368 struct is padded to
};


mBuildVersionNumber=mTelemetryData.sBuildVersionNumber=(u16)pMemory->mBuildVersionNumber; // u32->u16
mTelemetryData.sPacketType=0|((mCount&63)<<2); // Packet type | (sequence<<2)

// Game state
mTelemetryData.sGameSessionState=((u8)pMemory->mGameState)|(((u8)pMemory->mSessionState)<<4); // (enum 3 bits/enum 3 bits)->u8
mTelemetryData.sRaceStateFlags=((u8)pMemory->mRaceState) | // (enum 3 bits)->u8
(pMemory->mLapInvalidated?8:0)|(pMemory->mAntiLockActive?16:0)|(pMemory->mBoostActive?32:0); // (bool/bool/bool)->u8

// Participant info
mTelemetryData.sViewedParticipantIndex=(s8)pMemory->mViewedParticipantIndex; // s32->s8
mTelemetryData.sNumParticipants=(s8)pMemory->mNumParticipants; // s32->s8

// Unfiltered input
mTelemetryData.sUnfilteredThrottle=(u8)(Clamp(pMemory->mUnfilteredThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredBrake=(u8)(Clamp(pMemory->mUnfilteredBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredSteering=(s8)(Clamp(pMemory->mUnfilteredSteering, -1.0f, 1.0f)*127.0f); // f32->s8
mTelemetryData.sUnfilteredClutch=(u8)(Clamp(pMemory->mUnfilteredClutch, 0.0f, 1.0f)*255.0f); // f32->u8

// Event information
mTelemetryData.sTrackLength=(f32)pMemory->mTrackLength; // f32->f32
mTelemetryData.sLapsInEvent=(u8)min(pMemory->mLapsInEvent,255); // u32->u8

// Timings
mTelemetryData.sBestLapTime=pMemory->mBestLapTime; // f32->f32
mTelemetryData.sLastLapTime=pMemory->mLastLapTime; // f32->f32
mTelemetryData.sCurrentTime=pMemory->mCurrentTime; // f32->f32
mTelemetryData.sSplitTimeAhead=pMemory->mSplitTimeAhead; // f32->f32
mTelemetryData.sSplitTimeBehind=pMemory->mSplitTimeBehind; // f32->f32
mTelemetryData.sSplitTime=pMemory->mSplitTime; // f32->f32
mTelemetryData.sEventTimeRemaining=pMemory->mEventTimeRemaining; // f32->f32
mTelemetryData.sPersonalFastestLapTime=pMemory->mPersonalFastestLapTime; // f32->f32
mTelemetryData.sWorldFastestLapTime=pMemory->mWorldFastestLapTime; // f32->f32
mTelemetryData.sCurrentSector1Time=pMemory->mCurrentSector1Time; // f32->f32
mTelemetryData.sCurrentSector2Time=pMemory->mCurrentSector2Time; // f32->f32
mTelemetryData.sCurrentSector3Time=pMemory->mCurrentSector3Time; // f32->f32
mTelemetryData.sFastestSector1Time=pMemory->mFastestSector1Time; // f32->f32
mTelemetryData.sFastestSector2Time=pMemory->mFastestSector2Time; // f32->f32
mTelemetryData.sFastestSector3Time=pMemory->mFastestSector3Time; // f32->f32
mTelemetryData.sPersonalFastestSector1Time=pMemory->mPersonalFastestSector1Time; // f32->f32
mTelemetryData.sPersonalFastestSector2Time=pMemory->mPersonalFastestSector2Time; // f32->f32
mTelemetryData.sPersonalFastestSector3Time=pMemory->mPersonalFastestSector3Time; // f32->f32
mTelemetryData.sWorldFastestSector1Time=pMemory->mWorldFastestSector1Time; // f32->f32
mTelemetryData.sWorldFastestSector2Time=pMemory->mWorldFastestSector2Time; // f32->f32
mTelemetryData.sWorldFastestSector3Time=pMemory->mWorldFastestSector3Time; // f32->f32

// Flags
mTelemetryData.sHighestFlag=((u8)pMemory->mHighestFlagColour) | (((u8)pMemory->mHighestFlagReason)<<4); // (enum 3 bits/enum 2 bits)

// Pit info
mTelemetryData.sPitModeSchedule=((u8)pMemory->mPitMode) | (((u8)pMemory->mPitSchedule)<<4); // (enum 3 bits/enum 2 bits)

// Car state
mTelemetryData.sCarFlags=(u8)pMemory->mCarFlags; // enum->u8
mTelemetryData.sOilTempCelsius=(s16)pMemory->mOilTempCelsius; // f32->s16
mTelemetryData.sOilPressureKPa=(u16)pMemory->mOilPressureKPa; // f32->u16
mTelemetryData.sWaterTempCelsius=(s16)pMemory->mWaterTempCelsius; // f32->s16
mTelemetryData.sWaterPressureKpa=(u16)pMemory->mWaterPressureKPa; // f32->u16
mTelemetryData.sFuelPressureKpa=(u16)pMemory->mFuelPressureKPa; // f32->u16
mTelemetryData.sFuelCapacity=(u8)pMemory->mFuelCapacity; // f32->u8
mTelemetryData.sBrake=(u8)(Clamp(pMemory->mBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sFuelLevel=pMemory->mFuelLevel; // f32->f32
mTelemetryData.sSpeed=pMemory->mSpeed; // f32->f32
mTelemetryData.sRpm=(u16)pMemory->mRpm; // f32->u16
mTelemetryData.sMaxRpm=(u16)pMemory->mMaxRPM; // f32->u16
mTelemetryData.sThrottle=(u8)(Clamp(pMemory->mThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sClutch=(u8)(Clamp(pMemory->mClutch, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSteering=(s8)(Clamp(pMemory->mSteering, -1.0f, 1.0f)*127.0f); // f32->s8
u8 gear=pMemory->mGear<0?0x0f:min((u8)(pMemory->mGear&0xff), 7);
u8 numGears=max((u8)(pMemory->mNumGears&0xff), 0);
mTelemetryData.sGearNumGears=(gear&0x0f)|((numGears&0x0f)<<4); // s32/s32->u8
mTelemetryData.sOdometerKM=pMemory->mOdometerKM; // f32->f32
mTelemetryData.sBoostAmount=(u8)pMemory->mBoostAmount; // f32->u8
mTelemetryData.sOrientation[0]=pMemory->mOrientation[0]; // f32->f32
mTelemetryData.sOrientation[1]=pMemory->mOrientation[1]; // f32->f32
mTelemetryData.sOrientation[2]=pMemory->mOrientation[2]; // f32->f32
mTelemetryData.sLocalVelocity[0]=pMemory->mLocalVelocity[0]; // f32->f32
mTelemetryData.sLocalVelocity[1]=pMemory->mLocalVelocity[1]; // f32->f32
mTelemetryData.sLocalVelocity[2]=pMemory->mLocalVelocity[2]; // f32->f32
mTelemetryData.sWorldVelocity[0]=pMemory->mWorldVelocity[0]; // f32->f32
mTelemetryData.sWorldVelocity[1]=pMemory->mWorldVelocity[1]; // f32->f32
mTelemetryData.sWorldVelocity[2]=pMemory->mWorldVelocity[2]; // f32->f32
mTelemetryData.sAngularVelocity[0]=pMemory->mAngularVelocity[0]; // f32->f32
mTelemetryData.sAngularVelocity[1]=pMemory->mAngularVelocity[1]; // f32->f32
mTelemetryData.sAngularVelocity[2]=pMemory->mAngularVelocity[2]; // f32->f32
mTelemetryData.sLocalAcceleration[0]=pMemory->mLocalAcceleration[0]; // f32->f32
mTelemetryData.sLocalAcceleration[1]=pMemory->mLocalAcceleration[1]; // f32->f32
mTelemetryData.sLocalAcceleration[2]=pMemory->mLocalAcceleration[2]; // f32->f32
mTelemetryData.sWorldAcceleration[0]=pMemory->mWorldAcceleration[0]; // f32->f32
mTelemetryData.sWorldAcceleration[1]=pMemory->mWorldAcceleration[1]; // f32->f32
mTelemetryData.sWorldAcceleration[2]=pMemory->mWorldAcceleration[2]; // f32->f32
mTelemetryData.sExtentsCentre[0]=pMemory->mExtentsCentre[0]; // f32->f32
mTelemetryData.sExtentsCentre[1]=pMemory->mExtentsCentre[1]; // f32->f32
mTelemetryData.sExtentsCentre[2]=pMemory->mExtentsCentre[2]; // f32->f32

// Wheels / Tyres
u32 i;
for (i=0;i<4;i++)
{
mTelemetryData.sTyreFlags[i]=(u8)pMemory->mTyreFlags[i]; // (enum 3 bits)->u8
mTelemetryData.sTerrain[i]=(u8)pMemory->mTerrain[i]; // (enum 6 bits)->u8
mTelemetryData.sTyreY[i]=pMemory->mTyreY[i]; // f32->f32
mTelemetryData.sTyreRPS[i]=pMemory->mTyreRPS[i]; // f32->f32
mTelemetryData.sTyreSlipSpeed[i]=pMemory->mTyreSlipSpeed[i]; // f32->f32
mTelemetryData.sTyreTemp[i]=(u8)Clamp(pMemory->mTyreTemp[i], 0.0f, 255.0f); // f32->u8
mTelemetryData.sTyreGrip[i]=(u8)Clamp(pMemory->mTyreGrip[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sTyreHeightAboveGround[i]=pMemory->mTyreHeightAboveGround[i]; // f32->f32
mTelemetryData.sTyreLateralStiffness[i]=pMemory->mTyreLateralStiffness[i]; // f32->f32
mTelemetryData.sTyreWear[i]=(u8)(Clamp(pMemory->mTyreWear[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeDamage[i]=(u8)(Clamp(pMemory->mBrakeDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSuspensionDamage[i]=(u8)(Clamp(pMemory->mSuspensionDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeTempCelsius[i]=(s16)pMemory->mBrakeTempCelsius[i]; // f32->s16
mTelemetryData.sTyreTreadTemp[i]=(u16)pMemory->mTyreTreadTemp[i]; // f32->u16
mTelemetryData.sTyreLayerTemp[i]=(u16)pMemory->mTyreLayerTemp[i]; // f32->u16
mTelemetryData.sTyreCarcassTemp[i]=(u16)pMemory->mTyreCarcassTemp[i]; // f32->u16
mTelemetryData.sTyreRimTemp[i]=(u16)pMemory->mTyreRimTemp[i]; // f32->u16
mTelemetryData.sTyreInternalAirTemp[i]=(u16)pMemory->mTyreInternalAirTemp[i]; // f32->u16
mTelemetryData.sWheelLocalPositionY[i]=pMemoryExtras->mWheelLocalPositionY[i]; // f32->f32
mTelemetryData.sRideHeight[i]=pMemoryExtras->mRideHeight[i]; // f32->f32
mTelemetryData.sSuspensionTravel[i]=pMemoryExtras->mSuspensionTravel[i]; // f32->f32
mTelemetryData.sSuspensionVelocity[i]=pMemoryExtras->mSuspensionVelocity[i]; // f32->f32
mTelemetryData.sAirPressure[i]=pMemoryExtras->mAirPressure[i]; // f32->u16
}

// Extras
mTelemetryData.sEngineSpeed=pMemoryExtras->mEngineSpeed; // f32->f32
mTelemetryData.sEngineTorque=pMemoryExtras->mEngineTorque; // f32->f32
mTelemetryData.sWings[0]=pMemoryExtras->mWings[0]; // f32->u8
mTelemetryData.sWings[1]=pMemoryExtras->mWings[1]; // f32->u8
mTelemetryData.sEnforcedPitStopLap=(s8)pMemoryExtras->mEnforcedPitStopLap; // S32->s8

//Car damage
mTelemetryData.sCrashState=(u8)pMemory->mCrashState; // (enum 3 bits)->u8
mTelemetryData.sAeroDamage=(u8)(Clamp(pMemory->mAeroDamage, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sEngineDamage=(u8)(Clamp(pMemory->mEngineDamage, 0.0f, 1.0f)*255.0f); // f32->u8

// Weather
mTelemetryData.sAmbientTemperature=(s8)Clamp(pMemory->mAmbientTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sTrackTemperature=(s8)Clamp(pMemory->mTrackTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sRainDensity=(u8)(Clamp(pMemory->mRainDensity, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sWindSpeed=(u8)(Clamp(pMemory->mWindSpeed*0.5f, 0.0f, 255.0f)); // f32->u8
mTelemetryData.sWindDirectionX=(s8)Clamp(pMemory->mWindDirectionX*127.0f, -127.0f, 127.0f); // f32->s8
mTelemetryData.sWindDirectionY=(s8)Clamp(pMemory->mWindDirectionY*127.0f, -127.0f, 127.0f); // f32->s8

for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 56);i++)
{
mTelemetryData.sParticipantInfo[i].sWorldPosition[0]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[0], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[1]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[1], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[2]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[2], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sCurrentLapDistance=(u16)min(pMemory->mParticipantInfo[i].mCurrentLapDistance, 65535.0f); // f32->u16
mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?127:0); // u32+bool->u8
mTelemetryData.sParticipantInfo[i].sLapsCompleted=(u8)min(pMemory->mParticipantInfo[i].mLapsCompleted, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sCurrentLap=(u8)min(pMemory->mParticipantInfo[i].mCurrentLap, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sSector=(u8)pMemory->mParticipantInfo[i].mCurrentSector; // (enum 3 bits)->u8
// Extra accuracy bits for x/z
u32 x=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[0]*4.0f))&3;
u32 z=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[2]*4.0f))&3;
mTelemetryData.sParticipantInfo[i].sSector=((u8)pMemory->mParticipantInfo[i].mCurrentSector)|((u8)x<<6)|((u8)z<<4); // (enum 3 bits)+(x 2 bits, z 2 bits)->u8
mTelemetryData.sParticipantInfo[i].sLastSectorTime=pMemoryExtras->mLastSectorTime[i]; // f32->f32
}

mTelemetryData.sJoyPad=(u16)JOYPAD BUTTON MASK
mTelemetryData.sDPad=(u8)JOYPAD DPAD MASK

// This packet below is sent less often
BStrcpy(mParticipantStrings.sCarName, 64, pMemory->mCarName);
BStrcpy(mParticipantStrings.sCarClassName, 64, pMemory->mCarClassName);
BStrcpy(mParticipantStrings.sTrackLocation, 64, pMemory->mTrackLocation);
BStrcpy(mParticipantStrings.sTrackVariation, 64, pMemory->mTrackVariation);
for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 16);i++)
{
BStrcpy(mParticipantStrings.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStrings.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStrings.sPacketType=1|((mCount&63)<<2); // Packet type | (sequence<<2)


// These extra packets are sent if participants>16
for (groups of 16)
{
BStrcpy(mParticipantStringsAdditional.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStringsAdditional.sOffset=(u8)OFFSET IN 16's, so 1st packet of this type offset will be 16, 2nd 32 etc
mParticipantStringsAdditional.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStringsAdditional.sPacketType=2|((mCount&63)<<2); // Packet type | (sequence<<2)

221897

SUBGTRACER
11-11-2015, 21:19
I have no idea what all that is ! :) hey but well done Tim

221898

2stains
12-11-2015, 03:46
Yeah I'm pretty sure it must mean something to someone or Tim wouldn't have taken the time to type all that out . Looks like jiberish to me. Hope it translates to something really cool for us on console . Thanks heaps for all the work people have put in .

mr_belowski
12-11-2015, 10:02
I think I've got my stuff all updated now and I'm getting sensible data at my end. The ambient temp and track temp values are always zero though.

I'm not entirely confident that I'm extracting the mIsActive flag and mRacePosition int from the sRacePosition byte. My data look reasonable but it doesn't mean they're right. I'm doing...

sRacePosition >> 7 for the active flag
sRacePosition & 127 for the race position int

does that look right to you guys?

Fil140
12-11-2015, 10:26
I have no idea what all that is ! :) hey but well done Tim

221898

Omg! How can you not understand? Obviously its things n stuff n words n numbers n they do all that bizz with......nah i dont get it either???? Looks cool though, is it swahili?

mr_belowski
12-11-2015, 10:51
Tim - I really can't see how the sequence number stuff can be reliably used to detect and discard out-of-date packets. Because it wraps, and the number of packets lost or delayed in transit can vary, how do we know if a packet with a lower sequence number than the one we're expecting has been delayed and should be discarded? This packet might actually be newer, but all the packets in between have been lost.

There's no sensible rule I can come up with here that'll work.

I know you really need to finalise the structure, but in order for the clients to be able to reliably detect and discard out-of-order packets, I think we really need the sequence number to be an unsigned long

Tim Mann
12-11-2015, 10:52
I think I've got my stuff all updated now and I'm getting sensible data at my end. The ambient temp and track temp values are always zero though.

I'm not entirely confident that I'm extracting the mIsActive flag and mRacePosition int from the sRacePosition byte. My data look reasonable but it doesn't mean they're right. I'm doing...

sRacePosition >> 7 for the active flag
sRacePosition & 127 for the race position int

does that look right to you guys?

Should be about 15 & 20 for temps.

mr_belowski
12-11-2015, 10:57
Gah, my bad, cockup in my mapping, they're both set properly

Tim Mann
12-11-2015, 11:09
Tim - I really can't see how the sequence number stuff can be reliably used to detect and discard out-of-date packets. Because it wraps, and the number of packets lost or delayed in transit can vary, how do we know if a packet with a lower sequence number than the one we're expecting has been delayed and should be discarded? This packet might actually be newer, but all the packets in between have been lost.

There's no sensible rule I can come up with here that'll work.

I know you really need to finalise the structure, but in order for the clients to be able to reliably detect and discard out-of-order packets, I think we really need the sequence number to be an unsigned long

Could always use the current lap time to verify it.

mr_belowski
12-11-2015, 11:11
i'll see what I can come up with

What's the track length being set as?

f32 sTrackLength; // 1362

or

mTelemetryData.sTrackLength=(u16)pMemory->mTrackLength; // f32->u16

Tim Mann
12-11-2015, 11:20
Edited, it's a float.

Tim Mann
12-11-2015, 11:24
If anyone wants their app 'live' tested, it will be useful to give our QA people something to work with.

mr_belowski
12-11-2015, 11:29
Happy to have mine fiddled about with, but bear in mind that I'm building it 'blind' - if I've done something daft with, say, the world position data I can't really tell with just the UDP.bin file, so your testers might get lots of silly spotter calls and stuff. I'm checking some stuff over at the moment, then I'll build an updated version with the new stuff in and give you a shout.

That track length is still not right - it's coming through as something very close to float.min_value at my end. In my struct it's a an f32 immediately before the sDPad byte (after the participantInfo array)

mr_belowski
12-11-2015, 11:55
OK, my app is now updated to use the latest format - the download links are near the bottom of the first post in my Crew Chief thread here:

http://forum.projectcarsgame.com/showthread.php?38922-Crew-Chief-an-alternative-race-engineer-for-PC-users

The "Game" list box at the top right can be scrolled down to show the "Project Cars (network data)" option - select this and click "start application" and the app should be listening for the UDP data. The port number is in the properties UI, and defaults to 5606. Not sure if my app is the best thing to use for testing as it's not going to be displaying much data, but your testers are most welcome to give it a whirl :)

Tim Mann
12-11-2015, 11:58
Happy to have mine fiddled about with, but bear in mind that I'm building it 'blind' - if I've done something daft with, say, the world position data I can't really tell with just the UDP.bin file, so your testers might get lots of silly spotter calls and stuff. I'm checking some stuff over at the moment, then I'll build an updated version with the new stuff in and give you a shout.

That track length is still not right - it's coming through as something very close to float.min_value at my end. In my struct it's a an f32 immediately before the sDPad byte (after the participantInfo array)

You're right, it looks like the packet is truncated and chopping off 2 bytes.

mr_belowski
12-11-2015, 12:01
Does that mean another change to the packet length or struct?

Tim Mann
12-11-2015, 12:13
Does that mean another change to the packet length or struct?

Just checking, packet length is correct, looks like the embedded struct alignment.

Tim Mann
12-11-2015, 12:47
Okay, I needed to swap round a couple of bits at the end, as the embedded struct was getting aligned and the f32 was on a bad boundary. Packet size stays the same:

struct sParticipantInfo
{
s16 sWorldPosition[3]; // 0
u16 sCurrentLapDistance; // 6
u8 sRacePosition; // 8
u8 sLapsCompleted; // 9
u8 sCurrentLap; // 10
u8 sSector; // 11
f32 sLastSectorTime; // 14
// 16
};

struct sParticipantInfoStrings
{
static const u32 sPacketSize = 1347;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
char sCarName[64]; // 3
char sCarClassName[64]; // 131
char sTrackLocation[64]; // 195
char sTrackVariation[64]; // 259
char sName[16][64]; // 323
// 1347
};

struct sParticipantInfoStringsAdditional
{
static const u32 sPacketSize = 1028;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2
u8 sOffset; // 3
char sName[16][64]; // 4
// 1028
};

struct sTelemetryData
{
static const u32 sPacketSize = 1367;
u16 sBuildVersionNumber; // 0
u8 sPacketType; // 2

// Game states
u8 sGameSessionState; // 3

// Participant info
s8 sViewedParticipantIndex; // 4
s8 sNumParticipants; // 5

// Unfiltered input
u8 sUnfilteredThrottle; // 6
u8 sUnfilteredBrake; // 7
s8 sUnfilteredSteering; // 8
u8 sUnfilteredClutch; // 9
u8 sRaceStateFlags; // 10

// Event information
u8 sLapsInEvent; // 11

// Timings
f32 sBestLapTime; // 12
f32 sLastLapTime; // 16
f32 sCurrentTime; // 20
f32 sSplitTimeAhead; // 24
f32 sSplitTimeBehind; // 28
f32 sSplitTime; // 32
f32 sEventTimeRemaining; // 36
f32 sPersonalFastestLapTime; // 40
f32 sWorldFastestLapTime; // 44
f32 sCurrentSector1Time; // 48
f32 sCurrentSector2Time; // 52
f32 sCurrentSector3Time; // 56
f32 sFastestSector1Time; // 60
f32 sFastestSector2Time; // 64
f32 sFastestSector3Time; // 68
f32 sPersonalFastestSector1Time; // 72
f32 sPersonalFastestSector2Time; // 76
f32 sPersonalFastestSector3Time; // 80
f32 sWorldFastestSector1Time; // 84
f32 sWorldFastestSector2Time; // 88
f32 sWorldFastestSector3Time; // 92

u16 sJoyPad; // 96

// Flags
u8 sHighestFlag; // 98

// Pit info
u8 sPitModeSchedule; // 99

// 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
u8 sBoostAmount; // 129
s8 sEnforcedPitStopLap; // 130
u8 sCrashState; // 131

f32 sOdometerKM; // 132
f32 sOrientation[3]; // 136
f32 sLocalVelocity[3]; // 148
f32 sWorldVelocity[3]; // 160
f32 sAngularVelocity[3]; // 172
f32 sLocalAcceleration[3]; // 184
f32 sWorldAcceleration[3]; // 196
f32 sExtentsCentre[3]; // 208

// Wheels / Tyres
u8 sTyreFlags[4]; // 220
u8 sTerrain[4]; // 224
f32 sTyreY[4]; // 228
f32 sTyreRPS[4]; // 244
f32 sTyreSlipSpeed[4]; // 260
u8 sTyreTemp[4]; // 276
u8 sTyreGrip[4]; // 280
f32 sTyreHeightAboveGround[4]; // 284
f32 sTyreLateralStiffness[4]; // 300
u8 sTyreWear[4]; // 316
u8 sBrakeDamage[4]; // 320
u8 sSuspensionDamage[4]; // 324
s16 sBrakeTempCelsius[4]; // 328
u16 sTyreTreadTemp[4]; // 336
u16 sTyreLayerTemp[4]; // 344
u16 sTyreCarcassTemp[4]; // 352
u16 sTyreRimTemp[4]; // 360
u16 sTyreInternalAirTemp[4]; // 368
f32 sWheelLocalPositionY[4]; // 376
f32 sRideHeight[4]; // 392
f32 sSuspensionTravel[4]; // 408
f32 sSuspensionVelocity[4]; // 424
u16 sAirPressure[4]; // 440

// Extras
f32 sEngineSpeed; // 448
f32 sEngineTorque; // 452

// Car damage
u8 sAeroDamage; // 456
u8 sEngineDamage; // 457

// Weather
s8 sAmbientTemperature; // 458
s8 sTrackTemperature; // 459
u8 sRainDensity; // 460
s8 sWindSpeed; // 461
s8 sWindDirectionX; // 462
s8 sWindDirectionY; // 463

sParticipantInfo sParticipantInfo[56]; // 464
// 56*16=896
// Buttons
f32 sTrackLength; // 1360
u8 sWings[2]; // 1364
u8 sDPad; // 1366
// 1368 struct is padded to
};


mBuildVersionNumber=mTelemetryData.sBuildVersionNumber=(u16)pMemory->mBuildVersionNumber; // u32->u16
mTelemetryData.sPacketType=0|((mCount&63)<<2); // Packet type | (sequence<<2)

// Game state
mTelemetryData.sGameSessionState=((u8)pMemory->mGameState)|(((u8)pMemory->mSessionState)<<4); // (enum 3 bits/enum 3 bits)->u8
mTelemetryData.sRaceStateFlags=((u8)pMemory->mRaceState) | // (enum 3 bits)->u8
(pMemory->mLapInvalidated?8:0)|(pMemory->mAntiLockActive?16:0)|(pMemory->mBoostActive?32:0); // (bool/bool/bool)->u8

// Participant info
mTelemetryData.sViewedParticipantIndex=(s8)pMemory->mViewedParticipantIndex; // s32->s8
mTelemetryData.sNumParticipants=(s8)pMemory->mNumParticipants; // s32->s8

// Unfiltered input
mTelemetryData.sUnfilteredThrottle=(u8)(Clamp(pMemory->mUnfilteredThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredBrake=(u8)(Clamp(pMemory->mUnfilteredBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sUnfilteredSteering=(s8)(Clamp(pMemory->mUnfilteredSteering, -1.0f, 1.0f)*127.0f); // f32->s8
mTelemetryData.sUnfilteredClutch=(u8)(Clamp(pMemory->mUnfilteredClutch, 0.0f, 1.0f)*255.0f); // f32->u8

// Event information
mTelemetryData.sTrackLength=(f32)pMemory->mTrackLength; // f32->f32
mTelemetryData.sLapsInEvent=(u8)min(pMemory->mLapsInEvent,255); // u32->u8

// Timings
mTelemetryData.sBestLapTime=pMemory->mBestLapTime; // f32->f32
mTelemetryData.sLastLapTime=pMemory->mLastLapTime; // f32->f32
mTelemetryData.sCurrentTime=pMemory->mCurrentTime; // f32->f32
mTelemetryData.sSplitTimeAhead=pMemory->mSplitTimeAhead; // f32->f32
mTelemetryData.sSplitTimeBehind=pMemory->mSplitTimeBehind; // f32->f32
mTelemetryData.sSplitTime=pMemory->mSplitTime; // f32->f32
mTelemetryData.sEventTimeRemaining=pMemory->mEventTimeRemaining; // f32->f32
mTelemetryData.sPersonalFastestLapTime=pMemory->mPersonalFastestLapTime; // f32->f32
mTelemetryData.sWorldFastestLapTime=pMemory->mWorldFastestLapTime; // f32->f32
mTelemetryData.sCurrentSector1Time=pMemory->mCurrentSector1Time; // f32->f32
mTelemetryData.sCurrentSector2Time=pMemory->mCurrentSector2Time; // f32->f32
mTelemetryData.sCurrentSector3Time=pMemory->mCurrentSector3Time; // f32->f32
mTelemetryData.sFastestSector1Time=pMemory->mFastestSector1Time; // f32->f32
mTelemetryData.sFastestSector2Time=pMemory->mFastestSector2Time; // f32->f32
mTelemetryData.sFastestSector3Time=pMemory->mFastestSector3Time; // f32->f32
mTelemetryData.sPersonalFastestSector1Time=pMemory->mPersonalFastestSector1Time; // f32->f32
mTelemetryData.sPersonalFastestSector2Time=pMemory->mPersonalFastestSector2Time; // f32->f32
mTelemetryData.sPersonalFastestSector3Time=pMemory->mPersonalFastestSector3Time; // f32->f32
mTelemetryData.sWorldFastestSector1Time=pMemory->mWorldFastestSector1Time; // f32->f32
mTelemetryData.sWorldFastestSector2Time=pMemory->mWorldFastestSector2Time; // f32->f32
mTelemetryData.sWorldFastestSector3Time=pMemory->mWorldFastestSector3Time; // f32->f32

// Flags
mTelemetryData.sHighestFlag=((u8)pMemory->mHighestFlagColour) | (((u8)pMemory->mHighestFlagReason)<<4); // (enum 3 bits/enum 2 bits)

// Pit info
mTelemetryData.sPitModeSchedule=((u8)pMemory->mPitMode) | (((u8)pMemory->mPitSchedule)<<4); // (enum 3 bits/enum 2 bits)

// Car state
mTelemetryData.sCarFlags=(u8)pMemory->mCarFlags; // enum->u8
mTelemetryData.sOilTempCelsius=(s16)pMemory->mOilTempCelsius; // f32->s16
mTelemetryData.sOilPressureKPa=(u16)pMemory->mOilPressureKPa; // f32->u16
mTelemetryData.sWaterTempCelsius=(s16)pMemory->mWaterTempCelsius; // f32->s16
mTelemetryData.sWaterPressureKpa=(u16)pMemory->mWaterPressureKPa; // f32->u16
mTelemetryData.sFuelPressureKpa=(u16)pMemory->mFuelPressureKPa; // f32->u16
mTelemetryData.sFuelCapacity=(u8)pMemory->mFuelCapacity; // f32->u8
mTelemetryData.sBrake=(u8)(Clamp(pMemory->mBrake, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sFuelLevel=pMemory->mFuelLevel; // f32->f32
mTelemetryData.sSpeed=pMemory->mSpeed; // f32->f32
mTelemetryData.sRpm=(u16)pMemory->mRpm; // f32->u16
mTelemetryData.sMaxRpm=(u16)pMemory->mMaxRPM; // f32->u16
mTelemetryData.sThrottle=(u8)(Clamp(pMemory->mThrottle, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sClutch=(u8)(Clamp(pMemory->mClutch, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSteering=(s8)(Clamp(pMemory->mSteering, -1.0f, 1.0f)*127.0f); // f32->s8
u8 gear=pMemory->mGear<0?0x0f:min((u8)(pMemory->mGear&0xff), 7);
u8 numGears=max((u8)(pMemory->mNumGears&0xff), 0);
mTelemetryData.sGearNumGears=(gear&0x0f)|((numGears&0x0f)<<4); // s32/s32->u8
mTelemetryData.sOdometerKM=pMemory->mOdometerKM; // f32->f32
mTelemetryData.sBoostAmount=(u8)pMemory->mBoostAmount; // f32->u8
mTelemetryData.sOrientation[0]=pMemory->mOrientation[0]; // f32->f32
mTelemetryData.sOrientation[1]=pMemory->mOrientation[1]; // f32->f32
mTelemetryData.sOrientation[2]=pMemory->mOrientation[2]; // f32->f32
mTelemetryData.sLocalVelocity[0]=pMemory->mLocalVelocity[0]; // f32->f32
mTelemetryData.sLocalVelocity[1]=pMemory->mLocalVelocity[1]; // f32->f32
mTelemetryData.sLocalVelocity[2]=pMemory->mLocalVelocity[2]; // f32->f32
mTelemetryData.sWorldVelocity[0]=pMemory->mWorldVelocity[0]; // f32->f32
mTelemetryData.sWorldVelocity[1]=pMemory->mWorldVelocity[1]; // f32->f32
mTelemetryData.sWorldVelocity[2]=pMemory->mWorldVelocity[2]; // f32->f32
mTelemetryData.sAngularVelocity[0]=pMemory->mAngularVelocity[0]; // f32->f32
mTelemetryData.sAngularVelocity[1]=pMemory->mAngularVelocity[1]; // f32->f32
mTelemetryData.sAngularVelocity[2]=pMemory->mAngularVelocity[2]; // f32->f32
mTelemetryData.sLocalAcceleration[0]=pMemory->mLocalAcceleration[0]; // f32->f32
mTelemetryData.sLocalAcceleration[1]=pMemory->mLocalAcceleration[1]; // f32->f32
mTelemetryData.sLocalAcceleration[2]=pMemory->mLocalAcceleration[2]; // f32->f32
mTelemetryData.sWorldAcceleration[0]=pMemory->mWorldAcceleration[0]; // f32->f32
mTelemetryData.sWorldAcceleration[1]=pMemory->mWorldAcceleration[1]; // f32->f32
mTelemetryData.sWorldAcceleration[2]=pMemory->mWorldAcceleration[2]; // f32->f32
mTelemetryData.sExtentsCentre[0]=pMemory->mExtentsCentre[0]; // f32->f32
mTelemetryData.sExtentsCentre[1]=pMemory->mExtentsCentre[1]; // f32->f32
mTelemetryData.sExtentsCentre[2]=pMemory->mExtentsCentre[2]; // f32->f32

// Wheels / Tyres
u32 i;
for (i=0;i<4;i++)
{
mTelemetryData.sTyreFlags[i]=(u8)pMemory->mTyreFlags[i]; // (enum 3 bits)->u8
mTelemetryData.sTerrain[i]=(u8)pMemory->mTerrain[i]; // (enum 6 bits)->u8
mTelemetryData.sTyreY[i]=pMemory->mTyreY[i]; // f32->f32
mTelemetryData.sTyreRPS[i]=pMemory->mTyreRPS[i]; // f32->f32
mTelemetryData.sTyreSlipSpeed[i]=pMemory->mTyreSlipSpeed[i]; // f32->f32
mTelemetryData.sTyreTemp[i]=(u8)Clamp(pMemory->mTyreTemp[i], 0.0f, 255.0f); // f32->u8
mTelemetryData.sTyreGrip[i]=(u8)Clamp(pMemory->mTyreGrip[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sTyreHeightAboveGround[i]=pMemory->mTyreHeightAboveGround[i]; // f32->f32
mTelemetryData.sTyreLateralStiffness[i]=pMemory->mTyreLateralStiffness[i]; // f32->f32
mTelemetryData.sTyreWear[i]=(u8)(Clamp(pMemory->mTyreWear[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeDamage[i]=(u8)(Clamp(pMemory->mBrakeDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sSuspensionDamage[i]=(u8)(Clamp(pMemory->mSuspensionDamage[i], 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sBrakeTempCelsius[i]=(s16)pMemory->mBrakeTempCelsius[i]; // f32->s16
mTelemetryData.sTyreTreadTemp[i]=(u16)pMemory->mTyreTreadTemp[i]; // f32->u16
mTelemetryData.sTyreLayerTemp[i]=(u16)pMemory->mTyreLayerTemp[i]; // f32->u16
mTelemetryData.sTyreCarcassTemp[i]=(u16)pMemory->mTyreCarcassTemp[i]; // f32->u16
mTelemetryData.sTyreRimTemp[i]=(u16)pMemory->mTyreRimTemp[i]; // f32->u16
mTelemetryData.sTyreInternalAirTemp[i]=(u16)pMemory->mTyreInternalAirTemp[i]; // f32->u16
mTelemetryData.sWheelLocalPositionY[i]=pMemoryExtras->mWheelLocalPositionY[i]; // f32->f32
mTelemetryData.sRideHeight[i]=pMemoryExtras->mRideHeight[i]; // f32->f32
mTelemetryData.sSuspensionTravel[i]=pMemoryExtras->mSuspensionTravel[i]; // f32->f32
mTelemetryData.sSuspensionVelocity[i]=pMemoryExtras->mSuspensionVelocity[i]; // f32->f32
mTelemetryData.sAirPressure[i]=pMemoryExtras->mAirPressure[i]; // f32->u16
}

// Extras
mTelemetryData.sEngineSpeed=pMemoryExtras->mEngineSpeed; // f32->f32
mTelemetryData.sEngineTorque=pMemoryExtras->mEngineTorque; // f32->f32
mTelemetryData.sWings[0]=pMemoryExtras->mWings[0]; // f32->u8
mTelemetryData.sWings[1]=pMemoryExtras->mWings[1]; // f32->u8
mTelemetryData.sEnforcedPitStopLap=(s8)pMemoryExtras->mEnforcedPitStopLap; // S32->s8

//Car damage
mTelemetryData.sCrashState=(u8)pMemory->mCrashState; // (enum 3 bits)->u8
mTelemetryData.sAeroDamage=(u8)(Clamp(pMemory->mAeroDamage, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sEngineDamage=(u8)(Clamp(pMemory->mEngineDamage, 0.0f, 1.0f)*255.0f); // f32->u8

// Weather
mTelemetryData.sAmbientTemperature=(s8)Clamp(pMemory->mAmbientTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sTrackTemperature=(s8)Clamp(pMemory->mTrackTemperature, -127.0f, 127.0f); // f32->s8
mTelemetryData.sRainDensity=(u8)(Clamp(pMemory->mRainDensity, 0.0f, 1.0f)*255.0f); // f32->u8
mTelemetryData.sWindSpeed=(u8)(Clamp(pMemory->mWindSpeed*0.5f, 0.0f, 255.0f)); // f32->u8
mTelemetryData.sWindDirectionX=(s8)Clamp(pMemory->mWindDirectionX*127.0f, -127.0f, 127.0f); // f32->s8
mTelemetryData.sWindDirectionY=(s8)Clamp(pMemory->mWindDirectionY*127.0f, -127.0f, 127.0f); // f32->s8

for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 56);i++)
{
mTelemetryData.sParticipantInfo[i].sWorldPosition[0]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[0], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[1]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[1], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sWorldPosition[2]=(s16)Clamp(pMemory->mParticipantInfo[i].mWorldPosition[2], -32768.0f, 32767.0f); // f32->s16
mTelemetryData.sParticipantInfo[i].sCurrentLapDistance=(u16)min(pMemory->mParticipantInfo[i].mCurrentLapDistance, 65535.0f); // f32->u16
mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?127:0); // u32+bool->u8
mTelemetryData.sParticipantInfo[i].sLapsCompleted=(u8)min(pMemory->mParticipantInfo[i].mLapsCompleted, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sCurrentLap=(u8)min(pMemory->mParticipantInfo[i].mCurrentLap, 255); // u32->u8
mTelemetryData.sParticipantInfo[i].sSector=(u8)pMemory->mParticipantInfo[i].mCurrentSector; // (enum 3 bits)->u8
// Extra accuracy bits for x/z
u32 x=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[0]*4.0f))&3;
u32 z=((u32)floorf(pMemory->mParticipantInfo[i].mWorldPosition[2]*4.0f))&3;
mTelemetryData.sParticipantInfo[i].sSector=((u8)pMemory->mParticipantInfo[i].mCurrentSector)|((u8)x<<6)|((u8)z<<4); // (enum 3 bits)+(x 2 bits, z 2 bits)->u8
mTelemetryData.sParticipantInfo[i].sLastSectorTime=pMemoryExtras->mLastSectorTime[i]; // f32->f32
}

mTelemetryData.sJoyPad=(u16)JOYPAD BUTTON MASK
mTelemetryData.sDPad=(u8)JOYPAD DPAD MASK

// This packet below is sent less often
BStrcpy(mParticipantStrings.sCarName, 64, pMemory->mCarName);
BStrcpy(mParticipantStrings.sCarClassName, 64, pMemory->mCarClassName);
BStrcpy(mParticipantStrings.sTrackLocation, 64, pMemory->mTrackLocation);
BStrcpy(mParticipantStrings.sTrackVariation, 64, pMemory->mTrackVariation);
for (i=0;i<(u32)Clamp(pMemory->mNumParticipants, 0, 16);i++)
{
BStrcpy(mParticipantStrings.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStrings.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStrings.sPacketType=1|((mCount&63)<<2); // Packet type | (sequence<<2)


// These extra packets are sent if participants>16
for (groups of 16)
{
BStrcpy(mParticipantStringsAdditional.sName[i], 64, pMemory->mParticipantInfo[i].mName);
}
mParticipantStringsAdditional.sOffset=(u8)OFFSET IN 16's, so 1st packet of this type offset will be 16, 2nd 32 etc
mParticipantStringsAdditional.sBuildVersionNumber=mBuildVersionNumber;
mParticipantStringsAdditional.sPacketType=2|((mCount&63)<<2); // Packet type | (sequence<<2)


221909

mr_belowski
12-11-2015, 13:15
hmm... the second sParticipantInfoStringsAdditional (type 2) packet I receive has an sOffset value of 101

mr_belowski
12-11-2015, 13:32
I also see that the enforcedPitStopLap value is getting set to a very large number, the fuelLevel is a very small number, and the engineTorque is negative

Tim Mann
12-11-2015, 13:35
pit stop is 0xff if not set, can you confirm the offset thing?, it's looking correct in the struct

mr_belowski
12-11-2015, 13:40
looking now, will be a while. According to my stuff, the .bin file is sending a type 2 (additional strings) before the type 1 (strings)

cjorgens79
12-11-2015, 14:09
ive just been trying to track down an issue with the previous udp.bin relating to raceposition, as its outputting a race position of 65 at one point (see byte 1904346 of the previous udp.bin). Is that intended to be a -1? using the 7th bit as the negaive sign since the 8th bit is the IsActive bool.?

cjorgens79
12-11-2015, 14:14
actually i see what the issue is, you've somehow reverted to the bug you had earlier where you were or'ing with 127 instead of 128

mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?127:0); // u32+bool->u8

cjorgens79
12-11-2015, 14:20
something does appear screwy with the latest bin file.. trying to figure out what now

mr_belowski
12-11-2015, 14:22
I think it's quite a mess to be honest - looks like the alignment is getting screwed up somewhere

cjorgens79
12-11-2015, 14:26
yep, goto the packet starting at position 125425, it should be 1367 bytes, but its actually 1706 bytes until the next packet starts, something is getting corrupted

mr_belowski
12-11-2015, 14:26
I've been Ninja'd :)

And I've been incorrect :(

Good spot fella - again, I've been chasing around in the dark looking for where I've screwed up

cjorgens79
12-11-2015, 14:37
If anyone wants their app 'live' tested, it will be useful to give our QA people something to work with.

Yes please, PM me with the email addresses of some account(s) the QA people can use for iTunes or Google play (and which store it is) and ill add those addresses to the appropriate beta program so they can download the beta builds. Tablets will provide best experience, ideally its probably worth testing both an iOS and Android device if possible to see if there is any problems receiving the UDP broadcast stream.

cjorgens79
12-11-2015, 14:39
I've been Ninja'd :)

And I've been incorrect :(

Good spot fella - again, I've been chasing around in the dark looking for where I've screwed up

i just added a little validator to my udp.bin transmitter to check the file structure is as expected all the way through and if not, where exactly it breaks.

Tim Mann
12-11-2015, 14:41
actually i see what the issue is, you've somehow reverted to the bug you had earlier where you were or'ing with 127 instead of 128

mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?127:0); // u32+bool->u8

That's only wrong in the description, the race position comes from the normal telemetry struct.

Tim Mann
12-11-2015, 14:46
yep, goto the packet starting at position 125425, it should be 1367 bytes, but its actually 1706 bytes until the next packet starts, something is getting corrupted

Oh that's weird, that looks like the last part of the packet has been duplicated, I think that's more down to the file being corrupt (It's actually being saved from the PS4, so travels back across the network to the host PC). I'll save another one out now. I'll slow the rate down, I think I may actually be causing my own packet loss...

Tim Mann
12-11-2015, 14:58
Sorry about that chaps, sending out dud test data is bad form.

221919

cjorgens79
12-11-2015, 15:20
That's only wrong in the description, the race position comes from the normal telemetry struct.

I was seeing bad values in the raceposition field, which is why i investigated. For example i was seeing a race position of 65, which is outside the valid range.

cjorgens79
12-11-2015, 15:34
tested the latest bin file and all seems to be ok, no bad values in that one that ive found, but its alot shorter than the other ones due to the low capture rate.

cjorgens79
12-11-2015, 15:39
Tim - I really can't see how the sequence number stuff can be reliably used to detect and discard out-of-date packets. Because it wraps, and the number of packets lost or delayed in transit can vary, how do we know if a packet with a lower sequence number than the one we're expecting has been delayed and should be discarded? This packet might actually be newer, but all the packets in between have been lost.

I may be wrong here, but i dont think you need to worry about getting packets out of order on a local network, i think that only applies to sending over WAN where each packet can actually be routed through a different path to get to the endpoint, and one path may be shorter / quicker than the other hence they arrive out of order. In a wifi LAN environment there is only one path, so i wouldn't think its an issue. You may however lose packets, but if you just take them as you get them they should be in order.

Jussi Viljami Karjalainen
12-11-2015, 15:47
Quick question to clarify: Are programs running on the same computer the game is running on capable of using this new data without wifi? My desktop doesn't actually have wifi. =/

TheReaper GT
12-11-2015, 15:48
Quick question to clarify: Are programs running on the same computer the game is running on capable of using this new data without wifi? My desktop doesn't actually have wifi. =/

It is connected to the network, right?

Tim Mann
12-11-2015, 16:03
I was seeing bad values in the raceposition field, which is why i investigated. For example i was seeing a race position of 65, which is outside the valid range.

Just a thought, but I think on that test I got DQ'd, is the participant that has that race position me?

mr_belowski
12-11-2015, 16:03
Yes they are. Its how I'm testing my stuff

Jussi Viljami Karjalainen
12-11-2015, 16:38
It is connected to the network, right?My layout is maybe a tad unorthodox in that I have an RJ-45 socket right in my wall (the whole building shares a really quick fiber connection), which goes into a switch, which then goes to my PC with a normal cable, and a wifi router that handles my mobile devices. The reason I don't connect my PC to the wifi router is because of NAT reasons, I have to have my PC on a public IP straight up, but I also want to keep the NAT up on the router to give my mobile devices non-public IPs. Before Windows 8 removed support for some older wlan-chips I also had my desktop simultaneously on wired and wireless, but that isn't an option now (unless I buy a new wifi card just for this, which I'm not really inclined to do).

So yeah, my desktop does have a wired internet connection, and it is the one that'll run the game and all programs (I'm not looking into running any phone or tablet apps).
Yes they are. Its how I'm testing my stuffExcellent, thanks for the confirmation. =)

TheReaper GT
12-11-2015, 16:39
My layout is maybe a tad unorthodox in that I have an RJ-45 socket right in my wall (the whole building shares a really quick fiber connection), which goes into a switch, which then goes to my PC with a normal cable, and a wifi router that handles my mobile devices. The reason I don't connect my PC to the wifi router is because of NAT reasons, I have to have my PC on a public IP straight up, but I also want to keep the NAT up on the router to give my mobile devices non-public IPs. Before Windows 8 removed support for some older wlan-chips I also had my desktop simultaneously on wired and wireless, but that isn't an option now (unless I buy a new wifi card just for this, which I'm not really inclined to do).

So yeah, my desktop does have a wired internet connection, and it is the one that'll run the game and all programs (I'm not looking into running any phone or tablet apps).Excellent, thanks for the confirmation. =)

I guess if you run the apps on the same PC as the game all you have to do is point them to 127.0.0.1 (localhost) :D

To use the mobile apps on phones and tablets you will have to be under the same network...

Jussi Viljami Karjalainen
12-11-2015, 17:10
I guess if you run the apps on the same PC as the game all you have to do is point them to 127.0.0.1 (localhost) :DWas my thinking as well but wanted to make sure.
To use the mobile apps on phones and tablets you will have to be under the same network...Yeah, I know this much. =)

TheReaper GT
12-11-2015, 17:23
cjorgens79 can you put a Cosworth Omega dash skin on pCars Dash?

Tim Mann
12-11-2015, 20:42
OK, my app is now updated to use the latest format - the download links are near the bottom of the first post in my Crew Chief thread here:

http://forum.projectcarsgame.com/showthread.php?38922-Crew-Chief-an-alternative-race-engineer-for-PC-users

The "Game" list box at the top right can be scrolled down to show the "Project Cars (network data)" option - select this and click "start application" and the app should be listening for the UDP data. The port number is in the properties UI, and defaults to 5606. Not sure if my app is the best thing to use for testing as it's not going to be displaying much data, but your testers are most welcome to give it a whirl :)

Downloaded and tested.

I really didn't need it to say "You are last". Worked perfectly as far as I could tell. Was getting lap times, position reports etc.

mr_belowski
12-11-2015, 21:14
Ah, but *were* you last? Perhaps the app felt it needed to tell you :)

Glad to hear it's working. Did the spotter behave itself?

Tim Mann
12-11-2015, 21:23
Ah, but *were* you last? Perhaps the app felt it needed to tell you :)

Glad to hear it's working. Did the spotter behave itself?

I think the only time I've ever been first is with no other cars. I didn't see any issues, all the names seemed to come through, I'll pop the tty here (2 races, 2 laps):

20:24:56.317 : *** Processed radio_check/test
20:32:39.465 : Using player steam ID q-aa57635d-GB-en from the first reported viewed participant
20:32:39.480 : Using car class LMP1 for class name LMP1
20:32:39.491 : Player is using car class LMP1 (class name LMP1)
20:32:39.522 : New session, trigger...
20:32:39.534 : lastSessionType = Unavailable currentGameState.SessionData.SessionType = Practice
20:32:39.548 : Using car class LMP1 for class name LMP1
20:32:39.556 : Player is using car class LMP1 (class name LMP1)
20:32:39.577 : New session details...
20:32:39.586 : SessionType Practice
20:32:39.594 : EventIndex 0
20:32:39.603 : SessionIteration 0
20:32:39.610 : TrackName Brands Hatch:Grand Prix
20:32:39.617 : Clearing game state...
20:32:39.671 : Using unmapped driver last name Funnell for raw driver name Alex Funnell
20:32:39.688 : Using unmapped driver last name Gerrard for raw driver name Brosef Gerrard
20:32:39.701 : Using unmapped driver last name Motz for raw driver name Howard Motz
20:32:39.710 : Using unmapped driver last name de Smit for raw driver name Jaco de Smit
20:32:39.720 : Using unmapped driver last name Resende for raw driver name Laurent Resende
20:32:39.729 : Using unmapped driver last name Lebioda for raw driver name Mariusz Lebioda
20:32:39.738 : Using unmapped driver last name Octau for raw driver name Maxime Octau
20:32:39.747 : Using unmapped driver last name Zomaya for raw driver name Michael Zomaya
20:32:39.756 : Using unmapped driver last name Shiells for raw driver name Paul Shiells
20:32:39.764 : Using unmapped driver last name Jensen for raw driver name Peter Jensen
20:32:39.774 : Using unmapped driver last name Longley for raw driver name Peter Longley
20:32:39.783 : Using unmapped driver last name Tapper for raw driver name Stefan Tapper
20:32:39.792 : Using unmapped driver last name Baker for raw driver name Steven Baker
20:32:39.801 : Using unmapped driver last name de Vries for raw driver name Taeke de Vries
20:32:39.810 : Using unmapped driver last name Kerr for raw driver name Tom Kerr
20:32:39.819 : Unable to create a usable driver name for q-aa57635d-GB-en
20:32:39.998 : Cached sound files for driver names:
20:32:40.019 : de Vries, Gerrard, Jensen, Kerr, Resende, Shiells, Tapper
20:32:40.032 : These driver names have no sound file:
20:32:40.044 : Funnell, Motz, de Smit, Lebioda, Octau, Zomaya, Longley, Baker
20:32:40.110 : ********** starting spotter***********
20:32:40.134 : Invoking spotter every 50ms, pausing 6ms between invocations
20:32:48.477 : Using car class LMP1 for class name LMP1
20:32:48.498 : Player is using car class LMP1 (class name LMP1)
20:32:48.518 : Just gone green, session details...
20:32:48.527 : SessionType Practice
20:32:48.541 : SessionPhase Green
20:32:48.551 : previous SessionPhase Countdown
20:32:48.560 : EventIndex 0
20:32:48.574 : SessionIteration 0
20:32:48.584 : HasMandatoryPitStop False
20:32:48.593 : PitWindowStart 0
20:32:48.611 : PitWindowEnd 0
20:32:48.632 : NumCarsAtStartOfSession 21
20:32:48.641 : SessionNumberOfLaps 2
20:32:48.651 : SessionRunTime 0
20:32:48.668 : SessionStartPosition 0
20:32:48.689 : SessionStartTime 12/11/2015 20:32:39
20:32:48.706 : TrackName Brands Hatch:Grand Prix
20:32:48.725 : Laps completed = 0
20:32:48.735 : Time elapsed = 9.013045
20:32:48.744 : Position = 1
20:32:48.753 : Session phase = Green
20:32:54.486 : Initial fuel level = 11.93321
20:33:05.071 : Creating opponent for name Alberto Garcia
20:33:05.097 : Using unmapped driver last name Garcia for raw driver name Alberto Garcia
20:33:05.125 : Caching driver name sound file for Garcia
20:33:05.137 : Creating opponent for name Jagdeep Rai
20:33:05.148 : Using unmapped driver last name Rai for raw driver name Jagdeep Rai
20:33:05.167 : Creating opponent for name Arnaud Blondeel
20:33:05.178 : Using unmapped driver last name Blondeel for raw driver name Arnaud Blondeel
20:33:05.195 : Creating opponent for name Adam Birtwistle
20:33:05.204 : Using unmapped driver last name Birtwistle for raw driver name Adam Birtwistle
20:33:05.221 : Creating opponent for name André Behrami
20:33:05.231 : Using unmapped driver last name Behrami for raw driver name André Behrami
20:33:05.248 : Caching driver name sound file for Behrami
20:33:12.804 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:33:13.834 : *** Processed spotter/car_right
20:33:16.995 : *** Processed spotter/still_there
20:33:18.602 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:33:19.667 : *** Processed spotter/clear_right
20:33:31.599 : car left, carsOnLeftCount 1 carsOnRightCount 0 hasCarLeft False hasCarRight False
20:33:32.004 : clear left, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft True hasCarRight False
20:33:33.382 : *** Processed penalties/lap_deleted
20:33:34.282 : *** Processed spotter/clear_left
20:34:12.399 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:34:13.313 : *** Processed spotter/car_right
20:34:13.799 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:34:14.925 : *** Processed spotter/clear_right
20:34:24.402 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:34:24.605 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:34:25.200 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:34:26.187 : *** Processed spotter/car_right
20:34:26.209 : Closing channel left open in spotter
20:34:27.486 : Leader fast lap - this lap time = 96.6674 session best = 96.6674
20:34:31.543 : *** Processed COMPOUND_leader_good_laptime
20:34:43.468 : Car ahead fast lap - this lap time = 106.825 session best = 96.0101
20:34:47.651 : *** Processed COMPOUND_car_ahead_good_laptime
20:34:53.619 : Laps completed = 1
20:34:53.642 : Time elapsed = 134.1552
20:34:53.657 : Position = 21
20:34:53.671 : Session phase = Green
20:34:55.171 : *** Processed position/last
20:35:18.315 : *** Processed penalties/lap_deleted
20:35:59.850 : Leader fast lap - this lap time = 92.36345 session best = 92.36345
20:36:03.005 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:36:03.201 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:36:04.313 : *** Processed COMPOUND_leader_good_laptime
20:36:21.674 : Car ahead fast lap - this lap time = 98.63728 session best = 92.36345
20:36:25.698 : *** Processed COMPOUND_car_ahead_good_laptime
20:36:38.203 : Laps completed = 2
20:36:38.225 : Time elapsed = 238.7392
20:36:38.237 : Position = 21
20:36:38.249 : Session phase = Unavailable
20:37:27.363 : New session, trigger...
20:37:27.385 : lastSessionLapsCompleted = 2 currentGameState.SessionData.CompletedLaps = 0
20:37:27.404 : Using car class LMP1 for class name LMP1
20:37:27.418 : Player is using car class LMP1 (class name LMP1)
20:37:27.429 : New session details...
20:37:27.439 : SessionType Practice
20:37:27.448 : EventIndex 0
20:37:27.456 : SessionIteration 0
20:37:27.465 : TrackName Brands Hatch:Grand Prix
20:37:27.474 : Clearing game state...
20:37:27.490 : Using unmapped driver last name Birtwistle for raw driver name Adam Birtwistle
20:37:27.498 : Using unmapped driver last name Garcia for raw driver name Alberto Garcia
20:37:27.507 : Using unmapped driver last name Funnell for raw driver name Alex Funnell
20:37:27.516 : Using unmapped driver last name Behrami for raw driver name André Behrami
20:37:27.525 : Using unmapped driver last name Blondeel for raw driver name Arnaud Blondeel
20:37:27.534 : Using unmapped driver last name Gerrard for raw driver name Brosef Gerrard
20:37:27.543 : Using unmapped driver last name Motz for raw driver name Howard Motz
20:37:27.553 : Using unmapped driver last name de Smit for raw driver name Jaco de Smit
20:37:27.562 : Using unmapped driver last name Rai for raw driver name Jagdeep Rai
20:37:27.571 : Using unmapped driver last name Resende for raw driver name Laurent Resende
20:37:27.579 : Using unmapped driver last name Lebioda for raw driver name Mariusz Lebioda
20:37:27.589 : Using unmapped driver last name Octau for raw driver name Maxime Octau
20:37:27.597 : Using unmapped driver last name Zomaya for raw driver name Michael Zomaya
20:37:27.607 : Using unmapped driver last name Shiells for raw driver name Paul Shiells
20:37:27.616 : Using unmapped driver last name Jensen for raw driver name Peter Jensen
20:37:27.625 : Using unmapped driver last name Longley for raw driver name Peter Longley
20:37:27.634 : Using unmapped driver last name Tapper for raw driver name Stefan Tapper
20:37:27.643 : Using unmapped driver last name Baker for raw driver name Steven Baker
20:37:27.652 : Using unmapped driver last name de Vries for raw driver name Taeke de Vries
20:37:27.661 : Using unmapped driver last name Kerr for raw driver name Tom Kerr
20:37:27.670 : Unable to create a usable driver name for q-aa57635d-GB-en
20:37:27.718 : Cached sound files for driver names:
20:37:27.727 : Behrami, de Vries, Garcia, Gerrard, Jensen, Kerr, Resende, Shiells, Tapper
20:37:27.737 : These driver names have no sound file:
20:37:27.746 : Birtwistle, Funnell, Blondeel, Motz, de Smit, Rai, Lebioda, Octau, Zomaya, Longley, Baker
20:37:39.750 : Using car class LMP1 for class name LMP1
20:37:39.772 : Player is using car class LMP1 (class name LMP1)
20:37:39.790 : Just gone green, session details...
20:37:39.800 : SessionType Practice
20:37:39.810 : SessionPhase Green
20:37:39.819 : previous SessionPhase Countdown
20:37:39.828 : EventIndex 0
20:37:39.838 : SessionIteration 0
20:37:39.847 : HasMandatoryPitStop False
20:37:39.856 : PitWindowStart 0
20:37:39.865 : PitWindowEnd 0
20:37:39.874 : NumCarsAtStartOfSession 21
20:37:39.883 : SessionNumberOfLaps 2
20:37:39.892 : SessionRunTime 0
20:37:39.901 : SessionStartPosition 0
20:37:39.910 : SessionStartTime 12/11/2015 20:37:27
20:37:39.919 : TrackName Brands Hatch:Grand Prix
20:37:39.928 : Laps completed = 0
20:37:39.936 : Time elapsed = 12.38656
20:37:39.948 : Position = 1
20:37:39.957 : Session phase = Green
20:37:42.454 : Initial fuel level = 11.95667
20:38:03.949 : car left, carsOnLeftCount 1 carsOnRightCount 0 hasCarLeft False hasCarRight False
20:38:04.152 : clear left, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft True hasCarRight False
20:38:04.949 : car left, carsOnLeftCount 1 carsOnRightCount 0 hasCarLeft False hasCarRight False
20:38:05.949 : clear left, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft True hasCarRight False
20:38:06.042 : *** Processed spotter/car_left
20:38:06.928 : *** Processed spotter/clear_left
20:39:10.155 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:10.350 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:10.755 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:10.951 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:19.587 : Leader fast lap - this lap time = 97.34969 session best = 97.34969
20:39:23.221 : *** Processed COMPOUND_leader_good_laptime
20:39:25.851 : Car ahead fast lap - this lap time = 101.6726 session best = 97.34969
20:39:26.821 : Laps completed = 1
20:39:26.842 : Time elapsed = 119.4576
20:39:26.859 : Position = 7
20:39:26.868 : Session phase = Green
20:39:27.790 : Car behind fast lap - this lap time = 103.1793 session best = 97.34969
20:39:30.458 : *** Processed COMPOUND_car_ahead_good_laptime
20:39:30.480 : There are 2 more events in the queue, playing them...
20:39:34.663 : *** Processed position/p7, COMPOUND_car_behind_good_laptime
20:39:39.354 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:39.551 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:39.754 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:40.155 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:40.664 : *** Processed spotter/car_right
20:39:40.742 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:41.470 : *** Processed spotter/clear_right
20:39:41.548 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:41.627 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:42.356 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:42.945 : *** Processed spotter/car_right
20:39:43.023 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:43.802 : *** Processed spotter/clear_right
20:39:43.880 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:44.953 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:45.365 : *** Processed spotter/clear_right
20:39:45.752 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:46.924 : *** Processed spotter/clear_right
20:39:58.353 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:39:58.674 : *** Processed spotter/car_right
20:39:58.957 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:39:59.920 : *** Processed spotter/clear_right
20:40:01.955 : car left, carsOnLeftCount 1 carsOnRightCount 0 hasCarLeft False hasCarRight False
20:40:02.950 : *** Processed spotter/car_left
20:40:03.155 : clear left, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft True hasCarRight False
20:40:03.555 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:40:04.135 : *** Processed spotter/clear_left
20:40:05.356 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:40:05.612 : *** Processed spotter/car_right
20:40:06.545 : *** Processed spotter/clear_right
20:40:13.752 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:40:14.748 : *** Processed spotter/car_right
20:40:14.770 : 3 wide, carsOnLeftCount 1 carsOnRightCount 1 hasCarLeft False hasCarRight True
20:40:14.953 : clear left, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft True hasCarRight True
20:40:15.150 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:40:15.555 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:40:15.752 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:40:16.118 : *** Processed spotter/clear_right
20:40:16.153 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:40:16.351 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:40:50.157 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:40:50.355 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:40:53.795 : Leader fast lap - this lap time = 94.20728 session best = 94.20728
20:40:57.075 : *** Processed COMPOUND_leader_good_laptime
20:40:57.097 : There are 1 more events in the queue, playing them...
20:40:58.753 : car left, carsOnLeftCount 1 carsOnRightCount 0 hasCarLeft False hasCarRight False
20:41:00.758 : clear left, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft True hasCarRight False
20:41:00.812 : *** Processed COMPOUND_new_fastest_lap
20:41:00.824 : Clip spotter/car_left has expired
20:41:01.722 : *** Processed spotter/clear_left
20:41:11.406 : Car ahead fast lap - this lap time = 98.75633 session best = 93.66904
20:41:12.357 : car right, carsOnLeftCount 0 carsOnRightCount 1 hasCarLeft False hasCarRight False
20:41:12.555 : clear right, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft False hasCarRight True
20:41:15.611 : *** Processed COMPOUND_car_ahead_good_laptime
20:41:20.373 : Laps completed = 2
20:41:20.398 : Time elapsed = 233.0096
20:41:20.413 : Position = 19
20:41:20.423 : Session phase = Unavailable
20:41:23.552 : car left, carsOnLeftCount 1 carsOnRightCount 0 hasCarLeft False hasCarRight False
20:41:23.756 : clear left, carsOnLeftCount 0 carsOnRightCount 0 hasCarLeft True hasCarRight False
20:41:33.061 : Application stopped
20:41:33.071 : Stopping queue monitor

mr_belowski
12-11-2015, 21:31
Great stuff, thanks for testing it. I'll have a rummage through that log in the morning to see if anything looks like it needs attention

cjorgens79
13-11-2015, 02:38
cjorgens79 can you put a Cosworth Omega dash skin on pCars Dash?

not currently, but its probably something that could be added if suitable enough high quality images can be found of the dash that i can then translate into a functioning dash in the app. PM me with some links or examples of what you are looking for. Are you referring to this particular model (http://www.cosworth.com/media/366167/ICD%202nd%20and%20Lap%20TIme_TierThreeFourMainImgLarge.jpg)?

TheReaper GT
13-11-2015, 03:02
not currently, but its probably something that could be added if suitable enough high quality images can be found of the dash that i can then translate into a functioning dash in the app. PM me with some links or examples of what you are looking for. Are you referring to this particular model (http://www.cosworth.com/media/366167/ICD%202nd%20and%20Lap%20TIme_TierThreeFourMainImgLarge.jpg)?

Thank you, I'd really appreciate that since that's my favorite digital display.

Yes I think that is the same model. That particular screen that you've posted is used on the Clio Cup that we already have in game.
This one is used in both Ginetta GT3 and Bentley GT3
221972

cjorgens79
13-11-2015, 12:59
I think I asked this earlier, but I don't think I got a response, is the build number field at the start of the packet going to change for each patch of pcars? or will it only change when the api changes?

Tim Mann
13-11-2015, 13:25
I think I asked this earlier, but I don't think I got a response, is the build number field at the start of the packet going to change for each patch of pcars? or will it only change when the api changes?

It gets it from online, so will be the build version number which changes per patch. As the data isn't changing though you can pretty much ignore the field.

transfix
13-11-2015, 13:33
@cjorgens79 Really looking forward to getting PCars Dash on my iPad/iPhone. Been eyeing it for some time and wishing it would work on consoles. Thanks for supporting this.

Fil140
13-11-2015, 14:50
You guys speak a truly amazing alien language, maybe im wrong but to a virtual computer illiterate like me, it appears that you are doing a hell of a lot of work for us.
I just want you guys all to know that we are truly thankfull for your time and effort and that you are very much appreciated,cjorgens gtreaper pock1910 mrbelowski tim mann and any of the other guys that ive missed. Thankyou.

Elaine The Racer
13-11-2015, 16:26
I am a n00b but can I use my Sim Race Dash now for my Xbox or PS4? Or is it still work in progress?

mr_belowski
13-11-2015, 16:30
It's all work in progress at the moment. When patch 7 arrives (patch 6 only went live on the PC yesterday) then some of these apps will be available

Elaine The Racer
13-11-2015, 16:35
It's all work in progress at the moment. When patch 7 arrives (patch 6 only went live on the PC yesterday) then some of these apps will be available

Thank you for clearing that up :) I've got Race Sim Race Dash all set up to go

Fil140
13-11-2015, 19:27
Im still unclear(see thick!) as to how the apps will be installed and or run on ps4, can sm1 take 2 minutes to explain exactly what i will need to do in order to get a combination of dash app, crew chief and vdash running on a sony experia z and a samsung galaxy s tablet.
Please and thanks in advance.

Jussi Viljami Karjalainen
13-11-2015, 19:45
Im still unclear(see thick!) as to how the apps will be installed and or run on ps4, can sm1 take 2 minutes to explain exactly what i will need to do in order to get a combination of dash app, crew chief and vdash running on a sony experia z and a samsung galaxy s tablet.
Please and thanks in advance.Once the system is in, the game will broadcast the data in your wifi network. Any device in the network capable of picking up the data can use it to do whatever they want to do with it, be it running telemetry or a dash or anything else.

So in an optimal scenario, you'd need a PS4, a wifi router, and a phone with the app running on it. Most modern phones should be capable of doing it, but some older or cheaper ones might not.

TheReaper GT
13-11-2015, 19:57
Im still unclear(see thick!) as to how the apps will be installed and or run on ps4, can sm1 take 2 minutes to explain exactly what i will need to do in order to get a combination of dash app, crew chief and vdash running on a sony experia z and a samsung galaxy s tablet.
Please and thanks in advance.

What Jussi said + nothing has to be installed on the console side. The only requirement is the app to be able to grab the udp packets from the network. PCars dash and Crew Chief are confirmed as compatible.

Elaine The Racer
13-11-2015, 20:46
What Jussi said + nothing has to be installed on the console side. The only requirement is the app to be able to grab the udp packets from the network. PCars dash and Crew Chief are confirmed as compatible.


So if I buy PCARS Dash it will for my Xbox one or PS4 now or?

TheReaper GT
13-11-2015, 20:49
So if I buy PCARS Dash it will for my Xbox one or PS4 now or?
It will work with both, after patch 7.0

mr_belowski
13-11-2015, 21:17
Currently crew chief doesn't run on android but I have started porting from windows. Until that's done, you'll have to run it on a PC while you play on the console

TheReaper GT
13-11-2015, 21:19
Currently crew chief doesn't run on android but I have started porting from windows. Until that's done, you'll have to run it on a PC while you play on the console

I'm OK running it on Windows but i'll gladly buy the android version :D

Fil140
13-11-2015, 22:03
Wow, thankyou guys, this is why i love the sim racing community because when you ask a question you get a straight answer, nobody tries to over cimplicate things.I see the wayvthat you developement/ programmer guys comunicate and it baffles me but if i interupt to ask a question then you are always ready and willing to break it down into laymans terms....... "Ive got to stop now because im getting a lump in my throat......."(M.Walker).

Jussi Viljami Karjalainen
13-11-2015, 22:27
Wow, thankyou guys, this is why i love the sim racing community because when you ask a question you get a straight answer, nobody tries to over cimplicate things.Unfortunately as a sim races of many many years I think what you like is this particular community. In my long term experience the sim racing community as a whole is probably the worst internet community I've ever been involved with. The insane depths of deplorability they so often sink to when anyone asks something, or worse yet, dares mention a competing sim, is simply astounding. Never have I seen such massive amounts of vile, hateful refuse being heaped upon people only trying to figure things out, or heaven forbid make something new...

This place is pretty nice though. And it's not like all sim communities are like that outside either, but the hit rate has been astonishingly high. =)

TheReaper GT
13-11-2015, 22:33
Unfortunately as a sim races of many many years I think what you like is this particular community. In my long term experience the sim racing community as a whole is probably the worst internet community I've ever been involved with. The insane depths of deplorability they so often sink to when anyone asks something, or worse yet, dares mention a competing sim, is simply astounding. Never have I seen such massive amounts of vile, hateful refuse being heaped upon people only trying to figure things out, or heaven forbid make something new...

This place is pretty nice though. And it's not like all sim communities are like that outside either, but the hit rate has been astonishingly high. =)

One can have a glimpse of that complex negative behavior watching some simracers over twitch, they are rude, arrogant and most of the time treat their audience like they are doing a favor to the viewers...

inthebagbud
13-11-2015, 22:39
Unfortunately as a sim races of many many years I think what you like is this particular community. In my long term experience the sim racing community as a whole is probably the worst internet community I've ever been involved with. The insane depths of deplorability they so often sink to when anyone asks something, or worse yet, dares mention a competing sim, is simply astounding. Never have I seen such massive amounts of vile, hateful refuse being heaped upon people only trying to figure things out, or heaven forbid make something new...

This place is pretty nice though. And it's not like all sim communities are like that outside either, but the hit rate has been astonishingly high. =)

jussi

it is now but in the beginning it was all the negatives that you have stated. I am a newbie to racing games and an open forum for any type of game and found the initial comments from users to the devs amazing and sometimes border line outright ridiculous .

I am glad that that things have calmed down so we can discuss and improve the experience for everybody , yes there have been issues with the game just like any 21st century game (which is another discussion) but kudos for sms at least they have stuck with it and tried to improve the game and continue to do so.

mr_belowski
13-11-2015, 22:46
I'm OK running it on Windows but i'll gladly buy the android version :D

You've not seen how much I'm gonna charge for it yet ;)

Fil140
13-11-2015, 22:55
Ive been racing for 18years but only online for 10years.im very selective about the people i race with and i never use public lobbies,where i guess the trolls dwell. I mainly use isrtv for research and queries and those guys are great,ive got loads of help there since 2007.Im probably just lucky or i tend to have a good nose for when to leave a conversation before it turns sour.

Keithb23
13-11-2015, 23:08
How about a pint?
222023

memoric77
13-11-2015, 23:18
Hi,

I´am building up my ButtonBoxV2 with a Arduino Leonardo inside. Would it be possible to read the UDP Data from the Wifi with some kind of this Code?? Think so?! That would allow me the control of LED or outputting information on an LCD, on the button box is still some space for it :)

https://www.arduino.cc/en/Tutorial/WiFiSendReceiveUDPString

222021

Jussi Viljami Karjalainen
13-11-2015, 23:20
How about a pint?Not quite yet, I'm bottling next weekend, then two more weeks for carbonation and bottle conditioning, but soon. Soon... =)

cjorgens79
14-11-2015, 01:20
@Tim, just wondering if at some point you (or Tom) could do a longer recording? They are quite handy for testing, being able to play back the stream at whatever speed i want. Ideally a recording with a 5-10 min qualy and maybe 5 or so lap race would be plenty. One thing we havent tested yet is whether the damage is outputting correclty (should work, but worth checking anyway i would think). I would like to do an F1 style timing screen now that we can get the sector timing from participants, but i need a recording to test it with. The other one can be used, but it is quite short.

TheReaper GT
14-11-2015, 08:15
How about a pint?
Hey Keith, just checking with you if it's ok to send your art of the Omega to cjorgens? If you are ok with it would you mind share the rpm bar color codes? I changed the ginetta logo for the cosworth logo if you don't mind.

Keithb23
14-11-2015, 09:28
Hey Keith, just checking with you if it's ok to send your art of the Omega to cjorgens? If you are ok with it would you mind share the rpm bar color codes? I changed the ginetta logo for the cosworth logo if you don't mind.

It's all good, man. I'm happy to share. I've been the benefactor of many free downloads from others in the past through various mods, textures, and ideas. I don't think most of us are here to make a lot of money, but just want the 'perfect' bit of kit that we can't buy anywhere, and have been forced to either make it ourselves, or find someone that can make it for us. I went down that route with Alex (Flynny74) and his VDash app. We just sort of hit it off. I was looking for that perfect dash app, and he was developing one as a sort of school 'project' for his university courses. I started to learn how to work with some free graphics software (Gimp mostly) and I picked up a cheap wacom pen/tablet to help out with the finer details. I just kept asking for more features, and he was kind enough to keep working out how to do them. Alex has gone 'incognito' for now. I believe he is involved in some very hush, hush work and his online presence at the moment is severely limited. I'm hoping I haven't said too much and don't wake up tomorrow with 'cement boots' and a quick trip to the river, heh, heh, I'm kidding...I hope...gaaak!

In all seriousness, though, if there is anything I can do to help the UDP project along, just let me know, and I'll see what I can do. I still have a lot of dashes I would like to make for VDash, but if that ends up being dead in the water, I'll just start making backgrounds and/or graphic elements that people can use in other apps. Zappadoc's new emulator app for android is showing a lot of promise, and I imagine he would like to support the UDP protocol once it's ironed out, if he hasn't done so already. I guess I should do a little 'searching' and see what he has posted about it so far. He has indicated that he might be supporting user-created backgrounds for his app, which would be perfect for me.

It's exciting to see the consoles finally get some love with regards to the external hardware aspect of things. I warn you though, once you go down the rabbit hole and start playing around with external hardware for driving sims, it's extremely addictive! Start saving your money for those cool hardware bits!

TheReaper GT
14-11-2015, 09:34
^^thank you very much. I am up to help anyway I can too. What is the name of the emulator? I'll give it a try too. What I really want is a full Cosworth Omega experience, since it's the most complete interface in the market.

Keithb23
15-11-2015, 03:00
Here you go!

It's at EKSimracing.com
http://www.eksimracing.com/sliemu-sli-pro-emulator-for-android/

Fil140
15-11-2015, 22:33
Here you go!

It's at EKSimracing.com
http://www.eksimracing.com/sliemu-sli-pro-emulator-for-android/

Hi keith, so is the emulator going to be fully compatible with ps4 project cars?if so, will it be plug n play or will we need to do some form of configuration on pc?

Keithb23
16-11-2015, 01:03
This emulator is currently for Android using the pCars shared memory API. I don't think Zappadoc has specifically mentioned adding UDP compatibility to his SLIMax Manager Pro server application, but it also wouldn't surprise me at all, since he has been on board with developing for the current API from very early on. If he were to make his sever app UDP compatible, that would open up another very large market for him.

Fil140
16-11-2015, 09:28
This emulator is currently for Android using the pCars shared memory API. I don't think Zappadoc has specifically mentioned adding UDP compatibility to his SLIMax Manager Pro server application, but it also wouldn't surprise me at all, since he has been on board with developing for the current API from very early on. If he were to make his sever app UDP compatible, that would open up another very large market for him.
Thanks keith, heres hoping!

MikeyTT
16-11-2015, 11:19
Hi,

I´am building up my ButtonBoxV2 with a Arduino Leonardo inside. Would it be possible to read the UDP Data from the Wifi with some kind of this Code?? Think so?! That would allow me the control of LED or outputting information on an LCD, on the button box is still some space for it :)

https://www.arduino.cc/en/Tutorial/WiFiSendReceiveUDPString

222021

Theoretically I see no issue with reading direct from the UDP stream, but I'm not sure that the Arduino has the speed to do everything you'll need to do, and keep the data you'll need between reads. There are some nice gotchas that you'll have to account for like the timing and lap numbering not being in sync (be interesting to see if that goes away with the UDP data actually). There is a lot of data to process and quickly (depending on what you want to capture/display of course).

There is no reason you couldn't use an app on a Windows PC that drives the Arduino through the serial connection tho. That's what my app does.

BTW how do you get the Arduino to work with the PS4 to drive the switches?

cjorgens79
16-11-2015, 12:07
@Tim - just been doing some testing of the new participant info stuff (ie timing per participant) by building an F1 style timing screen, seems to be working ok with the small sample udp.bin data. The only issue i have is with regards to invalid laps, for the player its fine because its in the players data, but we don't get the invalid lap state for all participants. Is this actually available to you, and if so any chance of it getting added to the participant info struct (just as a single bit somewhere amongst the existing fields). Without it, it can result in the timing screen showing times that are actually invalid for a participant, which may appear to be faster than the times of other players above them on the leaderboard (as its sorted based on the correct position provided by the api).

TheReaper GT
16-11-2015, 22:01
cjorgens, any chance of the windows mobile app become a universal app?

Tim Mann
16-11-2015, 22:11
@Tim - just been doing some testing of the new participant info stuff (ie timing per participant) by building an F1 style timing screen, seems to be working ok with the small sample udp.bin data. The only issue i have is with regards to invalid laps, for the player its fine because its in the players data, but we don't get the invalid lap state for all participants. Is this actually available to you, and if so any chance of it getting added to the participant info struct (just as a single bit somewhere amongst the existing fields). Without it, it can result in the timing screen showing times that are actually invalid for a participant, which may appear to be faster than the times of other players above them on the leaderboard (as its sorted based on the correct position provided by the api).

mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?128:0); // u32+bool->u8 (top bit is active)
mTelemetryData.sParticipantInfo[i].sLapsCompleted=((u8)min(pMemory->mParticipantInfo[i].mLapsCompleted, 127))|(pMemoryExtras->mLapInvalidated[i]?128:0); // u32+bool->u8 (top bit is lap invalidated)

Careful with that though, it will set the flag as invalid before cars cross the start line.

Jussi Viljami Karjalainen
16-11-2015, 22:12
cjorgens, any chance of the windows mobile app become a universal app?Wait what, there's a windows mobile app?

TheReaper GT
16-11-2015, 22:15
Wait what, there's a windows mobile app?

Yep, Pcars Dash :D I've bought the Android version but I wanna buy the windows version too. If converted to universal app I can use it directly on my laptop...

Schnizz58
16-11-2015, 22:20
Not quite yet, I'm bottling next weekend, then two more weeks for carbonation and bottle conditioning, but soon. Soon... =)
Kegging is the way to go.

transfix
16-11-2015, 22:41
I'm almost as excited about the release of this as I was the game itself LOL.

inthebagbud
16-11-2015, 22:56
I'm almost as excited about the release of this as I was the game itself LOL.

Got to agree with you there let's hope they can get patch 7 out in time for Santa to deliver

Jussi Viljami Karjalainen
16-11-2015, 23:27
Kegging is the way to go.If you have the money, the space, an extra fridge, and don't intend to send any bottles to friends. =)

Just kidding. Kegging is tempting, but it isn't even remotely possible for me right now.

memoric77
16-11-2015, 23:49
Theoretically I see no issue with reading direct from the UDP stream, but I'm not sure that the Arduino has the speed to do everything you'll need to do, and keep the data you'll need between reads. There are some nice gotchas that you'll have to account for like the timing and lap numbering not being in sync (be interesting to see if that goes away with the UDP data actually). There is a lot of data to process and quickly (depending on what you want to capture/display of course).

There is no reason you couldn't use an app on a Windows PC that drives the Arduino through the serial connection tho. That's what my app does.

BTW how do you get the Arduino to work with the PS4 to drive the switches?

Thx for your answer. I use the Arduino Leonardo. It works as a HID Device. You can code the functions of the Buttons, control LED depending on the states of a button, control vibration engines etc..

Ivan Dumalovski Janjusic
17-11-2015, 09:32
As I understood from reading last few pages, in the patch 7.0 PS4 users will be able to have companion app such as vdash or others that will show telemetry data for pCars on mobile/tablet.
Correct me if wrong :-)

cjorgens79
17-11-2015, 09:50
mTelemetryData.sParticipantInfo[i].sRacePosition=((u8)pMemory->mParticipantInfo[i].mRacePosition)|(pMemory->mParticipantInfo[i].mIsActive?128:0); // u32+bool->u8 (top bit is active)
mTelemetryData.sParticipantInfo[i].sLapsCompleted=((u8)min(pMemory->mParticipantInfo[i].mLapsCompleted, 127))|(pMemoryExtras->mLapInvalidated[i]?128:0); // u32+bool->u8 (top bit is lap invalidated)

Careful with that though, it will set the flag as invalid before cars cross the start line.

Thanks Tim, can you clarify that point, is it invalid=1 only before crossing the start line at the very start of a race, or at a point before crossing the start line on each lap?

KkDrummer
17-11-2015, 10:02
I didn't know there was an app for Windows phone...hopefully it becomes universal and it works on desktop, phone and tablet (Windows 10)....and just a thought....the new Xbox dashboard is Windows 10 so we could potentially have the app running on the console? it would be amazing!

Fil140
17-11-2015, 10:06
I'm almost as excited about the release of this as I was the game itself LOL.

Im actually more excited by this, we knew for a long time that the game was coming but we didnt know on wich platforms it would be released, we have seen apps for sims running for years but never expected them to come to console sim racers, this developement will really add to the emmersion as a sim rig driver and make the experience even more fun.

Tim Mann
17-11-2015, 10:36
Thanks Tim, can you clarify that point, is it invalid=1 only before crossing the start line at the very start of a race, or at a point before crossing the start line on each lap?

Start of race, seems valid after that.

cjorgens79
17-11-2015, 11:21
Start of race, seems valid after that.

ok thats what I thought, I had noticed that occuring with the existing shared memory api too. It must have gotten broken somewhere along the way as it used to be ok.

cjorgens79
17-11-2015, 11:26
cjorgens, any chance of the windows mobile app become a universal app?

yeah at some point, i have a way of making win32 compatible builds but no easy way to manage sales / deployment / licensing like i have with iTunes/Google Play, so I was going to look at microsofts project centennial which would allow me to package it up and sell it on the windows store so it can be run on PC's, tablets etc. Another other option is maybe using steam, but haven't looked into that yet.

TheReaper GT
17-11-2015, 13:28
yeah at some point, i have a way of making win32 compatible builds but no easy way to manage sales / deployment / licensing like i have with iTunes/Google Play, so I was going to look at microsofts project centennial which would allow me to package it up and sell it on the windows store so it can be run on PC's, tablets etc. Another other option is maybe using steam, but haven't looked into that yet.

Thanks that's cool. I guess a universal app can save you some time :)

TheReaper GT
17-11-2015, 13:35
As I understood from reading last few pages, in the patch 7.0 PS4 users will be able to have companion app such as vdash or others that will show telemetry data for pCars on mobile/tablet.
Correct me if wrong :-)

If the app dev make the necessary charges to use the udp stream. Unfortunately vdash's dev did not confirmed yet. Pcars dash is confirmed though...

Ivan Dumalovski Janjusic
17-11-2015, 14:31
If the app dev make the necessary charges to use the udp stream. Unfortunately vdash's dev did not confirmed yet. Pcars dash is confirmed though...
I only mentioned vdash as an examle. any app that will support it gets my money :-)

STEELJOCKEY
17-11-2015, 19:36
If you have the money, the space, an extra fridge, and don't intend to send any bottles to friends. =)

Just kidding. Kegging is tempting, but it isn't even remotely possible for me right now.

Slightly off the OP topic, but on your topic, how about these for some options


https://youtu.be/S1ZZreXEqSY


https://youtu.be/c3kKA5-CXC0


https://youtu.be/xk5JNs7KO30

Elaine The Racer
18-11-2015, 14:41
If the app dev make the necessary charges to use the udp stream. Unfortunately vdash's dev did not confirmed yet. Pcars dash is confirmed though...

& that includes Xbox One right?

TheReaper GT
18-11-2015, 14:44
& that includes Xbox One right?

Yep, after 7.0 nay app that uses the new UDP stream will be compatible with all versions of the game.

Elaine The Racer
18-11-2015, 14:48
Phew! Just double checking this is like the best news ever for PCARS, can't wait to see my iPhone tell me to shift up haha PCARS making it real since 2015.

TheReaper GT
18-11-2015, 14:49
Phew! Just double checking this is like the best news ever for PCARS, can't wait to see my iPhone tell me to shift up haha PCARS making it real since 2015.

Same here. Gonna run Crew Chief on my lap top and pcars dash on my galaxy A7 using a clamp bracket support connected to my coffe table :D to have it in front of me.

KkDrummer
18-11-2015, 15:11
Same here. Gonna run Crew Chief on my lap top and pcars dash on my galaxy A7 using a clamp bracket support connected to my coffe table :D to have it in front of me.

Photos of that setup will be requested lol

TheReaper GT
18-11-2015, 15:14
Photos of that setup will be requested lol

Will do, for sure. Nothing fancy, I don't have a wheel yet, but I don't like to use hud, so either way it's a win for me :D

Tim Mann
18-11-2015, 16:02
You can test your apps live now against the PC 6.1 patch.

mr_belowski
18-11-2015, 16:12
Awesome :D.

I'm out mountain biking tonight so won't get to test or fix any of my stuff till tomorrow :(

mr_belowski
18-11-2015, 16:35
What's the 1 - 9 option for in the UDP setting?

Just had a 60 second glance and it does appear that my app is basically working, thanks for all the test data (except for the broken bit ;))

Tim Mann
18-11-2015, 16:48
What's the 1 - 9 option for in the UDP setting?

Just had a 60 second glance and it does appear that my app is basically working, thanks for all the test data (except for the broken bit ;))

Ah yes. I think I'll award prizes for the best suggestion of what that option actually does, before revealing all.

mr_belowski
18-11-2015, 16:55
<sigh>

Is it a "how well do you want it to work" option, where 1 is barely and 9 is mostly?

Update frequency? Its not port number. What do I win for guessing?

pock1910
18-11-2015, 17:01
Ah yes. I think I'll award prizes for the best suggestion of what that option actually does, before revealing all.
My suggestion: In future versions we can have different UDB stream in order to provide the functionality for different needs.:)

mr_belowski
18-11-2015, 17:09
Is it the relative frequency of the 'strings' and 'additional strings' data packets?

This is an interesting game. No, wait, the other thing... Tedious ;)

[Edit... Added winky face so as not to appear a pillock]

transfix
18-11-2015, 20:12
1-9 Definiton

I would say it's either which channel you select (better communication frequency e.g.: home wifi channels) or How much information you are wanting to allow.

mr_belowski
18-11-2015, 22:49
Nah, its got to be frequency / packet rate so you can tune it a bit to suit your network conditions - high enough rate to get lots of data, low enough to avoid flooding.

As my prize for guessing correctly I'll have the upcoming classics DLC, a helicopter, a solid gold house and a billion pounds thankyouplease

SUBGTRACER
18-11-2015, 22:54
1-9 things you can use at the same time e.g Ipad , Iphone , androids phone and so on ............ :) like sitting in the space shuttle