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)