Skip to content

Commit b2fd120

Browse files
Dora integration
Signed-off-by: Franco Cipollone <franco.c@ekumenlabs.com>
1 parent 5d3d3af commit b2fd120

15 files changed

Lines changed: 556 additions & 73 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
nodes:
2+
- id: dora_lekiwi_client
3+
build: uv pip install -e ../../node_hub/dora_lekiwi_client
4+
path: dora_lekiwi_client
5+
inputs:
6+
tick: dora/timer/millis/50
7+
actions: dora_lekiwi_action_publisher/actions
8+
outputs:
9+
# ["arm_shoulder_pan.pos", "arm_shoulder_lift.pos", "arm_elbow_flex.pos", "arm_wrist_flex.pos", "arm_wrist_roll.pos", "arm_gripper.pos", "x.vel", "y.vel", "theta.vel"]
10+
- observation_state
11+
- image_front
12+
- image_wrist
13+
# env:
14+
# TIMESTEP: 0.001 # [s]
15+
16+
- id: dora_lekiwi_action_publisher
17+
build: uv pip install -e ../../node_hub/dora_lekiwi_action_publisher
18+
path: dora_lekiwi_action_publisher
19+
inputs:
20+
tick: dora/timer/millis/50
21+
outputs:
22+
- actions
23+
env:
24+
LEKIWI_ACTION: "[0.0, -90, 90, 0.0, 0.0, 0.05, 0.0, 0.0, 0.0]"
25+
26+
- id: rerun-viz
27+
# TODO: Use tag once there is a new release
28+
build: cargo install --git https://github.com/dora-rs/dora-hub dora-rerun
29+
path: dora-rerun
30+
inputs:
31+
front_camera:
32+
source: dora_lekiwi_client/image_front
33+
wrist_camera:
34+
source: dora_lekiwi_client/image_wrist
35+
observation_state:
36+
# ["arm_shoulder_pan.pos", "arm_shoulder_lift.pos", "arm_elbow_flex.pos", "arm_wrist_flex.pos", "arm_wrist_roll.pos", "arm_gripper.pos", "x.vel", "y.vel", "theta.vel"]
37+
source: dora_lekiwi_client/observation_state
38+
actions:
39+
source: dora_lekiwi_action_publisher/actions
40+
env:
41+
OPERATING_MODE: SPAWN
42+
43+
- id: dora-record
44+
# TODO: Use tag once there is a new release
45+
build: cargo install --git https://github.com/dora-rs/dora-hub/ dora-record
46+
path: dora-record
47+
inputs:
48+
observation_state: dora_lekiwi_client/observation_state
49+
image_front: dora_lekiwi_client/image_front
50+
image_wrist: dora_lekiwi_client/image_wrist
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# dora_lekiwi_action_publisher
2+
3+
## Getting started
4+
5+
- Install it with uv:
6+
7+
```bash
8+
uv venv -p 3.11 --seed
9+
uv pip install -e .
10+
```
11+
12+
## Contribution Guide
13+
14+
- Format with [ruff](https://docs.astral.sh/ruff/):
15+
16+
```bash
17+
uv pip install ruff
18+
uv run ruff check . --fix
19+
```
20+
21+
- Lint with ruff:
22+
23+
```bash
24+
uv run ruff check .
25+
```
26+
27+
- Test with [pytest](https://github.com/pytest-dev/pytest)
28+
29+
```bash
30+
uv pip install pytest
31+
uv run pytest . # Test
32+
```
33+
34+
## YAML Specification
35+
36+
## Examples
37+
38+
## License
39+
40+
dora_lekiwi_action_publisher's code are released under the MIT License
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""TODO: Add docstring."""
2+
3+
import os
4+
5+
# Define the path to the README file relative to the package directory
6+
readme_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "README.md")
7+
8+
# Read the content of the README file
9+
try:
10+
with open(readme_path, encoding="utf-8") as f:
11+
__doc__ = f.read()
12+
except FileNotFoundError:
13+
__doc__ = "README file not found."
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""TODO: Add docstring."""
2+
3+
from .main import main
4+
5+
if __name__ == "__main__":
6+
main()
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""TODO: Add docstring."""
2+
3+
import os
4+
5+
import pyarrow as pa
6+
7+
from dora import Node # type: ignore
8+
9+
10+
def main() -> None:
11+
"""TODO: Add docstring."""
12+
node = Node()
13+
14+
# Process environment variables
15+
LEKIWI_ACTION = os.getenv(
16+
"LEKIWI_ACTION", "[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]"
17+
)
18+
if not LEKIWI_ACTION:
19+
raise ValueError("LEKIWI_ACTION environment variable is not set.")
20+
# Convert to a list of floats
21+
action_to_send = [float(x) for x in LEKIWI_ACTION.strip("[]").strip(" ").split(",")]
22+
print(f"Action to send: {action_to_send}")
23+
24+
for event in node:
25+
if event["type"] == "INPUT":
26+
if event["id"] == "tick":
27+
metadata = event["metadata"]
28+
metadata["primitive"] = "series"
29+
node.send_output(
30+
output_id="actions",
31+
data=pa.array(action_to_send),
32+
metadata=metadata,
33+
)
34+
35+
36+
if __name__ == "__main__":
37+
main()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[project]
2+
name = "dora_lekiwi_action_publisher"
3+
version = "0.1.0"
4+
authors = [{ name = "Franco Cipollone", email = "franco.c@ekumenlabs.com" }]
5+
description = "dora_lekiwi_action_publisher"
6+
license = { text = "MIT" }
7+
readme = "README.md"
8+
requires-python = ">=3.8"
9+
10+
dependencies = ["dora-rs >= 0.3.13"]
11+
12+
[build-system]
13+
requires = ["setuptools"]
14+
build-backend = "setuptools.build_meta"
15+
16+
[dependency-groups]
17+
dev = ["pytest >=8.1.1", "ruff >=0.9.1"]
18+
19+
[project.scripts]
20+
dora_lekiwi_action_publisher = "dora_lekiwi_action_publisher.main:main"
21+
22+
[tool.ruff.lint]
23+
extend-select = [
24+
"D", # pydocstyle
25+
"UP"
26+
]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""Test module for dora_lekiwi_action_publisher package."""
2+
3+
import pytest
4+
5+
6+
def test_import_main() -> None:
7+
"""Test importing and running the main function."""
8+
from dora_lekiwi_action_publisher.main import main
9+
10+
# Check that everything is working, and catch Dora RuntimeError
11+
# as we're not running in a Dora dataflow.
12+
with pytest.raises(RuntimeError):
13+
main()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# dora_lekiwi_client
2+
3+
## Getting started
4+
5+
- Install it with uv:
6+
7+
```bash
8+
uv venv -p 3.11 --seed
9+
uv pip install -e .
10+
```
11+
12+
## Contribution Guide
13+
14+
- Format with [ruff](https://docs.astral.sh/ruff/):
15+
16+
```bash
17+
uv pip install ruff
18+
uv run ruff check . --fix
19+
```
20+
21+
- Lint with ruff:
22+
23+
```bash
24+
uv run ruff check .
25+
```
26+
27+
- Test with [pytest](https://github.com/pytest-dev/pytest)
28+
29+
```bash
30+
uv pip install pytest
31+
uv run pytest . # Test
32+
```
33+
34+
## YAML Specification
35+
36+
## Examples
37+
38+
## License
39+
40+
dora_lekiwi_client's code are released under the MIT License
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""TODO: Add docstring."""
2+
3+
import os
4+
5+
# Define the path to the README file relative to the package directory
6+
readme_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "README.md")
7+
8+
# Read the content of the README file
9+
try:
10+
with open(readme_path, encoding="utf-8") as f:
11+
__doc__ = f.read()
12+
except FileNotFoundError:
13+
__doc__ = "README file not found."
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""TODO: Add docstring."""
2+
3+
from .main import main
4+
5+
if __name__ == "__main__":
6+
main()

0 commit comments

Comments
 (0)