emergent plugins are written in C++ and are then compiled into a shared object library (.so) that can be dynamically loaded when emergent starts, providing arbitrary additional functionality to the simulator. Writing plugins is a relatively quick and easy way to add new functionality to the software and requires much less knowledge than directly modifying emergent's core code.

This article will document the current emergent plugin infrastructure that has been set up for the Learn workgroup in addition to going over the essential concepts and skills that are needed to write plugins. Information relating to the Nao plugin, the Lyon's Cochlear Model plugin, the Auditory Image Model plugin, the emergent client plugin in addition to any future plugins that arise should be concentrated here.

Getting started

We are standardizing on Ubuntu for development. The latest version of Ubuntu called Natty is preferable, but users who are at least as recent as Ubuntu Lucid should be able to follow along.

Step 0: Install emergent beta

The first thing you need to do is install emergent beta. This will automatically make sure you have a compiler installed in addition to all of the other prerequisites you need to do development.

Add the following to /etc/apt/sources.list

deb http://grey.colorado.edu/ubuntu natty latest

Replace natty with maverick or lucid if that is the version of emergent you are running.

Next run sudo apt-get update followed by sudo apt-get install emergent. When it's done you can confirm that emergent is working by typing emergent at the command line.

Step 1: Grab the learn workgroup's subversion repository

First make sure you have subversion installed by running sudo apt-get install subversion.

It is strongly recommended that you do the next step with your laptop plugged into the gigabit ethernet in the lab since that is where the subversion repository is located and the repository is now quite large.

Next run the following command:

svn co https://neuromorphs.net/svn/ws2011/svn11/learn ~/learn

This is going to take a while - grab a coffee :) Once it's finished you will have a directory called learn in your home directory. It presently has the following structure:

~/learn/sims/lvis.proj                   # The Leabra Vision (LVis) Model
~/learn/sims/wts/*                       # The trained weights for LVis on the CU3D 
~/learn/sims/plugins                     # The root plugin directory
~/learn/sims/plugins/Nao                 # The Nao robot plugin
~/learn/sims/plugins/LyonsCochlearModel  # The plugin or Malcolm's implementation of Lyon's model
~/learn/sims/plugins/AIMC                # The plugin for the Auditory Image Model
~/learn/nao/naoqi-sdk-1.10.44-linux      # A modified version of naoqi.
                                         # If you already had naoqi delete your old one.

Step 2: Confirm you can compile the Nao plugin

Let's make sure your infrastructure is correctly in place. If this doesn't work and you want to use Nao from emergent let Brian know.

cd ~/learn/sims/plugins/Nao
cd build
make install

You should see some warnings. Warnings are often OK. Errors are bad. As long as you see this in the output everything was successful:

Linking CXX shared library libNao.so                                                                                                                                                                                                         
[100%] Built target Nao

How to create an emergent plugin

Step 0: Creating the plugin and understanding the code

Let's create a quick Hello World plugin.

  • Open emergent
  • Click on the PluginWizard
  • For plugin name enter HelloWorld
  • For plugin location enter /home/<yourusername/learn/sims/plugins/HelloWorld
  • For unique id you must enter a unique id like al.12a.11.5, ie, completely random if you want.
  • Click Validate. It should tell you there are no errors.
  • Click Create. This will create your plugin in the above plugin location.
  • cd ~/learn/sims/plugins/HelloWorld

In this directory there are many files, but only two matter to you: HelloWorld.cpp and HelloWorld.h. The .h file is the header file which contains class, method and member definitions and the .cpp file contains the actual implementations off those definitions. Let's look at a stripped down example from the plugin we just created. There are many complexities in the plugin template that was automatically created for you, but I am going to ignore almost all of them with the hope of touching base with your existing programming knowledge. In practice, you ignore most of the complexities and just get down to writing relatively simple code.

Among other things, the .h file contains:

class HELLOWORLD_API HelloWorldClass : public taNBase {
  String                example_member1;                                                                                                                            
  void                  Hello();                                                                                                                                                                          

  override void         UpdateAfterEdit_impl();                                                                                                    
  void  Initialize();
  void  Destroy();

And in the .cpp file we find, among other things:

void HelloWorldClass::Hello() {
  taMisc::Info("Hello from HelloWorldClass!");

It should be quite clear that the HelloWorldClass has a Hello method definition and that the .cpp file contains the implementation of that definition. When we call Hello it prints "Hello from HelloWorldClass". Not rocket science! ;-)

Step 1: Compiling the plugin

The procedure of compiling the plugin is very straightforward. You will find yourself trying to compile a lot. When writing C++ you will probably make lots of syntax and grammar mistakes and the most frequent method of finding those mistakes is that your code doesn't compile. Here is the method:

cd ~/learn/sims/plugins/HelloWorld
sh configure # will need to then press Enter, confirming the settings are OK
cd build
make install

If your plugin fails to build you have to study the compiler output, try to fix the code and then try to compile again until it works.

Step 2: Loading the plugin into emergent

After you get your plugin working the classes that you created are then available to emergent's built-in scripting language css. This is more generally known as program code. Let's go through the procedure of calling the Hello function, which you should have compiled and installed in the last step, from within an emergent program.

  • Open emergent
  • In the root view (the first window that opens) under plugins you should see a greyed out HelloWorld?. Click it
  • Check the enabled box. You will only have to do this (and the next two steps) once.
  • Close emergent
  • Re-open emergent. The plugin should no longer be greyed out, indicating that it was dynamically loaded.
  • Create a new LeabraProject?
  • In the project create a new program by right clicking on programs and selecting new. You can alternately highlight programs and push Ctrl+i
  • Click on your new program and go to the Edit Program tab
  • Create a new object in your program by right clicking on objs and selecting new (or using Ctrl+i)
  • Search for and select your HelloWorld? object. It will then be inserted into objs with a name like HelloWorld?_0 which ensures the name is unique.
  • Click on prog_code, press Ctrl+i, and search for and select MethodCall
  • Click on the MethodCall and for its obj select your HelloWorld_0 object
  • For the method select Hello
  • Click Init followed by Run. You should see the Hello World message printed to the console.

Step 3: Getting API help

emergent has an extensive API of utility objects and functions that you may wish to call. You can read about all of these objects and their methods using the HelpBrowser. This can be accessed by going to Help in any of emergent's windows and selecting the Help Browser. Once you find an object you are interested in using in a plugin, such as the ubiquitous DataTable, you must then include the correct header file (in this case ta_datatable.h) near the top of the .h file of your plugin. You will then be able to create new objects, for instance:

DataTable* my_table = new DataTable;
for (int i = 0; i < my_table.rows; ++i)
  my_table->SetVal(1.0, "column_of_floats", i);

Step 3a: Searching emergent's source code

There is one major caveat which is that the Help Browser won't tell you which header file contains the object you are interested in. For this reason it is useful to obtain emergent's source code and use a tool such as grep to search through it.

To obtain emergent's source code in ~/emergent use the following command:

svn checkout --username anonymous --password emergent http://grey.colorado.edu/svn/emergent/emergent/trunk ~/emergent

You can then use a command such as

cd ~/emergent/src
grep -R DataTable ./*

to figure out which header file the DataTable? class is defined in. Or just ask Brian!