Basic Examples

Writing a sequence

A Python real-time sequence is a Python function decorated with the niveristand.nivs_rt_sequence decorator. For example, the following sequence calls a function and checks the result.

1@nivs_rt_sequence
2def call_add_two_numbers_test():
3    result = DoubleValue(0)
4    result.value = add_two_numbers(1, 2)
5    if result.value != 3:
6        generate_error(-100, "Unexpected result", ErrorAction.ContinueSequenceExecution)

The function also takes in some parameters. You must define parameters using the niveristand.NivsParam decorator.

1@NivsParam('x', DoubleValue(0), NivsParam.BY_VALUE)
2@NivsParam('y', DoubleValue(0), NivsParam.BY_VALUE)
3@nivs_rt_sequence
4def add_two_numbers(x, y):
5    result = DoubleValue(0)
6    # There is an intentional mistake here. It multiplies when the function implies it adds.
7    result.value = x.value * y.value
8    return result.value

You can now run the test just like any other Python function. You can run it non-deterministically, as in the following example:

1    try:
2        call_add_two_numbers_test()
3    except RunError as run_error:
4        print("Something Non-deterministic went wrong:" + str(run_error))
5

Or, you can run the test deterministically on the VeriStand engine connected to your system.

1    try:
2        realtimesequencetools.run_py_as_rtseq(call_add_two_numbers_test)
3    except RunError as run_error:
4        print("Something Deterministic went wrong:" + str(run_error))

Combining the legacy API with real-time sequences

To create a fully-automated test environment, you can mix the Legacy API with Python real-time sequences.

 1import os
 2from examples.engine_demo.engine_demo_basic import run_engine_demo
 3from niveristand import run_py_as_rtseq
 4from niveristand.errors import RunError
 5from niveristand.legacy import NIVeriStand
 6
 7
 8def mix_legacy_and_rtseq_run():
 9    """Combines the legacy API with Python real-time sequences to run a deterministic test."""
10    # Ensures NI VeriStand is running.
11    NIVeriStand.LaunchNIVeriStand()
12    # Uses the ClientAPI interface to get a reference to Workspace2
13    workspace = NIVeriStand.Workspace2("localhost")
14    engine_demo_path = os.path.join(os.path.expanduser("~"), 'Documents', 'National Instruments', 'VeriStand 2018',
15                                    'Examples', 'Stimulus Profile', 'Engine Demo', 'Engine Demo.nivssdf')
16    # Deploys the system definition.
17    workspace.ConnectToSystem(engine_demo_path, True, 60000)
18    try:
19        # Uses Python real-time sequences to run a test.
20        run_py_as_rtseq(run_engine_demo)
21        print("Test Success")
22    except RunError as e:
23        print("Test Failed: %d -  %s" % (int(e.error.error_code), e.error.message))
24    finally:
25        # You can now disconnect from the system, so the next test can run.
26        workspace.DisconnectFromSystem('', True)
27
28
29if __name__ == '__main__':
30    mix_legacy_and_rtseq_run()

Array operations example

 1@nivs_rt_sequence
 2def array_operations():
 3    """
 4    Shows operations you can perform with array data types in a real-time sequence.
 5
 6    An array can hold multiple values of the same data type. You cannot have arrays of arrays.
 7    Use arrays to pass buffers of data for playback or storage.
 8
 9    Returns:
10        float: sum of all values in the array.
11
12    """
13    var = DoubleValue(0)
14    arr_size = I64Value(0)
15    array = DoubleValueArray([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
16
17    # Indexes a value out of an array.
18    var.value = array[4].value + 100
19    # Updates a value in an array.
20    array[2].value = 6.0
21    # Gets the size of an array.
22    arr_size.value = arraysize(array)
23    # Loops over each element of an array. Each time the loop iterates a value from the array is copied into x.
24    var.value = 0.0
25    for x in array:
26        var.value += x
27    return var.value

Measuring elapsed time example

 1@nivs_rt_sequence
 2def measure_elapsed_time():
 3    """
 4    Shows different ways to measure elapsed time in a sequence.
 5
 6    You can measure time in milliseconds, microseconds, or seconds.
 7
 8    Returns:
 9        int: time, in milliseconds, it took to run this sequence.
10
11    """
12    seqtime_timer = DoubleValue(0)
13    seqtime_us_timer = I64Value(0)
14    tick_ms_timer = I64Value(0)
15    tick_us_timer = I64Value(0)
16
17    # The following steps demonstrate different ways you can capture an initial timestamp:
18    seqtime_timer.value = seqtime()
19    seqtime_us_timer.value = seqtimeus()
20    tick_ms_timer.value = tickcountms()
21    tick_us_timer.value = tickcountus()
22
23    # Simulates work to time.
24    while iteration() < 1000:
25        nivs_yield()
26
27    # Measures the elapsed time by subtracting the initial timestamp from the current time.
28    seqtime_timer.value = seqtime() - seqtime_timer.value
29    seqtime_us_timer.value = seqtimeus() - seqtime_us_timer.value
30    tick_ms_timer.value = tickcountms() - tick_ms_timer.value
31    tick_us_timer.value = tickcountus() - tick_us_timer.value
32
33    return tick_ms_timer.value

State machine

 1@nivs_rt_sequence
 2def state_machine_example():
 3    state = I32Value(0)
 4    iters = I32Value(0)
 5    amplitude = DoubleValue(1000)
 6    stop = BooleanValue(False)
 7    output = ChannelReference('Aliases/DesiredRPM')
 8
 9    while stop.value != True and iters.value < 10:  # noqa: E712 NI recommends you use comparison instead of identity.
10        state.value = rand(7)
11        if state.value == 0:
12            wait(2)
13        elif state.value == 1:
14            sine_wave(output, amplitude, 1, 0, 0, 2)
15        elif state.value == 2:
16            square_wave(output, amplitude, 5, 0, 0, 50, 2)
17        elif state.value == 3:
18            triangle_wave(output, amplitude, 1, 0, 0, 2)
19        elif state.value == 4:
20            uniform_white_noise_wave(output, amplitude, tickcountus(), 2)
21        elif state.value == 5:
22            ramp(output, -amplitude.value, amplitude, 2)
23        elif state.value == 6:
24            sawtooth_wave(output, amplitude, 1, 0, 0, 2)
25        else:
26            stop.value = True
27        iters.value += 1
28        state.value = rand(7)