Skip to main content

roboflex.core

At its core, roboflex is a library to make Nodes that create, signal, and receive Messages to and from other nodes, in a distributed manner.

Roboflex.core defines what a Message is and what a Node is. It provides serialization services for eigen and xtensor. It provides a small library of core message types and useful Node sub-classes. The core only supports sending messages via direct function call to other nodes; the nodes in transport/ (zmq and mqtt so far) support sending messages from one thread to another, from one process to another, and from one computer to another via multiple methods.

One node may connect to multiple downstream nodes, supporting the pub-sub pattern.

Basic Types

Message

A roboflex Message is defined as:

  1. An 8-byte header. The first four bytes are the letters 'RFLX', and the next four bytes are a uint32, which is the size of the message in bytes (including the header).
  2. A data portion, encoded in flexbuffers.h. Please see MESSAGEFORMAT.md.
  3. roboflex.core provides the Message class to facilitate this, as well as meta data and 0-copy functionality. This class is designed to be inherited. Please see core_messages.h for examples.

Node

A roboflex Node represents a basic unit of computation. Nodes can connect to other nodes, can signal Messages, and can receive them. RunnableNode inherits from Node, and adds the ability to run a function in a thread. Both Node and Runnable are designed to be inherited: in order to perform custom logic on message reception, custom nodes should inherit from Node and override receive. In order to run in a thread, custom nodes should inherit RunnableNode and override child_thread_fn.

Nodes are designed for sub-classing, in python:

class MyNode(roboflex.Node):
    def receive(self, msg):
        signal(somenewmsg)

# or, to make a runnable (root) node that runs in a thread:

class MyRunnable(roboflex.RunnableNode):
    def child_thread_fn(self):
        do whatever
    def start(self):
        override if you want, probably not

and in c++:

struct MyNode: public roboflex::core::Node {
    MyNode(): Node("n007") {}
    void receive(core::MessagePtr m) override {
        std::cout << get_name() << " " << m->to_string() << std::endl;
        signal(m);
    }
};

struct MyRunnableNode: public roboflex::core::RunnableNode {
    MyRunnableNode(): roboflex::core::RunnableNode("n121") {}
    void child_thread_fn() override {
        // maybe read from a sensor in a loop? control a robot?
    }
};

// The examples in roboflex/core/core_nodes explore subclassing further.

Building (Only if you're doing c++)

mkdir build && cd build
cmake ..
make
make install

Install for python

pip install roboflex

Just Show Me The Code Example (in python):

import time
import numpy as np
from roboflex import FrequencyGenerator, MapFun, MessagePrinter, CallbackFun


# This example shows how to create a graph of nodes that pass messages containing
# numpy tensors (that can be interpreted at the c++-level as xtensor or eigen 
# objects) between each other in a chain.


# ----------- 
# create nodes of the graph

# The first node will signal at 2 hz. FrequencyGenerator is a library node that
# simply signals a BlankMessage at a given frequency. It runs in a thread, and must
# be started and stopped.
frequency_generator = FrequencyGenerator(2.0)

# Next, this MapFunction (a node that maps a message to another message) node 
# creates a message containing a numpy tensor. The python dict will be 
# encapsulated into a DynoFlex message, and be passed to the next node in 
# the graph.
tensor_creator = MapFun(lambda m: {"t": np.ones((2, 3)) * m.message_counter})

# These nodes print stuff out.
message_printer = MessagePrinter("MESSAGE IS:")
tensor_printer = CallbackFun(lambda m: print("TENSOR IS:", type(m["t"]), m["t"].shape, m["t"].dtype, "\n", m["t"]))


# ----------- 
# connect nodes of the graph. It's easy to distribute the graph into
# multiple cpus using nodes in roboflex/transport.
#
# 'frequency_generator > tensor_creator' is syntactic sugar for
# 'frequency_generator.connect(tensor_creator)'.
#
frequency_generator > tensor_creator > message_printer > tensor_printer

# ----------- 
# start the root node (the other nodes, in this case, will run in the root node's thread).
frequency_generator.start()

# ----------- 
# go for a while
time.sleep(3)
    
# ----------- 
# stop the root node
frequency_generator.stop()

Examples

see examples/README.md

🔗 Related

Metadata

Release files for roboflex 0.1.44

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for roboflex 0.1.44
File Size Uploaded
roboflex-0.1.44.tar.gz 76.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for roboflex 0.1.44
File Interpreter ABI Platform
roboflex-0.1.44-cp311-cp311-macosx_15_0_arm64.whl CPython 3.11 CPython 3.11 macOS 15.0+ ARM64 Details

Total release size: 681.4 kB

Release files / roboflex-0.1.44.tar.gz

Download URL roboflex-0.1.44.tar.gz
Size 76.8 kB
Tags Source
SHA-256 checksum
How to use checksums
85e6165e9b6c4604fb07e799dae68033e6feaceb21180c1a9cc80c1a05b159a3
BLAKE2b-256 checksum
How to use checksums
badc4b9985273438e2bb1c16f4ea33d82a8a6be545f8ebc4aedd21e2b1041e2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release files / roboflex-0.1.44-cp311-cp311-macosx_15_0_arm64.whl

Download URL roboflex-0.1.44-cp311-cp311-macosx_15_0_arm64.whl
Size 604.5 kB
Tags CPython 3.11 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
656e2ff0e207a80944e2de1fdc79ba20fb1e9638e5d2a5fb5adff9ff363b8c4d
BLAKE2b-256 checksum
How to use checksums
6db372b416c28ae07dd3daee018ed06b89088e4ab777720f8b3d95e2633cf640
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release history Release notifications | RSS feed

This release

0.1.44 This release

2 release files

0.1.40

2 release files

0.1.39

2 release files

0.1.38

2 release files

0.1.36

1 release file

0.1.35

1 release file

0.1.34

1 release file

0.1.33

1 release file

0.1.32

1 release file

0.1.31

1 release file

0.1.30

1 release file

0.1.29

1 release file

0.1.28

1 release file

0.1.27

1 release file

0.1.26

1 release file

0.1.25

1 release file

0.1.24

1 release file

0.1.23

1 release file

0.1.22

1 release file

0.1.21

1 release file

0.1.20

1 release file

0.1.19

1 release file

0.1.18

1 release file

0.1.17

1 release file

0.1.16

1 release file

0.1.15

1 release file

0.1.14

1 release file

0.1.13

1 release file

0.1.12

1 release file

0.1.11

1 release file

0.1.10

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page