Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
- Add ParameterClient for external parameter access
- Add structured error handling with class error hierarchy
- Add ParameterWatcher for real-time parameter monitoring
- Enhance Message Validation

- **[Martins Mozeiko](https://github.com/martins-mozeiko)**
- QoS new/delete fix
Expand Down
28 changes: 25 additions & 3 deletions example/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,29 @@ The `action_client/` directory contains examples of nodes that send goals to act
- Cleanup and shutdown handling
- **Run Command**: `node action_client/action-client-cancel-example.js`

#### 3. Action Client Validation (`action-client-validation-example.js`)

**Purpose**: Demonstrates goal validation features for action clients.

- **Action Type**: `action_tutorials_interfaces/action/Fibonacci`
- **Action Name**: `fibonacci`
- **Functionality**:
- Schema introspection for action goal types
- Client-level validation with `validateGoals: true` option
- Per-goal validation override with `{ validate: true/false }`
- Strict mode validation for detecting unknown fields
- Reusable goal validators with `createMessageValidator()`
- Error handling with `MessageValidationError`
- **Features**:
- **Goal Validation**: Catch invalid goals before sending to action server
- **Schema Introspection**: Use `getMessageSchema()` to inspect goal structure
- **Dynamic Toggle**: Enable/disable validation with `setValidation()`
- **Detailed Errors**: Field-level validation issues with expected vs received types
- **Strict Mode**: Detect extra fields that don't belong in the goal
- **Reusable Validators**: Create validators for repeated goal validation
- **Run Command**: `node action_client/action-client-validation-example.js`
- **Note**: Standalone example - demonstrates validation errors without requiring a running action server

### Action Server Examples

The `action_server/` directory contains examples of nodes that provide action services:
Expand Down Expand Up @@ -216,6 +239,8 @@ int32[] sequence
- **Feedback Handling**: Processing incremental updates during execution
- **Result Processing**: Handling final results and status
- **Goal Cancellation**: Canceling active goals with `cancelGoal()`
- **Goal Validation**: Pre-send validation with `validateGoals` option and `MessageValidationError`
- **Schema Introspection**: Programmatic access to action goal schemas

#### Action Server Concepts

Expand Down Expand Up @@ -260,19 +285,16 @@ All examples use ES6 classes to encapsulate action functionality:
### Common Issues

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need to revert these removed lines? @minggangw

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, by the way I noticed that these changes in the readme happens when I do npm run format

1. **Action Server Not Available**:

- Ensure action server is running before starting client
- Check that both use the same action name (`fibonacci`)
- Verify action type matches (`test_msgs/action/Fibonacci`)

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
2. **Goal Not Accepted**:

- Check server's `goalCallback` return value
- Verify goal message structure is correct
- Ensure server is properly initialized

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
3. **Missing Feedback**:

- Confirm feedback callback is properly bound
- Check server's `publishFeedback()` calls
- Verify feedback message structure
Expand Down
53 changes: 53 additions & 0 deletions example/actions/action_client/action-client-validation-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 2025 Mahmoud Alghalayini. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const rclnodejs = require('../../../index.js');

async function main() {
await rclnodejs.init();
const node = rclnodejs.createNode('action_client_validation_example_node');

const Fibonacci = rclnodejs.require(
'action_tutorials_interfaces/action/Fibonacci'
);

const actionClient = new rclnodejs.ActionClient(
node,
'action_tutorials_interfaces/action/Fibonacci',
'fibonacci',
{ validateGoals: true }
);

const validGoal = { order: 10 };
console.log(
'Valid goal:',
rclnodejs.validateMessage(validGoal, Fibonacci.Goal).valid
);

try {
await actionClient.sendGoal({ order: 'invalid' });
} catch (error) {
if (error instanceof rclnodejs.MessageValidationError) {
console.log('Caught validation error:', error.issues[0].problem);
}
}

actionClient.destroy();
node.destroy();
rclnodejs.shutdown();
}

main();
1 change: 0 additions & 1 deletion example/graph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Graph introspection allows you to:
This example creates a complete ROS 2 system with multiple nodes and then introspects the graph to display:

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
1. **Node Creation**: Creates several nodes with different communication patterns:

- `publisher_node` (namespace: `ns1`) - publishes to a topic
- `subscriber_node` (namespace: `ns1`) - subscribes to a topic
- `service_node` (namespace: `ns1`) - provides a service
Expand Down
3 changes: 0 additions & 3 deletions example/lifecycle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,19 +355,16 @@ Multiple lifecycle nodes can be coordinated using external lifecycle managers:
### Common Issues

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
1. **Publisher Not Publishing**:

- Ensure lifecycle publisher is activated in `onActivate()`
- Check that node is in active state
- Verify publisher is created in `onConfigure()`

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
2. **Timer Not Working**:

- Create timer in `onActivate()`, not `onConfigure()`
- Cancel timer in `onDeactivate()`
- Check timer interval format (BigInt nanoseconds)

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
3. **State Transition Failures**:

- Ensure callbacks return appropriate return codes
- Check for exceptions in callback implementations
- Verify resource cleanup in deactivate/shutdown
Expand Down
3 changes: 0 additions & 3 deletions example/rate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,19 +332,16 @@ while (running) {
### Common Issues

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
1. **Rate Drift**:

- Processing time exceeds rate period
- Solution: Optimize processing or reduce rate frequency
- Monitor actual vs. target frequency

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
2. **Missed Messages**:

- Rate limiting causes message drops
- Expected behavior in the example (only every 200th message processed)
- Use `ros2 topic echo` to see all messages

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes a blank line that appears to be unrelated to the message validation feature. This formatting change should not be included in this PR as it modifies content outside the scope of the PR's purpose (message validation).

Suggested change

Copilot uses AI. Check for mistakes.
3. **High CPU Usage**:

- Rate loop running too fast for processing capacity
- Solution: Reduce rate frequency or optimize processing
- Monitor system resource usage
Expand Down
24 changes: 24 additions & 0 deletions example/services/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,28 @@ ROS 2 services provide a request-response communication pattern where clients se
- **TypeScript Ready**: Full type safety with comprehensive TypeScript definitions
- **Run Command**: `node example/services/client/async-client-example.js`

#### Service Client Validation (`client/client-validation-example.js`)

**Purpose**: Demonstrates request validation features for service clients.

- **Service Type**: `example_interfaces/srv/AddTwoInts`
- **Service Name**: `add_two_ints`
- **Functionality**:
- Schema introspection for service request types
- Client-level validation with `validateRequests: true` option
- Per-request validation override with `{ validate: true/false }`
- Strict mode validation for detecting unknown fields
- Async request validation with `sendRequestAsync()`
- Error handling with `MessageValidationError`
- **Features**:
- **Request Validation**: Catch invalid requests before sending to service
- **Schema Introspection**: Use `getMessageSchema()` to inspect request structure
- **Dynamic Toggle**: Enable/disable validation with `setValidation()`
- **Detailed Errors**: Field-level validation issues with expected vs received types
- **Strict Mode**: Detect extra fields that don't belong in the request
- **Run Command**: `node example/services/client/client-validation-example.js`
- **Note**: Standalone example - demonstrates validation errors without requiring a running service

**Key API Differences**:

```javascript
Expand Down Expand Up @@ -333,6 +355,8 @@ This script automatically starts the service, tests the client, and cleans up.
- **Error Handling**: Proper error handling with try/catch blocks and specific error types (async only)
- **Timeout Management**: Built-in timeout support to prevent hanging requests (async only)
- **Request Cancellation**: AbortController support for user-cancellable operations (async only)
- **Request Validation**: Pre-send validation with `validateRequests` option and `MessageValidationError`
- **Schema Introspection**: Programmatic access to service request/response schemas
- **Resource Management**: Proper node shutdown and cleanup
- **Data Analysis**: Processing and interpreting received data
- **Visualization**: Converting data to human-readable formats
Expand Down
47 changes: 47 additions & 0 deletions example/services/client/client-validation-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2025 Mahmoud Alghalayini. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const rclnodejs = require('../../../index.js');

async function main() {
await rclnodejs.init();
const node = rclnodejs.createNode('client_validation_example_node');

const client = node.createClient(
'example_interfaces/srv/AddTwoInts',
'add_two_ints',
{ validateRequests: true }
);

const validRequest = { a: BigInt(5), b: BigInt(10) };
console.log(
'Valid request:',
rclnodejs.validateMessage(validRequest, client.typeClass.Request).valid
);

try {
client.sendRequest({ a: 'invalid', b: BigInt(10) }, () => {});
} catch (error) {
if (error instanceof rclnodejs.MessageValidationError) {
console.log('Caught validation error:', error.issues[0].problem);
}
}

node.destroy();
rclnodejs.shutdown();
}

main();
24 changes: 23 additions & 1 deletion example/topics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ The `publisher/` directory contains examples of nodes that publish messages to t
- **Run Command**: `node publisher/publisher-raw-message.js`
- **Pair**: Works with `subscription-raw-message.js`

### 7. Publisher Validation (`publisher-validation-example.js`)

**Purpose**: Demonstrates message validation features for publishers.

- **Message Type**: `std_msgs/msg/String`, `geometry_msgs/msg/Twist`
- **Topics**: Various validation test topics
- **Functionality**:
- Schema introspection with `getMessageSchema()`, `getFieldNames()`, `getFieldType()`
- Publisher-level validation with `validateMessages: true` option
- Per-publish validation override with `{ validate: true/false }`
- Strict mode validation for unknown fields
- Nested message validation (Twist with Vector3)
- Reusable validators with `createMessageValidator()`
- Error handling with `MessageValidationError`
- **Features**:
- Catch invalid messages before publishing
- Dynamic validation toggle with `setValidation()`
- Detailed error reports with field-level issues
- **Run Command**: `node publisher/publisher-validation-example.js`
- **Note**: Standalone example - no subscriber required

## Subscriber Examples

The `subscriber/` directory contains examples of nodes that subscribe to topics:
Expand Down Expand Up @@ -214,7 +235,8 @@ Several examples work together to demonstrate complete communication:
- **Service Events**: Monitoring service interactions
- **Multi-dimensional Arrays**: Complex data structures with layout information
- **Message Serialization**: TypedArray handling and JSON-safe conversion for web applications
- **Validation**: Name and topic validation utilities
- **Name Validation**: Topic names, node names, and namespace validation utilities
- **Message Validation**: Schema introspection and pre-publish message validation with detailed error reporting

## Notes

Expand Down
39 changes: 39 additions & 0 deletions example/topics/publisher/publisher-validation-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2025 Mahmoud Alghalayini. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const rclnodejs = require('../../../index.js');

rclnodejs.init().then(() => {
const node = rclnodejs.createNode('publisher_validation_example_node');

const publisher = node.createPublisher('std_msgs/msg/String', 'topic', {
validateMessages: true,
});

publisher.publish({ data: 'Hello ROS' });
console.log('Published valid message');

try {
publisher.publish({ data: 12345 });
} catch (error) {
if (error instanceof rclnodejs.MessageValidationError) {
console.log('Caught validation error:', error.issues[0].problem);
}
}

node.destroy();
rclnodejs.shutdown();
});
Loading
Loading