Browse Source

Rewrite terminal-print in rust and make it connect to multiple dataflow throughout time

tags/v0.3.6
haixuanTao 1 year ago
parent
commit
b29c6b2ec2
10 changed files with 70 additions and 166 deletions
  1. +10
    -2
      Cargo.lock
  2. +1
    -0
      Cargo.toml
  3. +6
    -0
      examples/echo/dataflow.yml
  4. +13
    -0
      node-hub/terminal-print/Cargo.toml
  5. +0
    -89
      node-hub/terminal-print/README.md
  6. +0
    -27
      node-hub/terminal-print/pyproject.toml
  7. +40
    -0
      node-hub/terminal-print/src/main.rs
  8. +0
    -11
      node-hub/terminal-print/terminal_print/__init__.py
  9. +0
    -35
      node-hub/terminal-print/terminal_print/main.py
  10. +0
    -2
      node-hub/terminal-print/tests/test_terminal_print.py

+ 10
- 2
Cargo.lock View File

@@ -4017,7 +4017,7 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite",
"socket2 0.4.10",
"socket2 0.5.7",
"tokio",
"tower-service",
"tracing",
@@ -9356,6 +9356,14 @@ dependencies = [
"winapi-util",
]

[[package]]
name = "terminal-print"
version = "0.3.5"
dependencies = [
"dora-node-api",
"eyre",
]

[[package]]
name = "terminal_size"
version = "0.3.0"
@@ -9838,7 +9846,7 @@ version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 0.1.10",
"cfg-if 1.0.0",
"static_assertions",
]



+ 1
- 0
Cargo.toml View File

