Skip to content

8.2 Hello World with protobuf (Python)

In the last section you learned how to send strings to an eCAL Topic. Using strings is great for simple data that has a textual representation. Quite often however your data will be more complex, so you need some kind of protocol that defines how your data is structured.

Our recommended way is to use Google protobuf to do that, because:

  • It solves the problem of how to serialize and de-serialize data for you
  • You get downward compatibility out of the box (if you follow the guidelines)
  • It is maintained by Google and the API is stable
  • The eCAL Monitor can display a nice reflection view of the data

8.2.1 Protobuf in Python

Let’s start with creating the protobuf file. As the sender and receiver need the same .proto files, we place them in a separate directory that will be accessible both for the sender and receiver script.

So, somewhere on your hard drive, create a directory proto_messages with a file hello_world.proto and paste the following content into that file.

hello_world.proto
1
syntax = "proto3";
2
3
package proto_messages;
4
5
message HelloWorld
6
{
7
string name = 1;
8
uint32 id = 2;
9
string msg = 3;
10
}

Now you have the description of your message structure. However, to make it available in python, we need to translate it to a python file. This is done by the Protobuf Compiler (protoc).

  • On Windows this tool is shipped with eCAL, so if you have eCAL installed, you already got it. If you don’t, please install eCAL.
    For running your python script, you don’t need to have eCAL installed, even though it may be beneficial e.g. to use eCAL Mon for introspection of your topics.

  • On Ubuntu you can easily obtain it standalone from the apt repository:

    Terminal window
    sudo apt-get install protobuf-compiler

Now convert the .proto file to a .py file on command line. The command is the same for both Windows and Linux.

Terminal window
cd proto_messages
protoc --python_out=. hello_world.proto

If you check the content of the proto_messages directory, you will now find a file hello_world_pb2.py. This is the file we are going to use in python in the next step.

8.2.2 Protobuf Sender

Now let’s start implementing the actual python code, that sends some protobuf-serialized data to an eCAL topic. For that, create a file protobuf_snd.py next to your proto_messages directory and paste the following content:

protobuf_snd.py
1
import sys
2
import time
3
4
import ecal.core.core as ecal_core
5
from ecal.core.publisher import ProtoPublisher
6
7
# Import the "hello_world_pb2.py" file that we have just generated from the
8
# proto_messages directory
9
import proto_messages.hello_world_pb2 as hello_world_pb2
10
11
if __name__ == "__main__":
12
# initialize eCAL API. The name of our Process will be
13
# "Python Protobuf Publisher"
14
ecal_core.initialize(sys.argv, "Python Protobuf Publisher")
15
16
# Create a Protobuf Publisher that publishes on the topic
17
# "hello_world_python_protobuf_topic". We also pass it the datatype we are
18
# going to send later. By doing this we enable the eCAL Monitor to dynamically
19
# show the content of the messages.
20
pub = ProtoPublisher("hello_world_python_protobuf_topic"
21
, hello_world_pb2.HelloWorld)
22
23
# Create a counter and some messages, so we see something changing in the
24
# message, later
25
counter = 0
26
dummy_messages = ["The story so far:"
27
, "In the beginning the Universe was created."
28
, "This has made a lot of people very angry"
29
, "and been widely regarded as a bad move."]
30
31
# Infinite loop (using ecal_core.ok() will enable us to gracefully shutdown
32
# the process from another application)
33
while ecal_core.ok():
34
# Create a message and fill it with some data
35
protobuf_message = hello_world_pb2.HelloWorld()
36
protobuf_message.name = "Douglas Adams"
37
protobuf_message.id = counter
38
protobuf_message.msg = dummy_messages[counter % 4]
39
40
print("Sending message {}".format(counter))
41
42
# actually send the message to the topic this publisher was created for
43
pub.send(protobuf_message)
44
45
# Sleep 1s
46
time.sleep(1)
47
48
counter = counter + 1
49
50
# finalize eCAL API
51
ecal_core.finalize()

When you execute the python script, you can now already see the data in the eCAL Monitor!

Hello World Python Protobuf in eCAL Monitor

8.2.3 Protobuf Receiver

We know that the sender already works. So, let’s implement a python script that can receive the serialized protobuf data, deserialize it and display the content of the message!

Create a file protobuf_rec.py next to the sender and paste the following content:

  • Directory
protobuf_rec.py
1
import sys
2
import time
3
4
import ecal.core.core as ecal_core
5
from ecal.core.subscriber import ProtoSubscriber
6
7
# Import the "hello_world_pb2.py" file that we have just generated from the
8
# proto_messages directory
9
import proto_messages.hello_world_pb2 as hello_world_pb2
10
11
# Callback for receiving messages
12
def callback(topic_name, hello_world_proto_msg, time):
13
print("Message {} from {}: {}".format(hello_world_proto_msg.id
14
, hello_world_proto_msg.name
15
, hello_world_proto_msg.msg))
16
17
if __name__ == "__main__":
18
# initialize eCAL API. The name of our Process will be
19
# "Python Protobuf Subscriber"
20
ecal_core.initialize(sys.argv, "Python Protobuf Subscriber")
21
22
# Create a Protobuf Publisher that publishes on the topic
23
# "hello_world_python_protobuf_topic". The second parameter tells eCAL which
24
# datatype we are expecting to receive on that topic.
25
sub = ProtoSubscriber("hello_world_python_protobuf_topic"
26
, hello_world_pb2.HelloWorld)
27
28
# Set the Callback
29
sub.set_callback(callback)
30
31
# Just don't exit
32
while ecal_core.ok():
33
time.sleep(0.5)
34
35
# finalize eCAL API
36
ecal_core.finalize()

Now execute both python scripts to see if they work!

Hello World Protobuf sender and eCAL Monitor

Congratulations, you have completed the Getting Started chapter! Now go ahead and use eCAL in your real-world scenario.

If you experience issues, you can create a GitHub issue, to get help.

8.2.4 Files