-
Notifications
You must be signed in to change notification settings - Fork 79
Add tutorial for type description service #1268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a comprehensive tutorial for the Type Description Service feature in rclnodejs. The tutorial provides detailed documentation on how to use the built-in ROS 2 introspection service that allows querying message and service type information from running nodes.
Key changes:
- Complete tutorial covering Type Description Service functionality, requirements, and usage patterns
- Multiple practical examples demonstrating basic usage, advanced features, and best practices
- Comprehensive troubleshooting guide and performance considerations
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| } | ||
|
|
||
| async discoverNodeTypes(nodeName) { | ||
| console.log(`\\nDiscovering types for node: ${nodeName}`); |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline character should be a literal newline. Replace \\n with \n.
| console.log(`\\nDiscovering types for node: ${nodeName}`); | |
| console.log(`\nDiscovering types for node: ${nodeName}`); |
| processTypeDescription(typeName, response) { | ||
| const typeDesc = response.type_description.type_description; | ||
|
|
||
| console.log(`\\n=== Type: ${typeName} ===`); |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline character should be a literal newline. Replace \\n with \n.
| console.log(`\\n=== Type: ${typeName} ===`); | |
| console.log(`\n=== Type: ${typeName} ===`); |
| } | ||
|
|
||
| printSummary() { | ||
| console.log(`\\n=== Discovery Summary ===`); |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline character should be a literal newline. Replace \\n with \n.
| console.log(`\\n=== Discovery Summary ===`); | |
| console.log(`\n=== Discovery Summary ===`); |
| let markdown = `# Type Documentation for Node: ${nodeName}\\n\\n`; | ||
| markdown += `Generated on: ${new Date().toISOString()}\\n\\n`; | ||
|
|
||
| this.documentation.forEach((doc) => { | ||
| markdown += `## ${doc.typeName}\\n\\n`; | ||
| markdown += `**Topic**: \`${doc.topicName}\`\\n\\n`; | ||
|
|
||
| if (doc.description.fields.length > 0) { | ||
| markdown += `### Fields\\n\\n`; | ||
| markdown += `| Field Name | Type | Default Value |\\n`; | ||
| markdown += `|------------|------|---------------|\\n`; | ||
|
|
||
| doc.description.fields.forEach((field) => { | ||
| const typeStr = this.formatFieldTypeForDoc(field.type); | ||
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\\n`; | ||
| }); | ||
| markdown += `\\n`; | ||
| } | ||
|
|
||
| if (doc.sources.length > 0) { | ||
| markdown += `### Source Definition\\n\\n`; | ||
| markdown += `\`\`\`${doc.sources[0].encoding}\\n`; | ||
| markdown += doc.sources[0].raw_file_contents; | ||
| markdown += `\`\`\`\\n\\n`; | ||
| } | ||
|
|
||
| markdown += `---\\n\\n`; |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline characters should be literal newlines. Replace \\n with \n.
| let markdown = `# Type Documentation for Node: ${nodeName}\\n\\n`; | |
| markdown += `Generated on: ${new Date().toISOString()}\\n\\n`; | |
| this.documentation.forEach((doc) => { | |
| markdown += `## ${doc.typeName}\\n\\n`; | |
| markdown += `**Topic**: \`${doc.topicName}\`\\n\\n`; | |
| if (doc.description.fields.length > 0) { | |
| markdown += `### Fields\\n\\n`; | |
| markdown += `| Field Name | Type | Default Value |\\n`; | |
| markdown += `|------------|------|---------------|\\n`; | |
| doc.description.fields.forEach((field) => { | |
| const typeStr = this.formatFieldTypeForDoc(field.type); | |
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\\n`; | |
| }); | |
| markdown += `\\n`; | |
| } | |
| if (doc.sources.length > 0) { | |
| markdown += `### Source Definition\\n\\n`; | |
| markdown += `\`\`\`${doc.sources[0].encoding}\\n`; | |
| markdown += doc.sources[0].raw_file_contents; | |
| markdown += `\`\`\`\\n\\n`; | |
| } | |
| markdown += `---\\n\\n`; | |
| let markdown = `# Type Documentation for Node: ${nodeName}\n\n`; | |
| markdown += `Generated on: ${new Date().toISOString()}\n\n`; | |
| this.documentation.forEach((doc) => { | |
| markdown += `## ${doc.typeName}\n\n`; | |
| markdown += `**Topic**: \`${doc.topicName}\`\n\n`; | |
| if (doc.description.fields.length > 0) { | |
| markdown += `### Fields\n\n`; | |
| markdown += `| Field Name | Type | Default Value |\n`; | |
| markdown += `|------------|------|---------------|\n`; | |
| doc.description.fields.forEach((field) => { | |
| const typeStr = this.formatFieldTypeForDoc(field.type); | |
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\n`; | |
| }); | |
| markdown += `\n`; | |
| } | |
| if (doc.sources.length > 0) { | |
| markdown += `### Source Definition\n\n`; | |
| markdown += `\`\`\`${doc.sources[0].encoding}\n`; | |
| markdown += doc.sources[0].raw_file_contents; | |
| markdown += `\`\`\`\n\n`; | |
| } | |
| markdown += `---\n\n`; |
| let markdown = `# Type Documentation for Node: ${nodeName}\\n\\n`; | ||
| markdown += `Generated on: ${new Date().toISOString()}\\n\\n`; | ||
|
|
||
| this.documentation.forEach((doc) => { | ||
| markdown += `## ${doc.typeName}\\n\\n`; | ||
| markdown += `**Topic**: \`${doc.topicName}\`\\n\\n`; | ||
|
|
||
| if (doc.description.fields.length > 0) { | ||
| markdown += `### Fields\\n\\n`; | ||
| markdown += `| Field Name | Type | Default Value |\\n`; | ||
| markdown += `|------------|------|---------------|\\n`; | ||
|
|
||
| doc.description.fields.forEach((field) => { | ||
| const typeStr = this.formatFieldTypeForDoc(field.type); | ||
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\\n`; | ||
| }); | ||
| markdown += `\\n`; | ||
| } | ||
|
|
||
| if (doc.sources.length > 0) { | ||
| markdown += `### Source Definition\\n\\n`; | ||
| markdown += `\`\`\`${doc.sources[0].encoding}\\n`; | ||
| markdown += doc.sources[0].raw_file_contents; | ||
| markdown += `\`\`\`\\n\\n`; | ||
| } | ||
|
|
||
| markdown += `---\\n\\n`; |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline characters should be literal newlines. Replace \\n with \n.
| let markdown = `# Type Documentation for Node: ${nodeName}\\n\\n`; | |
| markdown += `Generated on: ${new Date().toISOString()}\\n\\n`; | |
| this.documentation.forEach((doc) => { | |
| markdown += `## ${doc.typeName}\\n\\n`; | |
| markdown += `**Topic**: \`${doc.topicName}\`\\n\\n`; | |
| if (doc.description.fields.length > 0) { | |
| markdown += `### Fields\\n\\n`; | |
| markdown += `| Field Name | Type | Default Value |\\n`; | |
| markdown += `|------------|------|---------------|\\n`; | |
| doc.description.fields.forEach((field) => { | |
| const typeStr = this.formatFieldTypeForDoc(field.type); | |
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\\n`; | |
| }); | |
| markdown += `\\n`; | |
| } | |
| if (doc.sources.length > 0) { | |
| markdown += `### Source Definition\\n\\n`; | |
| markdown += `\`\`\`${doc.sources[0].encoding}\\n`; | |
| markdown += doc.sources[0].raw_file_contents; | |
| markdown += `\`\`\`\\n\\n`; | |
| } | |
| markdown += `---\\n\\n`; | |
| let markdown = `# Type Documentation for Node: ${nodeName}\n\n`; | |
| markdown += `Generated on: ${new Date().toISOString()}\n\n`; | |
| this.documentation.forEach((doc) => { | |
| markdown += `## ${doc.typeName}\n\n`; | |
| markdown += `**Topic**: \`${doc.topicName}\`\n\n`; | |
| if (doc.description.fields.length > 0) { | |
| markdown += `### Fields\n\n`; | |
| markdown += `| Field Name | Type | Default Value |\n`; | |
| markdown += `|------------|------|---------------|\n`; | |
| doc.description.fields.forEach((field) => { | |
| const typeStr = this.formatFieldTypeForDoc(field.type); | |
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\n`; | |
| }); | |
| markdown += `\n`; | |
| } | |
| if (doc.sources.length > 0) { | |
| markdown += `### Source Definition\n\n`; | |
| markdown += `\`\`\`${doc.sources[0].encoding}\n`; | |
| markdown += doc.sources[0].raw_file_contents; | |
| markdown += `\`\`\`\n\n`; | |
| } | |
| markdown += `---\n\n`; |
| markdown += `### Source Definition\\n\\n`; | ||
| markdown += `\`\`\`${doc.sources[0].encoding}\\n`; | ||
| markdown += doc.sources[0].raw_file_contents; | ||
| markdown += `\`\`\`\\n\\n`; |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline characters should be literal newlines. Replace \\n with \n.
| markdown += `\`\`\`\\n\\n`; | |
| markdown += `\`\`\`\n\n`; |
| let markdown = `# Type Documentation for Node: ${nodeName}\\n\\n`; | ||
| markdown += `Generated on: ${new Date().toISOString()}\\n\\n`; | ||
|
|
||
| this.documentation.forEach((doc) => { | ||
| markdown += `## ${doc.typeName}\\n\\n`; | ||
| markdown += `**Topic**: \`${doc.topicName}\`\\n\\n`; | ||
|
|
||
| if (doc.description.fields.length > 0) { | ||
| markdown += `### Fields\\n\\n`; | ||
| markdown += `| Field Name | Type | Default Value |\\n`; | ||
| markdown += `|------------|------|---------------|\\n`; | ||
|
|
||
| doc.description.fields.forEach((field) => { | ||
| const typeStr = this.formatFieldTypeForDoc(field.type); | ||
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\\n`; | ||
| }); | ||
| markdown += `\\n`; | ||
| } | ||
|
|
||
| if (doc.sources.length > 0) { | ||
| markdown += `### Source Definition\\n\\n`; | ||
| markdown += `\`\`\`${doc.sources[0].encoding}\\n`; | ||
| markdown += doc.sources[0].raw_file_contents; | ||
| markdown += `\`\`\`\\n\\n`; | ||
| } | ||
|
|
||
| markdown += `---\\n\\n`; |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline characters should be literal newlines. Replace \\n with \n.
| let markdown = `# Type Documentation for Node: ${nodeName}\\n\\n`; | |
| markdown += `Generated on: ${new Date().toISOString()}\\n\\n`; | |
| this.documentation.forEach((doc) => { | |
| markdown += `## ${doc.typeName}\\n\\n`; | |
| markdown += `**Topic**: \`${doc.topicName}\`\\n\\n`; | |
| if (doc.description.fields.length > 0) { | |
| markdown += `### Fields\\n\\n`; | |
| markdown += `| Field Name | Type | Default Value |\\n`; | |
| markdown += `|------------|------|---------------|\\n`; | |
| doc.description.fields.forEach((field) => { | |
| const typeStr = this.formatFieldTypeForDoc(field.type); | |
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` |\\n`; | |
| }); | |
| markdown += `\\n`; | |
| } | |
| if (doc.sources.length > 0) { | |
| markdown += `### Source Definition\\n\\n`; | |
| markdown += `\`\`\`${doc.sources[0].encoding}\\n`; | |
| markdown += doc.sources[0].raw_file_contents; | |
| markdown += `\`\`\`\\n\\n`; | |
| } | |
| markdown += `---\\n\\n`; | |
| let markdown = `# Type Documentation for Node: ${nodeName} | |
| `; | |
| markdown += `Generated on: ${new Date().toISOString()} | |
| `; | |
| this.documentation.forEach((doc) => { | |
| markdown += `## ${doc.typeName} | |
| `; | |
| markdown += `**Topic**: \`${doc.topicName}\` | |
| `; | |
| if (doc.description.fields.length > 0) { | |
| markdown += `### Fields | |
| `; | |
| markdown += `| Field Name | Type | Default Value | | |
| `; | |
| markdown += `|------------|------|---------------| | |
| `; | |
| doc.description.fields.forEach((field) => { | |
| const typeStr = this.formatFieldTypeForDoc(field.type); | |
| markdown += `| \`${field.name}\` | ${typeStr} | \`${field.default_value || 'N/A'}\` | | |
| `; | |
| }); | |
| markdown += ` | |
| `; | |
| } | |
| if (doc.sources.length > 0) { | |
| markdown += `### Source Definition | |
| `; | |
| markdown += `\`\`\`${doc.sources[0].encoding} | |
| `; | |
| markdown += doc.sources[0].raw_file_contents; | |
| markdown += `\`\`\` | |
| `; | |
| } | |
| markdown += `--- | |
| `; |
| console.log('\\n=== Type Hierarchy ==='); | ||
| this.typeHierarchy.forEach((typeInfo, typeName) => { | ||
| console.log(`\\n${typeName}:`); |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline character should be a literal newline. Replace \\n with \n.
| console.log('\\n=== Type Hierarchy ==='); | |
| this.typeHierarchy.forEach((typeInfo, typeName) => { | |
| console.log(`\\n${typeName}:`); | |
| console.log('\n=== Type Hierarchy ==='); | |
| this.typeHierarchy.forEach((typeInfo, typeName) => { | |
| console.log(`\n${typeName}:`); |
| console.log('\\n=== Type Hierarchy ==='); | ||
| this.typeHierarchy.forEach((typeInfo, typeName) => { | ||
| console.log(`\\n${typeName}:`); |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline character should be a literal newline. Replace \\n with \n.
| console.log('\\n=== Type Hierarchy ==='); | |
| this.typeHierarchy.forEach((typeInfo, typeName) => { | |
| console.log(`\\n${typeName}:`); | |
| console.log('\n=== Type Hierarchy ==='); | |
| this.typeHierarchy.forEach((typeInfo, typeName) => { | |
| console.log(`\n${typeName}:`); |
| const minTime = Math.min(...this.queryTimes); | ||
| const maxTime = Math.max(...this.queryTimes); | ||
|
|
||
| console.log('\\n=== Performance Results ==='); |
Copilot
AI
Sep 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escaped newline character should be a literal newline. Replace \\n with \n.
| console.log('\\n=== Performance Results ==='); | |
| console.log('\n=== Performance Results ==='); |
This PR adds a comprehensive tutorial for the Type Description Service feature in rclnodejs. The tutorial provides detailed documentation on how to use the built-in ROS 2 introspection service that allows querying message and service type information from running nodes. Key changes: - Complete tutorial covering Type Description Service functionality, requirements, and usage patterns - Multiple practical examples demonstrating basic usage, advanced features, and best practices - Comprehensive troubleshooting guide and performance considerations Fix: #1267
This PR adds a comprehensive tutorial for the Type Description Service feature in rclnodejs. The tutorial provides detailed documentation on how to use the built-in ROS 2 introspection service that allows querying message and service type information from running nodes.
Key changes:
Fix: #1267