Skip to content

Commit

Permalink
Adds Protobuf + ZeroMQ Networking Example
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-j-h committed Feb 11, 2017
1 parent 4af23e5 commit d8f5757
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 16 deletions.
14 changes: 3 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,23 @@ matrix:
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'cmake', 'python3', 'nodejs', 'npm', 'libsfml-dev']
packages: ['g++-6', 'cmake', 'python3', 'nodejs', 'npm', 'libsfml-dev', 'libprotobuf-dev', 'protobuf-compiler', 'libzmq-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6'

- os: linux
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5', 'cmake', 'python3', 'nodejs', 'npm', 'libsfml-dev']
packages: ['g++-5', 'cmake', 'python3', 'nodejs', 'npm', 'libsfml-dev', 'libprotobuf-dev', 'protobuf-compiler', 'libzmq-dev']
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5'

- os: linux
addons:
apt:
sources: ['llvm-toolchain-precise-3.8']
packages: ['clang-3.8', 'cmake', 'python3', 'nodejs', 'npm', 'libsfml-dev']
packages: ['clang-3.8', 'cmake', 'python3', 'nodejs', 'npm', 'libsfml-dev', 'libprotobuf-dev', 'protobuf-compiler', 'libzmq-dev']
env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8'

# Waiting on Travis whitelisting 3.9, see https://github.com/travis-ci/apt-source-whitelist/issues/300
#- os: linux
# addons:
# apt:
# sources: ['llvm-toolchain-precise-3.9']
# packages: ['clang-3.9']
# env: CCOMPILER='clang-3.9' CXXCOMPILER='clang++-3.9'


before_install:
- export CC=${CCOMPILER} CXX=${CXXCOMPILER}
Expand Down
14 changes: 14 additions & 0 deletions libsweep/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,17 @@ if (LIBSFML_FOUND)
else()
message(STATUS "SFML2 required for real-time viewer (libsfml-dev)")
endif()


# Optional Protobuf + ZeroMQ networking example
find_package(Protobuf 2.4.1)
pkg_check_modules(LIBZMQ libzmq)

if (Protobuf_FOUND AND LIBZMQ_FOUND)
protobuf_generate_cpp(ProtoSources ProtoHeaders net.proto)
add_executable(example-net net.cc ${ProtoSources} ${ProtoHeaders})
target_link_libraries(example-net PRIVATE ${LIBSWEEP_LIBRARY} ${Protobuf_LITE_LIBRARIES} ${LIBZMQ_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(example-net SYSTEM PRIVATE ${LIBSWEEP_INCLUDE_DIR} ${Protobuf_INCLUDE_DIRS} ${LIBZMQ_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
else()
message(STATUS "Protobuf2 and ZeroMQ required for networking example (libprotobuf-dev protobuf-compiler libzmq-dev)")
endif()
25 changes: 20 additions & 5 deletions libsweep/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,29 @@ To build:
cmake --build .
```

**Note:** the viewer requires SFML2 to be installed.
**Note:**
- The viewer requires SFML2 to be installed.
- The pub-sub networking example requires Protobuf and ZeroMQ to be installed.


```bash
# run the examples
./example-c
./example-c++
./example-viewer
./example-c
./example-c++
```

Real-time viewer:

```bash
./example-viewer
```

Pub-Sub networking example.
Start a publisher sending out full 360 degree scans via the network (localhost).
Then start some subscribers connecting to the publisher.

```bash
./example-net publisher
./example-net subscriber
```

### License
Expand Down
111 changes: 111 additions & 0 deletions libsweep/examples/net.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <cstdlib>
#include <cstring>

#include <iostream>
#include <iterator>
#include <string>
#include <vector>

#include <google/protobuf/stubs/common.h>
#include <sweep/sweep.hpp>
#include <zmq.hpp>

#include "net.pb.h"

static void usage() {
std::cout << "Usage: example-net [ publisher | subscriber ]\n";
std::exit(EXIT_SUCCESS);
}

void subscriber() {
zmq::context_t ctx{/*io_threads=*/1};
zmq::socket_t sub{ctx, ZMQ_SUB};

sub.connect("tcp://127.0.0.1:5555");
sub.setsockopt(ZMQ_SUBSCRIBE, "", 0);

std::cout << "Subscribing." << std::endl;

for (;;) {
zmq::message_t msg;

if (!sub.recv(&msg))
continue;

sweep::proto::scan in;
in.ParseFromArray(msg.data(), msg.size());

const auto n = in.angle_size();

for (auto i = 0; i < n; ++i) {
std::cout << "Angle: " << in.angle(i) //
<< " Distance: " << in.distance(i) //
<< " Signal strength: " << in.signal_strength(i) //
<< std::endl;
}
}
}

void publisher() try {
zmq::context_t ctx{/*io_threads=*/1};
zmq::socket_t pub{ctx, ZMQ_PUB};

pub.bind("tcp://127.0.0.1:5555");

sweep::sweep device;
device.start_scanning();

std::cout << "Publishing. Each dot is a full 360 degree scan." << std::endl;

for (;;) {
const sweep::scan scan = device.get_scan();

sweep::proto::scan out;

for (const sweep::sample& sample : scan.samples) {
out.add_angle(sample.angle);
out.add_distance(sample.distance);
out.add_signal_strength(sample.signal_strength);
}

auto encoded = out.SerializeAsString();

zmq::message_t msg{encoded.size()};
std::memcpy(msg.data(), encoded.data(), encoded.size());

const auto ok = pub.send(msg);

if (ok)
std::cout << "." << std::flush;
}

device.stop_scanning();

} catch (const sweep::device_error& e) {
std::cerr << "Error: " << e.what() << '\n';
}

int main(int argc, char** argv) {
std::vector<std::string> args{argv, argv + argc};

if (args.size() != 2)
usage();

const auto isPublisher = args[1] == "publisher";
const auto isSubscriber = args[1] == "subscriber";

if (!isPublisher && !isSubscriber)
usage();

GOOGLE_PROTOBUF_VERIFY_VERSION;

struct AtExit {
~AtExit() { ::google::protobuf::ShutdownProtobufLibrary(); }
} sentry;

if (isPublisher)
publisher();

if (isSubscriber)
subscriber();
}
9 changes: 9 additions & 0 deletions libsweep/examples/net.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package sweep.proto;

option optimize_for = LITE_RUNTIME;

message scan {
repeated int32 angle = 1 [packed=true];
repeated int32 distance = 2 [packed=true];
repeated int32 signal_strength = 3 [packed=true];
}

0 comments on commit d8f5757

Please sign in to comment.