Skip to content

Latest commit

 

History

History
262 lines (188 loc) · 7.96 KB

File metadata and controls

262 lines (188 loc) · 7.96 KB

Reading data (Input)

Getting the input

To read/take samples, first get a reference to the :class:`Input`:

input = connector.getInput('MySubscriber::MySquareReader')

:meth:`Connector.getInput()` returns an :class:`Input` object. This example, obtains the Input defined by the data_reader named MySquareReader within the <subscriber> named MySubscriber:

<subscriber name="MySubscriber">
  <data_reader name="MySquareReader" topic_ref="Square" />
</subscriber>

This <subscriber> is defined inside the <domain_participant> selected to create this connector (see :ref:`Creating a new Connector`).

Reading or taking the data

Call :meth:`Input.take()` to access and remove the samples:

input.take()

or :meth:`Input.read()` to access the samples but leave them available for a future read() or take():

input.read()

The method :meth:`Input.wait()` can be used to identify when there is new data available on a specific :class:`Input`. It returns a Promise that will be resolved when new data is available, or rejected if the supplied timeout expires.

You can wait for the Promise using await in an async function:

await input.wait()
input.take()

Or using the then method:

input.wait()
  .then(() => {
    input.take()
  })

The method :meth:`Connector.wait()` has the same behavior as :meth:`Input.wait()`, but the returned promise will be resolved when data is available on any of the :class:`Input` objects within the :class:`Connector`:

await connector.wait()

You can also install a listener in a :class:`Connector`. :class:`Connector` inherits from EventEmitter. If a listener for the on_data_available event is attached to a :class:`Connector`, this event will be emitted whenever new data is available on any :class:`Input defined within the :class:`Connector`.

// Store all the inputs in an array
const inputs = [
  connector.getInput('MySubscriber::MySquareReader'),
  connector.getInput('MySubscriber::MyCircleReader'),
  connector.getInput('MySubscriber::MyTriangleReader')
]

// Install the listener
connector.on('on_data_available', () => {
  // One or more inputs have data
  inputs.forEach(input => {
    input.take()
    for (const sample of input.samples.validDataIter) {
      // Access the data
    }
  }
})

For more information on how to use the event-based notification, refer to the documentation of the events module.

The web_socket example shows how to use this event.

Warning

There are additional threading concerns to take into account when using the on_data_available event. Refer to :ref:`Additional considerations when using event-based functionality` for more information.

Note

When using the event-based methods to be notified of available data, errors are propagated using the error event. See :ref:`Error Handling` for more information.

Accessing the data samples

After calling :meth:`Input.read()` or :meth:`Input.take()`, :attr:`Input.samples` contains the data samples:

for (const sample of input.samples) {
   if (sample.validData) {
      console.log(JSON.stringify(sample.getJson()))
   }
}

:meth:`SampleIterator.getJson()` retrieves all the fields of a sample.

If you don't need to access the meta-data (see :ref:`Accessing sample meta-data`), the simplest way to access the data is to use :attr:`Samples.validDataIter` to skip samples with invalid data:

for (const sample of input.samples.validDataIter) {
   // It is not necessary to check the sample.validData field
   console.log(JSON.stringify(sample.getJson()))
}

It is also possible to access an individual sample:

// Obtain the first sample in the Input's queue
const theSample = input.samples.get(0)
if (theSample.validData) {
   console.log(JSON.stringify(theSample.getJson()))
}

Both of the iterables shown above also provide iterator implementations, allowing them to be incremented outside of a for loop:

const iterator = input.samples.validDataIter.iterator()
let sample = iterator.next()
// sample.value contains contains the current sample and sample.done is a
// boolean value which will become true when we have iterated over all of
// the available samples
console.log(JSON.stringify(sample.value.getJson()))

Warning

All the methods described in this section return generators. Calling read/take again invalidates all generators currently in use.

:meth:`Samples.getJson` can receive a fieldName to only return the fields of a complex member. In addition to getJson, you can get the values of specific primitive fields using :meth:`SampleIterator.getNumber()`, :meth:`SampleIterator.getBoolean()` and :meth:`SampleIterator.getString()`, for example:

for (const sample of input.samples.validDataIter) {
   const x = sample.getNumber('x')
   const y = sample.getNumber('y')
   const size = sample.getNumber('shapesize')
   const color = sample.getString('color')
}

See more information and examples in :ref:`Accessing the data`.

Accessing sample meta-data

Every sample contains an associated SampleInfo with meta-information about the sample:

for (const sample of input.samples) {
   const sourceTimestamp = sample.info.get('source_timestamp')
}

See :attr:`SampleIterator.info` for the list of available meta-data fields.

Connext DDS can produce samples with invalid data, which contain meta-data only. For more information about this, see Valid Data Flag in the RTI Connext DDS Core Libraries User's Manual. These samples indicate a change in the instance state. Samples with invalid data still provide the following information:

Matching with a Publication

The method :meth:`Input.waitForPublications()` can be used to detect when a compatible DDS publication is matched or unmatched. It returns a promise that resolves to the change in the number of matched publications since the last time it was called:

// From within an async function. Otherwise, use the .then() syntax
let changeInMatches = await input.waitForPublications()

For example, if 1 new compatible publication is discovered within the specified timeout, the promise will resolve to 1; if a previously matching publication no longer matches, it resolves to -1.

You can obtain information about the existing matched publications through the :attr:`Input.matchedPublications` property:

input.matchedPublications.forEach((match) => {
   pubName = match.name
}

Class reference: Input, Samples, SampleIterator

Input class

.. autoclass:: Input
   :members:

Samples class

.. autoclass:: Samples
   :members:

SampleIterator class

.. autoclass:: SampleIterator
   :members:

ValidSampleIterator class

.. autoclass:: ValidSampleIterator
   :members:

SampleInfo class

.. autoclass:: SampleInfo
   :members: