Skip to content

Controlling pony from the host side

osenmukdav edited this page Apr 27, 2020 · 2 revisions

Functions controlling pony

Typically, pony is controlled by the host through one fuction (however, check Multithreaded applications), often main(), but not neccessarily.

In general, the part managing pony in such a function looks like this:

if ((
    pony_add_plugin(plugin1)
    && pony_add_plugin(plugin2)
    && pony_add_plugin(plugin3)
    && pony_add_plugin(plugin4)
    ))
{
    if (pony_init( "configuration string" ))
    {
        while (pony_step());
    }
}

pony_add_plugin(plugin_name) adds the plugin to the plugin execution list, and plugins are later called in the order they were added. If the plugin is added several times, it will be called this number of times in one iteration.

pony_init("configuration string") uses the configuration string (covered below) passed to it to initialise parts of the bus needed for this instance of pony.

pony_step() calls every plugin in the plugin execution list once and then returns the value indicating whether pony needs to continue running (continue running - 1, stop - 0). Before returning 0, pony_step() clears pony.

If either pony_add_plugin() or pony_init() fails, they return 0 and clear pony. Otherwise they return 1.

Technically, pony_init() can be called not only after pony_add_plugin(), but also before and even in between them. However, there is "after one fails next ones don't get called" rule for these two functions, which is necessary to ensure a clean pony in case of failure (to avoid memory leaks and to allow reinitialisation). So, the heaviest on calculation function probably shouldn't be called first in case one of the next 10 fails and wipes everything. And placing in between just doesn't really help reading code.

Don't call pony_init() the second time if pony hasn't been cleared, otherwise thre will be a huge mess. Just don't.

There are also advanced functions for managing plugins, which are covered here.

Configuration string

Configuration string determines which parts of the bus will have memory allocated for them. Right now, the tree of parts allocated depending on the configuration string looks like this:

parts allocated depending on confuguration string scheme

If you want to initialise a part, you should include its group - its name followed by a colon and surrounded by braces ("{name:}") - in the configuration string (for instance, writing "{imu:}" would make imu structure allocated, "{gnss:{gps:}}" would allocate one gnss structure with a gps unit, and "{imu:}{gnss:{gps:}{glo:}}" would allocate an imu structure and one gnss structure with gps and glonass units). gnss can have up to 10 instances, to allocate just one use "gnss", and to allocate multiple use "gnss[i]", where i is an index from 0 to 9 (for example, "{gnss[0]{gps:}}{gnss[2]{gps:}{glo:}}". This would allocate instances 0, 1 and 2, but only 0 and 2 would have cfg not equal to NULL, which means that a bus part is initialised and can be used).

Each group can also have additional information - continuous block of text (not interrupted by inner groups). Additional information common for all pony is written outside any groups, and additional information for a group is written after ":" and before "}" of this group (again, separately from groups that are inside this one). For example, "{imu: dt = 0.02} {gnss[0]: stl = 8 {gps:} } {gnss[1]: {gps: a = 1} stl = 10} {gnss[2]: {gps:} stl = 7, b = 9 {glo:}} outIndex = 301". Spaces, commas and non-printable charachters (such as '\n') are not considered additional information and are skipped over. For each piece of additional information, a bus part has a pointer to the character where the information starts and the length of the string until the group finishing, inner group starting or the end of the configuration string.

The configuration string passed can be hardcoded or read from file, pony anyway stores a separate copy, so you can clear your copy after initialisation if you need to.