Acquisition¶
The Acquisition interface offers a mechanism for obtaining cycle-accurate signal values.
Concept¶
Acquisition concept provides a conceptual overview of acquisition. The controller monitors the trigger start and stop conditions and constructs samples of acquired signal values when acquisition is running. The controller locally buffers those samples before they are transferred to the client, typically over Ethernet. On the client, an acquisition instance acquires samples and pushes these to subscribers. These subscribers can either be built-in acquisition subscribers, i.e. Acquisition sink, or custom handlers implemented by the customer application.
Usage¶
A typical usage pattern of the Acquisition and AcqSink interfaces is as follows:
Reserve an acquisition instance using the ReserveAcquisition method on the TopController interface.
Add signals to the acquisition instance.
(optional) Configure start/stop trigger conditions to automatically start/stop the sampling of data.
Reserve a predefined acquisition sink using the ReserveAcqSink method on the Acquisition interface.
Start the acquisition of samples using the Start method on the Acquisition interface or via the configured start trigger condition.
…
Stop the acquisition of samples using the Stop method on the Acquisition interface or via the configured stop trigger condition.
Wait until all samples have been received using the WaitComplete method on the AcqSink interface.
The received samples can be used or stored:
by iterating the Samples collection on the AcqSink Interface; or
by storing the samples to file using the WriteToFile method on the AcqSink Interface.
An acquisition is released by calling Dispose (for C#), or by letting all shared pointers to the acquisition instance go out of scope (for C++).
Configuration and control¶
Acquisition instances are reserved using the ReserveAcquisition method on the TopController interface. An acquisition instance is configured by adding signals to the AcquisitionSignalCollection (for C#) or SignalCollection (for C++) of the reserved instance. The acquisition configuration is considered valid if the signal collection consists of at least one signal.
Note
An acquisition instance that is reserved via a particular controller can only be used to sample signals on that controller and its sub-controller(s).
Additionally, the sample interval, OnNext interval, and trigger configuration can be defined.
Sample interval¶
Samples are taken at a defined interval. The default interval is equal to the controller sample period, i.e. SamplePeriod. The interval can be modified using the Interval property on the Acquisition interface.
Upon configuration of the sample interval the configured value is rounded to the nearest supported interval. Furthermore, the value is limited to the minimum and maximum supported interval. For example, when an interval of \(62.5 \mu s\) is requested and the minimum interval supported by the controller equals \(125 \mu s\) the value is ‘rounded’ to \(125 \mu s\).
Two types of sampling are discerned:
single-rate: all samples are acquired with the same sample period.
multi-rate: samples are acquired with multiple sample periods; all sample periods are common multiples or unit fractions of the top-controller sample period.
For single-rate sampling the signals can be added using the Add method on the AcquisitionSignalCollection (for C#) or the AddSignal method on the SignalCollection (for C++).
For multi-rate sampling the signals with a deviating sample interval need to be added using the Add method on the AcquisitionSignalCollection.WithInterval collection (for C#) or the AddSignalWithInterval method on the SignalCollection (for C++). When a negative interval is provided via these interfaces, the acquisition sample interval, configured at the moment of adding the signal, is used.
Compared to single-rate sampling, multi-rate sampling has impact on the signal collection that a sample contains. In case of single-rate sampling, each sample contains the same and full signal collection, i.e. values of all signals. In case of multi-rate sampling, this is not the case as shown in Acquired values of signals A and B.
The figure shows that the sampling frequency of signal B is twice that of signal A. As a consequence, values of signal A are only contained in half of the acquired samples, whereas all samples will include the sampled value of signal B. Signals A and B together demonstrate multi-rate sampling.
OnNext interval¶
The OnNext interval defines the approximate interval at which samples are pushed to subscribers, i.e. OnNext callbacks are called. The default interval equals \(100 ms\) and can be modified using the OnNextInterval property on the Acquisition interface.
Typically it is not required to change the default interval. Tweaking the interval is however possible to balance the network load caused by acquisition, i.e. many small data packets versus fewer large data packets.
Note
The actual OnNext interval is dependent on various properties of the client hardware, such as the used OS and the available processor time.
Note
A large configured interval in combination with a small sample buffer may cause missed samples. The Samples section explains how missed samples can be detected.
A call to update the OnNext interval is processed immediately, i.e. the wait for the current interval is interrupted, the available samples are pushed to subscribers and a wait for the new interval is started.
During two occasions, the configured OnNext interval is ignored:
The first occasion is during delivery of pre-trigger samples. To relieve the controller sample buffer of the stored pre-trigger samples as quickly as possible, the OnNext callback is called without delay as many times as needed to deliver all pre-trigger samples to subscribers. They are sent in batches of a size comparable to what is sent when the OnNext interval is taken into account, i.e. they have a maximum size of \(\lceil OnNextInterval \times SamplePeriod \rceil\) samples.
Second, in order to retrieve the final samples as quickly as possible when acquisition is stopped, the configured OnNext interval is ignored for the final OnNext callback.
Triggers¶
By using the AcquisitionTrigger interface, one can configure acquisition of samples in a particular context. The trigger configuration consists of a trigger mode, a start condition, a stop condition, and a pre- and post-trigger sample duration. The controller evaluates these conditions and starts/stops acquisition in case the configured condition is met.
Mode |
Description |
OneShot (default) |
Acquisition will transition to Sampling once before going back to Prepared. |
Continuous |
Acquisition will stay running and transition to Sampling every time the start condition is met in either PreSampling or PostSampling. |
Default values of the trigger conditions are True for the start condition and False for the stop condition. The default start condition causes acquisition to be started immediately after calling the Start method on the Acquisition interface. The default stop condition causes acquisition to continue indefinitely until the Stop method on the Acquisition interface is called.
Note
Depending on how soon after the start of acquisition a trigger condition becomes valid, the observed pre-trigger sample duration may be less than the configured duration.
State machine¶
Acquisition behavior is linked to a state machine. The state machine is depicted in Acquisition state machine and the states are described in Acquisition states.
State |
Description |
Idle |
Acquisition is idle. |
Prepared |
Acquisition is prepared. |
PreSampling |
Acquisition is pre-sampling while waiting for the configured start condition to be met. |
Sampling |
Acquisition is sampling. |
PostSampling |
Acquisition is post-sampling after the configured stop condition was met. |
Modification of configuration (e.g. configured signals, sample interval, or trigger configuration) with the exception of the trigger mode is not allowed in states PreSampling, Sampling, and PostSampling.
Note
A configuration change in state Prepared causes a transition to state Idle.
Acquisition callbacks (e.g. OnNext, OnComplete) can always be subscribed to the acquisition instance. Handlers subscribed while the acquisition state equals Sampling or PostSampling receive samples from the moment of subscription.
Subscribers¶
A client can subscribe to several notifications from an acquisition instance by means of callback subscriptions. At any time, zero, one or more callbacks can be subscribed to each of the notifications.
Callbacks can be subscribed to five kinds of notifications:
SubscribeNext: next collection of acquisition samples in stream is available;
SubscribeComplete: end of the sample stream was reached, i.e. acquisition is no longer running;
SubscribeError: next samples could not be provided due to an error;
SubscribeTriggerStart: the start condition was met and acquisition has started; and
SubscribeTriggerStop: the stop condition was met and acquisition has stopped.
Subscriber interaction in OneShot mode with stop trigger shows the callback order during an interaction sequence between an acquisition and a client that is subscribed to all five callbacks when the trigger mode is OneShot and the stop condition is met. Subscriber interaction in OneShot mode with stop call shows the interaction when an explicit Stop call is made.
After the user starts acquisition using Start method, the controller starts buffering samples according to the configured pre-trigger sample duration. As soon as the start condition is met, available samples are sent to subscribers of OnNext. When all pre-trigger samples have been delivered, OnTriggerStart callbacks are executed, providing the subscriber with the trigger occurrence’s stream position and values of all signals present in the condition.
Note
When the start condition is met before the pre-trigger sample duration has elapsed, less samples are made available to subscribers. In the case of the default True condition, there are no pre-trigger samples and OnTriggerStart callbacks are executed immediately.
Stopping behavior¶
OnTriggerStop callbacks are executed whenever acquisition transitions to state PostSampling. OnNext callbacks are then executed for all remaining samples during the post-trigger duration. Afterwards, when the trigger mode is OneShot, OnComplete callbacks are executed and all subscriptions for all five notifications are automatically unsubscribed, to guarantee that no callbacks follow anymore.
When the trigger mode is Continuous, the post-trigger samples are typically followed by pre-trigger samples as soon as the next start condition match occurs. In case the start condition match happens during postsampling, acquisition can immediately transition to Sampling without presampling, as all samples of the pre-trigger sample duration have aleady been delivered to subscribers. While in this trigger mode, OnComplete is only called after an explicit Stop call.
When the user stops acquisition using the Stop method on the Acquisition interface, the call blocks until OnComplete callbacks have been executed and all subscriptions have been unsubscribed. An explicit Stop call prevents or interrupts acquisition of samples in any state. As a result, neither the start nor stop condition are still monitored and no executions of OnTriggerStart or OnTriggerStop callbacks will follow. When all samples have been delivered, OnComplete callbacks are executed and all subscriptions are again automatically unsubscribed.
If an error occurs, acquisition is halted and OnError callbacks are executed. After that, OnComplete callbacks are still executed and all subscriptions are unsubscribed.
The order in which multiple simultaneous subscribers of the same notification receive callbacks from the same acquisition instance is not specified. It is, however, guaranteed that they receive samples in the same, chronological order.
Acquisition sink¶
The motion API provides a built-in subscriber implementation called AcqSink, which can keep track of a single acquisition run. Upon reservation of the AcqSink it is automatically subscribed to all callbacks of the acquisition instance. It is unsubscribed when an OnComplete callback is received or when all references are released.
The implementation uses a buffer to store the samples received by the OnNext callbacks. The size of the buffer can be configured upon reservation of the sink using the ReserveAcqSink method on the Acquisition interface.
When configured with an ‘infinite’ capacity the buffer is theoretically unconstrained, i.e. it grows on demand and is only constrained by available client memory. When configured with a maximum capacity the user can specify the behavior regarding buffer overflow by means of the Acquisition sink modes.
Trigger occurrences are also stored in the sink. They each contain:
a stream position;
an Acquisition trigger occurrence indicating whether it represents the start or the stop condition; and
a dictionary mapping all signals present in the trigger condition to their value at the moment of the trigger occurrence.
Whenever samples are discarded because of the configured sink mode and buffer size, corresponding trigger occurrences are also removed.
Mode |
Description |
DiscardNewSamples |
In case of buffer overflow newly received samples are ignored. |
DiscardOldSamples |
In case of buffer overflow newly received samples are stored in the buffer; oldest samples are removed. |
Occurrence type |
Description |
Start |
The start condition of the trigger has been met. |
Stop |
The stop condition of the trigger has been met. |
The user application can detect completion of acquisition either synchronously using the WaitComplete method on the AcqSink interface, or asynchronously by subscribing an AcqSinkCompleteHandler using the SubscribeComplete method on the AcqSink interface. Sample objects collected by the AcqSink stay accessible until all references are released.
Export samples to file¶
Acquired samples can be directly export to file using the WriteToFile method on the AcqSink interface. The file format can be specified using the Acquisition export file format.
Format |
Description |
Msf |
MSF file format |
MSF file format
The Motion Scope File format version 2.1 is described below in Extended Backus-Naur Form (EBNF) notation.:
msf = header, samples ;
header = version, reserved1, signal-fullnames, signal-datatypes, signal-masks ;
version = "MSF_VERSION_2_1", newline ;
reserved1 = 46 * newline, 8 * null ;
signal-fullnames = { signal-fullname }, newline ;
signal-fullname = signal-fullname-char, { signal-fullname-char }, null ;
signal-fullname-char = alpha-lower | alpha-upper | digit | "-" | "." | ":" | "_" | " " | "/" ;
signal-datatypes = { signal-datatype }, newline ;
signal-datatype = { "UINT32" | "FLOAT" | "DOUBLE" }, " " ;
signal-masks = { signal-mask }, newline ; (* Legacy, not used. *)
signal-mask = "-1 " ;
alpha-lower = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" |
"n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" ;
alpha-upper = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" |
"N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
newline = ? newline character, i.e. '\n' ? ;
null = ? null character, i.e. '\0' ? ;
samples = { sample } ;
sample = { signal-data } ;
signal-data = uint32 | float | double ;
uint32 = ? 4 octets containing 32-bit unsigned integer, little-endian ?;
float = ? 4 octets containing single precision floating point number in IEEE 754 format, little-endian ? ;
double = ? 8 octets containing double precision floating point number in IEEE 754 format, little-endian ? ;
Additional details which cannot be expressed in EBNF notation:
Two signals named StreamPos (data type UINT32) and SampleTime (data type DOUBLE) are always present. They represent the stream position and timestamp of each sample.
The number of signal names, signal data types, signal masks and signal data items in each sample is equal.
Signal masks are present for legacy reasons. They do not contain relevant information.
Samples¶
The Sample interface provides access to a single sample. A sample consists of the signals of which the value was acquired at a particular timestamp. The timestamp of a sample can be retrieved.
The value of the signals in a sample is equal to the value of the signal at the time the sample was acquired. The other properties of the signals, such as unit, description and bounds, are cached at the call to Prepare, except for the IsWritable property, which is always set to False for the signals in a sample.
Additional to the timestamp, every sample has a zero-based stream position. The stream position of the first sample equals zero. Each subsequent sample the stream position is incremented by one.
Note
In case of triggered acquisition the first sample is defined as the sample where monitoring for the start condition was started, not the first sample returned via the OnNext callbacks.
Note
In case of very long acquisition runs, the stream position wraps around to zero at the maximum value of a 32-bit unsigned integer.
Barring the wrap around, stream positions of consecutive samples should always be monotonously incrementing. This holds for both the samples within the collection received from an OnNext subscription as well as for the last and first samples of the collection received in consecutive invocations of an OnNext subscription. Samples are missing when this premise does not hold.
The order of signals in each sample is equal to the order in which the signals were are added to the signal collection on the Acquisition interface.