-
Notifications
You must be signed in to change notification settings - Fork 79
Add functions to run ros2 run/launch #1222
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -57,6 +57,7 @@ const { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| serializeMessage, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deserializeMessage, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } = require('./lib/serialization.js'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { spawn } = require('child_process'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Get the version of the generator that was used for the currently present interfaces. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -89,6 +90,79 @@ async function getCurrentGeneratorVersion() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let _rosVersionChecked = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Run a ROS2 package executable using 'ros2 run' command. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param {string} packageName - The name of the ROS2 package. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param {string} executableName - The name of the executable to run. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param {string[]} [args=[]] - Additional arguments to pass to the executable. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return {Promise<{process: ChildProcess}>} A Promise that resolves with the process. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function ros2Run(packageName, executableName, args = []) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new Promise((resolve, reject) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (typeof packageName !== 'string' || !packageName.trim()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| reject(new Error('Package name must be a non-empty string')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (typeof executableName !== 'string' || !executableName.trim()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| reject(new Error('Executable name must be a non-empty string')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!Array.isArray(args)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| reject(new Error('Arguments must be an array')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const command = 'ros2'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cmdArgs = ['run', packageName, executableName, ...args]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const childProcess = spawn(command, cmdArgs); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| childProcess.on('error', (error) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| reject(new Error(`Failed to start ros2 run: ${error.message}`)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resolve({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| process: childProcess, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| process: childProcess, | |
| childProcess.once('error', (error) => { | |
| reject(new Error(`Failed to start ros2 run: ${error.message}`)); | |
| }); | |
| childProcess.once('spawn', () => { | |
| resolve({ | |
| process: childProcess, | |
| }); |
Copilot
AI
Aug 9, 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 spawn call lacks proper validation of the command and arguments, which could lead to command injection if packageName, launchFile, or args contain shell metacharacters. Consider sanitizing inputs or using shell: false option explicitly.
| const childProcess = spawn(command, cmdArgs); | |
| const childProcess = spawn(command, cmdArgs, { shell: false }); |
Copilot
AI
Aug 9, 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 function resolves immediately after spawning the process without waiting for it to start successfully. Consider waiting for the 'spawn' event or checking if the process is running before resolving to provide better error handling.
| }); | |
| // Wait for immediate errors before resolving | |
| childProcess.once('error', (error) => { | |
| reject(new Error(`Failed to start ros2 launch: ${error.message}`)); | |
| }); | |
| setImmediate(() => { | |
| // If no error occurred, resolve | |
| resolve({ | |
| process: childProcess, | |
| }); | |
| }); |
Copilot
AI
Aug 9, 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 'spawn' event is not standard in Node.js child_process. Use 'childProcess.pid' check or a timeout to confirm successful spawn instead of relying on a non-existent event.
| }); | |
| // The 'spawn' event is not standard; instead, check for childProcess.pid | |
| if (childProcess.pid) { | |
| resolve({ | |
| process: childProcess, | |
| }); | |
| } else { | |
| // Fallback: wait a short time to see if pid is set | |
| setTimeout(() => { | |
| if (childProcess.pid) { | |
| resolve({ | |
| process: childProcess, | |
| }); | |
| } else { | |
| reject(new Error('Failed to spawn ros2 process')); | |
| } | |
| }, 50); | |
| } |
Outdated
Copilot
AI
Aug 9, 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.
[nitpick] The method is a simple wrapper around the standalone function. Consider removing the duplication by either using the standalone function directly or implementing the logic only in the object method.
| }, |
Outdated
Copilot
AI
Aug 9, 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.
[nitpick] The method is a simple wrapper around the standalone function. Consider removing the duplication by either using the standalone function directly or implementing the logic only in the object method.
| }, | |
| ros2Launch: ros2Launch, |
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 spawn call lacks proper validation of the command and arguments, which could lead to command injection if packageName, executableName, or args contain shell metacharacters. Consider sanitizing inputs or using shell: false option explicitly.