wiki:Manual/PropagationModels/UserDefined

You are here: Manual / PropagationModels / User Defined

TracNav


Creating a propagation model plugin

The SEAMCAT-4 allows you to set your own propagation models with maximum freedom in the number and type of input parameters. With this "User-defined" propagation models plugin concept you may define very complex propagation modelling using standard Java programming language.

You are able to provide description to your input value in a "tooltip" format, to set default value that you can refresh, and there are no limit to the number of inputs.

The very detailed and illustrated description of programming and connecting plugins with user defined propagation model is provided below on this page.

Click on the following link to get directly to the section of this page

A video decribing how to install the plug-in is available here (8 MB - note: the sound is fading towards the end.). Note that the new embeddement feature is not presented in the video.

Environment

Before you can start developing SEAMCAT post processing plugins you will need to ensure that your system has been correctly configured.

Information on how to do this is located in the Basic Enviroment Setup section.

Creating the plugin

To create the plugin you create a file called .java and place it in a directory of your choice, eg. C:\Seamcat\plugins and then you open this file in your favorite texteditor.

In this file you paste the contents here below to create the skeleton of a plugin.

import org.seamcat.model.propagation.*;
import java.util.ArrayList;
import java.util.List;

public class MyPlugin implements PropagationPluginModel {

    @Override
    public double evaluate(double frequency, double distance, double TxHeight, double RxHeight, boolean variation,
            Parameter... params) {

        double loss = 0;

        Double param_1 = params[0].getValue();
        
        //Your model implementation goes here
        
        return loss; //losses are positive value
    }

    @Override
    public List<ParameterDefinition> getParameterDefinitions() {
        List<ParameterDefinition> parameters = new ArrayList<ParameterDefinition>();

        parameters.add(new DoubleParameter("Parameter 1").defaultValue(10).unit("m")
                .description("description of parameter 1 in a tooltip"));

        return parameters;
    }
}

This is the base skeleton you need to implement in order to create a Seamcat plugin. When creating the java-file, it is important to observe the java-code conventions, ie. the name of the class must match the name of the java-file, ie. the class MyPlugin must be defined in a file called MyPlugin.java, also it is recommended to start the classname with a capital letter.

Now you are ready to implement the evaluate method with your own mathematical functions. Two examples are presented below with their respective interface.



Exampe of plugin 1

The following is a small sample plugin to show how to create the plugin and how to use System.out.println for debugging purposes.

This sample plugin is an implementation of the DualSlope Pathloss model.

import org.seamcat.model.propagation.*;

import java.util.ArrayList;
import java.util.List;

public class DualSlope implements PropagationPluginModel {
        
        @Override
        public double evaluate(double frequency, double distance, double TxHeight, double RxHeight,
                                                                  boolean variation, Parameter... params) {
                Double loss = 0.0;
                Double REFERENCE_DISTANCE = params[0].getValue();
                Double PATH_LOSS_COEFFICIENT = params[1].getValue();
                
                //Convert distances into meters 
                distance *= 1000; 
                REFERENCE_DISTANCE *= 1000; 
                Double l = 300 / frequency; 

                if ((distance) < REFERENCE_DISTANCE) { 
                        loss = 20 *Math.log10(l / (4* Math.PI * distance)); 
                        System.out.println("Distance is below reference distance and loss is " + loss + " dB"); 
                } 
                else { 
                        loss = 20 *Math.log10(l / (4* Math.PI *REFERENCE_DISTANCE)) + 10* PATH_LOSS_COEFFICIENT* Math.log10(REFERENCE_DISTANCE / distance); 
                        System.out.println("Distance is above reference distance and loss is " + loss + " dB"); 
                } 

                loss=(-1)*loss;

                return loss; //losses are positive value
        }

        @Override
        public List<ParameterDefinition> getParameterDefinitions() {
                List<ParameterDefinition> parameters = new ArrayList<ParameterDefinition>();

                parameters.add(new DoubleParameter("Reference distance").defaultValue(10).unit("m").description("This is the reference distance of the dual slope"));
                parameters.add(new DoubleParameter("Path loss coefficient").defaultValue(10).unit("no unit").description("Path loss coefficient"));
                return parameters;
        }

}


