.. _section-replay_tutorials: Tutorials ========= .. _section-replay-getting-started: Example: Getting Started with Replay and Shapes Demo ---------------------------------------------------- Start by recording Square data, as described in :numref:`section-record-getting-started`. Edit the Replay Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In your /user_config/recording_service directory, edit the USER_REPLAY_SERVICE.xml file. Change the storage_format to be JSON_SQLITE. .. code-block:: xml JSON_SQLITE 0 * rti/* Start Shapes Demo and Subscribe to Squares ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Start *Shapes Demo* from the *Launcher* tool and create a Square subscriber as described in :numref:`section-record-getting-started`. .. figure:: ../static/CreateSubscriber.png :alt: Create a Shapes Demo subscriber :name: FigureCreateSubscriber2 :align: center :figwidth: 70 % Start Replay Service ^^^^^^^^^^^^^^^^^^^^ Start *Replay Service*: .. code-block:: bash /bin/rtireplayservice -cfgName UserReplayService -verbosity 3 You should see Square data replayed in *Shapes Demo*. .. _section-replay-different-rate: Example: Replaying Data at a Different Rate ------------------------------------------- To replay data at a faster or slower rate than it was recorded, you can edit the configuration file to specify a playback rate. Start by recording Square data as described in :numref:`section-record-getting-started`. Edit the Replay Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In your /user_config/recording_service directory, edit the USER_REPLAY_SERVICE.xml file. Add a playback rate, as seen in the following XML: .. code-block:: xml JSON_SQLITE json_recording 2 0 * rti/* Start Shapes Demo ^^^^^^^^^^^^^^^^^^^^^ Start *Shapes Demo* from the *Launcher* tool and create a Square subscriber. .. figure:: ../static/CreateSubscriber.png :alt: Create a Shapes Demo subscriber :name: FigureCreateSubscriber :align: center :figwidth: 70 % Start Replay Service ^^^^^^^^^^^^^^^^^^^^ Start *Replay Service*: .. code-block:: bash /bin/rtireplayservice -cfgName UserReplayService -verbosity 3 You should see Square data replayed in *Shapes Demo* twice as fast as it was originally recorded. .. _section-replay-custom-storage: Example: Plugging in Custom Storage ----------------------------------- If you created a storage plugin to record data into your own custom storage, you can also create a plugin to replay from that same storage. .. note:: The APIs for custom storage are not available in the Basic bundle. There are full examples written in C and C++ about plugging in custom storage in *Recording Service*, in the :link_community_examples_recording_c_storage:`RTI Community Recording Service examples: C storage plugin <>` and :link_community_examples_recording_cpp_storage:`RTI Community Recording Service examples: C++ storage plugin <>`. Custom Storage API Overview ^^^^^^^^^^^^^^^^^^^^^^^^^^^ To retrieve data for replay, you must implement the following APIs: - A create storage reader API: - This is used to create a StorageReader object. - This API is a C function. In C++, you can use macros to declare and define the C function for your class. For example: - ``RTI_RECORDING_STORAGE_READER_CREATE_DECL(FileStorageReader)`` - ``RTI_RECORDING_STORAGE_READER_CREATE_DEF(FileStorageReader)`` - The StorageReader is used to create and delete StorageStreamInfoReaders and StorageStreamReaders. - StorageReader: - A create stream info reader API, where you create a stream reader that provides information about what streams (topics) are in your storage. - A delete stream info reader API, where you delete a stream info reader - A create stream reader API, where you create a stream reader - A delete stream reader API, where you delete a stream reader - StorageStreamInfoReader: - Read: An API to retrieve discovery data from the storage. It uses a selector object to determine the kind of samples (not read or any kind) to be returned, as well as the time range. The samples should be returned in increasing time-stamp order. - Return loan: An API that notifies the plugin that it can release resources associated with the data passed to the read API - Get service start time: An API to query the recorded time from which to start replaying - Get service stop time: An API to query the recorded time at which to stop replaying - Finished: An API to tell *Replay Service* and *Converter* that there are no more stream infos to read. - Reset: An API called by the *Replay Service* to tell the plug-in to reset its state because it is looping. After this method is called, the stream reader should be ready to start reading data from the beginning of the stream, again. - StorageStreamReader - Read: An API to retreive data from storage. It uses a selector object to determine the kind of samples (not read or any kind) to be returned, as well as the time range. The samples should be returned in increasing time-stamp order. - Return loan: An API that notifies the plugin that it can release resources associated with the data passed to the take API - Finished: An API that notifies the plugin that there is no more data in this data stream The APIs provide a mechanism to have strongly-typed StorageStreamReader classes and a builtin one is provided based on ``dds::core::xtypes::DynamicData``. More detailed API documentation is located in: - :link_c_api:`Recording Service C API documentation <>`. - :link_cpp_api:`Recording Service C++ API documentation <>`. .. _section-replay-tags: Using Timestamp Tags with Replay Service ---------------------------------------- If your recording was originally made with the builtin SQLite storage plugin, and you used the ``tag_timestamp`` remote command to tag certain events, then your recording contains timestamp tags: symbolic timestamp names you can use in place of timestamps expressed in units of time. For more information on timestamp tags, see :numref:`section-record-tags`. You can list the timestamp tags that are in your recorded database by using the ``rtirecordingservice_list_tags`` script. Use the ``-d`` argument to point to the directory that contains your recorded database, as follows: .. code-block:: bash /bin/rtirecordingservice_list_tags -d /database/directory/ This command will analyze the recording in /database/directory/ and list the details of any timestamp tags in the recording, including the tag names, descriptions, and associated timestamps. You can use the tag_name of the timestamp tags you find in a recording when you are creating an XML configuration file for *Replay Service* by using the ```` tag. For example, if after running ``rtirecordingservice_list_tags``, you see output such as: .. code-block:: bash tag_name timestamp_ms tag_description -------------------------- ------------- ------------------------ /my_example/my_events/tag1 1546484663309 first tag description /my_example/my_events/tag2 1546484703360 a second tag description Then you can have a ```` tag in your XML for *Replay Service*, after the ```` tag, that looks like the following: .. code-block:: xml /my_example/my_events/tag1 /my_example/my_events/tag2 *Replay* will replay data between those tags. Note that when expressing a ```` tag, you can mix and match timestamps and timestamp tags. For example, you can use a ```` (by referring to a tag_name) to express the time when replay should begin, and an ```` with an end time timestamp (expressed in time units) to express when replay should end. If you do not provide one of the bounds, then the start of recording is the default begin bound and the end of recording is the default end bound.