hlptr format questions

Any discussion on using LapTimer. Please use this forum in case you need guidance on how to use LapTimer or perform a certain operation
Post Reply
cars4enjoying
20 or more Posts ★★★
20 or more Posts ★★★
Posts: 27
Joined: Wed Jun 01, 2022 2:00 pm

hlptr format questions

Post by cars4enjoying »

I've now got code which is getting close to being able to convert to LapTimer hlptr from from trackaddict's CSV but there's a number details I'm not sure of and couldn't find on the forums.
  • What are the valid values for <lapRecordingType>?
  • Should <overallDistance> include altitude changes?
  • What are the components of <positioning>?
  • lap->date looks like it is in local time without any centiseconds (one hour ahead in my export) where as lap->recording->fix->date is UTC with centiseconds, is that correct?
  • Are all measurements in metric, so speed: kmh, distance: meters, pressure: kpa etc?
  • Do fix indexes need to be sequential without gaps?
  • Is accuracy GPS accuracy in meters or some other measurement?
  • How does acceleration lateral and lineral correlate to acceleration x, y, z?
  • Should I default hdop to 0 or something else?
  • Should coordinates, speed etc be interpellated between fix entries when obd is occurring at a different frequency?
  • I found the following OBD entries: rpm, maf, speed, throttle, fuelLevel, coolant, map and iat are there any other valid ones?
  • Some float fields seem to be to different decimal places, is that needed or will LapTimer parse what it finds?
User avatar
Harry
Site Admin
Site Admin
Posts: 10248
Joined: Sun Sep 12, 2010 10:32 am
Location: Siegum, Germany
Contact:

Re: hlptr format questions

Post by Harry »

lapRecordingType:

Code: Select all

typedef
enum
{
	LapRecordingUnknown,				//	Used for old recordings with unknown state or as null value
	LapRecordingManual,				//	User triggered manual recording
	LapRecordingTriggered,				//	Fully triggered recording with no information on status of track set used
	LapRecordingIncomplete				//	Recording with one end triggered and the other manual (both situations happen)

}	LapRecordingType;
Using canonic int mapping (Unknown = 0 etc).

overallDistance:
2D only

positioning:
components are differential, positioning, interpolated

Code: Select all

typedef
enum
{
	dsUnknown = 0,
	ds2D3D,
	dsDGPS,
	dsInvalid
		
} 	DifferentialStatus;

typedef
enum
{
	psNoFix = 0,		//	Invalid fix
	ps2D,			//	Either a fix measured with a too small number of satellites, or a triangulated fix
	ps3D,			//	Standard measured fix
	psVirtual2D3D,		//	Unknown quality of a fix, mostly used to signal a virtual (generated) fix
	ps2DIndoor		//	Position delivered by some (non-GPS) indoor positioning system

} 	PositionFixing;
interpolated is either 1 or 0 for true or false. Any fix delivered by the GPS chip and stored "as-is" will come with 0, any fix calculated by LapTimer using interpolation is 1. The later occurs for fixes approximating a trigger line passed.

lap -> date:
true and actually a design flaw; converting it to UTC during an automatic migration would require the time zone for every track; we haven't done that yet

LapTimer uses metric unit internally - including import / export to HLPTRL

fix indexes are ignored during import (out of my head without checking the code)

accuracy GPS:
meters

acceleration:
G values lateral and lineal relative to driving direction in multiples of G; see the Acceleration Handling on http://www.gps-laptimer.de/documentation

hdop:
set either hdop or accuracy or some default value in case you do not have it (hdop = 1)

OBD synchronization:
LapTimer full interpolates OBD to the (GPS) storage rate

OBD parameters:
this is the raw code doing the OBD export; values not set are not exported

