Skip to content

Commit bbd40a9

Browse files
committed
Add a demo for actions using typescript (#1212)
This PR adds a comprehensive TypeScript demo for ROS2 actions using rclnodejs. The demo implements a Fibonacci sequence calculator with both action client and server components, providing a complete example of how to use actions in TypeScript. - Implements TypeScript action server and client for Fibonacci calculation - Provides comprehensive documentation and setup instructions - Includes build configuration with proper TypeScript tooling - Fixes a minor issue in the existing JavaScript action client example Fix: #1211
1 parent 61078b3 commit bbd40a9

File tree

6 files changed

+719
-4
lines changed

6 files changed

+719
-4
lines changed

example/actions/action_client/action-client-example.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,12 @@ class FibonacciActionClient {
6868

6969
rclnodejs
7070
.init()
71-
.then(() => {
71+
.then(async () => {
7272
const node = rclnodejs.createNode('action_client_example_node');
7373
const client = new FibonacciActionClient(node);
74-
75-
client.sendGoal();
76-
7774
rclnodejs.spin(node);
75+
76+
await client.sendGoal();
7877
})
7978
.catch((err) => {
8079
console.error(err);

ts_demo/actions/README.md

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
# TypeScript Actions Demo for rclnodejs
2+
3+
This demo showcases how to use ROS2 actions with rclnodejs in TypeScript. It includes both an action client and server implementation using the Fibonacci action as an example.
4+
5+
## What are ROS2 Actions?
6+
7+
Actions in ROS2 are a communication pattern for long-running tasks that:
8+
9+
- Have a **goal** (what you want to achieve)
10+
- Provide **feedback** during execution (progress updates)
11+
- Return a **result** when completed (final outcome)
12+
- Can be **canceled** while running
13+
14+
Actions are perfect for tasks like navigation, manipulation, or any long-running computation where you need progress updates.
15+
16+
## Demo Overview
17+
18+
This demo implements a Fibonacci sequence calculator using ROS2 actions:
19+
20+
- **Action Server** (`server.ts`): Calculates Fibonacci sequences up to a given order
21+
- **Action Client** (`client.ts`): Sends goals to the server and receives feedback
22+
23+
### Features
24+
25+
-**Goal handling**: Accept/reject goals based on input validation
26+
-**Feedback**: Real-time progress updates during calculation
27+
-**Result**: Final Fibonacci sequence
28+
-**Cancellation**: Support for canceling running goals
29+
-**Error handling**: Graceful error handling and logging
30+
-**TypeScript**: Full type safety and modern TypeScript features
31+
32+
## Project Structure
33+
34+
```
35+
ts_demo/actions/
36+
├── src/
37+
│ ├── client.ts # Action client implementation
38+
│ └── server.ts # Action server implementation
39+
├── types/
40+
│ └── rclnodejs.d.ts # Type definitions
41+
├── package.json # Project configuration
42+
├── tsconfig.json # TypeScript configuration
43+
├── .gitignore # Git ignore rules
44+
└── README.md # This file
45+
```
46+
47+
## Prerequisites
48+
49+
Before running this demo, ensure you have:
50+
51+
1. **ROS2** installed (tested with ROS2 Humble/Iron/Jazzy)
52+
2. **Node.js** (version 16 or higher)
53+
3. **rclnodejs** built and configured in the parent directory (`../../`)
54+
4. **test_msgs** package available (usually included with ROS2)
55+
56+
**Important**: This demo uses rclnodejs as a peer dependency, so you must ensure that the main rclnodejs package in the parent directory is properly built and configured with ROS2 before running this demo.
57+
58+
## Setup and Installation
59+
60+
1. **Ensure ROS2 is sourced**:
61+
62+
```bash
63+
source /opt/ros/humble/setup.bash # or your ROS2 distribution
64+
```
65+
66+
2. **Build the main rclnodejs package** (if not already done):
67+
68+
```bash
69+
cd ../../ # Go to main rclnodejs directory
70+
npm install
71+
npm run build
72+
```
73+
74+
3. **Navigate to the demo directory**:
75+
76+
```bash
77+
cd ts_demo/actions
78+
```
79+
80+
4. **Install dependencies**:
81+
82+
```bash
83+
npm install
84+
```
85+
86+
5. **Build the TypeScript code**:
87+
```bash
88+
npm run build
89+
```
90+
91+
## Running the Demo
92+
93+
### Option 1: Run Server and Client Separately
94+
95+
1. **Start the action server** (in terminal 1):
96+
97+
```bash
98+
npm run start:server
99+
```
100+
101+
You should see output like:
102+
103+
```
104+
🚀 Starting TypeScript Action Server Demo...
105+
✓ rclnodejs initialized
106+
✓ Created node: /ts_action_server_demo
107+
✓ Fibonacci action server created on topic 'fibonacci'
108+
✓ Fibonacci action server is ready to receive goals
109+
```
110+
111+
2. **Start the action client** (in terminal 2):
112+
113+
```bash
114+
npm run start:client
115+
```
116+
117+
You should see the client sending a goal and receiving feedback:
118+
119+
```
120+
🚀 Starting TypeScript Action Client Demo...
121+
✓ rclnodejs initialized
122+
✓ Created node: /ts_action_client_demo
123+
✓ Action server is available
124+
Sending goal request for Fibonacci(10)...
125+
✓ Goal accepted by server
126+
📊 Received feedback: [0, 1]
127+
📊 Received feedback: [0, 1, 1]
128+
...
129+
✓ Goal succeeded! Fibonacci(10) = 0,1,1,2,3,5,8,13,21,34,55
130+
```
131+
132+
### Option 2: Run Both Simultaneously
133+
134+
Run both server and client together using concurrently:
135+
136+
```bash
137+
npm run start:both
138+
```
139+
140+
This will start both the server and client in parallel, showing interleaved output.
141+
142+
### Option 3: Development Mode (with ts-node)
143+
144+
For development with hot reloading:
145+
146+
1. **Server**:
147+
148+
```bash
149+
npm run dev:server
150+
```
151+
152+
2. **Client**:
153+
```bash
154+
npm run dev:client
155+
```
156+
157+
## Testing with ROS2 CLI Tools
158+
159+
You can also test the action server using ROS2 command-line tools:
160+
161+
1. **Start the server**:
162+
163+
```bash
164+
npm run start:server
165+
```
166+
167+
2. **Send a goal using ros2 action**:
168+
169+
```bash
170+
ros2 action send_goal /fibonacci test_msgs/action/Fibonacci "{order: 15}"
171+
```
172+
173+
3. **List available actions**:
174+
175+
```bash
176+
ros2 action list
177+
```
178+
179+
4. **Get action info**:
180+
```bash
181+
ros2 action info /fibonacci
182+
```
183+
184+
## Available Scripts
185+
186+
- `npm run build` - Compile TypeScript to JavaScript
187+
- `npm run clean` - Remove compiled files
188+
- `npm run start:server` - Run the action server
189+
- `npm run start:client` - Run the action client
190+
- `npm run start:both` - Run both server and client concurrently
191+
- `npm run dev:server` - Run server in development mode
192+
- `npm run dev:client` - Run client in development mode
193+
- `npm run check-types` - Type check without compilation
194+
195+
## Understanding the Code
196+
197+
### Action Server (`server.ts`)
198+
199+
The action server implements three main callbacks:
200+
201+
1. **Goal Callback**: Decides whether to accept or reject incoming goals
202+
203+
```typescript
204+
goalCallback(goalHandle: any): rclnodejs.GoalResponse {
205+
// Validate the goal and return ACCEPT or REJECT
206+
}
207+
```
208+
209+
2. **Execute Callback**: Performs the actual work (Fibonacci calculation)
210+
211+
```typescript
212+
async executeCallback(goalHandle: any): Promise<any> {
213+
// Calculate Fibonacci sequence and provide feedback
214+
}
215+
```
216+
217+
3. **Cancel Callback**: Handles goal cancellation requests
218+
```typescript
219+
cancelCallback(goalHandle: any): rclnodejs.CancelResponse {
220+
// Return ACCEPT to allow cancellation
221+
}
222+
```
223+
224+
### Action Client (`client.ts`)
225+
226+
The action client:
227+
228+
1. Waits for the action server to be available
229+
2. Creates and sends a goal
230+
3. Handles feedback during execution
231+
4. Processes the final result
232+
233+
```typescript
234+
const goalHandle = await this.actionClient.sendGoal(goal, (feedback) =>
235+
this.feedbackCallback(feedback)
236+
);
237+
```
238+
239+
## Customization
240+
241+
You can modify the demo to:
242+
243+
- **Change the Fibonacci order**: Edit `FIBONACCI_ORDER` in `client.ts`
244+
- **Adjust timing**: Modify the delay in the server's execute callback
245+
- **Add validation**: Enhance goal validation in the server
246+
- **Handle errors**: Add more sophisticated error handling
247+
248+
## Troubleshooting
249+
250+
### Common Issues
251+
252+
1. **"Cannot find module 'rclnodejs'"**:
253+
254+
- Ensure rclnodejs is properly built in the parent directory
255+
- Run `npm install` in the main rclnodejs directory
256+
257+
2. **"Action server not available"**:
258+
259+
- Make sure the action server is running before starting the client
260+
- Check that both nodes are using the same action name
261+
262+
3. **TypeScript compilation errors**:
263+
264+
- Run `npm run check-types` to see detailed type errors
265+
- Ensure all dependencies are installed: `npm install`
266+
267+
4. **ROS2 environment not sourced**:
268+
```bash
269+
source /opt/ros/humble/setup.bash # or your ROS2 distribution
270+
```
271+
272+
### Debugging
273+
274+
Enable debug logging by setting the environment variable:
275+
276+
```bash
277+
export RCUTILS_LOGGING_SEVERITY=DEBUG
278+
npm run start:server
279+
```
280+
281+
## Next Steps
282+
283+
After exploring this demo, you might want to:
284+
285+
1. **Create custom actions**: Define your own `.action` files
286+
2. **Handle multiple goals**: Implement concurrent goal handling
287+
3. **Add persistence**: Store goal state across restarts
288+
4. **Integrate with other nodes**: Combine actions with topics and services
289+
5. **Add visualization**: Create a web interface to monitor action progress
290+
291+
## Related Examples
292+
293+
- **Topics Demo**: `../topics/` - Publisher/Subscriber pattern
294+
- **Services Demo**: `../services/` - Request/Response pattern
295+
- **JavaScript Actions**: `../../example/actions/` - JavaScript implementation
296+
297+
## Resources
298+
299+
- [ROS2 Actions Documentation](https://docs.ros2.org/latest/Tutorials/Understanding-ROS2-Actions.html)
300+
- [rclnodejs Documentation](https://github.com/RobotWebTools/rclnodejs)
301+
- [test_msgs Package](https://github.com/ros2/rcl_interfaces/tree/master/test_msgs)
302+
303+
---
304+
305+
**Happy coding with ROS2 Actions and TypeScript! 🚀**

ts_demo/actions/package.json

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

0 commit comments

Comments
 (0)