5.5 Add Custom Properties

Introduction

In this section you will learn how to add your own properties to the setup file and how to load it. As example we store a new property which contains the fuel required for one lap. We load this property and compute from that the whole amount of fuel we need for the race. Then we pass that back to the simulation, so that our car starts with the ideal amount of fuel.

Implementation

First I show you the changes needed in the setup file. For the example we take the driver bt 1 on g-track-3 in practice mode. From that follows that we have to modify the file 0/practice/g-track-3.xml. Add the following to the file above from </params>.

    <section name="bt private">
        <attnum name="fuelperlap" val="2.0"/>
    </section>

We define a new section type for all our private settings. Inside the section we define our new property "fuelperlap" as numeric property and assign the value 2.0. You could also put your properties into another file.

Now we add the code to load the property to driver.cpp. First we define new constants to access the section and the attribute.

#define BT_SECT_PRIV "bt private"
#define BT_ATT_FUELPERLAP "fuelperlap"

The code to load and initialize settings has to be in Driver::initTrack(). Append the following code at the end of the method.

    float fuel = GfParmGetNum(*carParmHandle, BT_SECT_PRIV, 
        BT_ATT_FUELPERLAP, (char*)NULL, 5.0);

Try to load our property. If it fails the value defaults to 5.0. After that compute the required fuel for the race. That's the number of laps times the fuel required per lap. To play safe we add fuel for an additional lap. After that set the initial fuel up.

    fuel *= (s->_totLaps + 1.0);
    GfParmSetNum(*carParmHandle, SECT_CAR, PRM_FUEL, (char*)NULL, MIN(fuel, 100.0));

If you run a practice session with bt 1 on g-track-3 the initial fuel should be 42.0 if everything works.

Accessing Subsections

You have seen that it is possible to have subsections in the setup files, so that it is possible to structure the parameters. But how do we access parameters in subsections? As example we assume that we add a subsection "test" in our private section, which contains the parameter "cool".

    <section name="bt private">
        <attnum name="fuelperlap" val="2.0"/>
        <section name="test">
            <attnum name="cool" val="2.0"/>
        </section>
    </section>

To access the parameter "cool" you have to assemble a path for the subsection, which contains simply the section names top down to the subsection separated by "/". So the path would be "bt private/test". Here is an example how to implement it.

#define BT_SECT_PRIV_TEST "test"
#define BT_ATT_COOL "cool"

float cool;
char path[256];
sprintf(path, "%s/%s", BT_SECT_PRIV, BT_SECT_PRIV_TEST);
cool = GfParmGetNum(*carParmHandle, path, BT_ATT_COOL, (char*)NULL, 0.0);

Downloads

In case you got lost, you can download my robot for TORCS 1.2.0 or later.

Summary

  • You know how to load custom properties.
  • You know how to access and create subsections.
  • You know how to set up your car with computed values.