Code: Select all

	builder.appendXMLTaggedChannelStorageValue (ENGINE_RPM_CID, recordP->obdFix.rpm1);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_MAF_CID, recordP->obdFix.maf100, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_SPEED_CID, recordP->obdFix.obdSpeed10);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_TPS_CID, recordP->obdFix.throttlePos100);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_FLI_CID, recordP->obdFix.fuelLevel100, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_ECT_CID, recordP->obdFix.coolantTemperature10, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_EOT_CID, recordP->obdFix.oilTemperature10, true);

	if (recordP->obdFix.map1)
		builder.appendXMLTaggedChannelValue (ENGINE_MAP_CID, 2, recordP->obdFix.map1/100.0);

	builder.appendXMLTaggedChannelStorageValue (ENGINE_IAT_CID, recordP->obdFix.iatCelsius40, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_GEAR_CID, recordP->obdFix.gear, true);

	if (recordP->obdFix.oilPressureI10)
		builder.appendXMLTaggedChannelValue (ENGINE_OILP_CID, 1, recordP->obdFix.oilPressureI10/10.0); // Special version to map kpa to bar in export

	if (recordP->obdFix.brakePressureI50)
		builder.appendXMLTaggedChannelValue (ENGINE_BRAKEPRESSURE_CID, 1, recordP->obdFix.brakePressureI50/2.0); // Special version to map kpa to bar in export

	builder.appendXMLTaggedChannelStorageValue (ENGINE_SPEEDRL_CID, recordP->obdFix.obdSpeedRL10, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_SPEEDRR_CID, recordP->obdFix.obdSpeedRR10, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_SPEEDFL_CID, recordP->obdFix.obdSpeedFL10, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_SPEEDFR_CID, recordP->obdFix.obdSpeedFR10, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_YAWRATE_CID, recordP->obdFix.yawRate100, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_ODOMETER_CID, recordP->obdFix.odometer1000, true);

	builder.appendXMLTaggedChannelStorageValue (ENGINE_STEERANGLE_CID, recordP->obdFix.steeringWheelAngle10, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_STEERRATE_CID, recordP->obdFix.steeringWheelAngleRate1, true);

	builder.appendXMLTaggedChannelStorageValue (ENGINE_FIXTYPE_CID, recordP->obdFix.fixType, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_SUPPORTLEVEL_CID, recordP->obdFix.supportLevel, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_DRIVERPOWER_CID, recordP->obdFix.driverPower1000, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_BATTERYTEMP_CID, recordP->obdFix.batteryTemperature10, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_BATTERYVOLTAGE_CID, recordP->obdFix.batteryVoltage100, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_CONSUMEDPOWER_CID, recordP->obdFix.engineConsumedPower1000, true);
float fields:
please name a sample, I need to look into it; internally, LapTimer is working with integers frequently (100 instead or 1.00)
Image Image Image Image
cars4enjoying
20 or more Posts ★★★
20 or more Posts ★★★
Posts: 27
Joined: Wed Jun 01, 2022 2:00 pm

Re: hlptr format questions

Post by cars4enjoying »

Thanks Harry, that's awesome!

Here's an example of a fix exported using hlptr which seems to have different float formats:

Code: Select all

<fix index="7484">
	<date>31-MAY-22,08:01:34.00</date>
	<coordinate>50.85790750,-0.75272170,28.2</coordinate>
	<speed>54.0</speed>		// 1dp?
	<positioning>0,2,0</positioning>
	<satellites>0</satellites>
	<direction>165.7</direction>	// 1dp?
	<hdop>0.00</hdop>		// 2dp?
	<accuracy>0.0</accuracy>	// 1dp?
	<relativeToStart>15.4,00:00.20</relativeToStart>
	<acceleration>
		<source>0</source>
		<lateral>0.00</lateral>	// 2dp?
		<lineal>0.21</lineal>	// 2dp?
		<coordinate>50.85790750,-0.75272170</coordinate>
	</acceleration>
	<obd>
		<rpm>734</rpm>
		<maf>3.13</maf>			// 2dp?
		<speed>3.0</speed>		// 1dp?
		<throttle>0.00</throttle>	// 2dp?
		<fuelLevel>1.00</fuelLevel>	// 2dp?
		<coolant>89.0</coolant>		// 1dp?
		<map>0.39</map>			// 2dp?
		<iat>43</iat>			// 0dp?
	</obd>
