Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ and verification commands.
| `RobotCalibrationRecorder` | Safely records released-arm limits and a home pose for one physical robot |
| `RobotDriverLauncher` | Starts/stops a driver process from the descriptor |
| `RobotConnectionDashboard` | Shows USB, driver, ROS interface, live joint positions, home references, safe ranges, and calibration source in one view |
| `RobotMonitor` | Opens a read-only live canvas view for a registered robot's connection, motion state, telemetry, streams, and joints |
| `RobotROSInterfaceCheck` | Matches a live ROS graph to a supported robot interface profile without publishing commands |

## Hiwonder ROSOrin Pro
Expand Down
4 changes: 2 additions & 2 deletions blacknode-package.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "blacknode-robot"
version = "0.3.0"
version = "0.3.1"
description = "Generic robot discovery, USB permission checks, driver launch, and robot profile contracts."
requires-blacknode = ">=0.3.0"
layer = "robot"
Expand Down Expand Up @@ -64,7 +64,7 @@ capabilities = ["robot.capabilities"]

# Declared for the package roadmap; sources land in components/authorization/nodes.
node-types = [
"RobotConnectionDashboard", "RobotDiscovery", "RobotROSInterfaceCheck", "RobotUSBDiscovery"
"RobotConnectionDashboard", "RobotDiscovery", "RobotMonitor", "RobotROSInterfaceCheck", "RobotUSBDiscovery"
]

[components.authorization]
Expand Down
1 change: 1 addition & 0 deletions nodes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from . import interfaces # noqa: F401
from . import monitoring # noqa: F401
from . import presets # noqa: F401
from . import robot # noqa: F401
31 changes: 31 additions & 0 deletions nodes/monitoring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Read-only robot monitoring targets for the Blacknode canvas."""

from blacknode.node import Dict, Text, node


@node(
name="RobotMonitor",
component="capabilities",
category="Robot",
inputs={
"robot_id": Text(default=""),
"robot_name": Text(default=""),
},
outputs={"robot": Dict},
primary_inputs=[],
primary_outputs=["robot"],
description="Show a registered robot's live state, telemetry, and streams on the canvas.",
)
def robot_monitor(robot_id: str = "", robot_name: str = "") -> dict:
"""Describe the stable, read-only target used by the live canvas monitor."""
target_id = str(robot_id or "").strip()
target_name = str(robot_name or "").strip()
return {
"robot": {
"kind": "blacknode.robot-monitor-target",
"schema_version": 1,
"robot_id": target_id,
"robot_name": target_name,
"configured": bool(target_id),
},
}
18 changes: 18 additions & 0 deletions tests/test_robot_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"RobotDriverPreset",
"Robot",
"RobotConnectionDashboard",
"RobotMonitor",
"RobotROSInterfaceCheck",
"RobotJointDefinition",
"RobotJointList",
Expand All @@ -39,6 +40,23 @@ def test_robot_nodes_registered_with_category():
assert _NODE_REGISTRY[name]._bn_package == "blacknode-robot"


def test_robot_monitor_exposes_a_read_only_portable_target():
fn = _NODE_REGISTRY["RobotMonitor"]

result = fn({"robot_id": "robot-2", "robot_name": "Workshop arm"})

assert result["robot"] == {
"kind": "blacknode.robot-monitor-target",
"schema_version": 1,
"robot_id": "robot-2",
"robot_name": "Workshop arm",
"configured": True,
}
assert fn._bn_component == "capabilities"
assert fn._bn_primary_inputs == []
assert fn._bn_primary_outputs == ["robot"]


def test_rosorin_interface_check_matches_documented_topic_variants():
result = _NODE_REGISTRY["RobotROSInterfaceCheck"]({
"preset": "hiwonder_rosorin_pro",
Expand Down