Skip to content

Tutorial to configure vscode for ros2 cpp build and debugging. #217

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

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Update configure_vscode_for_ros2.md
  • Loading branch information
N7-Kitrak authored May 4, 2025
commit 7f7e99b816447299a00470ac4f202ac5e79c867c
286 changes: 157 additions & 129 deletions wiki/common-platforms/configure_vscode_for_ros2.md
Original file line number Diff line number Diff line change
@@ -1,177 +1,205 @@
# Debugging and Building ROS 2 Packages in Visual Studio Code
@@ -1,106 +1,127 @@
# Debugging and Compiling ROS 2 Packages in Visual Studio Code

This tutorial covers how to configure Visual Studio Code (VS Code) for building and debugging ROS 2 packages using C++. It assumes that you already have both ROS 2 (e.g., Humble) and VS Code installed and set up properly.
This tutorial explains how to set up **Visual Studio Code** for building and debugging ROS 2 packages effectively.

---
# Jekyll 'Front Matter' goes here. Most are set by default, and should NOT be
# overwritten except in special circumstances.
# You should set the date the article was last updated like this:
date: 2020-05-11 # YYYY-MM-DD
# This will be displayed at the bottom of the article
# You should set the article's title:
title: Title goes here
# The 'title' is automatically displayed at the top of the page
# and used in other parts of the site.
---
This template acts as a tutorial on writing articles for the Robotics Knowledgebase. In it we will cover article structure, basic syntax, and other useful hints. Every tutorial and article should start with a proper introduction.

## 1. Background: Why Debugging Matters
This goes above the first subheading. The first 100 words are used as an excerpt on the Wiki's Index. No images, HTML, or special formating should be used in this section as it won't be displayed properly.
## 🧱 1. Preparing for Debugging

Sometimes your C++ ROS 2 code compiles successfully, but fails during runtime—perhaps with a segmentation fault and little information to guide you. To address such issues effectively, it's essential to:
Imagine this scenario: You comment out a line that creates a publisher in your ROS 2 C++ node. The code compiles fine, but running the node gives a **segmentation fault**, with no helpful error message.

* Enable debug symbol generation during compilation.
* Use a debugger like GDB.
* Connect VS Code to GDB for a visual debugging experience.
To debug such issues, we'll configure **GDB debugging** inside VS Code.

If you're writing a tutorial, use this section to specify what the reader will be able to accomplish and the tools you will be using. If you're writing an article, this section should be used to encapsulate the topic covered. Use Wikipedia for inspiration on how to write a proper introduction to a topic.
---

## 2. Example ROS 2 Publisher Code

We'll use a basic publisher node in C++ as our example.

```cpp
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

class MinimalPublisher : public rclcpp::Node {
public:
MinimalPublisher() : Node("minimal_publisher") {
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
timer_ = this->create_wall_timer(
std::chrono::milliseconds(500),
[this]() {
auto message = std_msgs::msg::String();
message.data = "Hello, world!";
publisher_->publish(message);
}
);
}

private:
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char *argv[]) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalPublisher>());
rclcpp::shutdown();
return 0;
}
```
In both cases, tell them what you're going to say, use the sections below to say it, then summarize at the end (with suggestions for further study).
## 🧰 2. Install GDB Server (If Needed)

---

## 3. Compiling with Debug Symbols

To generate debugging symbols, compile your workspace using the following command:
## First subheading
Use this section to cover important terms and information useful to completing the tutorial or understanding the topic addressed. Don't be afraid to include to other wiki entries that would be useful for what you intend to cover. Notice that there are two \#'s used for subheadings; that's the minimum. Each additional sublevel will have an added \#. It's strongly recommended that you create and work from an outline.
Ensure `gdbserver` is installed:

This section covers the basic syntax and some rules of thumb for writing.
```bash
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo
sudo apt update
sudo apt install gdbserver
```

You can automate this with VS Code using the `tasks.json` setup below.

### Basic syntax
A line in between create a separate paragraph. *This is italicized.* **This is bold.** Here is [a link](/). If you want to display the URL, you can do it like this <http://ri.cmu.edu/>.
---

