The online racing simulator
OutSim With Dirt2 and Grid?
2
(39 posts, started )
Quote from bvillersjr :Awesome! That was an amazingly quick reverse engineering time!

Fortunately they didn't change the structure between titles significantly, that obviously made it a lot easier.
Still need to figure out what the remaining data is, or rather, how to interpret it. I'm fairly certain the first 6 (in the unknown slice) are roll, pitch and yaw, but I don't quite know how to interpret them. The last 8 (again, unknown slice) appear to be per-wheel / per-corner data, what exactly remains unknown.
I don't actually own a motion simulator and might lack the experience to recognise the type of information based on patterns or range.

Quote from bvillersjr :Now to sort out the best way to integrate this into InSim.

Since the ExtraData =1 outputs entirely different structs, I'm gusssing that DarkTimes has lost interest in this?

The principle, that is, the way the communication happens, is still the same, the datagram just looks a bit different. It might not be directly InSim / OutSim related, but Alex might still be interested.

Quote from bvillersjr :If so, I'll look at maintaining some kind of derived work that supports all of the above. 99.5% of the plumbing for this is already in the InSim project.

That shouldn't be difficult, seeing as all of Alex's InSim related projects are, to my knowledge, open source and released under licences that permit derivative work.

Quote from bvillersjr :Also, who do I have to talk to about commercial use of LFS? A friend of mine wants to make a Sim Center and is interested in LFS as a basis for this.

http://www.lfs.net/?page=commercial_use
Quote :2) Licensed Commercial Use

This is the situation where you use Live for Speed in a permanent or temporary simulator setup and you make profit by charging customers who use the system.

For this purpose, you must contact the LFS developers and arrange a commercial license. A commercial license requires a small recurring payment and gives you permission to charge customers and make profit from the use of Live for Speed. Payments may be monthly or annually. Although you have only a single license, we will provide sufficient unlocks to keep your machines up to date, and will always be available in less than 24 hours to help you with any support issues you may have.

Our charges for this are very reasonable and can be adjusted to your circumstances, such as how many machines you are running and how many days per week they will be in use. We can give good discounts for commercial license customers in countries where the exchange rate to UK currency is unfavourable. We will arrange with you a charge that we both agree is reasonable and suitable for the purpose.

Some example charges for a single machine setup at full price e.g. USA / Europe / Australia :

Full time use (5 or more days per week) : £24 per month
Part time use (for example weekends only) : £12 per month
Educational license (use in a school) : £24 per year

For more information about commercial licenses please contact the LFS developers.

Thank you.

Recorded data from a run on Li River in my Mk2 Escort, see attachments
track.png is the X and Y position samples plotted onto a grid, 1px = 1 metre, green = first recorded sample, red = last recorded sample.
driver_input.png, as the name suggests, are my inputs. green = throttle, red = brakes, yellow = clutch (technically not me), pink = gear.

If anyone cares, the time was 2:50.46, wasn't a particularly good run though.

I'm a little closer to identifying the remaining values, here's a single sample, vehicle standing still on relatively flat ground, facing south. The values in brackets are the range I observed.
11: 0.005378 [-1.00 1.00] Heading 1 (relative to road direction?)
12: 0.006104 [-1.00 1.00] Roll
13: -0.999967 [-1.00 1.00] Heading 2 (relative to world?)
14: -0.999944 [-1.00 1.00] Heading 3 (relative to world?)
15: 0.009186 [-1.00 1.00] Pitch
16: -0.005322 [-1.00 1.00] Heading 4 (relative to road direction?)

The remaining 8 floats are most certainly suspension related, the first set of 4 being the position (travel) and the second set appears to be force or acceleration, but I'm not sure what exactly and which unit it is in. I'll provide some samples once I've collected the range and average.
Attached images
driver_input.png
track.png
11: 0.005378 [-1.00 1.00] Heading 1 (relative to road direction?)
12: 0.006104 [-1.00 1.00] Roll
13: -0.999967 [-1.00 1.00] Heading 2 (relative to world?)
14: -0.999944 [-1.00 1.00] Heading 3 (relative to world?)
15: 0.009186 [-1.00 1.00] Pitch
16: -0.005322 [-1.00 1.00] Heading 4 (relative to road direction?)

It seems to me they are using such a matrix
I mean that:

number |offset | value
14 | 56 | = sin(yaw)
16 | 64 | = cos(yaw)
or something like this. I still need some time to find out.
-
(E.Reiljans) DELETED by E.Reiljans
Here example how to get Yaw (azimuth) of car.
Sorry that code written in object pascal, have no time to translate...

TMatrix33 = array[0..2] of array[0..2] of Single;
BufferRet = array[0..BufferRetLen] of Byte;
TVector = record
X, Y, Z: Single;
end;

LocMat : TMatrix33;
eul : TVector;
FB : BufferRet; // our buffer
sinx, cosx : single;

Movememory(@sinx, @FB[56], 4);
Movememory(@cosx, @FB[64], 4);
LocMat[0,0]:=cosx;
LocMat[0,1]:=0;
LocMat[0,2]:=-sinx;
LocMat[1,0]:=0;
LocMat[1,1]:=1;
LocMat[1,2]:=0;
LocMat[2,0]:=sinx;
LocMat[2,1]:=0;
LocMat[2,2]:=cosx;
eul := CalcEulerM33(@LocMat); // direction in euler

Grad := eul.Y*(180/pi); // azimuth in degrees


