clawdb-ros2 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ClawDB Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: clawdb-ros2
3
+ Version: 0.4.2
4
+ Summary: Official ROS2 Robotics SDK & Spatial Memory Bridge for ClawDB
5
+ Home-page: https://github.com/Claw-DB/clawdb-ros2
6
+ Author-email: ClawDB Robotics Team <dev@clawdb.dev>
7
+ Maintainer: ClawDB Robotics Team
8
+ Maintainer-email: dev@clawdb.dev
9
+ License: MIT
10
+ Project-URL: Homepage, https://clawdb.dev
11
+ Project-URL: Repository, https://github.com/Claw-DB/clawdb-ros2
12
+ Project-URL: Documentation, https://docs.clawdb.dev/robotics
13
+ Project-URL: Bug Tracker, https://github.com/Claw-DB/clawdb-ros2/issues
14
+ Keywords: ros2,robotics,clawdb,memory,amr,navigation,nav2,spatial-ai,autonomous-systems
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: requests>=2.28.0
30
+ Requires-Dist: numpy>=1.20.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
34
+ Requires-Dist: black>=23.0.0; extra == "dev"
35
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: maintainer
39
+ Dynamic: maintainer-email
40
+
41
+ # ClawDB ROS2 Robotics SDK (`clawdb-ros2`)
42
+
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
44
+ [![ROS 2](https://img.shields.io/badge/ROS_2-Humble%20%7C%20Iron%20%7C%20Rolling%20%7C%20Jazzy-22314E?logo=ros)](https://docs.ros.org)
45
+ [![PyPI version](https://img.shields.io/pypi/v/clawdb-ros2.svg)](https://pypi.org/project/clawdb-ros2/)
46
+
47
+ Official ROS2 package and Python SDK for connecting autonomous mobile robots (AMRs), inspection drones, and robotic manipulators to **ClawDB** persistent spatial memory.
48
+
49
+ ---
50
+
51
+ ## ⚡ Key Capabilities
52
+
53
+ - **Sub-0.1ms Local Spatial Recall**: In-memory spatial index ensures trajectory planners and obstacle avoidance controllers run at full frequency without cloud latency bottlenecks.
54
+ - **Multi-Robot Collective Memory**: Synchronize obstacles, blocked warehouse aisles, and spatial landmarks across an entire fleet in real-time.
55
+ - **Nav2 Costmap Integration**: Easily feed dynamic spatial memories directly into ROS2 Nav2 costmap layers.
56
+ - **Cloud & Edge Resilience**: Local offline caching with automatic background delta sync when network connectivity is restored.
57
+
58
+ ---
59
+
60
+ ## 🚀 Installation
61
+
62
+ ### Option 1: Standard Python Package (PyPI)
63
+ ```bash
64
+ pip install clawdb-ros2
65
+ ```
66
+
67
+ ### Option 2: Build inside your ROS2 Colcon Workspace
68
+ ```bash
69
+ cd ~/ros2_ws/src
70
+ git clone https://github.com/Claw-DB/clawdb-ros2.git
71
+ cd ~/ros2_ws
72
+ colcon build --packages-select clawdb_ros2
73
+ source install/setup.bash
74
+ ```
75
+
76
+ ---
77
+
78
+ ## 🤖 Quickstart
79
+
80
+ ### 1. Launch the Spatial Memory Bridge Node
81
+ ```bash
82
+ ros2 launch clawdb_ros2 memory_bridge.launch.py \
83
+ api_key:="your_clawdb_api_key" \
84
+ workspace_id:="your_workspace_id" \
85
+ robot_id:="amr_01"
86
+ ```
87
+
88
+ ### 2. Record an Obstacle Memory in Python
89
+ ```python
90
+ from clawdb_ros2 import ClawClient, SpatialMemoryRecord
91
+
92
+ # Initialize client
93
+ client = ClawClient(
94
+ api_key="your_clawdb_api_key",
95
+ workspace_id="your_workspace_id"
96
+ )
97
+
98
+ # Record spatial blockage
99
+ client.record_spatial_event(
100
+ SpatialMemoryRecord(
101
+ frame_id="map",
102
+ x=14.5,
103
+ y=8.2,
104
+ z=0.0,
105
+ obstacle_type="pallet_spill",
106
+ confidence=0.98,
107
+ tags=["aisle_4", "amr_01"]
108
+ )
109
+ )
110
+ ```
111
+
112
+ ### 3. Query Spatial Horizon in Real-Time (<0.1ms)
113
+ ```python
114
+ from clawdb_ros2 import SpatialMemoryIndex
115
+
116
+ index = SpatialMemoryIndex(memory_ttl_seconds=3600.0)
117
+
118
+ # Query obstacles within 5.0m radius of current robot coordinates
119
+ nearby = index.query_radius(x=14.0, y=7.5, radius=5.0)
120
+
121
+ for record, dist in nearby:
122
+ print(f"Warning: {record.obstacle_type} at distance {dist:.2f}m")
123
+ ```
124
+
125
+ ---
126
+
127
+ ## 🧭 ROS2 Node Topics & Parameters
128
+
129
+ ### Subscribed Topics
130
+ | Topic | Type | Description |
131
+ |---|---|---|
132
+ | `~/detected_obstacle` | `geometry_msgs/Point` | Local point detection to ingest into memory |
133
+
134
+ ### Published Topics
135
+ | Topic | Type | Description |
136
+ |---|---|---|
137
+ | `~/fleet_updates` | `std_msgs/String` | JSON stream of spatial deltas received from fleet |
138
+
139
+ ### Parameters
140
+ | Parameter | Type | Default | Description |
141
+ |---|---|---|---|
142
+ | `api_key` | string | `""` | ClawDB API Key |
143
+ | `workspace_id` | string | `""` | Workspace namespace ID |
144
+ | `robot_id` | string | `"amr-01"` | Machine node identifier |
145
+ | `store_name` | string | `"robot-fleet-memory"` | ClawDB memory store name |
146
+ | `frame_id` | string | `"map"` | Coordinate frame ID |
147
+ | `sync_rate_hz` | double | `1.0` | Background fleet sync frequency |
148
+ | `local_ttl_seconds` | double | `7200.0` | Cache retention TTL (seconds) |
149
+
150
+ ---
151
+
152
+ ## 🧪 Testing
153
+
154
+ Run unit tests locally:
155
+ ```bash
156
+ pytest tests/
157
+ ```
158
+
159
+ ---
160
+
161
+ ## 📜 License
162
+
163
+ MIT Licensed. Maintained by the ClawDB Robotics Team and open-source contributors.
@@ -0,0 +1,123 @@
1
+ # ClawDB ROS2 Robotics SDK (`clawdb-ros2`)
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
4
+ [![ROS 2](https://img.shields.io/badge/ROS_2-Humble%20%7C%20Iron%20%7C%20Rolling%20%7C%20Jazzy-22314E?logo=ros)](https://docs.ros.org)
5
+ [![PyPI version](https://img.shields.io/pypi/v/clawdb-ros2.svg)](https://pypi.org/project/clawdb-ros2/)
6
+
7
+ Official ROS2 package and Python SDK for connecting autonomous mobile robots (AMRs), inspection drones, and robotic manipulators to **ClawDB** persistent spatial memory.
8
+
9
+ ---
10
+
11
+ ## ⚡ Key Capabilities
12
+
13
+ - **Sub-0.1ms Local Spatial Recall**: In-memory spatial index ensures trajectory planners and obstacle avoidance controllers run at full frequency without cloud latency bottlenecks.
14
+ - **Multi-Robot Collective Memory**: Synchronize obstacles, blocked warehouse aisles, and spatial landmarks across an entire fleet in real-time.
15
+ - **Nav2 Costmap Integration**: Easily feed dynamic spatial memories directly into ROS2 Nav2 costmap layers.
16
+ - **Cloud & Edge Resilience**: Local offline caching with automatic background delta sync when network connectivity is restored.
17
+
18
+ ---
19
+
20
+ ## 🚀 Installation
21
+
22
+ ### Option 1: Standard Python Package (PyPI)
23
+ ```bash
24
+ pip install clawdb-ros2
25
+ ```
26
+
27
+ ### Option 2: Build inside your ROS2 Colcon Workspace
28
+ ```bash
29
+ cd ~/ros2_ws/src
30
+ git clone https://github.com/Claw-DB/clawdb-ros2.git
31
+ cd ~/ros2_ws
32
+ colcon build --packages-select clawdb_ros2
33
+ source install/setup.bash
34
+ ```
35
+
36
+ ---
37
+
38
+ ## 🤖 Quickstart
39
+
40
+ ### 1. Launch the Spatial Memory Bridge Node
41
+ ```bash
42
+ ros2 launch clawdb_ros2 memory_bridge.launch.py \
43
+ api_key:="your_clawdb_api_key" \
44
+ workspace_id:="your_workspace_id" \
45
+ robot_id:="amr_01"
46
+ ```
47
+
48
+ ### 2. Record an Obstacle Memory in Python
49
+ ```python
50
+ from clawdb_ros2 import ClawClient, SpatialMemoryRecord
51
+
52
+ # Initialize client
53
+ client = ClawClient(
54
+ api_key="your_clawdb_api_key",
55
+ workspace_id="your_workspace_id"
56
+ )
57
+
58
+ # Record spatial blockage
59
+ client.record_spatial_event(
60
+ SpatialMemoryRecord(
61
+ frame_id="map",
62
+ x=14.5,
63
+ y=8.2,
64
+ z=0.0,
65
+ obstacle_type="pallet_spill",
66
+ confidence=0.98,
67
+ tags=["aisle_4", "amr_01"]
68
+ )
69
+ )
70
+ ```
71
+
72
+ ### 3. Query Spatial Horizon in Real-Time (<0.1ms)
73
+ ```python
74
+ from clawdb_ros2 import SpatialMemoryIndex
75
+
76
+ index = SpatialMemoryIndex(memory_ttl_seconds=3600.0)
77
+
78
+ # Query obstacles within 5.0m radius of current robot coordinates
79
+ nearby = index.query_radius(x=14.0, y=7.5, radius=5.0)
80
+
81
+ for record, dist in nearby:
82
+ print(f"Warning: {record.obstacle_type} at distance {dist:.2f}m")
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 🧭 ROS2 Node Topics & Parameters
88
+
89
+ ### Subscribed Topics
90
+ | Topic | Type | Description |
91
+ |---|---|---|
92
+ | `~/detected_obstacle` | `geometry_msgs/Point` | Local point detection to ingest into memory |
93
+
94
+ ### Published Topics
95
+ | Topic | Type | Description |
96
+ |---|---|---|
97
+ | `~/fleet_updates` | `std_msgs/String` | JSON stream of spatial deltas received from fleet |
98
+
99
+ ### Parameters
100
+ | Parameter | Type | Default | Description |
101
+ |---|---|---|---|
102
+ | `api_key` | string | `""` | ClawDB API Key |
103
+ | `workspace_id` | string | `""` | Workspace namespace ID |
104
+ | `robot_id` | string | `"amr-01"` | Machine node identifier |
105
+ | `store_name` | string | `"robot-fleet-memory"` | ClawDB memory store name |
106
+ | `frame_id` | string | `"map"` | Coordinate frame ID |
107
+ | `sync_rate_hz` | double | `1.0` | Background fleet sync frequency |
108
+ | `local_ttl_seconds` | double | `7200.0` | Cache retention TTL (seconds) |
109
+
110
+ ---
111
+
112
+ ## 🧪 Testing
113
+
114
+ Run unit tests locally:
115
+ ```bash
116
+ pytest tests/
117
+ ```
118
+
119
+ ---
120
+
121
+ ## 📜 License
122
+
123
+ MIT Licensed. Maintained by the ClawDB Robotics Team and open-source contributors.
@@ -0,0 +1,21 @@
1
+ """
2
+ ClawDB ROS2 Robotics SDK
3
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
4
+ Official ROS2 persistent spatial memory bridge and cognitive state client for ClawDB.
5
+
6
+ :copyright: (c) 2026 ClawDB Inc.
7
+ :license: MIT, see LICENSE for more details.
8
+ """
9
+
10
+ from .client import ClawClient, SpatialMemoryRecord, QueryResult
11
+ from .spatial_index import SpatialMemoryIndex
12
+ from .node import ClawSpatialMemoryNode
13
+
14
+ __version__ = "0.4.2"
15
+ __all__ = [
16
+ "ClawClient",
17
+ "SpatialMemoryRecord",
18
+ "QueryResult",
19
+ "SpatialMemoryIndex",
20
+ "ClawSpatialMemoryNode",
21
+ ]
@@ -0,0 +1,174 @@
1
+ """
2
+ ClawDB Client for Robotics & ROS2 Nodes
3
+ """
4
+
5
+ import time
6
+ import json
7
+ import logging
8
+ from typing import List, Dict, Any, Optional, Tuple
9
+ from dataclasses import dataclass, field, asdict
10
+ import requests
11
+
12
+ logger = logging.getLogger("clawdb_ros2.client")
13
+
14
+ @dataclass
15
+ class SpatialMemoryRecord:
16
+ """Represents a spatial memory event, obstacle, or waypoint heuristic."""
17
+ id: Optional[str] = None
18
+ frame_id: str = "map"
19
+ x: float = 0.0
20
+ y: float = 0.0
21
+ z: float = 0.0
22
+ obstacle_type: str = "general_obstacle"
23
+ confidence: float = 1.0
24
+ tags: List[str] = field(default_factory=list)
25
+ metadata: Dict[str, Any] = field(default_factory=dict)
26
+ timestamp: float = field(default_factory=time.time)
27
+
28
+ def to_dict(self) -> Dict[str, Any]:
29
+ return asdict(self)
30
+
31
+ @classmethod
32
+ def from_dict(cls, data: Dict[str, Any]) -> "SpatialMemoryRecord":
33
+ return cls(
34
+ id=data.get("id"),
35
+ frame_id=data.get("frame_id", "map"),
36
+ x=float(data.get("x", 0.0)),
37
+ y=float(data.get("y", 0.0)),
38
+ z=float(data.get("z", 0.0)),
39
+ obstacle_type=data.get("obstacle_type", "general_obstacle"),
40
+ confidence=float(data.get("confidence", 1.0)),
41
+ tags=data.get("tags", []),
42
+ metadata=data.get("metadata", {}),
43
+ timestamp=float(data.get("timestamp", time.time())),
44
+ )
45
+
46
+ @dataclass
47
+ class QueryResult:
48
+ """Result from spatial radius or semantic memory search."""
49
+ records: List[SpatialMemoryRecord]
50
+ latency_ms: float
51
+ total_count: int
52
+
53
+ class ClawClient:
54
+ """
55
+ High-performance HTTP/REST Client for synchronizing robot memory with ClawDB.
56
+ """
57
+
58
+ def __init__(
59
+ self,
60
+ api_key: str,
61
+ workspace_id: str,
62
+ endpoint: str = "https://api.clawdb.dev/v1",
63
+ timeout_seconds: float = 2.0,
64
+ store_name: str = "robot-fleet-memory"
65
+ ):
66
+ self.api_key = api_key
67
+ self.workspace_id = workspace_id
68
+ self.endpoint = endpoint.rstrip("/")
69
+ self.timeout = timeout_seconds
70
+ self.store_name = store_name
71
+
72
+ self._session = requests.Session()
73
+ self._session.headers.update({
74
+ "Authorization": f"Bearer {self.api_key}",
75
+ "X-Workspace-Id": self.workspace_id,
76
+ "User-Agent": "clawdb-ros2/0.4.2",
77
+ "Content-Type": "application/json",
78
+ })
79
+
80
+ def record_spatial_event(self, record: SpatialMemoryRecord) -> Dict[str, Any]:
81
+ """
82
+ Record a spatial memory point (obstacle, landmark, or navigation failure).
83
+ """
84
+ url = f"{self.endpoint}/workspaces/{self.workspace_id}/memory/insert"
85
+ payload = {
86
+ "store": self.store_name,
87
+ "fields": {
88
+ "frame_id": record.frame_id,
89
+ "x": record.x,
90
+ "y": record.y,
91
+ "z": record.z,
92
+ "obstacle_type": record.obstacle_type,
93
+ "confidence": record.confidence,
94
+ "timestamp": record.timestamp,
95
+ **record.metadata,
96
+ },
97
+ "tags": list(set(record.tags + ["robotics", record.obstacle_type])),
98
+ }
99
+
100
+ try:
101
+ start_t = time.perf_counter()
102
+ resp = self._session.post(url, json=payload, timeout=self.timeout)
103
+ resp.raise_for_status()
104
+ elapsed_ms = (time.perf_counter() - start_t) * 1000.0
105
+ data = resp.json()
106
+ data["latency_ms"] = elapsed_ms
107
+ return data
108
+ except Exception as e:
109
+ logger.warning(f"Failed to push spatial memory to ClawDB cloud: {e}")
110
+ return {"status": "offline_cached", "error": str(e)}
111
+
112
+ def search_nearby(
113
+ self,
114
+ x: float,
115
+ y: float,
116
+ radius_meters: float = 5.0,
117
+ frame_id: str = "map",
118
+ limit: int = 10
119
+ ) -> QueryResult:
120
+ """
121
+ Query nearby spatial memories and obstacle alerts around (x, y) coordinate.
122
+ """
123
+ url = f"{self.endpoint}/workspaces/{self.workspace_id}/memory/search"
124
+ payload = {
125
+ "store": self.store_name,
126
+ "query": f"spatial location near ({x:.2f}, {y:.2f}) in frame {frame_id}",
127
+ "filter": {
128
+ "frame_id": frame_id,
129
+ },
130
+ "limit": limit,
131
+ }
132
+
133
+ start_t = time.perf_counter()
134
+ try:
135
+ resp = self._session.post(url, json=payload, timeout=self.timeout)
136
+ resp.raise_for_status()
137
+ elapsed_ms = (time.perf_counter() - start_t) * 1000.0
138
+ data = resp.json()
139
+ records: List[SpatialMemoryRecord] = []
140
+
141
+ for item in data.get("records", []):
142
+ fields = item.get("fields", {})
143
+ records.append(SpatialMemoryRecord(
144
+ id=item.get("id"),
145
+ frame_id=fields.get("frame_id", frame_id),
146
+ x=float(fields.get("x", x)),
147
+ y=float(fields.get("y", y)),
148
+ z=float(fields.get("z", 0.0)),
149
+ obstacle_type=fields.get("obstacle_type", "obstacle"),
150
+ confidence=float(fields.get("confidence", 1.0)),
151
+ tags=item.get("tags", []),
152
+ metadata=fields,
153
+ timestamp=float(fields.get("timestamp", time.time()))
154
+ ))
155
+
156
+ return QueryResult(records=records, latency_ms=elapsed_ms, total_count=len(records))
157
+ except Exception as e:
158
+ logger.warning(f"Failed to query ClawDB cloud: {e}")
159
+ elapsed_ms = (time.perf_counter() - start_t) * 1000.0
160
+ return QueryResult(records=[], latency_ms=elapsed_ms, total_count=0)
161
+
162
+ def pull_fleet_deltas(self, since_timestamp: float) -> List[SpatialMemoryRecord]:
163
+ """
164
+ Pull memory records written by other fleet nodes since timestamp.
165
+ """
166
+ url = f"{self.endpoint}/workspaces/{self.workspace_id}/memory/sync"
167
+ try:
168
+ resp = self._session.get(url, params={"store": self.store_name, "since": since_timestamp}, timeout=self.timeout)
169
+ if resp.status_code == 200:
170
+ data = resp.json()
171
+ return [SpatialMemoryRecord.from_dict(item) for item in data.get("deltas", [])]
172
+ return []
173
+ except Exception:
174
+ return []
@@ -0,0 +1,33 @@
1
+ """
2
+ Standalone Fleet Memory Daemon & Sync CLI
3
+ """
4
+
5
+ import sys
6
+ import time
7
+ import argparse
8
+ from .client import ClawClient
9
+
10
+ def main():
11
+ parser = argparse.ArgumentParser(description="ClawDB Fleet Memory Synchronization CLI")
12
+ parser.add_argument("--api-key", required=True, help="ClawDB API Key")
13
+ parser.add_argument("--workspace-id", required=True, help="ClawDB Workspace ID")
14
+ parser.add_argument("--store", default="robot-fleet-memory", help="Memory store name")
15
+ parser.add_argument("--interval", type=float, default=2.0, help="Sync interval in seconds")
16
+ args = parser.parse_args()
17
+
18
+ client = ClawClient(api_key=args.api_key, workspace_id=args.workspace_id, store_name=args.store)
19
+ print(f"ClawDB Fleet Sync daemon started for workspace: {args.workspace_id} (Store: {args.store})")
20
+
21
+ last_sync = time.time()
22
+ try:
23
+ while True:
24
+ deltas = client.pull_fleet_deltas(since_timestamp=last_sync)
25
+ last_sync = time.time()
26
+ if deltas:
27
+ print(f"[{time.strftime('%X')}] Pulled {len(deltas)} updates from fleet.")
28
+ time.sleep(args.interval)
29
+ except KeyboardInterrupt:
30
+ print("\nFleet sync daemon stopped.")
31
+
32
+ if __name__ == "__main__":
33
+ main()