LogixNG Tutorial - Chapter 22

The future of LogixNG - Expanding it further

These examples are not implemented yet and doesn't exist in the source tree.

This chapter may seem like "up in the air", describing things that are pure fantasies, and let it be it. But if you understand how to extend LogixNG beyond, you might also get a deeper understanding on why it is designed the way it is today.

The code in this section is in the package jmri.jmrit.logixng.future. To use these these actions and expressions, you need to enable "Demo examples" in the LogixNG preferences. These examples are only skeletons that doesn't do anything useful, except explaining the inner details of LogixNG.

Note that the actions and expressions in this example is disabled by default. In order to use them, go to menu Edit / Preferences / LogixNG and select "Enable demo actions and expressions". If you have loaded the example panel file and then have stored it again without enable demo, these actions and expressions will not be stored in the panel file. If so, enable demo actions and expressions in the preferences and then go back to the original panel file which has these actions and expressions.

Lets assume that a scientist wants to use JMRI and LogixNG to experiment with articifial intelligence on a model railroad. He has a camera and a small image processing computer inside the engines that takes images and try to figure out if there is a signal or a sign next to the track and if it finds one, it sends that image to the computer running JMRI.

First we need to decide on what data we will work on. For this example, we want some image and a position.

public interface AI_Image {

    // Get the address of the loco that sends the image
    public int getLocoAddress();

    // Set the address of the loco that sends the image
    public void setLocoAddress(int locoAddress);

    // Get the image
    public Image getImage();

    // Set the image
    public void setImage(Image image);

    // Get the position
    public Position getPosition();

    // Set the position
    public void setPosition(Position position);

}

Note that local variables, memories and tables work with Java Object so you can store an AI_Image into these.

Then we need to decide what we want to do with this. Lets assume we want expressions that gets an AI_Image, for example an expression that fetches the image from a particular enigne. And that we want actions that can take an AI_Image and do something, for example do some image processing on it or to check if it's a signal and then take action like stopping the engine. So we create interfaces for AI_Image expression and AI_Image action.

public interface AI_ImageExpression extends Base {
    
    public AI_Image evaluate() throws JmriException;
    
}
public interface AI_ImageAction extends Base {
    
    public void doSomething(AI_Image image) throws JmriException;
    
}
These interfaces implements the jmri.jmrit.logixng.Base interface. It has some methods that are common to all actions/expressions in LogixNG, for example methods for getting the parent, finding the root of the tree, getting the number of children and getting a particular child.

The managers works on items that are NamedBeans so we also needs an interface that extends NamedBean. The reason that the AI_ImageExpression and AI_ImageAction does not implement NamedBeans is that the female sockets should not be NamedBeans and that the female socket needs to implement the interface it is socket for. So instead, we create additional interfaces, AI_ImageExpressionBean and AI_ImageActionBean that extends both the action/expression and NamedBean.

public interface AI_ImageExpressionBean extends NamedBean, AI_ImageExpression {
}
public interface AI_ImageActionBean extends NamedBean, AI_ImageAction {
}
After that, we need to create the male and female sockets. A male socket wraps the actions/expressions so that it can be connected to a female socket. And a female socket allowes an action/expression to be connected to something else.

Then we need to create the managers for the actions and expressions.

The actions:

  • Actions
  • Many
  • IfImageIsSignal - Do something if the image shows a signal with aspect green.
  • IfImageIsSign - Do something if the image shows a sign with a speed limit.
The expressions:
  • GetImageFromLoco - Read the last image from loco NN.