Opening the memory-mapped file GPBProxyObject
g_hMapFile = OpenFileMapping(FILE_MAP_READ,FALSE,"Local\\GPBProxyObject");
void *pBuf = MapViewOfFile(g_hMapFile,FILE_MAP_READ,0,0,sizeof(SProxyData_t));
external programs can read GP Bikes output data.
The source code and data structure is available here: http://www.gp-bikes.com/downloads/gpb_proxy.c
Proxy plugin updated to the latest interface.
Silly question maybe, I'm not familiar with this shared memory stuff: are there synchronization problems between the writer (the .dlo) and the external reader ?
Could the reader be in the middle of the read operation when the writer starts to write (or vice versa) ?
MaX.
Proxy plugin updated to the latest interface.
Proxy plugin updated to the latest interface.
Hi PiBoSo,
is there a way to test the output of the plugin. I compiled it as a .dll and copied it as a .dlo in the plugins folder. Then I used the two lines of your first post in another program to read the output. I used the following code lines to copy the *pBuf Data to a SProxyData_t Object:
SProxyData_t data;
memcpy(&data, &pBuf, sizeof(SProxyData_t));
while(1)
{
printf("%f\n", data.m_sData.m_fRPM);
Sleep(500);
}
The problem is, that the m_fRPM field is empty.
Thanks, Obelix90
Quote from: Obelix90 on November 20, 2014, 08:54:54 PM
Hi PiBoSo,
is there a way to test the output of the plugin.
Works fine for me.
Can you post the totality of your code ?
This is my test code:
int main(int argc, char* argv[])
{
while (true) {
HANDLE g_hMapFile = OpenFileMapping(FILE_MAP_READ,FALSE,"Local\\GPBProxyObject");
if (g_hMapFile) {
void *pBuf = MapViewOfFile(g_hMapFile,FILE_MAP_READ,0,0,sizeof(SProxyData_t));
SProxyData_t *p = (SProxyData_t *) pBuf;
while (true) {
printf("State: %d\n", p->m_iState);
if (p->m_iState == 2) {
// On track, simulator running.
printf(" Speed: %.1f Kmh\n", p->m_sData.m_fSpeedometer * 3.6);
printf(" RPM : %.0f rpm\n", p->m_sData.m_fRPM);
}
Sleep(1000);
}
} else {
printf("Can't open file mapping, GPB may not be running !\n");
}
Sleep(1000);
}
return 0;
}
MaX.
Hi MaX,
I think I see my mistake. I only copied the pBuf once in the data-field at the beginning of my program, so it isn't updated. I try this when I'm at home. If it's not working I post the rest of my code.
Thank you MaX.
Obelix90
That should be the reason.
Notice that you may not need to make a copy of the data (e.g. in my example, I don't copy it), just be sure to avoid writing on it (I should probably use a "const *").
MaX.
The memcpy is not working for me, also when I put it in the while loop. So I use your lineSProxyData_t *p = (SProxyData_t *) pBuf;
and now it works perfect.
Thank you.
Quote from: Obelix90 on November 21, 2014, 08:12:45 PM
The memcpy is not working for me, also when I put it in the while loop. So I use your lineSProxyData_t *p = (SProxyData_t *) pBuf;
and now it works perfect.
Thank you.
Your memcpy is wrong I think:
memcpy(&data,
&pBuf, sizeof(SProxyData_t));
Should probably be:
memcpy(&data, pBuf, sizeof(SProxyData_t));
MaX.
Ah yes, because pBuf is already a pointer, you're right.
Source code updated to the latest interface.
Quick question: at which frequency is the default proxy plugin data updated ?
Custom plugins can specify that at 10/20/50/100 Hz, but what about the default proxy.dlo ?
The sample code you provide (http://www.gp-bikes.com/downloads/gpb_proxy.c (http://www.gp-bikes.com/downloads/gpb_proxy.c)) seems to read from a proxy.ini file: is that the case for the default proxy.dlo ?
Quote from: HornetMaX on March 12, 2016, 06:41:06 PM
Quick question: at which frequency is the default proxy plugin data updated ?
Custom plugins can specify that at 10/20/50/100 Hz, but what about the default proxy.dlo ?
The sample code you provide (http://www.gp-bikes.com/downloads/gpb_proxy.c (http://www.gp-bikes.com/downloads/gpb_proxy.c)) seems to read from a proxy.ini file: is that the case for the default proxy.dlo ?
The default is 10hz.
Quote from: PiBoSo on March 12, 2016, 09:32:43 PM
Quote from: HornetMaX on March 12, 2016, 06:41:06 PM
Quick question: at which frequency is the default proxy plugin data updated ?
Custom plugins can specify that at 10/20/50/100 Hz, but what about the default proxy.dlo ?
The sample code you provide (http://www.gp-bikes.com/downloads/gpb_proxy.c (http://www.gp-bikes.com/downloads/gpb_proxy.c)) seems to read from a proxy.ini file: is that the case for the default proxy.dlo ?
The default is 10hz.
OK. Can it be changed with a proxy.ini ?
As the source code shows:
1) create a file named proxy.ini in the "plugins" folder
2) add the following lines:
[params]
sample_rate = 50
You can check in the source code that the supported values are 10, 20, 50 and 100.
Thx ! Wasn't sure of the example code was the one in use in proxy.dlo.
Source code updated to the latest interface.
Source code updated to the latest interface.
Source code updated to the latest interface.
Source code updated to the latest interface.
Hey guys, can you please help me out?
Sorry for possibly a noob question but I'm tad confused. I'm using Max's test code from the first page and getting the data, but it's in some strange format like this when starting the bike:
''Speed940.48Kmh
Revs1117953633Rpm
State: 2
Speed938.721Kmh
Revs1117925790Rpm
State: 2
Speed936.422Kmh
Revs1117905668Rpm
State: 1""
So data isn't too realistic.
So what am I doing wrong here, is the data in some specific format?
Hi,
I don't have the time to look into this, hence just speculating: looks like garbage, so potentially data structure misalignment.
Have you compiled your app as x64 ?
Quote from: HornetMaX on December 21, 2018, 10:44:45 AM
Hi,
I don't have the time to look into this, hence just speculating: looks like garbage, so potentially data structure misalignment.
Have you compiled your app as x64 ?
Just tried x64, no change.
Ye, apparently something with data structure but I've just copy pasted structure code posted by Piboso so no idea really where mistake can be.
Will have to have a look. Won't happen before a week or two.
Thanks Max, I appreciate it!
I just have a feeling something obvious is missed so maybe second look can help. Insterestingly though, state parameter of the structure is read well, problem is just with telemetry data.
I can post a code but there's just copy paste from Piboso's and your code from the first page.
Quote from: Fightone on December 26, 2018, 07:32:09 PM
Thanks Max, I appreciate it!
I just have a feeling something obvious is missed so maybe second look can help. Insterestingly though, state parameter of the structure is read well, problem is just with telemetry data.
I can post a code but there's just copy paste from Piboso's and your code from the first page.
Just tested it, works fine for me.
Be sure to:
- Compile as x64.
- Use latest definitiopns for data structures (the ones I currently use are below).
typedef struct
{
char m_szRiderName[100];
char m_szBikeID[100];
char m_szBikeName[100];
int m_iNumberOfGears;
int m_iMaxRPM;
int m_iLimiter;
int m_iShiftRPM;
float m_fEngineOptTemperature; /* degrees Celsius */
float m_afEngineTemperatureAlarm[2]; /* degrees Celsius. Lower and upper limits */
float m_fMaxFuel; /* fuel tank capacity. liters */
float m_afSuspMaxTravel[2]; /* maximum travel of the shocks. meters. 0 = front; 1 = rear. */
float m_fSteerLock; /* degrees */
char m_szCategory[100];
char m_szTrackID[100];
char m_szTrackName[100];
float m_fTrackLength; /* centerline length. meters */
int m_iType; /* 1 = testing; 2 = race */
} SPluginsBikeEvent_t;
typedef struct
{
int m_iSession; /* testing: always 0. Race: 0 = waiting; 1 = practice; 2 = qualify; 3 = warmup; 4 = race */
int m_iConditions; /* 0 = sunny; 1 = cloudy; 2 = rainy */
float m_fAirTemperature; /* degrees Celsius */
float m_fTrackTemperature; /* degrees Celsius */
char m_szSetupFileName[100];
} SPluginsBikeSession_t;
typedef struct
{
int m_iRPM; /* engine rpm */
float m_fEngineTemperature; /* degrees Celsius */
float m_fWaterTemperature; /* degrees Celsius */
int m_iGear; /* 0 = Neutral */
float m_fFuel; /* liters */
float m_fSpeedometer; /* meters/second */
float m_fPosX,m_fPosY,m_fPosZ; /* world position of a reference point attached to chassis ( not CG ) */
float m_fVelocityX,m_fVelocityY,m_fVelocityZ; /* velocity of CG in world coordinates. meters/second */
float m_fAccelerationX,m_fAccelerationY,m_fAccelerationZ; /* acceleration of CG local to chassis rotation, expressed in G ( 9.81 m/s2 ) and averaged over the latest 10ms */
float m_aafRot[3][3]; /* rotation matrix of the chassis. It incorporates lean and wheeling */
float m_fYaw,m_fPitch,m_fRoll; /* degrees, -180 to 180 */
float m_fYawVelocity,m_fPitchVelocity,m_fRollVelocity; /* degress / second */
float m_afSuspLength[2]; /* shocks length. meters. 0 = front; 1 = rear. */
float m_afSuspVelocity[2]; /* shocks velocity. meters/second. 0 = front; 1 = rear */
int m_iCrashed; /* 1 = rider is detached from bike */
float m_fSteer; /* degrees. Negative = right */
float m_fThrottle; /* 0 to 1 */
float m_fFrontBrake; /* 0 to 1 */
float m_fRearBrake; /* 0 to 1 */
float m_fClutch; /* 0 to 1. 0 = Fully engaged */
float m_afWheelSpeed[2]; /* meters/second. 0 = front; 1 = rear */
int m_aiWheelMaterial[2]; /* material index. 0 = not in contact */
float m_fSteerTorque; /* Nm */
int m_iPitLimiter; /* 1 = pit limiter is activated */
int m_iECUMode; /* 0 = engine mapping; 1 = traction control; 2 = engine braking */
char m_szEngineMapping[3];
int m_iTractionControl;
int m_iEngineBraking;
int m_iAntiWheeling;
int m_iECUState; /* bit field. Bit 1 = TC active; bit 2 = engine braking active; bit 3 = antiwheeling active */
} SPluginsBikeData_t;
typedef struct
{
int m_iLapNum; /* lap index */
int m_iInvalid;
int m_iLapTime; /* milliseconds */
int m_iBest; /* 1 = best lap */
} SPluginsBikeLap_t;
typedef struct
{
int m_iSplit; /* split index */
int m_iSplitTime; /* milliseconds */
int m_iBestDiff; /* milliseconds. Difference with best lap */
} SPluginsBikeSplit_t;
typedef struct
{
int m_iVersion;
int m_iState; /* -1: software not running; 0: software running; 1: on-track, simulation paused; 2: on-track, simulation running */
SPluginsBikeEvent_t m_sEvent;
SPluginsBikeSession_t m_sSession;
SPluginsBikeLap_t m_sLap;
int m_iSplit;
SPluginsBikeSplit_t m_sSplit;
SPluginsBikeData_t m_sData;
float m_fTime;
float m_fPos;
} SProxyData_t;
Thanks!
After few days of troubleshooting bit by bit I finally nailed it.
The issue was with the output structure being 4 bytes shorter (from m_iVersion till m_sData part) than the structure you posted. Can't say what's exactly missing in the game output but that's it. It's weird if it works for you at the same time but that's what I get from my GP Bikes.:)
I removed "int m_iSplit;" (just random value) and it works well now. I especially compared several times to your code, but yep, no other difference.
Likely you have a problem somewhere then.
You can't arbitrarily take one filed off the data structure GPB writes ...
Source code updated to the latest interface.
Source code updated to the latest interface.
Source code updated to the latest interface.
Source code updated to the latest interface.