-
Notifications
You must be signed in to change notification settings - Fork 35
Trick Integration
IDF offers several conveniences to ease integration with a Trick simulation. They can all be found under the 3rdParty/trick
directory.
3rdParty/trick/makefiles/core.mk
handles all of the stuff you'd usually have to put in your sim's S_overrides.mk
file:
- including the path to header files in
TRICK_CFLAGS
andTRICK_CXXFLAGS
- including the path to sim objects in
TRICK_SFLAGS
- including necessary (OS-specific) libraries in
TRICK_USER_LINK_LIBS
- setting (if not already set) and making
IDF_HOME
available as an environment variable at run time
A bunch of details about which you'd rather not worry! Rest easy, my friend, and simply include IDF's makefile from your sim's S_overrides.mk
:
include <path to IDF>/3rdParty/trick/makefiles/core.mk
Frequent users of IDF will find themselves implementing the same infrastructure over and over again to manage IDF devices. For more than trivial uses, you usually need some sort of manager to handle maintaining a list of devices and performing operations on them as a group (like opening, updating, and closing). On top of that, you'll probably want to wrap it in a SimObject
with appropriately-classed jobs that call manager functions. Most managers end up looking pretty similar with the same core structure and some additional application-specific extras. I have a special hatred in my heart for duplicated code, so IDF offers you a ready-to-use SimObject
that takes care of all that boiler-plate code for you! Take a look at 3rdParty/trick/sim_objects/IdfInputDeviceManager.sm
, and you'll find:
- an initialization job that opens all devices
- a shutdown job that closes all devices
- a job (with a configurable phase, period, and class) to update all devices
- functions for adding devices
- functions for setting properties of all devices at once
Now that all the boring standard infrastructure stuff is taken care of, you're left with the decidedly more enjoyable task of adding your application-specific functionality by deriving your SimObject
from IdfInputDeviceManager
like so:
/**
* make sure you include 3rdParty/trick/makefiles/core.mk from your
* S_overrides.mk so this file can be found!
*/
#include "IdfInputDeviceManager.sm"
class MyInputDeviceManager : public IdfInputDeviceManager {
public:
/**
* IdfInputDeviceManager's constructor requires the period at which you want
* to run the update job. It has some optional arguments too, so be sure to
* check it out!
*/
MyInputDeviceManager() :
IdfInputDeviceManager(<period>) {}
// no boiler-plate code, only cool extra stuff!
};
IDF's own example simulations use this approach, so if you need a little more substance, head on over to 3rdParty/trick/examples
and peruse an S_define
or two.
Are you still programming in the compiled side of Trick? Didn't you know that you can write entire simulations in the input file!? Type safety and proactive syntax checking be damned! If you like your errors at run time, 3rdParty/trick/python/idf
is for you. It's primary feature is the idf.config.Configurator
class which, in cooperation with an IdfInputDeviceManager
, allows you to configure your input devices from the input file. It's constructor looks like this:
def __init__(self, deviceManager, vhcVariableName = None)
The required argument is an instance of an IdfInputDeviceManager
or a derivative thereof (from the section above). The optional argument is a string containing the full name of an instance of VirtualLayout
(see include/VirtualLayout.hh
) and is used to enable automatic launching of the Virtual Hand Controller.
IDF searches for devices using the following algorithm:
- If
~/.idf/config.py
exists, IDFexec
's it in the context of theConfigurator
instance. The use of this config file allows the specification of available devices to be independent of the simulation files. For instance, you could configure IDF right in your input file. But then that input file only works for developers who have your input device. If Bob in the cube across the hall has a different device, now he has to change the input file, which is surely tracked in your repository, breaking it for everyone who doesn't have his device. Since this sort of configuration is machine-specific, you should keep it with the machine and out of your repository. Becauseexec
preserves the caller's context, you can accessConfigurator
methods in your config file viaself
. For instance:
self.addMasterDevice(trick.UsbWingMan())
- If
~/.idf/config.py
does not exist, IDF tries~/.idf_<hostname>/config.py
instead. This can be useful if you have multiple machines that share the same home directory but need individual config files. - If neither of those files exist, IDF uses the first connected HID-class device (USB or Bluetooth) that it knows about and calls
addMasterDevice
, described below. - If no devices can be found, IDF launches the Virtual Hand Controller if support has been enabled as described above.
While the Configurator
is pretty flexible as to how it searches for devices, once it's found them, someone has to tell it what to do with them. That someone, of course, is you! addMasterDevice
is an abstract method that you must override, providing the logic necessary to connect the specified device to your simulation. This could be as simple as creating a single Controller
and assigning it to a pointer in your IdfInputDeviceManager
subclass or as complex as creating multiple Controller
s and MutualExclusionGroup
s and adding them to CompositeController
s. It all depends on what you want a device added via this method to do.