@chart-sg/node-red-ros2-manager 1.0.1
Shared ROS2 context manager for Node-RED plugins. Eliminates conflicts and enables multi-plugin compatibility.
@chart-sg/node-red-ros2-manager
A Node-RED module providing shared ROS2 context management and global configuration for Node-RED ROS2 plugins. This package enables multiple ROS2 plugins to coexist harmoniously in the same Node-RED process without conflicts.
Quick Start
⚠️ IMPORTANT: Cannot be installed via Node-RED Palette Manager
These packages require terminal installation with ROS2/RMF environment sourced. The Palette Manager installation will fail because rclnodejs needs access to ROS2 libraries during installation.
Important: This package requires rclnodejs to be pre-installed with proper ROS2 environment.
1. One-Time Setup
# Source your ROS2 environment
source /opt/ros/jazzy/setup.bash # (or your ROS2 distro)
# For RMF users, also source RMF workspace
source ~/rmf_ws/install/setup.bash
# Install rclnodejs in Node-RED directory
cd ~/.node-red
npm install rclnodejs
2. Install ROS2 Packages
After setup, install the packages (this manager is installed automatically as dependency):
# Install from npm registry
cd ~/.node-red
npm install @chart-sg/node-red-ros2
# or
npm install @chart-sg/node-red-rmf
Purpose
Critical Problem Solved: Direct rclnodejs usage in Node-RED's dynamic environment causes fundamental conflicts:
The Chaos Without Manager:
// Multiple plugins = Multiple contexts = Crashes
[node-red-ros2] → rclnodejs.init() → Context A
[node-red-rmf] → rclnodejs.init() → Context B → CRASH
[other-plugin] → rclnodejs.init() → Context C
The Harmony With Manager:
// Single shared context + global config = Stable operation
[node-red-ros2] ↘
[node-red-rmf] → [ROS2 Manager] → Single Context + Config → SUCCESS
[other-plugin] ↗
Specific Issues Resolved:
- Context Conflicts: Multiple
rclnodejs.init()calls crash the process - Domain Conflicts: Multiple packages with different domains cause silent failures
- ActionClient Spinning: Direct ActionClient usage blocks spinning → nullptr errors
- Resource Leaks: Improper cleanup during Node-RED redeployments
- Multi-Node Coordination: Complex callback processing across dynamic nodes
- Configuration Chaos: No single source of truth for domain/namespace settings
Architecture
Node-RED Module Classification
This package is a Node-RED module that provides:
- ros2-config configuration node for global ROS2 settings
- SharedManager library for centralized ROS2 context management
- Required dependency for all Chart ROS2 Node-RED packages
What Users See in Node-RED
After installation, users get a ros2-config configuration node that is accessed through:
- Configuration Nodes sidebar (Ctrl+G → Configuration Nodes tab)
- Other ROS2 nodes' edit dialogs (when selecting ROS2 configuration)
System Architecture
┌─────────────────────────────────────────────────────────────────┐
│ @chart-sg/node-red-ros2-manager │
│ (Node-RED Module) │
│ │
│ ┌─────────────────────┐ ┌──────────────────────────────┐ │
│ │ ros2-config │ │ SharedManager │ │
│ │ (Node-RED Node) │ │ (JavaScript Library) │ │
│ │ │ │ │ │
│ │ • Domain ID │◄──►│ • Single ROS2 Context │ │
│ │ • Namespace │ │ • Multi-Node Coordination │ │
│ │ • Visual Status │ │ • Resource Management │ │
│ └─────────────────────┘ │ • Error Recovery │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
▲ ▲
│ │
┌───────────┴──────────┐ ┌─────────┴─────────┐
│ @chart-sg/node- │ │ @chart-sg/node- │
│ red-ros2 │ │ red-rmf │
│ │ │ │
│ • publisher │ │ • start-task │
│ • subscriber │ │ • goto-place │
│ • action-client │ │ • end-task │
│ • service-client │ │ • rmf-config │
└──────────────────────┘ └───────────────────┘
Dependency Status - REQUIRED for Node-RED ROS2 Packages
This package is a required dependency for Chart ROS2 Node-RED packages and provides the centralized ros2-config node:
@chart-sg/node-red-ros2:
"dependencies": {
"@chart-sg/node-red-ros2-manager": "^1.0.0" ← Automatically installed
}
@chart-sg/node-red-rmf:
"dependencies": {
"@chart-sg/node-red-ros2-manager": "^1.0.0" ← Automatically installed
}
Why Required:
- Centralized Configuration: Single ros2-config node controls all ROS2 operations
- Domain Conflict Prevention: Ensures all packages use same domain/namespace
- SharedManager Benefits: Eliminates ROS2 context conflicts and resource issues
### **Spinning Coordination**
```javascript
// 100Hz Multi-Node Spinning Loop
setInterval(() => {
for (const [nodeId, nodeInfo] of this.nodes) {
try {
rclnodejs.spinOnce(nodeInfo.node); // Process each node's callbacks
// Actions receive responses
// Subscriptions get messages
// Services handle requests
} catch (error) {
// Conservative backoff: 100ms → 1000ms
}
}
}, 10);
Installation
# 1. Source ROS2 environment
source /opt/ros/jazzy/setup.bash # (or your ROS2 distro)
# 2. Install in Node-RED directory
cd ~/.node-red
npm install rclnodejs
npm install @chart-sg/node-red-ros2-manager
This package is automatically installed as a dependency when you install other Chart ROS2 packages.
Node-RED ros2-config Node
This package provides a ros2-config configuration node that appears in Node-RED's palette:
Location in Node-RED:
Configuration nodes are not visible in the palette. Access ros2-config through:
- Configuration Nodes sidebar: Ctrl+G → Configuration Nodes tab → ros2-config
- ROS2 node edit dialogs: When editing any ROS2 node, select ros2-config from dropdown
Configuration:
- Domain ID (0-232): ROS2 domain for all operations
- Namespace (optional): Global namespace prefix for topics/services/actions
Visual Status Indicators:
- Green: "domain: X" - ROS2 available and configured
- Red: "ROS2 setup required" - rclnodejs not properly installed
- Red: "config error" - Configuration error occurred
Usage Pattern:
- Create ros2-config node with your domain and namespace
- Reference from other nodes: All ROS2/RMF nodes reference this config
- Centralized control: Change domain once, affects all nodes
- Conflict prevention: Multiple ros2-config nodes with different domains show warnings
Example Configurations:
Standard Setup (Most Common):
ros2-config:
├── Domain ID: 69
└── Namespace: "" (empty)
Results in:
├── topic "/cmd_vel" stays "/cmd_vel"
├── action "/navigate" stays "/navigate"
└── All operations on domain 69
Development/Testing Setup:
ros2-config:
├── Domain ID: 1
└── Namespace: "" (empty)
Result: Complete isolation from production (domain 0)
Usage
Node-RED Usage (Primary)
1. Basic Setup:
1. Install @chart-sg/node-red-ros2 or @chart-sg/node-red-rmf via Palette Manager
2. Add any ROS2 node (publisher, subscriber, etc.) to your flow
3. Double-click the ROS2 node to edit it
4. In the "ROS2 Config" dropdown, click the pencil icon to create new ros2-config
5. Configure domain (e.g., 69) and optional namespace
6. Deploy and use!
2. Node-RED Plugin Development:
// In your Node-RED plugin's .js file
module.exports = function(RED) {
function MyROS2Node(config) {
RED.nodes.createNode(this, config);
// Get ROS2 configuration from ros2-config node
this.ros2Config = RED.nodes.getNode(config.ros2_config);
if (!this.ros2Config) {
this.error("ros2-config is required");
return;
}
// Access domain and namespace
const domain = this.ros2Config.domain;
const namespace = this.ros2Config.namespace;
// Use SharedManager
this.initializeROS2();
}
MyROS2Node.prototype.initializeROS2 = async function() {
try {
const { getROS2Manager } = require('@chart-sg/node-red-ros2-manager');
const manager = getROS2Manager();
// Initialize with ros2-config settings (handled by ros2-config node)
await manager.initialize();
// Create node through manager
const result = await manager.createNode(`${this.type}_${this.id}`);
this.nodeId = result.nodeId;
this.node = result.node;
this.status({fill: "green", shape: "dot", text: "connected"});
} catch (error) {
this.error("ROS2 initialization failed: " + error.message);
this.status({fill: "red", shape: "ring", text: "error"});
}
};
MyROS2Node.prototype.close = function(done) {
if (this.nodeId) {
const { getROS2Manager } = require('@chart-sg/node-red-ros2-manager');
const manager = getROS2Manager();
manager.destroyNode(this.nodeId);
}
done();
};
RED.nodes.registerType("my-ros2-node", MyROS2Node);
};
Direct Node.js Usage (Advanced)
const { getROS2Manager } = require('@chart-sg/node-red-ros2-manager');
// Get the shared manager instance
const manager = getROS2Manager();
// Configure domain and namespace (usually done by ros2-config node in Node-RED)
manager.configure({
domain: 69,
namespace: '/robot1'
});
// Initialize shared ROS2 context
await manager.initialize();
// Create nodes and use normally...
Note: In Node-RED environments, configuration is typically handled by the ros2-config node automatically.
## API Reference
### **Getting the Manager**
```javascript
const { getROS2Manager } = require('@chart-sg/node-red-ros2-manager');
const manager = getROS2Manager();
Configuration Methods
configure(config)
Configure global ROS2 settings (usually called by ros2-config node).
manager.configure({
domain: 69, // ROS2 domain ID (0-232)
namespace: '/robot1' // Optional namespace prefix
});
Core Manager Methods
initialize(options)
Initialize the shared ROS2 context (idempotent - safe to call multiple times).
await manager.initialize({
owner: 'my-application' // Optional owner identifier
});
createNode(nodeName)
Create a ROS2 node through the shared manager.
const result = await manager.createNode('my_unique_node_name');
// Returns: { nodeId: string, node: rclnodejs.Node }
destroyNode(nodeId)
Properly destroy a node and clean up resources.
manager.destroyNode(nodeId);
shutdown()
Shutdown the entire shared ROS2 context.
await manager.shutdown();
Key Benefits
Centralized Configuration
- Single ros2-config node: Controls domain/namespace for all ROS2 operations
- Conflict Prevention: Impossible to have domain conflicts between packages
- Visual Feedback: Clear status indicators show ROS2 availability
🚫 Conflict Resolution
- Single ROS2 Context: Eliminates multiple initialization crashes
- Resource Isolation: Components don't interfere with each other
- Proper Cleanup: Handles Node-RED's dynamic redeployment cycles
Developer Experience
- Simple Integration: Drop-in replacement for direct rclnodejs
- Automatic Installation: Installed as dependency, no manual setup
- Clear Error Messages: Helpful guidance when ROS2 setup is incomplete
- Node-RED Native: Works seamlessly with Palette Manager installation
Node-RED Specific
- Dynamic Lifecycle: Handles Node-RED's deploy/redeploy cycles
- Plugin Compatibility: Multiple ROS2 packages can coexist
- Hot Reload Support: Proper resource cleanup during redeployments
- Configuration UI: Visual ros2-config node for easy setup
🔗 Compatible Packages
Node-RED Packages Using This Manager
[@chart-sg/node-red-ros2]: Basic ROS2 nodes (publisher, subscriber, action-client, service-client)
- Dependency: Required (SharedManager is mandatory)
- Configuration: Uses ros2-config node for domain/namespace
[@chart-sg/node-red-rmf]: RMF fleet management nodes
- Dependency: Required (SharedManager is mandatory)
- Configuration: Uses ros2-config node + rmf-config for additional RMF settings
Package Relationship
User installs: This manager provides:
┌─────────────────┐ ┌──────────────────────────┐
│ node-red-ros2 │────►│ • ros2-config node │
└─────────────────┘ │ • SharedManager library │
OR │ • Conflict prevention │
┌─────────────────┐ │ • Resource management │
│ node-red-rmf │────►│ │
└─────────────────┘ └──────────────────────────┘
Troubleshooting
Installation Issues
"rclnodejs not found" during package installation
This means the one-time rclnodejs setup wasn't completed:
# 1. Source ROS2 environment
source /opt/ros/jazzy/setup.bash
# 2. For RMF users, also source RMF workspace
source ~/rmf_ws/install/setup.bash
# 3. Install rclnodejs in Node-RED directory
cd ~/.node-red
npm install rclnodejs
# 4. Retry package installation
Package installs but ros2-config shows "ROS2 setup required"
This means Node-RED wasn't started with ROS2 environment sourced:
# Stop Node-RED, then restart with ROS2 environment
source /opt/ros/jazzy/setup.bash
source ~/rmf_ws/install/setup.bash # RMF users only
node-red
Configuration Issues
Domain conflict warnings
If you see warnings about different domains:
- Check all ros2-config nodes in your flows
- Ensure they all use the same domain ID
- Delete/reconfigure conflicting ros2-config nodes
Namespace not working
Verify your ros2-config settings:
- Open ros2-config node editor
- Check namespace field (should start with "/" if not empty)
- Redeploy flows after changes
Runtime Issues
Nodes stuck in "connecting" state
- Check ros2-config node status (should be green)
- Verify ROS2 environment was sourced before starting Node-RED
- Check Node-RED console for detailed error messages
Can't see ROS2 topics/services from other applications
- Verify domain ID matches between Node-RED and other ROS2 applications
- Check namespace settings - empty namespace for global visibility
- Use
ros2 topic listto verify topic visibility
Package-Specific Environment Checks
While this manager handles basic ROS2 setup, individual packages may have additional requirements:
# For RMF functionality, check RMF-specific requirements
cd ~/.node-red/node_modules/@chart-sg/node-red-rmf
npm run check-rmf
# For other packages, check their documentation for package-specific scripts
Debug Mode
Enable detailed logging:
ROS2_MANAGER_DEBUG=true node-red
📄 License
ISC License - see LICENSE file for details.
🏢 About CHART
This package is developed by CHART to enable robust, conflict-free ROS2 integration in Node-RED and Node.js environments.
📚 Related Documentation
- [Node-RED ROS2 Integration FAQ] - Comprehensive guide covering architecture, troubleshooting, and best practices
- [rclnodejs Documentation] - Underlying ROS2 Node.js bindings
- [ROS2 Documentation] - Official ROS2 resources
Summary: @chart-sg/node-red-ros2-manager provides the ros2-config node for centralized ROS2 configuration and the SharedManager library for conflict-free multi-package operation. Essential for any Node-RED ROS2 deployment with multiple packages or complex flows.