Open-Game-Standards-Alliance / Local-Telemetry-Standard

MIT License
2 stars 0 forks source link

Find a more minimal data format than JSON #3

Open ItsVRK opened 7 months ago

ItsVRK commented 7 months ago

@pmvcda on XSimulator forums suggested struct.

Whichever format we end up with probably needs to allow for the areas of spec where there can be multiple subitems added in an array of objects (see drivePoints and feedbackItems from my starting draft)

ItsVRK commented 7 months ago

Toml may be a better option https://toml.io/en/

https://json-schema-everywhere.github.io/toml

Language implementations https://github.com/toml-lang/toml/wiki#toml-v100

TheFlyPT commented 7 months ago

Like I said in XSimulator forums, I would go with binary structs equal both for MMF and UDP. A base one at the start of each packet.

struct Base // This is the base of the info, it will be at the start of all packets
{
    float time; // Time stamp of the data
    uint packetCounter; // Increasing value to control packet order in UDP, odd for when the MMF is being writen and pair for while not being writen
    int packetType; // For example: 1=MotionData 2=DashData 3=EventDataData 4=TimesData....
    ..... After this we have the corresponding structs with the data
}

Followed by the respective struct with the info related to the type of struct in the base one:

struct MotionData // Would be sent for example at 100Hz, defined by the game creator
{
    float time; // Would be the absolute time in the game (should change only when in the game, not in menus or when paused)
    float[3] headPositionRelativeToCOG; // 0,0,0 if data received is already relative to the head
    float[4] rotation // World rotatin given by a quaternion (xyzw, 4 floats, no gimbal lock or rotation order problems)
    float[3] worldPosition; // Position in the world
    float[3] localLinearSpeed; // meters per second
    float[3] localLinearAcceleration; // meters per second^2
    float[3] localRotationSpeed; // radians per second
    float[3] localRotationAcceleration; // radians per second^2
    int wheelsAmount; // Number of wheels
    WheelsData []; // Info about the wheels
}

struct WheelsData
{
    float[3] PositionRelativeToCOG; // Position of the wheel
    float suspensionPosition;
    float suspensionSpeed;
    float suspensionAcceleration;
    float pressure; // If zero you have a flat tire
    flaot slipAngle; // radians
    float slipRation; // 0 to 1
    float surfaceType; // 0 for a perfect flat surface, bigger for bad surface
    ....
}

struct DashData
{
    float rpm;
    float rpmMax;
    float gear; // -1=reverse 0=neutral
    float gearMax;
    ....
}

struct TimesData
{
    int lap;
    float trackPosition; // meters
    float lapTime; // Seconds
    float sectorTime; // Seconds
    int sector;
    ....
}

struct EventData // Would be sent for example at 0.5Hz, defined by the game creator
{
    int lapMax;
    float trackLenght; // meters
    string location;
    string vehicle;
    string vehicleClass;
    ....
}

In MMF case we could have multiple files in memory, one for each type of struct instead of updating the same memory file with different packets (and use different frequencies). Would keep all the same, but multiple shared memory files.

Also, I really like the customizable UDP used by Codemasters in DiRT Rally 2 where you can define the pretended structure. But this is more work for the game creators. Giving them a base structure that is filled with the info they have might be better to make them use it. We can always define multiple levels of packets, like Motion1, Motion2, Motion3 with different levels of info inside.

Yes we can make it really complicated. Honestly I don't seem them using it, but we can always do the stuff, they use if they want.