function CalcEulerM33(M:PMatrix33) : TVector;
begin
if (M[0,1] > 0.9998) then // singularity at north pole
begin
Result.Y := arctan2(M[2,0], M[2,2]);
Result.Z := PI/2;
Result.X := 0;
exit;
end
else if (M[1,0] < -0.9998) then // singularity at south pole
begin
Result.Y := arctan2(M[2,0], M[2,2]);
Result.Z := -PI/2;
Result.X := 0;
exit;
end;
Result.Y := arctan2(-M[0,2], M[0,0]);
Result.Z := arcsin(M[0,1]);
Result.X := arctan2(-M[2,1],M[1,1]);
end;

Quote from morpha :track.png is the X and Y position samples plotted onto a grid, 1px = 1 metre, green = first recorded sample, red = last recorded sample.

May I please ask you what software have you used to produce that image?
Quote from m2yor :Here example how to get Yaw (azimuth) of car.
Sorry that code written in object pascal, have no time to translate...

Awesome! Have you verified the results yet? I'll port this to Python and/or PHP later and try it myself

Quote from E.Reiljans :May I please ask you what software have you used to produce that image?

You may, you may also burst out laughing once you read it: GD via PHP

I needed a really quick way to do this, GD/PHP is the quickest I could think of, faster than anything available for Python that I'm familiar with. I had this running collecting live samples and rendering them out to PNG every second. When I opened the two images in Windows Photo Viewer, I discovered that it had the very pleasant feature of detecting file changes and reloading the image upon such changes. In effect, giving me telemetry data at 1Hz while in-game.

It works reasonably well, especially considering that I didn't keep the images in memory between renderings but re-allocated them every time. A Li River run is about 7500 samples.
Quote from morpha :You may, you may also burst out laughing once you read it: GD via PHP

Why laugh? That's very handy way to do it compared to e.g. Excel (which some ppl use to plot data :| )

Btw, thanks for the idea - I just wrote a C++ app that.. writes a PHP script. (due to lazyness of learning any graphical funcs in C++ myself)
This app parses a .pth file, and outputs PHP code which plots the node data on a PNG. Optionally you can lay it down directly on track's TIF.
An example of how it looks (after merging with TIF using PS): http://localhostr.com/files/LwY8BId/BL1.png
#include <stdio.h>
struct data { int a[3]; float b[7]; };
int main(int argc, char **argv)
{
FILE *file;
struct data data;
if (argc != 2) { fprintf(stderr, "usage: %s <file>.pth", argv[0]); return 1; }
file = fopen(argv[1], "rb");
if (!file) { fprintf(stderr, "error: cannot open file"); return 1; }
fseek(file, 16, SEEK_SET); // first 16 bytes are of no use for this
printf("<?php\n");
printf("Header('Content-Type: image/png');\n");
printf("$gd = imagecreatetruecolor(2560, 2560);\n");
printf("$color = imagecolorallocate($gd, 255, 0, 0);\n");
while (fread(&data, sizeof(struct data), 1, file) == 1) {
printf("imagesetpixel($gd, %d, %d, $color);\n",data.a[0]/65536+1280,data.a[1]/65536+1280);
/*printf("imagesetpixel($gd, %d, %d, $color);\n",data.a[0]/65536+1280,data.a[1]/65536+1279);
printf("imagesetpixel($gd, %d, %d, $color);\n",data.a[0]/65536+1279,data.a[1]/65536+1280);
printf("imagesetpixel($gd, %d, %d, $color);\n",data.a[0]/65536+1279,data.a[1]/65536+1279);
// uncomment this part to have nice bold dots. :P */
}
printf("imagepng($gd); ?>");
fclose(file);
return 0;
}

Quote from morpha :In effect, giving me telemetry data at 1Hz while in-game.

Didn't PHP raped your CPU tho?
DiRT2 has a pretty efficient multithreading strategy, which is great in normal conditions but was indeed noticeably affected by PHP's single threaded high load bursts. The socket stuff was fine, but the GD rendering was comparable to the kind of microlag associated with SLI / CrossFire.

I had thought about rendering PTH or LYT files and I probably would have used PHP+GD for that too
Any thoughts about Dirt 3?

From hardware_settings_config.xml:

<?php 
<motion enabled="true" ip="dbox" port="20777" delay="1" extradata="0" />
?>

It's likely to be identical to DiRT2, but I don't have it so I can't make sure.
Same question here. Any chance these will get integrated into InSim. If not, any recomendation as to where I should inject this so as to not be suffering when new InSim releases are made?

Also, does InSim have some kind of proxy capability that can be used to forward the raw data steam back out on a specificed port for other devices to grab? Or is there another recognized way of forwarding?
Integrating this into an InSim library is rather pointless since CM titles don't actually implement InSim, only OutSim, and not 100% to LFS's specification at that. With ExtraData=1, it becomes something entirely unrelated altogether.

What is it you're ultimately looking for? Logging? Displaying? Sending to a motion sim?
Receiving and processing the data is simple in virtually ever language, so the choice depends on how interfacing with the motion sim works, if that's what you intend to do.
Quote from morpha :Integrating this into an InSim library is rather pointless since CM titles don't actually implement InSim, only OutSim, and not 100% to LFS's specification at that. With ExtraData=1, it becomes something entirely unrelated altogether.

What is it you're ultimately looking for? Logging? Displaying? Sending to a motion sim?
Receiving and processing the data is simple in virtually ever language, so the choice depends on how interfacing with the motion sim works, if that's what you intend to do.

I want to send data to a motion sim and log as well. The way the data is split into two streams in LFS is an issue for me since I need all of the OutSim data and a few tidbits from OutGauge. I need to do all of this without interfering with other devices like gauges that also need OutGauge data. I can write a UDP forwarder for this. I'm guessing that this problem has already been solved though, or that LFS has a way of sending OutGauge data to multiple ports?
You need the Pythoin interpreter to run og_rely. This send OutGauge packets to several IP/ports
2

OutSim With Dirt2 and Grid?
(39 posts, started )
FGED GREDG RDFGDR GSFDG