Skip to content

Commit ed74249

Browse files
committed
Add a subscriber/publisher demo for typescript (#1194)
Adds a TypeScript-based ROS2 topics demo using rclnodejs, including publisher and subscriber examples, build configuration, and documentation. - Introduce `tsconfig.json` for TypeScript compilation. - Add `publisher.ts` and `subscriber.ts` demo implementations. - Provide `package.json` scripts and detailed `README.md` guide. Fix: #1192
1 parent 58fa9f7 commit ed74249

File tree

5 files changed

+554
-0
lines changed

5 files changed

+554
-0
lines changed

ts_demo/topics/README.md

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
# rclnodejs TypeScript Topics Demo
2+
3+
This demo demonstrates how to use **rclnodejs** with TypeScript to create ROS2 publishers and subscribers. The demo includes a publisher that sends string messages to a topic called `ts_demo` and a subscriber that receives and displays those messages.
4+
5+
## Features
6+
7+
- 🚀 **TypeScript Support**: Fully typed ROS2 node implementation using rclnodejs TypeScript interfaces
8+
- 📤 **Publisher**: Sends timestamped string messages at regular intervals
9+
- 📥 **Subscriber**: Receives and displays messages with timestamps
10+
- 🛡️ **Type Safety**: Leverages TypeScript's type system for compile-time safety
11+
- 🎯 **Error Handling**: Comprehensive error handling and graceful shutdown
12+
- 📊 **Message Counting**: Tracks published and received message counts
13+
- 🎨 **Console Output**: Colorful and informative console messages
14+
15+
## Prerequisites
16+
17+
Before running this demo, ensure you have:
18+
19+
1. **Node.js** (>= 16.13.0)
20+
2. **ROS 2** installed and sourced
21+
3. **rclnodejs** built and available
22+
23+
### ROS 2 Setup
24+
25+
Make sure your ROS 2 environment is properly sourced before running the demo:
26+
27+
```bash
28+
# For example, if using ROS 2 Jazzy
29+
source /opt/ros/jazzy/setup.bash
30+
31+
# Or if you have a custom workspace
32+
source /path/to/your/ros2_ws/install/setup.bash
33+
```
34+
35+
### Verify rclnodejs Installation
36+
37+
From the root of the rclnodejs project, ensure it's built:
38+
39+
```bash
40+
cd /path/to/rclnodejs
41+
npm install
42+
npm run build
43+
```
44+
45+
## Installation
46+
47+
Navigate to this demo directory and install dependencies:
48+
49+
```bash
50+
cd ts_demo/topics
51+
npm install
52+
```
53+
54+
## Usage
55+
56+
### Build and Run
57+
58+
1. **Build the TypeScript code:**
59+
60+
```bash
61+
npm run build
62+
```
63+
64+
2. **Run the publisher (in one terminal):**
65+
66+
```bash
67+
npm run start:publisher
68+
```
69+
70+
3. **Run the subscriber (in another terminal):**
71+
72+
```bash
73+
npm run start:subscriber
74+
```
75+
76+
4. **Or run both simultaneously:**
77+
```bash
78+
npm run start:both
79+
```
80+
81+
### Development Mode
82+
83+
For development, you can run TypeScript files directly with ts-node:
84+
85+
1. **Run the publisher:**
86+
87+
```bash
88+
npm run dev:publisher
89+
```
90+
91+
2. **Run the subscriber:**
92+
93+
```bash
94+
npm run dev:subscriber
95+
```
96+
97+
3. **Type check only:**
98+
```bash
99+
npm run check-types
100+
```
101+
102+
## TypeScript Setup
103+
104+
This demo includes a self-contained TypeScript configuration that allows compilation without requiring the full rclnodejs installation to be built first. The key components are:
105+
106+
### Local Type Definitions
107+
108+
The `types/rclnodejs.d.ts` file provides basic TypeScript declarations for rclnodejs, enabling:
109+
110+
- ✅ TypeScript compilation without dependencies
111+
- ✅ Type checking and IntelliSense support
112+
- ✅ Proper interface definitions for common ROS2 operations
113+
114+
### TypeScript Configuration
115+
116+
The `tsconfig.json` is configured to:
117+
118+
- Use local type definitions from the `types/` directory
119+
- Compile TypeScript to JavaScript in the `dist/` directory
120+
- Generate source maps and declaration files
121+
- Enable strict type checking
122+
123+
### Development vs Runtime
124+
125+
- **Compilation**: Uses local type definitions (no rclnodejs dependency)
126+
- **Runtime**: Requires actual rclnodejs installation and ROS 2 environment
127+
128+
## Expected Output
129+
130+
### Publisher Output:
131+
132+
```
133+
Starting TypeScript Publisher Demo...
134+
✓ rclnodejs initialized
135+
✓ Created node: /ts_publisher_demo
136+
✓ Created publisher on topic: ts_demo
137+
✓ Created timer with 1000ms interval
138+
🚀 Publisher is running. Press Ctrl+C to stop...
139+
140+
📤 Published: "Hello from TypeScript publisher! Message #1 at 2025-07-16T10:30:00.123Z"
141+
📤 Published: "Hello from TypeScript publisher! Message #2 at 2025-07-16T10:30:01.125Z"
142+
📤 Published: "Hello from TypeScript publisher! Message #3 at 2025-07-16T10:30:02.127Z"
143+
...
144+
```
145+
146+
### Subscriber Output:
147+
148+
```
149+
Starting TypeScript Subscriber Demo...
150+
✓ rclnodejs initialized
151+
✓ Created node: /ts_subscriber_demo
152+
✓ Created subscription on topic: ts_demo
153+
👂 Subscriber is listening. Press Ctrl+C to stop...
154+
155+
📥 [1] Received: "Hello from TypeScript publisher! Message #1 at 2025-07-16T10:30:00.123Z"
156+
Timestamp: 2025-07-16T10:30:00.124Z
157+
📥 [2] Received: "Hello from TypeScript publisher! Message #2 at 2025-07-16T10:30:01.125Z"
158+
Timestamp: 2025-07-16T10:30:01.126Z
159+
...
160+
```
161+
162+
## Project Structure
163+
164+
```
165+
ts_demo/topics/
166+
├── package.json # Project dependencies and scripts
167+
├── tsconfig.json # TypeScript configuration
168+
├── README.md # This file
169+
├── src/ # TypeScript source files
170+
│ ├── publisher.ts # Publisher implementation
171+
│ └── subscriber.ts # Subscriber implementation
172+
└── dist/ # Compiled JavaScript (after build)
173+
├── publisher.js
174+
└── subscriber.js
175+
```
176+
177+
## Code Explanation
178+
179+
### Publisher (`src/publisher.ts`)
180+
181+
The publisher demonstrates:
182+
183+
- **Node Creation**: Creates a ROS2 node using TypeScript
184+
- **Publisher Setup**: Creates a publisher for `std_msgs/msg/String` messages
185+
- **Timer Usage**: Uses `node.createTimer()` for periodic message publishing
186+
- **Message Creation**: Uses `rclnodejs.createMessageObject()` with proper typing
187+
- **Graceful Shutdown**: Handles SIGINT for clean shutdown
188+
189+
Key TypeScript features used:
190+
191+
```typescript
192+
import * as rclnodejs from 'rclnodejs';
193+
194+
const node = new rclnodejs.Node('ts_publisher_demo');
195+
const publisher = node.createPublisher('std_msgs/msg/String', TOPIC_NAME);
196+
const message = rclnodejs.createMessageObject('std_msgs/msg/String');
197+
```
198+
199+
### Subscriber (`src/subscriber.ts`)
200+
201+
The subscriber demonstrates:
202+
203+
- **Subscription Creation**: Creates a typed subscription for string messages
204+
- **Callback Handling**: Processes incoming messages with proper TypeScript typing
205+
- **Message Processing**: Displays received messages with timestamps
206+
207+
Key TypeScript features used:
208+
209+
```typescript
210+
const subscription = node.createSubscription(
211+
'std_msgs/msg/String',
212+
TOPIC_NAME,
213+
(message: rclnodejs.std_msgs.msg.String) => {
214+
console.log(`Received: "${message.data}"`);
215+
}
216+
);
217+
```
218+
219+
## TypeScript Benefits
220+
221+
This demo showcases several TypeScript advantages:
222+
223+
1. **Type Safety**: Compile-time checking prevents common errors
224+
2. **IntelliSense**: Better IDE support with autocompletion
225+
3. **Interface Definitions**: Clear contract definitions for ROS2 messages
226+
4. **Refactoring Safety**: Easier to maintain and modify code
227+
5. **Documentation**: Types serve as inline documentation
228+
229+
## Troubleshooting
230+
231+
### Common Issues
232+
233+
1. **Module not found error for 'rclnodejs':**
234+
235+
```
236+
Cannot find module 'rclnodejs' or its corresponding type declarations
237+
```
238+
239+
**Solution**: Ensure you're in the correct directory and rclnodejs is properly linked:
240+
241+
```bash
242+
cd ts_demo/topics
243+
npm install
244+
```
245+
246+
2. **ROS 2 environment not sourced:**
247+
248+
```
249+
Error: Unable to find ROS 2 installation
250+
```
251+
252+
**Solution**: Source your ROS 2 setup file:
253+
254+
```bash
255+
source /opt/ros/jazzy/setup.bash
256+
```
257+
258+
3. **Build errors:**
259+
```
260+
TypeScript compilation errors
261+
```
262+
**Solution**: Check TypeScript configuration and ensure all dependencies are installed:
263+
```bash
264+
npm install
265+
npm run clean
266+
npm run build
267+
```
268+
269+
### Debugging Tips
270+
271+
1. **Enable verbose logging:**
272+
273+
```bash
274+
export RCUTILS_LOGGING_SEVERITY=DEBUG
275+
```
276+
277+
2. **Check ROS 2 topic list:**
278+
279+
```bash
280+
ros2 topic list
281+
ros2 topic echo /ts_demo
282+
```
283+
284+
3. **Monitor topic info:**
285+
```bash
286+
ros2 topic info /ts_demo
287+
```
288+
289+
## Customization
290+
291+
You can easily customize this demo:
292+
293+
### Change Topic Name
294+
295+
Edit the `TOPIC_NAME` constant in both files:
296+
297+
```typescript
298+
const TOPIC_NAME = 'your_custom_topic';
299+
```
300+
301+
### Change Message Type
302+
303+
To use a different message type, update the type string and interface:
304+
305+
```typescript
306+
// For example, using geometry_msgs/msg/Twist
307+
const publisher = node.createPublisher('geometry_msgs/msg/Twist', 'cmd_vel');
308+
const message = rclnodejs.createMessageObject('geometry_msgs/msg/Twist');
309+
```
310+
311+
### Adjust Publishing Rate
312+
313+
Modify the `PUBLISH_INTERVAL` in the publisher:
314+
315+
```typescript
316+
const PUBLISH_INTERVAL = 500; // Publish every 500ms
317+
```
318+
319+
## Next Steps
320+
321+
After running this demo, you might want to explore:
322+
323+
1. **Different Message Types**: Try using other ROS2 message types like `geometry_msgs/msg/Twist`
324+
2. **Services**: Implement ROS2 services with TypeScript
325+
3. **Actions**: Create action servers and clients
326+
4. **Parameters**: Use ROS2 parameters in your TypeScript nodes
327+
5. **Lifecycle Nodes**: Implement managed lifecycle nodes
328+
329+
## Contributing
330+
331+
This demo is part of the rclnodejs project. To contribute:
332+
333+
1. Fork the rclnodejs repository
334+
2. Create a feature branch
335+
3. Make your changes
336+
4. Add tests if applicable
337+
5. Submit a pull request
338+
339+
## License
340+
341+
This demo is licensed under the Apache License 2.0, same as the rclnodejs project.

ts_demo/topics/package.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "rclnodejs-ts-topics-demo",
3+
"version": "1.0.0",
4+
"description": "TypeScript demo for rclnodejs topics (publisher and subscriber)",
5+
"main": "dist/publisher.js",
6+
"scripts": {
7+
"prebuild": "npm run clean",
8+
"build": "tsc",
9+
"start:publisher": "npm run build && node dist/publisher.js",
10+
"start:subscriber": "npm run build && node dist/subscriber.js",
11+
"start:both": "npm run build && concurrently \"node dist/publisher.js\" \"node dist/subscriber.js\"",
12+
"clean": "rimraf dist",
13+
"dev:publisher": "ts-node src/publisher.ts",
14+
"dev:subscriber": "ts-node src/subscriber.ts",
15+
"check-types": "tsc --noEmit"
16+
},
17+
"keywords": [
18+
"rclnodejs",
19+
"ros2",
20+
"typescript",
21+
"publisher",
22+
"subscriber",
23+
"demo"
24+
],
25+
"author": "rclnodejs contributors",
26+
"license": "Apache-2.0",
27+
"devDependencies": {
28+
"@types/node": "^22.16.4",
29+
"concurrently": "^9.2.0",
30+
"rimraf": "^6.0.1",
31+
"ts-node": "^10.9.2",
32+
"typescript": "^5.8.3"
33+
},
34+
"dependencies": {
35+
"rclnodejs": "file:../../"
36+
}
37+
}

0 commit comments

Comments
 (0)