osiris-agent 0.1.0__tar.gz → 0.1.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,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: osiris_agent
3
+ Version: 0.1.2
4
+ Summary: OSIRIS agent for ROS2/Humble
5
+ Home-page: https://github.com/nicolaselielll/osiris_agent
6
+ Author: Nicolas Tuomaala
7
+ Author-email: nicolas.tuomaala00@gmail.com
8
+ License: Apache-2.0
9
+ Keywords: ros2 humble agent
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Operating System :: OS Independent
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: websockets
19
+ Requires-Dist: psutil
20
+ Provides-Extra: ros
21
+ Requires-Dist: rclpy; extra == "ros"
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: keywords
29
+ Dynamic: license
30
+ Dynamic: license-file
31
+ Dynamic: provides-extra
32
+ Dynamic: requires-dist
33
+ Dynamic: summary
34
+
35
+ # OSIRIS Agent
36
+
37
+ ![PyPI](https://img.shields.io/pypi/v/osiris_agent.svg)
38
+ ![Python](https://img.shields.io/pypi/pyversions/osiris_agent.svg)
39
+ ![License](https://img.shields.io/pypi/l/osiris_agent.svg)
40
+ ![CI](https://github.com/nicolaselielll/osiris_agent/actions/workflows/ci.yml/badge.svg)
41
+
42
+ A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
43
+
44
+ ## Install
45
+
46
+ From PyPI:
47
+ ```bash
48
+ python -m pip install --upgrade pip
49
+ python -m pip install osiris_agent
50
+ ```
51
+
52
+ Editable / development install:
53
+ ```bash
54
+ git clone https://github.com/nicolaselielll/osiris_agent.git
55
+ cd osiris_agent
56
+ python -m pip install -e .
57
+ ```
58
+
59
+ ## Quick Start
60
+
61
+ Set the auth token and run the agent:
62
+ ```bash
63
+ export OSIRIS_AUTH_TOKEN="your-robot-token-here"
64
+ agent_node
65
+ ```
66
+
67
+ Verify installation:
68
+ ```bash
69
+ python -c "import importlib.metadata as m; print(m.version('osiris_agent'))"
70
+ ```
71
+
72
+ ## Usage & Configuration
73
+
74
+ - Environment: OSIRIS_AUTH_TOKEN — your robot token.
75
+ - Editable install reflects code changes immediately.
76
+ - Common constants are in `osiris_agent/agent_node.py`:
77
+ - MAX_SUBSCRIPTIONS, ALLOWED_TOPIC_PREFIXES, GRAPH_CHECK_INTERVAL, PARAMETER_REFRESH_INTERVAL, TELEMETRY_INTERVAL
78
+
79
+ ## Badge suggestions
80
+
81
+ - PyPI: https://img.shields.io/pypi/v/osiris_agent.svg
82
+ - Python versions: https://img.shields.io/pypi/pyversions/osiris_agent.svg
83
+ - License: https://img.shields.io/pypi/l/osiris_agent.svg
84
+ - GitHub Actions CI: https://github.com/<user>/osiris_agent/actions
85
+
86
+ ## Contributing
87
+
88
+ Open issues and PRs at: https://github.com/nicolaselielll/osiris_agent
89
+
90
+ ## License
91
+
92
+ Apache-2.0 — see the LICENSE file.
93
+
94
+ ## Changelog
95
+
96
+ See release notes on GitHub Releases for v0.1.0 and future versions.
@@ -0,0 +1,62 @@
1
+ # OSIRIS Agent
2
+
3
+ ![PyPI](https://img.shields.io/pypi/v/osiris_agent.svg)
4
+ ![Python](https://img.shields.io/pypi/pyversions/osiris_agent.svg)
5
+ ![License](https://img.shields.io/pypi/l/osiris_agent.svg)
6
+ ![CI](https://github.com/nicolaselielll/osiris_agent/actions/workflows/ci.yml/badge.svg)
7
+
8
+ A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
9
+
10
+ ## Install
11
+
12
+ From PyPI:
13
+ ```bash
14
+ python -m pip install --upgrade pip
15
+ python -m pip install osiris_agent
16
+ ```
17
+
18
+ Editable / development install:
19
+ ```bash
20
+ git clone https://github.com/nicolaselielll/osiris_agent.git
21
+ cd osiris_agent
22
+ python -m pip install -e .
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ Set the auth token and run the agent:
28
+ ```bash
29
+ export OSIRIS_AUTH_TOKEN="your-robot-token-here"
30
+ agent_node
31
+ ```
32
+
33
+ Verify installation:
34
+ ```bash
35
+ python -c "import importlib.metadata as m; print(m.version('osiris_agent'))"
36
+ ```
37
+
38
+ ## Usage & Configuration
39
+
40
+ - Environment: OSIRIS_AUTH_TOKEN — your robot token.
41
+ - Editable install reflects code changes immediately.
42
+ - Common constants are in `osiris_agent/agent_node.py`:
43
+ - MAX_SUBSCRIPTIONS, ALLOWED_TOPIC_PREFIXES, GRAPH_CHECK_INTERVAL, PARAMETER_REFRESH_INTERVAL, TELEMETRY_INTERVAL
44
+
45
+ ## Badge suggestions
46
+
47
+ - PyPI: https://img.shields.io/pypi/v/osiris_agent.svg
48
+ - Python versions: https://img.shields.io/pypi/pyversions/osiris_agent.svg
49
+ - License: https://img.shields.io/pypi/l/osiris_agent.svg
50
+ - GitHub Actions CI: https://github.com/<user>/osiris_agent/actions
51
+
52
+ ## Contributing
53
+
54
+ Open issues and PRs at: https://github.com/nicolaselielll/osiris_agent
55
+
56
+ ## License
57
+
58
+ Apache-2.0 — see the LICENSE file.
59
+
60
+ ## Changelog
61
+
62
+ See release notes on GitHub Releases for v0.1.0 and future versions.
@@ -938,7 +938,10 @@ class WebBridge(Node):
938
938
  def _get_telemetry_snapshot(self):
939
939
  """Return a snapshot of system telemetry (CPU, RAM, disk)."""
940
940
  return {
941
- 'cpu': psutil.cpu_percent(interval=None),
941
+ 'cpu': {
942
+ 'percent': psutil.cpu_percent(interval=None),
943
+ 'cores': psutil.cpu_count(logical=False),
944
+ },
942
945
  'ram': {
943
946
  'percent': psutil.virtual_memory().percent,
944
947
  'used_mb': psutil.virtual_memory().used / (1024 * 1024),
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: osiris_agent
3
+ Version: 0.1.2
4
+ Summary: OSIRIS agent for ROS2/Humble
5
+ Home-page: https://github.com/nicolaselielll/osiris_agent
6
+ Author: Nicolas Tuomaala
7
+ Author-email: nicolas.tuomaala00@gmail.com
8
+ License: Apache-2.0
9
+ Keywords: ros2 humble agent
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Operating System :: OS Independent
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: websockets
19
+ Requires-Dist: psutil
20
+ Provides-Extra: ros
21
+ Requires-Dist: rclpy; extra == "ros"
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: keywords
29
+ Dynamic: license
30
+ Dynamic: license-file
31
+ Dynamic: provides-extra
32
+ Dynamic: requires-dist
33
+ Dynamic: summary
34
+
35
+ # OSIRIS Agent
36
+
37
+ ![PyPI](https://img.shields.io/pypi/v/osiris_agent.svg)
38
+ ![Python](https://img.shields.io/pypi/pyversions/osiris_agent.svg)
39
+ ![License](https://img.shields.io/pypi/l/osiris_agent.svg)
40
+ ![CI](https://github.com/nicolaselielll/osiris_agent/actions/workflows/ci.yml/badge.svg)
41
+
42
+ A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
43
+
44
+ ## Install
45
+
46
+ From PyPI:
47
+ ```bash
48
+ python -m pip install --upgrade pip
49
+ python -m pip install osiris_agent
50
+ ```
51
+
52
+ Editable / development install:
53
+ ```bash
54
+ git clone https://github.com/nicolaselielll/osiris_agent.git
55
+ cd osiris_agent
56
+ python -m pip install -e .
57
+ ```
58
+
59
+ ## Quick Start
60
+
61
+ Set the auth token and run the agent:
62
+ ```bash
63
+ export OSIRIS_AUTH_TOKEN="your-robot-token-here"
64
+ agent_node
65
+ ```
66
+
67
+ Verify installation:
68
+ ```bash
69
+ python -c "import importlib.metadata as m; print(m.version('osiris_agent'))"
70
+ ```
71
+
72
+ ## Usage & Configuration
73
+
74
+ - Environment: OSIRIS_AUTH_TOKEN — your robot token.
75
+ - Editable install reflects code changes immediately.
76
+ - Common constants are in `osiris_agent/agent_node.py`:
77
+ - MAX_SUBSCRIPTIONS, ALLOWED_TOPIC_PREFIXES, GRAPH_CHECK_INTERVAL, PARAMETER_REFRESH_INTERVAL, TELEMETRY_INTERVAL
78
+
79
+ ## Badge suggestions
80
+
81
+ - PyPI: https://img.shields.io/pypi/v/osiris_agent.svg
82
+ - Python versions: https://img.shields.io/pypi/pyversions/osiris_agent.svg
83
+ - License: https://img.shields.io/pypi/l/osiris_agent.svg
84
+ - GitHub Actions CI: https://github.com/<user>/osiris_agent/actions
85
+
86
+ ## Contributing
87
+
88
+ Open issues and PRs at: https://github.com/nicolaselielll/osiris_agent
89
+
90
+ ## License
91
+
92
+ Apache-2.0 — see the LICENSE file.
93
+
94
+ ## Changelog
95
+
96
+ See release notes on GitHub Releases for v0.1.0 and future versions.
@@ -6,7 +6,7 @@ long_description = (HERE / "README.md").read_text(encoding="utf-8")
6
6
 
7
7
  setup(
8
8
  name='osiris_agent',
9
- version='0.1.0',
9
+ version='0.1.2',
10
10
  description='OSIRIS agent for ROS2/Humble',
11
11
  long_description=long_description,
12
12
  long_description_content_type="text/markdown",
@@ -1,315 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: osiris_agent
3
- Version: 0.1.0
4
- Summary: OSIRIS agent for ROS2/Humble
5
- Home-page: https://github.com/nicolaselielll/osiris_agent
6
- Author: Nicolas Tuomaala
7
- Author-email: nicolas.tuomaala00@gmail.com
8
- License: Apache-2.0
9
- Keywords: ros2 humble agent
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: Apache Software License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3 :: Only
15
- Classifier: Operating System :: OS Independent
16
- Description-Content-Type: text/markdown
17
- License-File: LICENSE
18
- Requires-Dist: websockets
19
- Requires-Dist: psutil
20
- Provides-Extra: ros
21
- Requires-Dist: rclpy; extra == "ros"
22
- Dynamic: author
23
- Dynamic: author-email
24
- Dynamic: classifier
25
- Dynamic: description
26
- Dynamic: description-content-type
27
- Dynamic: home-page
28
- Dynamic: keywords
29
- Dynamic: license
30
- Dynamic: license-file
31
- Dynamic: provides-extra
32
- Dynamic: requires-dist
33
- Dynamic: summary
34
-
35
- # OSIRIS Agent
36
-
37
- A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
38
-
39
- ## Overview
40
-
41
- The OSIRIS Agent (`osiris_agent`) is a ROS2 node that provides real-time bidirectional communication between your ROS2 robot and a remote WebSocket gateway. It monitors the ROS2 graph, collects system telemetry, and enables dynamic topic subscription from the remote platform.
42
-
43
- ## Features
44
-
45
- ### Real-time Graph Monitoring
46
- - **Node Detection**: Automatically detects when ROS2 nodes start/stop
47
- - **Topic Tracking**: Monitors topic creation, destruction, and subscription changes
48
- - **Action Discovery**: Tracks ROS2 actions and their lifecycle
49
- - **Service Discovery**: Detects available services and their endpoints
50
- - **Publisher/Subscriber Relations**: Maps which nodes publish to and subscribe from each topic
51
-
52
- ### Dynamic Topic Subscription
53
- - Subscribe to any ROS2 topic remotely via WebSocket commands
54
- - Automatic message type resolution and serialization
55
- - Configurable subscription limits (default: 100 concurrent subscriptions)
56
- - Thread-safe subscription management
57
- - Topic publishing rate calculation
58
-
59
- ### Node Parameters
60
- - Automatic discovery of node parameters
61
- - Periodic parameter refresh (every 5 seconds)
62
- - Asynchronous parameter fetching to avoid blocking
63
-
64
- ### System Telemetry
65
- - CPU usage monitoring
66
- - Memory (RAM) utilization tracking
67
- - Disk space monitoring
68
- - Enable/disable telemetry on demand
69
-
70
- ### Quality of Service (QoS) Support
71
- - Full QoS profile inspection for publishers and subscribers
72
- - Reliability, durability, history policy, depth, and liveliness information
73
-
74
- ### Robust Connection Management
75
- - Automatic reconnection with exponential backoff
76
- - Initial delay: 1 second, max delay: 10 seconds
77
- - Secure WebSocket (WSS) connection
78
- - Token-based authentication
79
-
80
- ## Architecture
81
-
82
- ```
83
- WebBridge Node (osiris_agent)
84
-
85
- ├─ Main Thread (rclpy.spin)
86
- │ ├─ ROS2 Node Callbacks
87
- │ ├─ Graph Change Detector (timer: 100ms)
88
- │ ├─ Parameter Refresh (timer: 5s)
89
- │ └─ Telemetry Collector (timer: 1s)
90
-
91
- └─ Daemon Thread (WebSocket Client)
92
- └─ Asyncio Event Loop
93
- ├─ Send Loop (queue consumer)
94
- ├─ Receive Loop (command handler)
95
- └─ Reconnection Logic (exponential backoff)
96
- ```
97
-
98
- **Key Components:**
99
- - **Graph Monitor**: Polls ROS2 graph for changes (nodes, topics, actions, services)
100
- - **Subscription Manager**: Handles dynamic topic subscriptions with `threading.Lock()` for thread-safe access to the subscription dictionary
101
- - **Telemetry Collector**: Gathers CPU, RAM, and disk metrics using `psutil`
102
- - **WebSocket Client**: Maintains persistent connection with automatic reconnection
103
- - **Message Queue**: `asyncio.Queue` created on the websocket event loop for serializing all outgoing messages
104
-
105
- **Threading Model:**
106
- - Main thread runs ROS2 executor (`rclpy.spin`) with timers and callbacks
107
- - Daemon thread runs asyncio event loop with websocket client (send/receive coroutines)
108
- - Shared data (`_topic_subs`) protected by `threading.Lock` to prevent race conditions
109
- - Cross-thread communication via `asyncio.run_coroutine_threadsafe()` to schedule coroutines from ROS thread onto websocket loop
110
-
111
- ## Installation
112
-
113
- ```bash
114
- # Clone the repository into your workspace
115
- cd ~/ros2_ws/src
116
- git clone https://github.com/nicolaselielll/osiris_agent.git
117
-
118
- # Install the package
119
- cd osiris_agent
120
- pip3 install -e .
121
- ```
122
-
123
- The `-e` flag installs in editable mode so changes to the code are reflected immediately.
124
-
125
- ## Configuration
126
-
127
- Set your authentication token as an environment variable:
128
-
129
- ```bash
130
- export OSIRIS_AUTH_TOKEN="your-robot-token-here"
131
- ```
132
-
133
- **Tip**: Add to `~/.bashrc` to persist across sessions:
134
- ```bash
135
- echo 'export OSIRIS_AUTH_TOKEN="your-token"' >> ~/.bashrc
136
- ```
137
-
138
- ### Optional: Customize Behavior
139
-
140
- Edit constants in `osiris_agent/agent_node.py`:
141
-
142
- - `MAX_SUBSCRIPTIONS = 100`: Maximum concurrent topic subscriptions
143
- - `ALLOWED_TOPIC_PREFIXES = ['/']`: Restrict subscribable topics (e.g., `['/robot/', '/sensors/']`)
144
- - `GRAPH_CHECK_INTERVAL = 0.1`: Graph polling interval (seconds)
145
- - `PARAMETER_REFRESH_INTERVAL = 5.0`: Parameter refresh interval (seconds)
146
- - `TELEMETRY_INTERVAL = 1.0`: Telemetry collection interval (seconds)
147
-
148
- ## Running
149
-
150
- ```bash
151
- export OSIRIS_AUTH_TOKEN="your-token"
152
- agent_node
153
- ```
154
-
155
- You should see:
156
- ```
157
- [INFO] [bridge_node]: Attempting to connect to gateway...
158
- [INFO] [bridge_node]: Connected to gateway
159
- [INFO] [bridge_node]: Sent initial state: 5 nodes, 12 topics, 0 actions, 8 services
160
- ```
161
-
162
- ## Updating
163
-
164
- ```bash
165
- cd ~/ros2_ws/src/osiris_agent
166
- git pull
167
- # Changes apply immediately if installed with -e
168
- ```
169
-
170
- ## WebSocket Protocol
171
-
172
- ### Commands (Gateway → Agent)
173
-
174
- **Subscribe to Topic**
175
- ```json
176
- {"type": "subscribe", "topic": "/cmd_vel"}
177
- ```
178
-
179
- **Unsubscribe**
180
- ```json
181
- {"type": "unsubscribe", "topic": "/cmd_vel"}
182
- ```
183
-
184
- **Control Telemetry**
185
- ```json
186
- {"type": "start_telemetry"}
187
- {"type": "stop_telemetry"}
188
- ```
189
-
190
- ### Events (Agent → Gateway)
191
-
192
- **Initial State** (on connect)
193
- ```json
194
- {
195
- "type": "initial_state",
196
- "timestamp": 1234567890.123,
197
- "data": {
198
- "nodes": {},
199
- "topics": {},
200
- "actions": {},
201
- "services": {},
202
- "telemetry": {}
203
- }
204
- }
205
- ```
206
-
207
- **Graph Changes**
208
- ```json
209
- {"type": "node_event", "node": "/my_node", "event": "started", "timestamp": 123}
210
- {"type": "topic_event", "topic": "/my_topic", "event": "created", "timestamp": 123}
211
- {"type": "action_event", "action": "/my_action", "event": "created", "timestamp": 123}
212
- {"type": "service_event", "service": "/my_service", "event": "created", "timestamp": 123}
213
- ```
214
-
215
- **Topic Data**
216
- ```json
217
- {
218
- "type": "topic_data",
219
- "topic": "/cmd_vel",
220
- "data": {"linear": {"x": 1.0}, "angular": {"z": 0.5}},
221
- "rate_hz": 10.0,
222
- "timestamp": 123
223
- }
224
- ```
225
-
226
- **Telemetry**
227
- ```json
228
- {
229
- "type": "telemetry",
230
- "data": {
231
- "cpu": 45.2,
232
- "ram": {"percent": 62.5, "used_mb": 5000, "total_mb": 8000},
233
- "disk": {"percent": 75.0, "used_gb": 150, "total_gb": 200}
234
- },
235
- "timestamp": 123
236
- }
237
- ```
238
-
239
- **Bridge Subscriptions**
240
- ```json
241
- {
242
- "type": "bridge_subscriptions",
243
- "subscriptions": ["/topic1", "/topic2"],
244
- "timestamp": 123
245
- }
246
- ```
247
-
248
- ## Troubleshooting
249
-
250
- **ModuleNotFoundError: websockets or psutil**
251
- ```bash
252
- pip3 install -e .
253
- ```
254
-
255
- **Connection drops**
256
- - Check firewall allows outbound HTTPS to `osiris-gateway.fly.dev:443`
257
- - View logs: `journalctl -u osiris-agent -f`
258
-
259
- **High CPU usage**
260
- - Increase `GRAPH_CHECK_INTERVAL` to `0.5` or `1.0`
261
- - Reduce `PARAMETER_REFRESH_INTERVAL` to `10.0`
262
- - Disable telemetry when not needed
263
-
264
- **Topics not appearing**
265
- - Verify topic exists: `ros2 topic list`
266
- - Check logs for validation warnings
267
- - Ensure under `MAX_SUBSCRIPTIONS` limit
268
-
269
- ## Performance Tuning
270
-
271
- **Large graphs (100+ nodes/topics)**
272
- ```python
273
- GRAPH_CHECK_INTERVAL = 0.5
274
- PARAMETER_REFRESH_INTERVAL = 10.0
275
- MAX_SUBSCRIPTIONS = 50
276
- ```
277
-
278
- **Resource-constrained robots**
279
- ```python
280
- GRAPH_CHECK_INTERVAL = 1.0
281
- PARAMETER_REFRESH_INTERVAL = 15.0
282
- TELEMETRY_INTERVAL = 2.0
283
- ```
284
-
285
- **Restrict topic access**
286
- ```python
287
- ALLOWED_TOPIC_PREFIXES = ['/robot/', '/sensors/']
288
- ```
289
-
290
- ## Security
291
-
292
- - Auth token sent via WSS (encrypted in transit)
293
- - **Never log `self.ws_url`** - it contains the authentication token in the query parameter
294
- - Set `ALLOWED_TOPIC_PREFIXES` to restrict which topics can be remotely subscribed
295
- - `MAX_SUBSCRIPTIONS` prevents resource exhaustion from excessive subscriptions
296
- - Ensure gateway scrubs tokens from access logs
297
-
298
- ## License
299
-
300
- This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
301
-
302
- ## Contributing
303
-
304
- Issues and PRs welcome at [github.com/nicolaselielll/osiris_agent](https://github.com/nicolaselielll/osiris_agent)
305
-
306
- ## Changelog
307
-
308
- ### v0.1.0
309
- - WebSocket bridge with secure WSS connection
310
- - Real-time graph monitoring
311
- - Dynamic topic subscription
312
- - System telemetry (CPU/RAM/disk)
313
- - Auto-reconnect with exponential backoff
314
- - Parameter discovery
315
- - QoS profile inspection
@@ -1,281 +0,0 @@
1
- # OSIRIS Agent
2
-
3
- A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
4
-
5
- ## Overview
6
-
7
- The OSIRIS Agent (`osiris_agent`) is a ROS2 node that provides real-time bidirectional communication between your ROS2 robot and a remote WebSocket gateway. It monitors the ROS2 graph, collects system telemetry, and enables dynamic topic subscription from the remote platform.
8
-
9
- ## Features
10
-
11
- ### Real-time Graph Monitoring
12
- - **Node Detection**: Automatically detects when ROS2 nodes start/stop
13
- - **Topic Tracking**: Monitors topic creation, destruction, and subscription changes
14
- - **Action Discovery**: Tracks ROS2 actions and their lifecycle
15
- - **Service Discovery**: Detects available services and their endpoints
16
- - **Publisher/Subscriber Relations**: Maps which nodes publish to and subscribe from each topic
17
-
18
- ### Dynamic Topic Subscription
19
- - Subscribe to any ROS2 topic remotely via WebSocket commands
20
- - Automatic message type resolution and serialization
21
- - Configurable subscription limits (default: 100 concurrent subscriptions)
22
- - Thread-safe subscription management
23
- - Topic publishing rate calculation
24
-
25
- ### Node Parameters
26
- - Automatic discovery of node parameters
27
- - Periodic parameter refresh (every 5 seconds)
28
- - Asynchronous parameter fetching to avoid blocking
29
-
30
- ### System Telemetry
31
- - CPU usage monitoring
32
- - Memory (RAM) utilization tracking
33
- - Disk space monitoring
34
- - Enable/disable telemetry on demand
35
-
36
- ### Quality of Service (QoS) Support
37
- - Full QoS profile inspection for publishers and subscribers
38
- - Reliability, durability, history policy, depth, and liveliness information
39
-
40
- ### Robust Connection Management
41
- - Automatic reconnection with exponential backoff
42
- - Initial delay: 1 second, max delay: 10 seconds
43
- - Secure WebSocket (WSS) connection
44
- - Token-based authentication
45
-
46
- ## Architecture
47
-
48
- ```
49
- WebBridge Node (osiris_agent)
50
-
51
- ├─ Main Thread (rclpy.spin)
52
- │ ├─ ROS2 Node Callbacks
53
- │ ├─ Graph Change Detector (timer: 100ms)
54
- │ ├─ Parameter Refresh (timer: 5s)
55
- │ └─ Telemetry Collector (timer: 1s)
56
-
57
- └─ Daemon Thread (WebSocket Client)
58
- └─ Asyncio Event Loop
59
- ├─ Send Loop (queue consumer)
60
- ├─ Receive Loop (command handler)
61
- └─ Reconnection Logic (exponential backoff)
62
- ```
63
-
64
- **Key Components:**
65
- - **Graph Monitor**: Polls ROS2 graph for changes (nodes, topics, actions, services)
66
- - **Subscription Manager**: Handles dynamic topic subscriptions with `threading.Lock()` for thread-safe access to the subscription dictionary
67
- - **Telemetry Collector**: Gathers CPU, RAM, and disk metrics using `psutil`
68
- - **WebSocket Client**: Maintains persistent connection with automatic reconnection
69
- - **Message Queue**: `asyncio.Queue` created on the websocket event loop for serializing all outgoing messages
70
-
71
- **Threading Model:**
72
- - Main thread runs ROS2 executor (`rclpy.spin`) with timers and callbacks
73
- - Daemon thread runs asyncio event loop with websocket client (send/receive coroutines)
74
- - Shared data (`_topic_subs`) protected by `threading.Lock` to prevent race conditions
75
- - Cross-thread communication via `asyncio.run_coroutine_threadsafe()` to schedule coroutines from ROS thread onto websocket loop
76
-
77
- ## Installation
78
-
79
- ```bash
80
- # Clone the repository into your workspace
81
- cd ~/ros2_ws/src
82
- git clone https://github.com/nicolaselielll/osiris_agent.git
83
-
84
- # Install the package
85
- cd osiris_agent
86
- pip3 install -e .
87
- ```
88
-
89
- The `-e` flag installs in editable mode so changes to the code are reflected immediately.
90
-
91
- ## Configuration
92
-
93
- Set your authentication token as an environment variable:
94
-
95
- ```bash
96
- export OSIRIS_AUTH_TOKEN="your-robot-token-here"
97
- ```
98
-
99
- **Tip**: Add to `~/.bashrc` to persist across sessions:
100
- ```bash
101
- echo 'export OSIRIS_AUTH_TOKEN="your-token"' >> ~/.bashrc
102
- ```
103
-
104
- ### Optional: Customize Behavior
105
-
106
- Edit constants in `osiris_agent/agent_node.py`:
107
-
108
- - `MAX_SUBSCRIPTIONS = 100`: Maximum concurrent topic subscriptions
109
- - `ALLOWED_TOPIC_PREFIXES = ['/']`: Restrict subscribable topics (e.g., `['/robot/', '/sensors/']`)
110
- - `GRAPH_CHECK_INTERVAL = 0.1`: Graph polling interval (seconds)
111
- - `PARAMETER_REFRESH_INTERVAL = 5.0`: Parameter refresh interval (seconds)
112
- - `TELEMETRY_INTERVAL = 1.0`: Telemetry collection interval (seconds)
113
-
114
- ## Running
115
-
116
- ```bash
117
- export OSIRIS_AUTH_TOKEN="your-token"
118
- agent_node
119
- ```
120
-
121
- You should see:
122
- ```
123
- [INFO] [bridge_node]: Attempting to connect to gateway...
124
- [INFO] [bridge_node]: Connected to gateway
125
- [INFO] [bridge_node]: Sent initial state: 5 nodes, 12 topics, 0 actions, 8 services
126
- ```
127
-
128
- ## Updating
129
-
130
- ```bash
131
- cd ~/ros2_ws/src/osiris_agent
132
- git pull
133
- # Changes apply immediately if installed with -e
134
- ```
135
-
136
- ## WebSocket Protocol
137
-
138
- ### Commands (Gateway → Agent)
139
-
140
- **Subscribe to Topic**
141
- ```json
142
- {"type": "subscribe", "topic": "/cmd_vel"}
143
- ```
144
-
145
- **Unsubscribe**
146
- ```json
147
- {"type": "unsubscribe", "topic": "/cmd_vel"}
148
- ```
149
-
150
- **Control Telemetry**
151
- ```json
152
- {"type": "start_telemetry"}
153
- {"type": "stop_telemetry"}
154
- ```
155
-
156
- ### Events (Agent → Gateway)
157
-
158
- **Initial State** (on connect)
159
- ```json
160
- {
161
- "type": "initial_state",
162
- "timestamp": 1234567890.123,
163
- "data": {
164
- "nodes": {},
165
- "topics": {},
166
- "actions": {},
167
- "services": {},
168
- "telemetry": {}
169
- }
170
- }
171
- ```
172
-
173
- **Graph Changes**
174
- ```json
175
- {"type": "node_event", "node": "/my_node", "event": "started", "timestamp": 123}
176
- {"type": "topic_event", "topic": "/my_topic", "event": "created", "timestamp": 123}
177
- {"type": "action_event", "action": "/my_action", "event": "created", "timestamp": 123}
178
- {"type": "service_event", "service": "/my_service", "event": "created", "timestamp": 123}
179
- ```
180
-
181
- **Topic Data**
182
- ```json
183
- {
184
- "type": "topic_data",
185
- "topic": "/cmd_vel",
186
- "data": {"linear": {"x": 1.0}, "angular": {"z": 0.5}},
187
- "rate_hz": 10.0,
188
- "timestamp": 123
189
- }
190
- ```
191
-
192
- **Telemetry**
193
- ```json
194
- {
195
- "type": "telemetry",
196
- "data": {
197
- "cpu": 45.2,
198
- "ram": {"percent": 62.5, "used_mb": 5000, "total_mb": 8000},
199
- "disk": {"percent": 75.0, "used_gb": 150, "total_gb": 200}
200
- },
201
- "timestamp": 123
202
- }
203
- ```
204
-
205
- **Bridge Subscriptions**
206
- ```json
207
- {
208
- "type": "bridge_subscriptions",
209
- "subscriptions": ["/topic1", "/topic2"],
210
- "timestamp": 123
211
- }
212
- ```
213
-
214
- ## Troubleshooting
215
-
216
- **ModuleNotFoundError: websockets or psutil**
217
- ```bash
218
- pip3 install -e .
219
- ```
220
-
221
- **Connection drops**
222
- - Check firewall allows outbound HTTPS to `osiris-gateway.fly.dev:443`
223
- - View logs: `journalctl -u osiris-agent -f`
224
-
225
- **High CPU usage**
226
- - Increase `GRAPH_CHECK_INTERVAL` to `0.5` or `1.0`
227
- - Reduce `PARAMETER_REFRESH_INTERVAL` to `10.0`
228
- - Disable telemetry when not needed
229
-
230
- **Topics not appearing**
231
- - Verify topic exists: `ros2 topic list`
232
- - Check logs for validation warnings
233
- - Ensure under `MAX_SUBSCRIPTIONS` limit
234
-
235
- ## Performance Tuning
236
-
237
- **Large graphs (100+ nodes/topics)**
238
- ```python
239
- GRAPH_CHECK_INTERVAL = 0.5
240
- PARAMETER_REFRESH_INTERVAL = 10.0
241
- MAX_SUBSCRIPTIONS = 50
242
- ```
243
-
244
- **Resource-constrained robots**
245
- ```python
246
- GRAPH_CHECK_INTERVAL = 1.0
247
- PARAMETER_REFRESH_INTERVAL = 15.0
248
- TELEMETRY_INTERVAL = 2.0
249
- ```
250
-
251
- **Restrict topic access**
252
- ```python
253
- ALLOWED_TOPIC_PREFIXES = ['/robot/', '/sensors/']
254
- ```
255
-
256
- ## Security
257
-
258
- - Auth token sent via WSS (encrypted in transit)
259
- - **Never log `self.ws_url`** - it contains the authentication token in the query parameter
260
- - Set `ALLOWED_TOPIC_PREFIXES` to restrict which topics can be remotely subscribed
261
- - `MAX_SUBSCRIPTIONS` prevents resource exhaustion from excessive subscriptions
262
- - Ensure gateway scrubs tokens from access logs
263
-
264
- ## License
265
-
266
- This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
267
-
268
- ## Contributing
269
-
270
- Issues and PRs welcome at [github.com/nicolaselielll/osiris_agent](https://github.com/nicolaselielll/osiris_agent)
271
-
272
- ## Changelog
273
-
274
- ### v0.1.0
275
- - WebSocket bridge with secure WSS connection
276
- - Real-time graph monitoring
277
- - Dynamic topic subscription
278
- - System telemetry (CPU/RAM/disk)
279
- - Auto-reconnect with exponential backoff
280
- - Parameter discovery
281
- - QoS profile inspection
@@ -1,315 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: osiris_agent
3
- Version: 0.1.0
4
- Summary: OSIRIS agent for ROS2/Humble
5
- Home-page: https://github.com/nicolaselielll/osiris_agent
6
- Author: Nicolas Tuomaala
7
- Author-email: nicolas.tuomaala00@gmail.com
8
- License: Apache-2.0
9
- Keywords: ros2 humble agent
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: Apache Software License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3 :: Only
15
- Classifier: Operating System :: OS Independent
16
- Description-Content-Type: text/markdown
17
- License-File: LICENSE
18
- Requires-Dist: websockets
19
- Requires-Dist: psutil
20
- Provides-Extra: ros
21
- Requires-Dist: rclpy; extra == "ros"
22
- Dynamic: author
23
- Dynamic: author-email
24
- Dynamic: classifier
25
- Dynamic: description
26
- Dynamic: description-content-type
27
- Dynamic: home-page
28
- Dynamic: keywords
29
- Dynamic: license
30
- Dynamic: license-file
31
- Dynamic: provides-extra
32
- Dynamic: requires-dist
33
- Dynamic: summary
34
-
35
- # OSIRIS Agent
36
-
37
- A ROS2 Humble node that bridges your robot to the OSIRIS remote monitoring platform via WebSocket.
38
-
39
- ## Overview
40
-
41
- The OSIRIS Agent (`osiris_agent`) is a ROS2 node that provides real-time bidirectional communication between your ROS2 robot and a remote WebSocket gateway. It monitors the ROS2 graph, collects system telemetry, and enables dynamic topic subscription from the remote platform.
42
-
43
- ## Features
44
-
45
- ### Real-time Graph Monitoring
46
- - **Node Detection**: Automatically detects when ROS2 nodes start/stop
47
- - **Topic Tracking**: Monitors topic creation, destruction, and subscription changes
48
- - **Action Discovery**: Tracks ROS2 actions and their lifecycle
49
- - **Service Discovery**: Detects available services and their endpoints
50
- - **Publisher/Subscriber Relations**: Maps which nodes publish to and subscribe from each topic
51
-
52
- ### Dynamic Topic Subscription
53
- - Subscribe to any ROS2 topic remotely via WebSocket commands
54
- - Automatic message type resolution and serialization
55
- - Configurable subscription limits (default: 100 concurrent subscriptions)
56
- - Thread-safe subscription management
57
- - Topic publishing rate calculation
58
-
59
- ### Node Parameters
60
- - Automatic discovery of node parameters
61
- - Periodic parameter refresh (every 5 seconds)
62
- - Asynchronous parameter fetching to avoid blocking
63
-
64
- ### System Telemetry
65
- - CPU usage monitoring
66
- - Memory (RAM) utilization tracking
67
- - Disk space monitoring
68
- - Enable/disable telemetry on demand
69
-
70
- ### Quality of Service (QoS) Support
71
- - Full QoS profile inspection for publishers and subscribers
72
- - Reliability, durability, history policy, depth, and liveliness information
73
-
74
- ### Robust Connection Management
75
- - Automatic reconnection with exponential backoff
76
- - Initial delay: 1 second, max delay: 10 seconds
77
- - Secure WebSocket (WSS) connection
78
- - Token-based authentication
79
-
80
- ## Architecture
81
-
82
- ```
83
- WebBridge Node (osiris_agent)
84
-
85
- ├─ Main Thread (rclpy.spin)
86
- │ ├─ ROS2 Node Callbacks
87
- │ ├─ Graph Change Detector (timer: 100ms)
88
- │ ├─ Parameter Refresh (timer: 5s)
89
- │ └─ Telemetry Collector (timer: 1s)
90
-
91
- └─ Daemon Thread (WebSocket Client)
92
- └─ Asyncio Event Loop
93
- ├─ Send Loop (queue consumer)
94
- ├─ Receive Loop (command handler)
95
- └─ Reconnection Logic (exponential backoff)
96
- ```
97
-
98
- **Key Components:**
99
- - **Graph Monitor**: Polls ROS2 graph for changes (nodes, topics, actions, services)
100
- - **Subscription Manager**: Handles dynamic topic subscriptions with `threading.Lock()` for thread-safe access to the subscription dictionary
101
- - **Telemetry Collector**: Gathers CPU, RAM, and disk metrics using `psutil`
102
- - **WebSocket Client**: Maintains persistent connection with automatic reconnection
103
- - **Message Queue**: `asyncio.Queue` created on the websocket event loop for serializing all outgoing messages
104
-
105
- **Threading Model:**
106
- - Main thread runs ROS2 executor (`rclpy.spin`) with timers and callbacks
107
- - Daemon thread runs asyncio event loop with websocket client (send/receive coroutines)
108
- - Shared data (`_topic_subs`) protected by `threading.Lock` to prevent race conditions
109
- - Cross-thread communication via `asyncio.run_coroutine_threadsafe()` to schedule coroutines from ROS thread onto websocket loop
110
-
111
- ## Installation
112
-
113
- ```bash
114
- # Clone the repository into your workspace
115
- cd ~/ros2_ws/src
116
- git clone https://github.com/nicolaselielll/osiris_agent.git
117
-
118
- # Install the package
119
- cd osiris_agent
120
- pip3 install -e .
121
- ```
122
-
123
- The `-e` flag installs in editable mode so changes to the code are reflected immediately.
124
-
125
- ## Configuration
126
-
127
- Set your authentication token as an environment variable:
128
-
129
- ```bash
130
- export OSIRIS_AUTH_TOKEN="your-robot-token-here"
131
- ```
132
-
133
- **Tip**: Add to `~/.bashrc` to persist across sessions:
134
- ```bash
135
- echo 'export OSIRIS_AUTH_TOKEN="your-token"' >> ~/.bashrc
136
- ```
137
-
138
- ### Optional: Customize Behavior
139
-
140
- Edit constants in `osiris_agent/agent_node.py`:
141
-
142
- - `MAX_SUBSCRIPTIONS = 100`: Maximum concurrent topic subscriptions
143
- - `ALLOWED_TOPIC_PREFIXES = ['/']`: Restrict subscribable topics (e.g., `['/robot/', '/sensors/']`)
144
- - `GRAPH_CHECK_INTERVAL = 0.1`: Graph polling interval (seconds)
145
- - `PARAMETER_REFRESH_INTERVAL = 5.0`: Parameter refresh interval (seconds)
146
- - `TELEMETRY_INTERVAL = 1.0`: Telemetry collection interval (seconds)
147
-
148
- ## Running
149
-
150
- ```bash
151
- export OSIRIS_AUTH_TOKEN="your-token"
152
- agent_node
153
- ```
154
-
155
- You should see:
156
- ```
157
- [INFO] [bridge_node]: Attempting to connect to gateway...
158
- [INFO] [bridge_node]: Connected to gateway
159
- [INFO] [bridge_node]: Sent initial state: 5 nodes, 12 topics, 0 actions, 8 services
160
- ```
161
-
162
- ## Updating
163
-
164
- ```bash
165
- cd ~/ros2_ws/src/osiris_agent
166
- git pull
167
- # Changes apply immediately if installed with -e
168
- ```
169
-
170
- ## WebSocket Protocol
171
-
172
- ### Commands (Gateway → Agent)
173
-
174
- **Subscribe to Topic**
175
- ```json
176
- {"type": "subscribe", "topic": "/cmd_vel"}
177
- ```
178
-
179
- **Unsubscribe**
180
- ```json
181
- {"type": "unsubscribe", "topic": "/cmd_vel"}
182
- ```
183
-
184
- **Control Telemetry**
185
- ```json
186
- {"type": "start_telemetry"}
187
- {"type": "stop_telemetry"}
188
- ```
189
-
190
- ### Events (Agent → Gateway)
191
-
192
- **Initial State** (on connect)
193
- ```json
194
- {
195
- "type": "initial_state",
196
- "timestamp": 1234567890.123,
197
- "data": {
198
- "nodes": {},
199
- "topics": {},
200
- "actions": {},
201
- "services": {},
202
- "telemetry": {}
203
- }
204
- }
205
- ```
206
-
207
- **Graph Changes**
208
- ```json
209
- {"type": "node_event", "node": "/my_node", "event": "started", "timestamp": 123}
210
- {"type": "topic_event", "topic": "/my_topic", "event": "created", "timestamp": 123}
211
- {"type": "action_event", "action": "/my_action", "event": "created", "timestamp": 123}
212
- {"type": "service_event", "service": "/my_service", "event": "created", "timestamp": 123}
213
- ```
214
-
215
- **Topic Data**
216
- ```json
217
- {
218
- "type": "topic_data",
219
- "topic": "/cmd_vel",
220
- "data": {"linear": {"x": 1.0}, "angular": {"z": 0.5}},
221
- "rate_hz": 10.0,
222
- "timestamp": 123
223
- }
224
- ```
225
-
226
- **Telemetry**
227
- ```json
228
- {
229
- "type": "telemetry",
230
- "data": {
231
- "cpu": 45.2,
232
- "ram": {"percent": 62.5, "used_mb": 5000, "total_mb": 8000},
233
- "disk": {"percent": 75.0, "used_gb": 150, "total_gb": 200}
234
- },
235
- "timestamp": 123
236
- }
237
- ```
238
-
239
- **Bridge Subscriptions**
240
- ```json
241
- {
242
- "type": "bridge_subscriptions",
243
- "subscriptions": ["/topic1", "/topic2"],
244
- "timestamp": 123
245
- }
246
- ```
247
-
248
- ## Troubleshooting
249
-
250
- **ModuleNotFoundError: websockets or psutil**
251
- ```bash
252
- pip3 install -e .
253
- ```
254
-
255
- **Connection drops**
256
- - Check firewall allows outbound HTTPS to `osiris-gateway.fly.dev:443`
257
- - View logs: `journalctl -u osiris-agent -f`
258
-
259
- **High CPU usage**
260
- - Increase `GRAPH_CHECK_INTERVAL` to `0.5` or `1.0`
261
- - Reduce `PARAMETER_REFRESH_INTERVAL` to `10.0`
262
- - Disable telemetry when not needed
263
-
264
- **Topics not appearing**
265
- - Verify topic exists: `ros2 topic list`
266
- - Check logs for validation warnings
267
- - Ensure under `MAX_SUBSCRIPTIONS` limit
268
-
269
- ## Performance Tuning
270
-
271
- **Large graphs (100+ nodes/topics)**
272
- ```python
273
- GRAPH_CHECK_INTERVAL = 0.5
274
- PARAMETER_REFRESH_INTERVAL = 10.0
275
- MAX_SUBSCRIPTIONS = 50
276
- ```
277
-
278
- **Resource-constrained robots**
279
- ```python
280
- GRAPH_CHECK_INTERVAL = 1.0
281
- PARAMETER_REFRESH_INTERVAL = 15.0
282
- TELEMETRY_INTERVAL = 2.0
283
- ```
284
-
285
- **Restrict topic access**
286
- ```python
287
- ALLOWED_TOPIC_PREFIXES = ['/robot/', '/sensors/']
288
- ```
289
-
290
- ## Security
291
-
292
- - Auth token sent via WSS (encrypted in transit)
293
- - **Never log `self.ws_url`** - it contains the authentication token in the query parameter
294
- - Set `ALLOWED_TOPIC_PREFIXES` to restrict which topics can be remotely subscribed
295
- - `MAX_SUBSCRIPTIONS` prevents resource exhaustion from excessive subscriptions
296
- - Ensure gateway scrubs tokens from access logs
297
-
298
- ## License
299
-
300
- This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
301
-
302
- ## Contributing
303
-
304
- Issues and PRs welcome at [github.com/nicolaselielll/osiris_agent](https://github.com/nicolaselielll/osiris_agent)
305
-
306
- ## Changelog
307
-
308
- ### v0.1.0
309
- - WebSocket bridge with secure WSS connection
310
- - Real-time graph monitoring
311
- - Dynamic topic subscription
312
- - System telemetry (CPU/RAM/disk)
313
- - Auto-reconnect with exponential backoff
314
- - Parameter discovery
315
- - QoS profile inspection
File without changes
File without changes