When running the above code 10 times, you will see something like the following in the Java console (depending on how you configured the run), which should give you an idea of how you can use System.out.println statements to debug your plugin if the plugin doesn't produce the results you were expecting.

You should remove any "System.out" statements before using your plugin in actual simulation, as these will clutter logfiles and slow down simulation speed signifigantly.


You can see that interface is very basic (i.e. only two inputs that are of type "double"). In some cases, you may need more than 2 inputs, or you may want your input to be of different types. The Exmaple 2, is a dummy plugin (from a mathematical point of view) with the purpose of showing you how to use the different type of input. You have total freedom to use:

  • combox box with selection
  • boolean
  • double
  • double optional
  • integer
  • integer optional

Note: When passing values from the input parameter interface, do not define them as primitive like double but instead as object like Double. This is important in order to avoid runtime errors. In case you need some switch/case a proposed work arround is to use if statement instead.

Exampe of plugin 2

import org.seamcat.model.propagation.*;

import java.util.ArrayList;
import java.util.List;

public class PropagationExampleParameters implements PropagationPluginModel {
        
        @Override
        public double evaluate(double frequency, double distance, double TxHeight, double RxHeight,
                                                                  boolean variation, Parameter... params) {
                Double result = 0.0;
                double env = 0.0;
                String environment = params[0].getValue();
                Boolean variation2 = params[1].getValue();
                Double height = params[2].getValue();
                Integer velocity = params[3].getValue();

                Integer velocity2 = 0;
                if ( params[4].isEnabled() ) {
                        velocity2 = params[4].getValue();
                }

                Double Maybe = 0.0;
                if ( params[5].isEnabled() ) {
                        Maybe = params[5].getValue();
                }

                if(environment == "Rural"){
                        env = 1;
                }else{
                        env = 2;
                }
                
                if (variation2){
                        result = env *(height*velocity+Maybe + (double)velocity2);
                }else{
                        result = env *(-1000.0);
                }

                return result;
        }

        @Override
        public List<ParameterDefinition> getParameterDefinitions() {
                List<ParameterDefinition> parameters = new ArrayList<ParameterDefinition>();

                parameters.add(new SelectionParameter("General Environment test", "Rural", "Suburban", "Urban").description("description Selection"));
                parameters.add(new BooleanParameter("Variation2").defaultValue(true).description("Perform variation measurement"));
                parameters.add(new DoubleParameter("Height").defaultValue(1.3).unit("m").description("Describe the height of the building"));
                parameters.add( new IntegerParameter("Velocity").defaultValue(45).unit("m/s").description("Velocity of mobile device"));
                parameters.add( new IntegerParameter("VelocityOptional").defaultValue(45).unit("m/s").optional().description("optional Velocity of mobile device"));
                parameters.add( new DoubleParameter("Maybe,maybenot").defaultValue(4.2).unit("no").optional().description("description to DoubleParameter optional") );
                return parameters;
        }

}


How to compile the plugin

In the following, it is assumed that you have set your PATH environment properly. To set the PATH environment follow the explanation as described in Basic enviroment setup. Make sure that the file "seamcat_needed_for_plugin.jar" and your plugin "DualSlope.java" or "PropagationExampleParameters.java" is in the same folder (for this example), if this is not the case, you need to change the paths in this section accordingly.)

Open a dos-prompt window and select the folder where your plugin is. for instance seamcat\plugins folder. Here you enter the command "javac -classpath seamcat_needed_for_plugin.jar DualSlope.java". This will compile your plugin so that it is ready to be added to the Seamcat application.

NOTE: Remember that the name of the file should be the same as the name of the class. I.e. the DualSlope class should be defined in DualSlope.java.



If the compiler complains about problems with your plugin, you need to fix these and try to compile again.



Now you should have DualSlope.class and PropagationExampleParameters.class

How to add your plugin to SEAMCAT with embeddement

Once you have compiled your plugin successfully, you will find a .class file in the same directory as your java file.

You can embed your propagation model plugins so that you can distribute your workspace with your plugin. This increases the flexibility in exchanging workspaces within the SEAMCAT community.

