Skip to content

Commit

Permalink
Dev/lamadio/ros2 improvements (#499)
Browse files Browse the repository at this point in the history
* Several ROS2 improvements

* Update Readme
  • Loading branch information
ooeygui authored Jul 14, 2021
1 parent 7d43d12 commit ad5823c
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 76 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ node_modules
# vscode-test
.vscode-test
.vscode/c_cpp_properties.json
.vscode/settings.json
.vscode/settings.json

vscode-ros-dev.vsix
67 changes: 28 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,13 @@
# Visual Studio Code Extension for ROS

The [Visual Studio Code][vscode] Extension for ROS provides support for [Robot Operating System (ROS)][ros] development. Providing an easier and more stream-lined developer experience.
The [Visual Studio Code][vscode] Extension for ROS provides support for [Robot Operating System (ROS)][ros] development for ROS1 and ROS2 on Windows and Linux.

## Getting Started

The extension will automatically start when you open a `catkin` or `colcon` workspace.
The build system (e.g. catkin_make or catkin build) will automatically be confirmed from the hidden files associated with
each system.
The ROS distro will automatically be confirmed from the parent environment, or you will be prompted to select a ROS
distro if this can't be done automatically.

> NOTE: You must build the catkin workspace at least once before the extension will recognise it.
To start ROS core, you can use the `ROS: Start Core` command from the [Visual Studio Code command pallet](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette). This command pallet can be accessed by pressing `ctrl` + `shift` + `p`.
The `ROS Core` indicator in the bottom left will show if the core is currently running, and you can click on this taskbar item to view the status of ROS.

The first time you open a ROS workspace the extension will automatically create build and test tasks and update the
C++ and Python paths. You can re-run this process later using the appropriate commands.

## Video Walkthrough

[![ROSCON 2019 ROS Extension Talk Video](https://i.vimeocdn.com/video/839088609_640.webp)](https://vimeopro.com/osrfoundation/roscon-2019/video/379127667)

## Features

* Automatic ROS environment configuration.
* Allows starting, stopping and viewing the ROS core status.
* Automatically discover `catkin_make` or `catkin build` build tasks.
* Automatically create `catkin_make` or `catkin build` build tasks.
* Create catkin packages using `catkin_create_pkg` script or `catkin create pkg`.
* Run `rosrun` or `roslaunch`
* Resolve dependencies with `rosdep` shortcut
Expand All @@ -38,34 +19,42 @@ C++ and Python paths. You can re-run this process later using the appropriate co
* Debug ROS nodes (C++ or Python) [launched from a `.launch` file][debug_support-launch].

## Commands
You can access the following commands from the [Visual Studio Code command pallet](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).

You can access the following commands from the [Visual Studio Code command pallet](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette), typically accessed by pressing `ctrl` + `shift` + `p` and typing the command name you'd like to use from the table below.

| Name | Description |
|---|:---|
| ROS: Create Catkin Package | Create a catkin package. You can right click on a folder in the explorer to create it in a specific location. |
| ROS: Create Terminal | Create a terminal with the ROS environment. |
| ROS: Show Core Status | Open a detail view showing ROS core runtime status. |
| ROS: Start Core | Start ROS core. |
| ROS: Stop Core | Terminate ROS core. |
| ROS: Update C++ Properties | Update the C++ include path to include ROS. |
| ROS: Update Python Path | Update the Python path to include ROS. |
| ROS: Preview URDF | Preview URDF and Xacro files. Updates after changes are saved. |
| ROS: Show Status | Open a detail view showing ROS core runtime status. |
| ROS: Start | Start ROS1 core or ROS2 Daemon. |
| ROS: Stop | Terminate ROS core or ROS2 Daemon. |
| ROS: Update C++ Properties | Update the C++ IntelliSense configuration to include ROS and your ROS components. |
| ROS: Update Python Path | Update the Python IntelliSense configuration to include ROS. |
| ROS: Preview URDF | Preview URDF and Xacro files. The display will update after the root URDF changes are saved. |
| ROS: Install ROS Dependencies for this workspace using rosdep | Shortcut for `rosdep install --from-paths src --ignore-src -r -y`. |

## Launch Debugging
The Visual Studio Code extension for ROS supports launch debugging for ROS 1 and ROS 2 nodes. The VSCode extension currently supports debugging ROS written in Python and C++. The ROS node or nodes to be debugged must be placed in a ROS launch file with the extension `.launch` for ROS1 or ROS2 or with the extension `.py` for ROS2.
## Tutorials and Walkthroughs

To debug a C++ ROS node, please build your workspace using `RelWithDebInfo` in order to generate debug symbols needed for the C++ debugger:
| Name | Description |
|---|:---|
| [Attaching to a running ROS Node][debug_support-attach] | Learn how to attach VSCode to a running ROS node |
| [Debugging all ROS Nodes in a launch file ][debug_support-launch] | Learn how to set up VSCode to debug the nodes in a ROS Launch file |
| [ROSCON 2019 ROS Extension Talk Video](https://vimeopro.com/osrfoundation/roscon-2019/video/379127667) | Walkthrough of VSCode from ROSCon 2019|


## Getting Started

The VSCode ROS extension will attempt to detect and automatically configure the workspace for the appropriate ROS Distro.

The extension will automatically start when you open a `catkin` or `colcon` workspace.
The build system (e.g. catkin_make or catkin build) will automatically be confirmed from the hidden files associated with
each system.

**ROS1**
```bash
catkin_make -DCMAKE_BUILD_TYPE=RelWithDebInfo
```

**ROS2**
```bash
colcon build --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo
```
## Launch Debugging

The Visual Studio Code extension for ROS supports launch debugging for ROS 1 and ROS 2 nodes. The VSCode extension currently supports debugging ROS written in Python and C++. The ROS node or nodes to be debugged must be placed in a ROS launch file with the extension `.launch` for ROS1 or ROS2 or with the extension `.py` for ROS2.

## Reporting Security Issues

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@
},
{
"command": "ros.showCoreStatus",
"title": "Show Core Status",
"title": "Show Status",
"category": "ROS"
},
{
"command": "ros.startCore",
"title": "Start Core",
"title": "Start",
"category": "ROS"
},
{
"command": "ros.stopCore",
"title": "Stop Core",
"title": "Stop",
"category": "ROS"
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/build-tool/colcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as common from "./common";
import * as rosShell from "./ros-shell";

function makeColcon(command: string, verb: string, args: string[], category?: string): vscode.Task {
const task = rosShell.make({type: command, command, args: [verb, '--base-paths', extension.baseDir, ...args]},
const task = rosShell.make({type: command, command, args: [verb, '--base-paths', extension.baseDir, `--cmake-args`, `-DCMAKE_BUILD_TYPE=RelWithDebInfo`,...args]},
category)

return task;
Expand Down
46 changes: 18 additions & 28 deletions src/debugger/configuration/resolvers/ros1/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,38 +37,28 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {

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
if (await rosApi.getCoreStatus() == false) {
console.log("ROS Core is not active, attempting to start automatically");
rosApi.startCore();

// Wait for the core to start up to a timeout
const timeout_ms: number = 30000;
const interval_ms: number = 100;
let timeWaited: number = 0;
while (await rosApi.getCoreStatus() == false &&
timeWaited < timeout_ms) {
timeWaited += interval_ms;
await delay(interval_ms);
}

console.log("Waited " + timeWaited + " for ROS Core to start");
// 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
if (await rosApi.getCoreStatus() == false) {
console.log("ROS Core is not active, attempting to start automatically");
rosApi.startCore();

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

console.log("Waited " + timeWaited + " for ROS Core to start");

if (timeWaited >= timeout_ms) {
throw new Error('Timed out (' + timeWaited / 1000 + ' seconds) waiting for ROS Core to start. Start ROSCore manually to avoid this error.');
}
}


const rosExecOptions: child_process.ExecOptions = {
env: await extension.resolvedEnv(),
Expand Down
27 changes: 26 additions & 1 deletion src/debugger/configuration/resolvers/ros2/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ 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";

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

Expand All @@ -40,6 +41,30 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {
throw new Error("Launch request requires an extension '.py' or '.xml' as target.");
}

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

// Manage the status of the ROS2 Daemon, starting one if not present
if (await rosApi.getCoreStatus() == false) {
console.log("ROS Daemon is not active, attempting to start automatically");
rosApi.startCore();

// Wait for the core to start up to a timeout
const timeout_ms: number = 30000;
const interval_ms: number = 100;
let timeWaited: number = 0;
while (await rosApi.getCoreStatus() == false &&
timeWaited < timeout_ms) {
timeWaited += interval_ms;
await delay(interval_ms);
}

console.log("Waited " + timeWaited + " for ROS2 Daemon to start");

if (timeWaited >= timeout_ms) {
throw new Error('Timed out (' + timeWaited / 1000 + ' seconds) waiting for ROS2 Daemon to start. Start ROS2 Daemon manually to avoid this error.');
}
}

const rosExecOptions: child_process.ExecOptions = {
env: {
...await extension.resolvedEnv(),
Expand Down Expand Up @@ -144,7 +169,7 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {
args: request.arguments,
environment: envConfigs,
stopAtEntry: stopOnEntry,
};
};
debugConfig = cppvsdbgLaunchConfig;
}

Expand Down
6 changes: 6 additions & 0 deletions src/ros/ros2/ros2-monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ export class XmlRpcApi {
this.client = xmlrpc.createClient(getDaemonUri());
}

public check() : Promise<boolean> {
// the ROS2 CLI doesn't have an API which returns detailed status,
// so we're just using another endpoint to verify it is running
return this.methodCall("get_node_names_and_namespaces").then(() => true, () => false);
}

public getNodeNamesAndNamespaces() : Promise<any> {
return this.methodCall("get_node_names_and_namespaces");
}
Expand Down
6 changes: 3 additions & 3 deletions src/ros/ros2/ros2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ export class ROS2 implements ros.ROSApi {
daemon.stopDaemon();
}

public getCoreStatus(): Promise<boolean> {
// TODO(#431): Core status checking not implemented for ROS2
return;
public async getCoreStatus(): Promise<boolean> {
const ros2cliApi = new ros2_monitor.XmlRpcApi();
return ros2cliApi.check();
}

public rosdep(): vscode.Terminal {
Expand Down

0 comments on commit ad5823c

Please sign in to comment.