Skip to content

Commit

Permalink
* Container playback example
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Berger <christian.berger@gu.se>
  • Loading branch information
chrberger committed Oct 25, 2017
1 parent f745774 commit 6e28c5e
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 0 deletions.
1 change: 1 addition & 0 deletions tutorials/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ ADD_SUBDIRECTORY (diningphilosophers)
ADD_SUBDIRECTORY (helloworld)
ADD_SUBDIRECTORY (logmessage)
ADD_SUBDIRECTORY (ipcsharedmemory)
ADD_SUBDIRECTORY (playcontainers)
ADD_SUBDIRECTORY (readzipfile)
ADD_SUBDIRECTORY (realtimeservice)
ADD_SUBDIRECTORY (serialreceivebytes)
Expand Down
1 change: 1 addition & 0 deletions tutorials/playcontainers/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
playcontainers
56 changes: 56 additions & 0 deletions tutorials/playcontainers/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# playcontainers - Sample application
# Copyright (C) 2017 Christian Berger
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

CMAKE_MINIMUM_REQUIRED (VERSION 2.8)

PROJECT (playcontainers)

###########################################################################
# Add a local CMake module search path dependent on the desired installation destination.
# Thus, artifacts from the complete source build can be given precendence over any installed versions.
IF(UNIX)
SET (CMAKE_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/share/cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules" ${CMAKE_MODULE_PATH})
ENDIF()
IF(WIN32)
SET (CMAKE_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/CMake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules" ${CMAKE_MODULE_PATH})
ENDIF()

###########################################################################
# Compile flags to enable C++11.
SET (CXX_OPTIONS "-std=c++11")
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC ${CXX_OPTIONS} -pipe")

###########################################################################
# Find OpenDaVINCI.
SET(OPENDAVINCI_DIR "${CMAKE_INSTALL_PREFIX}")
FIND_PACKAGE (OpenDaVINCI REQUIRED)

###############################################################################
# Set header files from OpenDaVINCI.
INCLUDE_DIRECTORIES (${OPENDAVINCI_INCLUDE_DIRS})
# Set include directory.
INCLUDE_DIRECTORIES(include)

###############################################################################
# Build this project.
ADD_EXECUTABLE (playcontainers "PlayContainers.cpp")
TARGET_LINK_LIBRARIES (playcontainers ${OPENDAVINCI_LIBRARIES})

###############################################################################
# Install this project.
INSTALL(TARGETS playcontainers RUNTIME DESTINATION bin COMPONENT tutorials)

39 changes: 39 additions & 0 deletions tutorials/playcontainers/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (C) 2017 Christian Berger
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

FROM ubuntu:14.04
MAINTAINER Christian Berger "christian.berger@gu.se"

# Set the env variable DEBIAN_FRONTEND to noninteractive
ENV DEBIAN_FRONTEND noninteractive

# The following list of libraries was determined from the binaries up to the
# top most layer.
RUN apt-get update -y && \
apt-get upgrade -y && \
apt-get dist-upgrade -y

RUN apt-get install -y --no-install-recommends \
ant \
build-essential \
cmake \
default-jdk \
default-jre \
python2.7

RUN apt-get autoremove && \
apt-get autoclean && \
apt-get clean

Binary file not shown.
81 changes: 81 additions & 0 deletions tutorials/playcontainers/PlayContainers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* OpenDaVINCI - Tutorial.
* Copyright (C) 2017 Christian Berger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <iostream>

#include <opendavinci/odcore/base/Lock.h>
#include <opendavinci/odcore/data/Container.h>
#include <opendavinci/odcore/io/URL.h>
#include <opendavinci/odtools/player/Player.h>

#include <opendavinci/odcore/wrapper/SharedMemory.h>
#include <opendavinci/odcore/wrapper/SharedMemoryFactory.h>

#include <opendavinci/generated/odcore/data/SharedPointCloud.h>

using namespace std;

int32_t main(int32_t argc, char **argv) {
if (2 != argc) {
cerr << "Use with: " << argv[0] << " file.rec" << endl;
return -1;
}
else {
// Setting file for playback.
odcore::io::URL url("file://" + string(argv[1]));
// Size of the memory buffer (should be large enough to hold point clouds for example).
const uint32_t MEMORY_SEGMENT_SIZE = 3*1024*1024;
// Number of memory segments.
const uint32_t NUMBER_OF_SEGMENTS = 3;
// If AUTO_REWIND is true, the file will be played endlessly.
const bool AUTO_REWIND = false;
// For sequential playback, THREADING must be set to false.
const bool TRHEADING = false;
// Construct the player.
odtools::player::Player player(url, AUTO_REWIND, MEMORY_SEGMENT_SIZE, NUMBER_OF_SEGMENTS, TRHEADING);

std::shared_ptr<odcore::wrapper::SharedMemory> spcSharedMemory;

while (player.hasMoreData()) {
// Read the next container from file.
odcore::data::Container c = player.getNextContainerToBeSent();

cout << "Found Container " << c.getDataType()
<< ", sent " << c.getSentTimeStamp().getYYYYMMDD_HHMMSSms()
<< ", received " << c.getReceivedTimeStamp().getYYYYMMDD_HHMMSSms()
<< ", sample time stamp " << c.getSampleTimeStamp().getYYYYMMDD_HHMMSSms() << endl;

if (c.getDataType() == odcore::data::SharedPointCloud::ID()) {
odcore::data::SharedPointCloud spc = c.getData<odcore::data::SharedPointCloud>();
cout << spc.toString() << endl;

if (spcSharedMemory.get() != NULL) {
// Attach the shared point cloud to the shared memory.
spcSharedMemory = odcore::wrapper::SharedMemoryFactory::attachToSharedMemory(spc.getName());
}
else {
odcore::base::Lock l(spcSharedMemory);
// TODO: Do something with the raw data in memory; cf. https://github.com/se-research/OpenDaVINCI/blob/master/odcockpit/src/plugins/environmentviewer/EnvironmentViewerGLWidget.cpp#L489-L558
}
}
}

}
}

104 changes: 104 additions & 0 deletions tutorials/playcontainers/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
How to read Containers from a .rec file
"""""""""""""""""""""""""""""""""""""""

OpenDaVINCI provides tools to process recordings (.rec, .rec.mem, and .h264
files). The sources for this example are available at
https://github.com/se-research/OpenDaVINCI/tree/master/tutorials/playcontainers

In order to read ``Containers``, which hold messages that are exchanged among
distributed software components.

PlayContainers.cpp::

.. code-block:: c++

#include <iostream>

#include <opendavinci/odcore/base/Lock.h>
#include <opendavinci/odcore/data/Container.h>
#include <opendavinci/odcore/io/URL.h>
#include <opendavinci/odtools/player/Player.h>

#include <opendavinci/odcore/wrapper/SharedMemory.h>
#include <opendavinci/odcore/wrapper/SharedMemoryFactory.h>

#include <opendavinci/generated/odcore/data/SharedPointCloud.h>

using namespace std;

int32_t main(int32_t argc, char **argv) {
if (2 != argc) {
cerr << "Use with: " << argv[0] << " file.rec" << endl;
return -1;
}
else {
// Setting file for playback.
odcore::io::URL url("file://" + string(argv[1]));
// Size of the memory buffer (should be large enough to hold point clouds for example).
const uint32_t MEMORY_SEGMENT_SIZE = 3*1024*1024;
// Number of memory segments.
const uint32_t NUMBER_OF_SEGMENTS = 3;
// If AUTO_REWIND is true, the file will be played endlessly.
const bool AUTO_REWIND = false;
// For sequential playback, THREADING must be set to false.
const bool TRHEADING = false;
// Construct the player.
odtools::player::Player player(url, AUTO_REWIND, MEMORY_SEGMENT_SIZE, NUMBER_OF_SEGMENTS, TRHEADING);
std::shared_ptr<odcore::wrapper::SharedMemory> spcSharedMemory;

while (player.hasMoreData()) {
// Read the next container from file.
odcore::data::Container c = player.getNextContainerToBeSent();

cout << "Found Container " << c.getDataType()
<< ", sent " << c.getSentTimeStamp().getYYYYMMDD_HHMMSSms()
<< ", received " << c.getReceivedTimeStamp().getYYYYMMDD_HHMMSSms()
<< ", sample time stamp " << c.getSampleTimeStamp().getYYYYMMDD_HHMMSSms() << endl;

if (c.getDataType() == odcore::data::SharedPointCloud::ID()) {
odcore::data::SharedPointCloud spc = c.getData<odcore::data::SharedPointCloud>();
cout << spc.toString() << endl;

if (spcSharedMemory.get() != NULL) {
// Attach the shared point cloud to the shared memory.
spcSharedMemory = odcore::wrapper::SharedMemoryFactory::attachToSharedMemory(spc.getName());
}
else {
odcore::base::Lock l(spcSharedMemory);
// TODO: Do something with the raw data in memory; cf. https://github.com/se-research/OpenDaVINCI/blob/master/odcockpit/src/plugins/environmentviewer/EnvironmentViewerGLWidget.cpp#L489-L558
}
}
}

}
}

To read ``Containers``, your application needs to include
``<opendavinci/odtools/player/Player.h>``.

``Player`` handles the processing of .rec and .rec.mem files; the former simply
contain the dump of any ``Container`` that is received during a recording session.
A ``Container`` is a Protobuf-encoded message prepended with the byte sequence
0x0D 0xA4 0xXX 0xYY 0xZZ; the last three bytes encode the length of the following
Protobuf-encoded message in little-endian encoding. The .rec.mem file contain a
dump of shared memory area at a given point in time as described by the meta
data structures ``SharedImage`` or ``SharedPointCloud``. These data structures
do not contain any useful payload but describe the actual payload that is stored
in a shared memory area.

In the example code, the instance of class ``Player`` is looping once through
all entries in a given .rec file and .rec.mem file. If the next ``Container``
to be handled is one of the meta-data structures, the example code is testing
for ``SharedPointCloud`` data and attaching to the shared memory area where
the payload data is available.

You can compile and link the example::

g++ -std=c++11 -I /usr/include -c PlayContainers.cpp -o PlayContainers.o
g++ -o playcontainers PlayContainers.o -lopendavinci -lpthread

To test the program, simply run it as follows::

$ ./playcontainers MyFile.rec

0 comments on commit 6e28c5e

Please sign in to comment.