</fix>
If you're using int values internally with a multiplier the precise nature would make sense, so just curious if I need to round the values to avoid issues?

Is odometer in meters, kilometers or other?

Could you clarify what the follow represent as it's not clear from the naming along.

Code: Select all

	builder.appendXMLTaggedChannelStorageValue (ENGINE_FIXTYPE_CID, recordP->obdFix.fixType, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_SUPPORTLEVEL_CID, recordP->obdFix.supportLevel, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_DRIVERPOWER_CID, recordP->obdFix.driverPower1000, true);
	builder.appendXMLTaggedChannelStorageValue (ENGINE_CONSUMEDPOWER_CID, recordP->obdFix.engineConsumedPower1000, true);
Could you post the values for ENGINE_XXX_CID constants so I know the name of the xml fields?

If you happen to have an example file which has all or a large number of the fields present that I can use to testing that would be fantastic.

You mention interpolation is true for fixes approximating a trigger line passed, could the lack of data in a import explain unidentified point of interest when passing the start / finish line at speed?
cars4enjoying
20 or more Posts ★★★
20 or more Posts ★★★
Posts: 27
Joined: Wed Jun 01, 2022 2:00 pm

Re: hlptr format questions

Post by cars4enjoying »

Could you also detail what Acceleration -> Source options are?
User avatar
Harry
Site Admin
Site Admin
Posts: 10248
Joined: Sun Sep 12, 2010 10:32 am
Location: Siegum, Germany
Contact:

Re: hlptr format questions

Post by Harry »

Different float formats:
I'm still not sure what exactly you reference. In case it is about the <coordinate> tag: the one in <fix> is the actual fix position and includes latitude, longitude, and height above zero. The one in <acceleration> is a coordinate that should actually be calculated "on the fly" when displaying lateral acceleration in a map type view. It is the position of the green / yellow / red acceleration display. I recommend to not generate this value and skip it. Once the migration is working, I can check what the effect is and how LapTimer can be triggered to augment it.

As another side note: lat/lon are the only values actually stored as doubles (instead of long ints) in the database.

Precision is defined for each channel id (CID), so the number of precision digits is consistent in LapTimer exports. For imports, the conversion routine will accept other precisions but round them.

<odometer> is in meters

I had added the list of builder.appendXMLTaggedChannelStorageValue calls only to give you an overview what LapTimer imports / exports. As this is a long list, please just let me know which parameters you have problems to map and I reply with the tag name.

For the sample file, please just export one of the Spa Francorchamps laps that come with LapTimer.
You mention interpolation is true for fixes approximating a trigger line passed, could the lack of data in a import explain unidentified point of interest when passing the start / finish line at speed?
What do you mean by "unidentified point of interest". POIs / triggers are in a different database table and not included in HLPTRL.
Image Image Image Image
cars4enjoying
20 or more Posts ★★★
20 or more Posts ★★★
Posts: 27
Joined: Wed Jun 01, 2022 2:00 pm

Re: hlptr format questions

Post by cars4enjoying »

For floats, if LapTimer handles conversion gracefully of different precisions I don't need to worry, so thanks for confirming :)

I've got the values from key names for the ones I found in an export. I checked out the Spa Francorchamps laps but they only has limited OBD data for example, as was looking for a more complete data set example for validation.

Code: Select all

<obd>
		<rpm>5690</rpm>
		<maf>438.69</maf>
		<speed>94.0</speed>
		<throttle>0.55</throttle>
		<coolant>87.0</coolant>
		<iat>27</iat>
</obd>
In this snippets below the xml:"<value>" tag is what the name of field will be so the variable name is unimportant. I'm currently using 64bit floats but also have Float2dp and Float1dp which are the same underlying type but alter how the data is output, limiting precision.