## 4. Setting Up `tasks.json`

Create a file named `.vscode/tasks.json` in the root of your workspace:

```json
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "source /opt/ros/humble/setup.bash && colcon build --symlink-install"
},
{
"label": "debug",
"type": "shell",
"command": "echo -e '\n\nRun the node using the following prefix: \n ros2 run --prefix 'gdbserver localhost:3000' <package_name> <executable_name> \n\nAnd modify the executable path in .vscode/launch.json file \n' && source /opt/ros/humble/setup.bash && colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo"
},
{
"label": "test",
"type": "shell",
"command": "colcon test && colcon test-result"
}
]
}
> This is a note. Use it to reinforce important points, especially potential show stoppers for your readers. It is also appropriate to use for long quotes from other texts.
## ⚙️ 3. Running a Node with GDB Server

Use this command to run a ROS 2 node with GDB server:

#### Bullet points and numbered lists
Here are some hints on writing (in no particular order):
- Focus on application knowledge.
- Write tutorials to achieve a specific outcome.
- Relay theory in an intuitive way (especially if you initially struggled).
- It is likely that others are confused in the same way you were. They will benefit from your perspective.
- You do not need to be an expert to produce useful content.
- Document procedures as you learn them. You or others may refine them later.
- Use a professional tone.
- Be non-partisan.
- Characterize technology and practices in a way that assists the reader to make intelligent decisions.
- When in doubt, use the SVOR (Strengths, Vulnerabilities, Opportunities, and Risks) framework.
- Personal opinions have no place in the Wiki. Do not use "I." Only use "we" when referring to the contributors and editors of the Robotics Knowledgebase. You may "you" when giving instructions in tutorials.
- Use American English (for now).
- We made add support for other languages in the future.
- The Robotics Knowledgebase is still evolving. We are using Jekyll and GitHub Pages in and a novel way and are always looking for contributors' input.
```bash
ros2 run --prefix 'gdbserver localhost:3000' <package_name> <executable_name>
```

Entries in the Wiki should follow this format:
1. Excerpt introducing the entry's contents.
- Be sure to specify if it is a tutorial or an article.
- Remember that the first 100 words get used else where. A well written excerpt ensures that your entry gets read.
2. The content of your entry.
3. Summary.
4. See Also Links (relevant articles in the Wiki).
5. Further Reading (relevant articles on other sites).
6. References.
Replace `<package_name>` and `<executable_name>` with your specific values.

#### Code snippets
There's also a lot of support for displaying code. You can do it inline like `this`. You should also use the inline code syntax for `filenames` and `ROS_node_names`.
---

## 5. Setting Up `launch.json`
Larger chunks of code should use this format:
## 🐞 4. Configure the Debugger in VS Code

To attach VS Code's debugger to a ROS 2 node, configure `.vscode/launch.json` like this:
Create or edit the file `.vscode/launch.json`:

```json
{
"version": "0.2.0",
"configurations": [
{
"name": "C++ Debugger",
"request": "launch",
"type": "cppdbg",
"miDebuggerServerAddress": "localhost:3000",
"cwd": "/",
"program": "/home/$USER/Workspaces/ros2_cpp_ws/install/udemy_ros2_pkg/lib/udemy_ros2_pkg/service_client"
}
]
"version": "0.2.0",
"configurations": [
{
"name": "C++ Debugger",
"request": "launch",
"type": "cppdbg",
"miDebuggerServerAddress": "localhost:3000",
"cwd": "/",
"program": "/home/$USER/Workspaces/ros2_cpp_ws/install/udemy_ros2_pkg/lib/udemy_ros2_pkg/service_client"
}
]
}
```
def recover_msg(msg):

Replace the `program` path with the absolute path to your ROS 2 node executable.

---

## 6. Running the Debugger
// Good coders comment their code for others.
> 📝 Replace the `program` path with your actual executable path inside `install/`.

### Step-by-step:
pw = ProtocolWrapper()
Now press `F5` to launch the debugger and catch segmentation faults right where they happen.

1. Build your workspace using:
// Explanation.
---

```bash
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo
```
2. Run your node under GDB server:
## 🔄 5. Use `--symlink-install` for Faster Builds

```bash
ros2 run --prefix 'gdbserver localhost:3000' <package_name> <executable_name>
```
3. In VS Code, press `F5` or go to `Run > Start Debugging`.
4. VS Code will connect to the GDB server and break at the error location if there is a crash.
By default, `colcon build` copies files from `build/` to `install/`. You can make builds faster by creating symbolic links:

---

## 7. Using the VS Code ROS Extension
if rec_crc != calc_crc:
return None
```bash
colcon build --symlink-install
```
This would be a good spot further explain you code snippet. Break it down for the user so they understand what is going on.

VS Code’s ROS extension adds convenience:
#### LaTex Math Support
Here is an example MathJax inline rendering $ \phi(x\|y) $ (note the additional escape for using \|), and here is a block rendering:
$$ \frac{1}{n^{2}} $$
To switch to this method, first clean your workspace:

* `ROS: Show Status` – View running nodes and topics.
* `ROS: Create Terminal` – Opens a sourced terminal.
* `ROS: Run ROS Command` – Run nodes from a graphical menu.
#### Images and Video
Images and embedded video are supported.
```bash
rm -rf build/ install/ log/
colcon build --symlink-install
```

Access these via the command palette (`F1`) and typing `ROS`.
![Put a relevant caption here](assets/images/Hk47portrait-298x300.jpg)
This is especially helpful when you're making small changes to files like `package.xml`, launch files, or interface definitions.

{% include video id="8P9geWwi9e0" provider="youtube" %}
---

## 8. Tips for Debugging
{% include video id="148982525" provider="vimeo" %}
## 🔧 6. Automate Build and Debug Tasks with `tasks.json`

* Use the left panel during debugging to inspect variables and the call stack.
* Use `readlink` to confirm symlink targets (for `--symlink-install` builds):
Add this to `.vscode/tasks.json`:

```bash
readlink install/your_pkg/lib/your_pkg/your_executable
```
* To fix symbol issues, clean your build:
```json
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "source /opt/ros/humble/setup.bash && colcon build --symlink-install"
},
{
"label": "debug",
"type": "shell",
"command": "echo -e '\n\nRun the node using the following prefix: \n ros2 run --prefix 'gdbserver localhost:3000' <package_name> <executable_name> \n\nAnd modify the executable path in .vscode/launch.json file \n' && source /opt/ros/humble/setup.bash && colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo"
},
{
"label": "test",
"type": "shell",
"command": "colcon test && colcon test-result"
}
]
}
```

```bash
rm -rf build/ install/ log/
```
Then in VS Code:
- Press `Ctrl+Shift+B` to build.
- Open the command palette (F1) → "Run Task" → choose `debug` or `test`.
- Use the printed instructions to launch your node under GDB.

The video id can be found at the end of the URL. In this case, the URLs were
`https://www.youtube.com/watch?v=8P9geWwi9e0`
& `https://vimeo.com/148982525`.
---

## 9. Summary

With the above setup:
## Summary
Use this space to reinforce key points and to suggest next steps for your readers.
## 📌 Final Tips

* You can compile and debug C++ ROS 2 nodes directly inside VS Code.
* The `tasks.json` makes builds reproducible.
* The `launch.json` connects VS Code's debugger to your running ROS node.
* You can track variables, memory, and exceptions visually during runtime.
## See Also:
- Links to relevant material within the Robotics Knowledgebase go here.
- Open your ROS workspace at the root level (`~/ros2_ws`) in VS Code.
- The ROS VS Code extension adds tools like:
- Sourced terminals
- Node runners
- ROS topic graph visualizers

## Further Reading
- Links to articles of interest outside the Wiki (that are not references) go here.
---

Now you're ready to debug efficiently in ROS 2 using Visual Studio Code!
## References
- Links to References go here.
- References should be in alphabetical order.
- References should follow IEEE format.
- If you are referencing experimental results, include it in your published report and link to it here.
Happy debugging! 🛠️🐢