Skip to content
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

Start ROSCore for launch debugging, if not running (ROS1) #429

Merged
merged 8 commits into from
Jun 7, 2021
33 changes: 33 additions & 0 deletions src/debugger/configuration/resolvers/ros1/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import * as vscode from "vscode";
import * as extension from "../../../../extension";
import * as requests from "../../../requests";
import * as utils from "../../../utils";
import { rosApi } from "../../../../ros/ros";
import { env } from "../../../../extension";

const promisifiedExec = util.promisify(child_process.exec);

Expand All @@ -32,7 +34,38 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {
if (!path.isAbsolute(config.target) || path.extname(config.target) !== ".launch") {
throw new Error("Launch request requires an absolute path as target.");
}

const delay = ms => new Promise(res => setTimeout(res, ms));

switch (env.ROS_VERSION.trim()) {
case "1": {
// Manage the status of the ROS core, starting one if not present
// The ROS core will continue to run until the VSCode window is closed
const core_active = rosApi.getCoreStatus();
if (!(await core_active).valueOf()) {
rosApi.startCore();

// Wait for the core to start up to a timeout
const timeout_ms: number = 3000;
const interval_ms: number = 100;
let attempts: number = 0;
while (!(await rosApi.getCoreStatus()).valueOf() && attempts * interval_ms < timeout_ms) {
attempts += 1;
await delay(interval_ms);
}
if (attempts * interval_ms >= timeout_ms) {
throw (new Error('Timed out waiting for ROSCore to start. Start ROSCore manually to avoid this error.'));
}
}
break;
}
case "2": {
// TODO(#431), support starting the ROS2 daemon automatically
break;
}
}


const rosExecOptions: child_process.ExecOptions = {
env: await extension.resolvedEnv(),
};
Expand Down
5 changes: 5 additions & 0 deletions src/ros/common/unknown-ros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export class UnknownROS implements ros.ROSApi {
return;
}

public getCoreStatus(): Promise<boolean> {
console.error("Unknown ROS distro.");
return;
}

public rosdep() {
console.error("Unknown ROS distro.");
return;
Expand Down
5 changes: 5 additions & 0 deletions src/ros/ros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ export interface ROSApi {
*/
stopCore: () => void;

/**
* Get ROS Core status
*/
getCoreStatus: () => Promise<boolean>;

/**
* Run ROSDep
*/
Expand Down
4 changes: 4 additions & 0 deletions src/ros/ros1/ros1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ export class ROS1 implements ros.ROSApi {
ros_core.stopCore(this.context, this._getXmlRpcApi());
}

public getCoreStatus(): Promise<boolean> {
return this._getXmlRpcApi().check();
}

public activateCoreMonitor(): vscode.Disposable {
if (typeof this.env.ROS_MASTER_URI === "undefined") {
return null;
Expand Down
5 changes: 5 additions & 0 deletions src/ros/ros2/ros2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ export class ROS2 implements ros.ROSApi {
daemon.stopDaemon();
}

public getCoreStatus(): Promise<boolean> {
// TODO(#431): Core status checking not implemented for ROS2
return;
}

public rosdep(): vscode.Terminal {
const terminal = ros_utils.createTerminal(this.context);
terminal.sendText(`rosdep install --from-paths src --ignore-src -r -y`);
Expand Down