R030 Signal Script Production


Outline

Signal scripts allow the users to analyze and interpret signals in many ways. Combine signals using mathematical operations, generate references, implement protocol parsers, extract statistical informations or search for conflicts automatically.

Platforms:
32/64bit 32/64bit 32/64bit
Requirements:
  • None
Known limitations:
  • None
Status:
  • Stable
Input signals:
  • 0..N signals of any type.
Output signal:
  • Configurable signal of any type.
Parameters:
  • Process type: Process type of the resulting signal.
  • Signal type: Signal type of the resulting signal.
  • Signal descriptor: Signal descriptor of the resulting signal.
  • Domain base: Domain base of the resulting signal.
  • Domain range: Domain range of the resulting signal.
  • Script: Enter the signal script definition.
  • Timeout[ms]: Increase the value in case of timeout events.
Operation:


Video

Screen Cast: The Signal Script Production



How to create a signal script ?

Signal scripts can be created either using the template menus Add->Scripting - xxx or by changing an existing configuration item into a script production, using the configuration dialogs Production combo box.



Input Signal Configuration

Primary Source
The primary source is the first source signal of the production. For productions with multiple inputs it can be left empty, thus the first input is taken from the "Additional" sources.
Additional (Sources)
If more than 1 source signal is required, add them into this table. Instead of using the table you may drag and drop (with a closed dialog) signals onto the plot item.

The production accepts 0..N input signals.



Output Signal Configuration

Productions are executed on the fly, as soon as the signal data is required for further processing, and re-executed when settings or input signal have been changed. Before executing a production, the system needs to know the source signals, the type and the domain of the signal. All these informations need to be entered into the plot configuration dialog. If you leave the configuration fields empty, impulse tries to extract the information from the sources. The fields will display this information in light gray <e.g. Derived(Float)>. 

Process type
You may select between discrete and continuous process type.
Signal type
Select the output signal type of your script (Float, Text, Logic, Integer, ..).
Signal descriptor
The signal descriptor describes the signal type in more details (e.g the bit width of a logic vector (default<bits=16>)). See below for more details. But in most case, you will use the standard settings (default<>) - Press CTRL-Space to view content proposals.
Domain Class/Base
The domain base is just required if your output signal has a different domain than the source signals. If not, just don't touch these settings.
Domain Range
Use this field to set the domain range, so the minimum and maximum value of the domain (e.g. 0 .. 1000 Hz)


Production Configuration

  • Script: Enter the signal script definition.
  • Timeout[ms]: Increase the value in case of timeout events.

Enter the script into the text field or use the build-in script editor. To avoid system timeout, the timeout parameter may be set.



How to get started with scripting ?

Have a look at the script examples. Select a script that is close to your requirements, than copy script and settings into the dialog. Most script examples are also available at the template menu.

10 Signal Script Script Examples



Use the eclipse script editor

You may use the built-in script editor instead of the text field in the dialog. Click on "Edit in js editor" to open a new eclipse editor. As soon as you save the content, its signals will be updated and changes get visible in a parallel impulse viewer. If there are errors in the script, log messages will be send to the console view.



The script itself

The impulse JDK

No matter if you develop a reader, a recJs script, a search expression or a Signal Script production, impulse provides you always with the same interfaces to read, compare, analyze or generate signal data.



impulse JDK Open JavaDoc Reference

Intro

Impulse uses JavaScript as its default language (other languages might be added in future). Rhino interpreter is used up to Java 6 and above the Nashorn interpreter that uses the byte code engine of java and improves performance a lot. The available scripts are compatible for both interpreters.

The typical goal of a script is to read the content of source signals and create one output signal. A simple script looks like this:

// input: an array of all input signals
// in0: primary input of type ISamplePointer,IReadableSamples
// in1..: additional inputs of type ISamplePointer,IReadableSamples
// out: output signal of type IFloatSamplesWriter
// console: console output of type MessageConsoleStream
// iter: iterator of type ISamplesIterator
// progress: progess control of type  IScriptProgress
progress.cont();
while ( iter.hasNext()) {
    var current <:Long:> = iter.next(out);
    out.write(current, false, input[0].floatValue() +  input[1].floatValue());
}