@@ -32,6 +32,7 @@ members = [
"libraries/extensions/telemetry/*",
"node-hub/dora-record",
"node-hub/dora-rerun",
"node-hub/terminal-print",
"libraries/extensions/ros2-bridge",
"libraries/extensions/ros2-bridge/msg-gen",
"libraries/extensions/ros2-bridge/python",


+ 6
- 0
examples/echo/dataflow.yml View File

@@ -14,3 +14,9 @@ nodes:
input: terminal-input/data
outputs:
- echo

- id: terminal-print
build: cargo build -p terminal-print
path: dynamic
inputs:
echo: dora-echo/echo

+ 13
- 0
node-hub/terminal-print/Cargo.toml View File

@@ -0,0 +1,13 @@
[package]
name = "terminal-print"
edition = "2021"
version.workspace = true
description.workspace = true
documentation.workspace = true
license.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dora-node-api = { workspace = true, features = ["tracing"] }
eyre = "0.6.8"

+ 0
- 89
node-hub/terminal-print/README.md View File

@@ -1,89 +0,0 @@
# Dora Node for plotting data with OpenCV

This node is used to plot a text and a list of bbox on a base image (ideal for object detection).

# YAML

```yaml
- id: opencv-plot
build: pip install ../../node-hub/opencv-plot
path: opencv-plot
inputs:
# image: Arrow array of size 1 containing the base image
# bbox: Arrow array of bbox
# text: Arrow array of size 1 containing the text to be plotted

env:
PLOT_WIDTH: 640 # optional, default is image input width
PLOT_HEIGHT: 480 # optional, default is image input height
```

# Inputs

- `image`: Arrow array containing the base image

```python
## Image data
image_data: UInt8Array # Example: pa.array(img.ravel())
metadata = {
"width": 640,
"height": 480,
"encoding": str, # bgr8, rgb8
}

## Example
node.send_output(
image_data, {"width": 640, "height": 480, "encoding": "bgr8"}
)

## Decoding
storage = event["value"]

metadata = event["metadata"]
encoding = metadata["encoding"]
width = metadata["width"]
height = metadata["height"]

if encoding == "bgr8":
channels = 3
storage_type = np.uint8

frame = (
storage.to_numpy()
.astype(storage_type)
.reshape((height, width, channels))
)
```

- `bbox`: an arrow array containing the bounding boxes, confidence scores, and class names of the detected objects

```Python

bbox: {
"bbox": np.array, # flattened array of bounding boxes
"conf": np.array, # flat array of confidence scores
"labels": np.array, # flat array of class names
}

encoded_bbox = pa.array([bbox], {"format": "xyxy"})

decoded_bbox = {
"bbox": encoded_bbox[0]["bbox"].values.to_numpy().reshape(-1, 4),
"conf": encoded_bbox[0]["conf"].values.to_numpy(),
"labels": encoded_bbox[0]["labels"].values.to_numpy(zero_copy_only=False),
}
```

- `text`: Arrow array containing the text to be plotted

```python
text: str

encoded_text = pa.array([text])

decoded_text = encoded_text[0].as_py()
```

## License

This project is licensed under Apache-2.0. Check out [NOTICE.md](../../NOTICE.md) for more information.

+ 0
- 27
node-hub/terminal-print/pyproject.toml View File

@@ -1,27 +0,0 @@
[tool.poetry]
name = "terminal-print"
version = "0.3.5"
authors = [
"Haixuan Xavier Tao <tao.xavier@outlook.com>",
"Enzo Le Van <dev@enzo-le-van.fr>",
]
description = "Dora Terminal Print"
license = "MIT License"
homepage = "https://github.com/dora-rs/dora.git"
readme = "README.md"
packages = [{ include = "terminal_print" }]

[tool.poetry.dependencies]
dora-rs = "0.3.5"
numpy = "< 2.0.0"
pyarrow = ">= 5.0.0"

[tool.poetry.scripts]
terminal-print = "terminal_print.main:main"

[build-system]
requires = ["poetry-core>=1.8.0"]
build-backend = "poetry.core.masonry.api"

[project]
readme = "README.md"

+ 40
- 0
node-hub/terminal-print/src/main.rs View File

@@ -0,0 +1,40 @@
use dora_node_api::{self, dora_core::config::NodeId, DoraNode, Event};
use eyre::Context;

fn main() -> eyre::Result<()> {
let mut printed = false;
loop {
if let Ok((node, mut events)) =
DoraNode::init_from_node_id(NodeId::from("terminal-print".to_string()))
{
printed = false;
println!("🔥 `terminal-print` connected to: {}", node.dataflow_id());

while let Some(event) = events.recv() {
match event {
Event::Input {
id,
metadata: _,
data,
} => match data.data_type() {
dora_node_api::arrow::datatypes::DataType::Utf8 => {
let received_string: &str =
TryFrom::try_from(&data).context("expected string message")?;
println!("Received id: {}, data: {}", id, received_string);
}
_other => {
println!("Received id: {}, data: {:#?}", id, data);
}
},
_other => {}
}
}
} else {
if !printed {
println!("🕐 waiting for node `terminal-print` to be available...");
printed = true;
}
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
}

+ 0
- 11
node-hub/terminal-print/terminal_print/__init__.py View File

@@ -1,11 +0,0 @@
import os

# Define the path to the README file relative to the package directory
readme_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "README.md")

# Read the content of the README file
try:
with open(readme_path, "r", encoding="utf-8") as f:
__doc__ = f.read()
except FileNotFoundError:
__doc__ = "README file not found."

+ 0
- 35
node-hub/terminal-print/terminal_print/main.py View File

@@ -1,35 +0,0 @@
import argparse
import os

import pyarrow as pa

from dora import Node

RUNNER_CI = True if os.getenv("CI") == "true" else False


def main():

# Handle dynamic nodes, ask for the name of the node in the dataflow, and the same values as the ENV variables.
parser = argparse.ArgumentParser(description="Simple arrow sender")

parser.add_argument(
"--name",
type=str,
required=False,
help="The name of the node in the dataflow.",
default="terminal-print",
)

args = parser.parse_args()

node = Node(
args.name
) # provide the name to connect to the dataflow if dynamic node
for event in node:
if event["type"] == "INPUT":
print(event["value"].to_pylist())


if __name__ == "__main__":
main()

+ 0
- 2
node-hub/terminal-print/tests/test_terminal_print.py View File

@@ -1,2 +0,0 @@
def test_placeholder():
pass

Loading…
Cancel
Save