This is an example of something I believe is currently correct:

Code: Select all

        // MassAirFlow is mass air flow in grams per second.
        // If not defined map is required.
        MassAirFlow Float2dp `xml:"maf,omitempty"`
Here are the ones I'm guessing the field name as I don't have an export with them in and for SupportLevel and FixType also unsure of the data type, sound like they might be strings?

Code: Select all

        // Gear is the selected gear which may be calculated.
        Gear int `xml:"gear,omitempty"`

        // OilPressure is the oil pressure in Bar not Kpa.
        OilPressure float64 `xml:"oilp,omitempty"`

        // BrakePressure is the applied break pressure in Bar not Kpa.
        BrakePressure float64 `xml:"brake,omitempty"`

        // WheelSpeedRearLeft is the speed in RPM of the rear left wheel.
        WheelSpeedRearLeft float64 `xml:"speedrl,omitempty"`

        // WheelSpeedReadRight is the speed in RPM of the rear right wheel.
        WheelSpeedRearRight float64 `xml:"speedrr,omitempty"`

        // WheelSpeedFrontLeft is the speed in RPM of the front left wheel.
        WheelSpeedFrontLeft float64 `xml:"speedfl,omitempty"`

        // WheelSpeedFrontLeft is the speed in RPM of the front right wheel.
        WheelSpeedFrontRight float64 `xml:"speedfr,omitempty"`

        // YawRate is the angular velocity of rotation.
        YawRate float64 `xml:"yaw,omitempty"`

        // Odometer measures the distance moved in meters.
        Odometer float64 `xml:"odometer,omitempty"`

        // SteerAngle is the angle of steering wheel in degrees.
        SteerAngle float64 `xml:"steer_angle,omitempty"`

        // SteerRate is the rate of steering wheel angle change.
        SteerRate float64 `xml:"steer_rate,omitempty"`

        // FixType TODO(steve): describe properly and confirm data type.
        FixType string `xml:"fix_type,omitempty"`

        // SupportLevel TODO(steve): describe properly and confirm data type.
        SupportLevel string `xml:"support_level,omitempty"`

        // DriverPower TODO(steve): describe properly.
        DriverPower float64 `xml:"driver_power,omitempty"`

        // BatteryTemp is the temperature in Celsius of the battery.
        BatteryTemp float64 `xml:"battery_temp,omitempty"`

        // BatteryVoltage is the voltage of battery.
        BatteryVoltage float64 `xml:"voltage,omitempty"`
Sorry I meant "Information Unspecified". I have recordings where some laps work just fine and others report "Information Unspecified" instead of "Start / Finish (flag)" as I pass the start / finish line. Based on your previous comment I wondered if the values haven't been interpolated correctly during import to trigger the Start / Finish POI detection correctly hence the issue?

As I'm manipulating the data anyway it shouldn't be too difficult to add interpolated fixes using a geodesic inverse line calculation to match the start / finish line etc if I had the GPS coords and you think that might help?

What type of interpolation would you recommend for the OBD data, currently using PiecewiseLinear but it's interface based so can swap that out for any number of other implementations such as AkimaSpline, FritschButland, NaturalCubic etc?
User avatar
Harry
Site Admin
Site Admin
Posts: 10248
Joined: Sun Sep 12, 2010 10:32 am
Location: Siegum, Germany
Contact:

Re: hlptr format questions

Post by Harry »

fixtype (not fix_type) is a qualifier for the type of engine:

Code: Select all

typedef enum
{
	OBDFixSubTypeCombustion,
	OBDFixSubTypeSpeedAndCadence,
	OBDFixSubTypeElectric,
	OBDFixSubTypeHybrid

}	OBDFixSubType;
If set, use 0 (for combustion) for most situations.

For all the other guesses: I'd rather not start documenting all the parameters not relevant for your import. That's a lot of work / investigation. So please let me know which CSV field you cannot map currently and I can help on this subset.
Image Image Image Image
Post Reply