SamplesIterator instance tier allows to iterate over events of multiple source signals. 'iter.next()' returns the current domain value (e.g current time). All input variable can be accessed as signal pointers: For each event found, the iterator set the pointers to the current position, e.g. floatValue() returns the float value at that position.

Variable out represents a samples writer of the configured type (e.g. IFloatSamplesWriter). You create the new signal by writing consecutively new values at given domain positions (write(domainValue,conflict,value).

The IScriptProgress instance progress let you control the execution of your script.
The line progress.cont() in the above example handles the execution of the script when the signal is extended (when you use a port, and data will be continuously added). If new data has been read, the script will be called again. With the above line, the iterator item will be pointed to the position of the previous end. If the line is not included, iter is set to the first source sample, and the script has to run over the complete signal again.

If there is just one input and data shall not be extended, you can simply iterate in the following way. Instead of floatValue(), you use floatValueAt(eventIdx).

for (var i=0;i<in0.getCount();i++){ 
	real[i] = in0.floatValueAt(i);
}

in0,in1,...,inN and the input array

Lookin into the script example and templates, you will find input definition like "in0" and "in1"  and also the variable "input". The first ones (in0,in1,..) allow you to reference inputs configured in the plot dialog (you will find on the left side of the plot dialog). "in0" refers to the primary input, in1 (and in2,..)refere to the additional inputs. The variable "input" combines all configured inputs into one array (this may include in0, if a primary input is configured, or not).


Reading the input

All input references combine the interfaces ISamplesPointer and IReadableSamples. The IReadableSamples interface defines the basic reader interface. It has methods like:

  • getCount()
  • valueAt(int idx)
  • intValueAt(int idx)

So you can get the total number of available samples and use one of the accessor methods to get the value at a given index.

The ISamplesPointer inteface allows to modify an index and read the value at the current index. You find functions like:

  • setIndex(int idx)
  • goPrev()
  • goNext()
  • val()
  • intValue();

If an input has a an additional dimension (struct members or arrays) you might read the value object and use the member accessors:

  • structAt(n).intValueOf("max")
  • intValueOf("max")

If you use a SamplesIterator, all pointers are updated by the iterator automatically. There is no need to use 'goNext()','goPrev()',... implicitly.

while ( iter.hasNext()) {
   .... in0.intValue() ....  }

Writing the output

Each signal type comes with a writer interface. The integer signal uses the IIntegerSamplesWriter interface (float: IFloatSamplesWriter, ...); a simple write includes the parameters for domain position, a conflict flag and one or more parameters describing the value.

In the IIntegerSamplesWriter example, we have three write methods for three value types (mainly used in Java); and three additional method with modified names for scripting purpose.

public interface IIntegerSamplesWriter extends ISamplesWriter{
   
    boolean write(long units, boolean conflict, int value);    
    boolean write(long units, boolean conflict, long value); 
    boolean write(long units, boolean conflict, BigInteger value);
	// scripting 
    boolean writeInt(long units, boolean conflict, int value);    
    boolean writeLong(long units, boolean conflict, long value); 
    boolean writeBig(long units, boolean conflict, BigInteger value);
}	

The parameters have the following meaning:

units
Domain position as no of domain units (e.g, domain base:ns, units = 1000 -> domain position = 1us)
conflict
Define this sample as a conflict one.
value
The given value in different formats (integer/long/BigInteger)

Handling time, frequency,...

As seen before, the domain value is given as a multiple of its domain base.

The domain base of the sources and the output are pre-set by the system, in case of the output, you can override the domain base in the plot dialogue (required if there are no inputs; just do in case you know what you do). You can get the actual domain base by using the getDomainBase() method.

If you are using a SamplesIterator, the current domain position is returned by the next() method.

for (var iter <:ISamplesIterator:> = new SamplesIterator(input); iter.hasNext();) {
    var current <:Long:> = iter.next(out);

Please be aware that the value is returned as a Long object. This Long object is not converted into any JavaScript type (as it is done for Integer and Float values).


toem

technical software and tooling

Company

Contact Us

This email address is being protected from spambots. You need JavaScript enabled to view it.