Example: Ping PongΒΆ

This example creates two different nodes, Ping and Pong. The first node is executed with a fixed timing (see Timed processing) and sends a “Ping!” event over its output port. The second component listens to its input port and answers with a “Pong!”.

  1. At first a Ping node is defined (lines 15-34). The node has one output port to send a string (line 30). In its main processing method it prints a “Ping!” to the console and sends the string over its output port (line 26).
  2. Then a Pong node is defined (lines 36-53). The node has one input port to receive a string (line 47). In its main processing method it prints a “Pong!” as answer.
  3. In the main function of this example we create a ping node and configure it to be timed (line 66, see Timed) and we configure the output port to send to the scope /ping (line 67).
  4. A pong node is created and configured to be triggered when an input arrives at its input port (line 71, see Port-Triggered) and we configure the input port to listen to the scope /ping.
  5. To run the program we need to send a timing signal to the ping node. We create a Beat and assign the ping node to it (lines 75-76). The pong node will be triggered by incoming input.

Note: You can inspect the application with the RSB Logger, since the output scope of the Ping node is configured to also send over a remote transport. This should show an event with 10Hz on the /ping scope. The input port of the pong node is configured to be only local, because otherwise the node would receive every event twice (over the local and the remote transport).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>

#include "cca/Node.h"
#include "cca/processing/all.h"
#include "cca/timing/PeriodicBeat.h"

#include "rsc/logging/LoggerFactory.h"

using namespace std;
using namespace boost;
using namespace cca;
using namespace rsc;
using namespace rsc::logging;

class Ping: public Node {
public:
    Ping(const std::string &cname) :
            Node(cname), op() {
        op = OutputPort<std::string>::create();
        registerPort("output", op);
    }
    ~Ping() {
    }
    void onProcess() {
        std::string ping = ">Ping!<";
        std::cout << ping << std::endl;

        OutputPort<std::string>::DataPtr send(new std::string(ping));

        op->publish(send);
    }
protected:
    OutputPort<std::string>::Ptr op;
};

class Pong: public Node {
public:
    Pong(const std::string &cname) :
            Node(cname), ip() {
        ip = InputPort<std::string>::create();
        registerPort("input", ip);
    }
    ~Pong() {
    }
    void onProcess() {
        if (ip->newItem()) {
            InputPort<std::string>::DataPtr in = ip->get();
            std::cout << " " << *in << " => >Pong!<" << std::endl;
        }
    }
protected:
    InputPort<std::string>::Ptr ip;
};

/**
 * Initializes one Ping and one Pong component. The Ping component is triggered
 * periodically (Timed), sending a string to Pong.
 * The Ping component is configrued to send the ping lcoally (where it is
 * received by the Pong component) AND remotely so it can be observed with the
 * rsb logger.
 */
int main() {
    LoggerFactory::getInstance().reconfigure(Logger::LEVEL_WARN);

    NodePtr ping = NodePtr(new Ping("Ping Node"));
    ping->setProcessingStrategy(Timed::samplerate());
    ping->configureOutputPort("output",
            PortConfiguration::LOCALREMOTE("/ping"));
    std::cout << ping->print() << std::endl;

    NodePtr pong = NodePtr(new Pong("Pong Node"));
    pong->setProcessingStrategy(PortTriggered::port("input"));
    pong->configureInputPort("input", PortConfiguration::LOCAL("/ping"));
    std::cout << pong->print() << std::endl;

    BeatPtr beat = PeriodicBeat::create(100);
    beat->registerReceiver(ping);

    beat->run();

    return EXIT_SUCCESS;
}

Table of Contents

Related Documentation

This Page