You need a copy of the seamcat_needed_for_plugin.jar in the Seamcat directory (%USER_HOME%seamcatplugins).

The following step-by-step procedure presents an example on how to embed propagation model plugin library. We are using the JTG5-6 model (available at http://tractool.seamcat.org/wiki/Manual/PropagationModels/JTG56):

  1. The .class files have to stored in a .jar file in the "plugins" folder. (this is simple, added to a zip file and then change the extension from .zip to .jar)
  2. In SEAMCAT, press Library -> Propagation model plugins ->

  1. Select the .jar file to be embedded in your library. You will see that the name of the file you have embedded is appearing under the choose button.
  2. Name is a name to identify your plugin.
  3. Description is a short description of your plugin (optional).
  4. Fully Qualified Classname is the fully qualified classname of your plugin. In Fully Qualified Classname form write: TestNewPropagationPlugin?1 (it should appear as you type and the red background should disappear). The Name/Reference will automatically update as you type in the Qualified Classname form. Note that you can edit this field if you want to.

  1. you will see that the propagation model that you have selected is embedded. This will allow you to share your workspace with others without sending separately your propagation model.
  2. you can add or delete propagation plugins
  3. You can now set your propagation model in the victim or the interfering link. You do not need to close and relaunch SEAMCAT.

Note that SEAMCAT will automatically save the .jar or .zip file on your “plugin” directory.

Requirements to embeddement

In addition to the existing requirements for plugins, embedded plugins will only work if:

  • The plugin must only refer to classes which are in the SEAMCAT classpath, not another plugin. This also goes for the class definitions, ie. extended classes, implemented interfaces, generics etc. A simple rule to stick to is to only use standard java functionality and SEAMCAT functions.
  • The plugin must use the default package (meaning that the "package"-statement should be omitted)

In the unlikely event that SEAMCAT fail to upload the embedded file, you will be prompted with the following error message as shown below.

Please contact seamcat@… if you have problem with your plugin.

How to add your plugin to SEAMCAT without embeddement

If you do not want to embed your plugins into your workspaces, copy the .class file to your Seamcat directory (%USER_HOME%seamcatplugins). You need to do that before you launch SEAMCAT.

Remember that if you have chosen to use a package for your plugin, you must recreate the package structure under the plugins directory. If you dont know what that last meant, then you probably didnt use a package and can ignore it.

  1. Keep the copy of the seamcat_needed_for_plugin.jar in this directory.

  1. Next start up SEAMCAT and add the plugin.
  2. Next fill out the information about your plugin.
  3. Now click OK and Close SEAMCAT.
  4. Restart SEAMCAT and your plugin should be ready for action.

How to test your plugin

You can test any of your plugins. Go to the following http://tractool.seamcat.org/wiki/Manual/PropagationModels/HowToTestPropagationModel to get more information.

Available Mathematical functions

Please go to the end of the following page http://tractool.seamcat.org/wiki/Manual/Library/Plugins/PostProcessing to get more information on the Mathematical functions.

Problems

Q: Why do I get an error telling me the class file has a wrong version ?
A: If you get an error like the one below, it is because you are trying to compile the plugin using a java-version earlier than 1.5.0.

Check your PATH environment variable if there is a reference to a directory containing another javac.exe. Alternatively use full path to the javac compiler when compiling the plugin.

MyPlugin.java:1: cannot access org.seamcat.mathematics.Mathematics bad class file: 
..libseamcat_needed_for_plugin.jar org/seamcat/mathematics/Mathematics.class) 
class file has wrong version 49.0, should be 48.0

Q: Why do I get an "The specified class failed to load" when trying to add a new plugin ?
A: Check your %HOME_DIR%seamcatseamcat.log file. If you see an "java.lang.NoClassDefFoundError: org/seamcat/model/propagation/PluginModel" error message, then you have forgotten to copy the seamcat_needed_for_plugins.jar file to the plugins dir. Copy this file and restart Seamcat.

Q: Why do I get an Unknown command error when trying to compile my plugin ?
A: You didn't add %JAVA_HOME%bin to your PATH environment variable.

Attachments