注:本博客涉及的环境系统为 Ubuntu22.04-ROS2 humble

工作空间就是类似CPP开发的Project,开发用到的所有源文件。

一般我会通过shell脚本新建工作空间

1.创建工作空间

#!/bin/bash

# 提示用户输入文件夹名称
echo "请输入文件夹名称:"
read folder_name

# 检查输入是否为空
if [ -z "$folder_name" ]; then
    echo "错误:文件夹名称不能为空!"
    exit 1
fi

# 创建文件夹
mkdir "$folder_name"

# 检查文件夹是否创建成功
if [ $? -eq 0 ]; then
    echo "工程文件夹 '$folder_name' 创建成功!"
else
    echo "错误:无法创建文件夹 '$folder_name'!"
    exit 1
fi
cd "$folder_name"
mkdir build
mkdir install
mkdir log
mkdir src
echo "Create Finish"

可以看到我再工程文件夹下创建了四个文件夹,

2.创建源文件

我们在src文件夹下创建一个cpp文件,实现一个Ros简单的节点(node)

#include <unistd.h>
#include "rclcpp/rclcpp.hpp"


/***
创建一个HelloWorld节点, 初始化时输出“hello world”日志
***/
class HelloWorldNode : public rclcpp::Node
{
    public:
        HelloWorldNode()
        : Node("node_helloworld_class")                          // ROS2节点父类初始化
        {
            while(rclcpp::ok())                                  // ROS2系统是否正常运行
            {
                RCLCPP_INFO(this->get_logger(), "Hello World");  // ROS2日志输出
                sleep(1);                                        // 休眠控制循环时间
            }
        }
};

// ROS2节点主入口main函数
int main(int argc, char * argv[])                               
{

    // ROS2 C++接口初始化
    rclcpp::init(argc, argv);        
    
    // 创建ROS2节点对象并进行初始化                 
    rclcpp::spin(std::make_shared<HelloWorldNode>()); 
    
    // 关闭ROS2 C++接口
    rclcpp::shutdown();                               
    
    return 0;
}

3.使用Rosdepc工具自动化创建依赖

sudo rosdepc init
rosdepc update
rosdepc install -i --from-path src --rosdistro humble -y

4.编译项目

colcon build

编译后将自动build、log、install中的内容,在终点输入命令

tree .

可以获得工程的文件树

.
├── build
│   ├── COLCON_IGNORE
│   └── learning_node_cpp
│       ├── ament_cmake_core
│       │   ├── learning_node_cppConfig.cmake
│       │   ├── learning_node_cppConfig-version.cmake
│       │   ├── package.cmake
│       │   └── stamps
│       │       ├── ament_prefix_path.sh.stamp
│       │       ├── nameConfig.cmake.in.stamp
│       │       ├── nameConfig-version.cmake.in.stamp
│       │       ├── package_xml_2_cmake.py.stamp
│       │       ├── package.xml.stamp
│       │       ├── path.sh.stamp
│       │       └── templates_2_cmake.py.stamp
│       ├── ament_cmake_environment_hooks
│       │   ├── ament_prefix_path.dsv
│       │   ├── local_setup.bash
│       │   ├── local_setup.dsv
│       │   ├── local_setup.sh
│       │   ├── local_setup.zsh
│       │   ├── package.dsv
│       │   └── path.dsv
│       ├── ament_cmake_index
│       │   └── share
│       │       └── ament_index
│       │           └── resource_index
│       │               ├── package_run_dependencies
│       │               │   └── learning_node_cpp
│       │               ├── packages
│       │               │   └── learning_node_cpp
│       │               └── parent_prefix_path
│       │                   └── learning_node_cpp
│       ├── ament_cmake_package_templates
│       │   └── templates.cmake
│       ├── ament_cmake_uninstall_target
│       │   └── ament_cmake_uninstall_target.cmake
│       ├── ament_cppcheck
│       ├── ament_lint_cmake
│       ├── ament_uncrustify
│       ├── ament_xmllint
│       ├── cmake_args.last
│       ├── CMakeCache.txt
│       ├── CMakeFiles
│       │   ├── 3.22.1
│       │   │   ├── CMakeCCompiler.cmake
│       │   │   ├── CMakeCXXCompiler.cmake
│       │   │   ├── CMakeDetermineCompilerABI_C.bin
│       │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│       │   │   ├── CMakeSystem.cmake
│       │   │   ├── CompilerIdC
│       │   │   │   ├── a.out
│       │   │   │   ├── CMakeCCompilerId.c
│       │   │   │   └── tmp
│       │   │   └── CompilerIdCXX
│       │   │       ├── a.out
│       │   │       ├── CMakeCXXCompilerId.cpp
│       │   │       └── tmp
│       │   ├── cmake.check_cache
│       │   ├── CMakeDirectoryInformation.cmake
│       │   ├── CMakeOutput.log
│       │   ├── CMakeRuleHashes.txt
│       │   ├── CMakeTmp
│       │   ├── learning_node_cpp_uninstall.dir
│       │   │   ├── build.make
│       │   │   ├── cmake_clean.cmake
│       │   │   ├── compiler_depend.make
│       │   │   ├── compiler_depend.ts
│       │   │   ├── DependInfo.cmake
│       │   │   └── progress.make
│       │   ├── Makefile2
│       │   ├── Makefile.cmake
│       │   ├── node_helloworld_class.dir
│       │   │   ├── build.make
│       │   │   ├── cmake_clean.cmake
│       │   │   ├── compiler_depend.make
│       │   │   ├── compiler_depend.ts
│       │   │   ├── DependInfo.cmake
│       │   │   ├── depend.make
│       │   │   ├── flags.make
│       │   │   ├── link.txt
│       │   │   ├── progress.make
│       │   │   └── src
│       │   │       ├── node_helloworld_class.cpp.o
│       │   │       └── node_helloworld_class.cpp.o.d
│       │   ├── progress.marks
│       │   ├── TargetDirectories.txt
│       │   └── uninstall.dir
│       │       ├── build.make
│       │       ├── cmake_clean.cmake
│       │       ├── compiler_depend.make
│       │       ├── compiler_depend.ts
│       │       ├── DependInfo.cmake
│       │       └── progress.make
│       ├── cmake_install.cmake
│       ├── colcon_build.rc
│       ├── colcon_command_prefix_build.sh
│       ├── colcon_command_prefix_build.sh.env
│       ├── CTestConfiguration.ini
│       ├── CTestCustom.cmake
│       ├── CTestTestfile.cmake
│       ├── install_manifest.txt
│       ├── Makefile
│       └── node_helloworld_class
├── CMakeLists.txt
├── install
│   ├── COLCON_IGNORE
│   ├── learning_node_cpp
│   │   ├── lib
│   │   │   └── learning_node_cpp
│   │   │       └── node_helloworld_class
│   │   └── share
│   │       ├── ament_index
│   │       │   └── resource_index
│   │       │       ├── package_run_dependencies
│   │       │       │   └── learning_node_cpp
│   │       │       ├── packages
│   │       │       │   └── learning_node_cpp
│   │       │       └── parent_prefix_path
│   │       │           └── learning_node_cpp
│   │       ├── colcon-core
│   │       │   └── packages
│   │       │       └── learning_node_cpp
│   │       └── learning_node_cpp
│   │           ├── cmake
│   │           │   ├── learning_node_cppConfig.cmake
│   │           │   └── learning_node_cppConfig-version.cmake
│   │           ├── environment
│   │           │   ├── ament_prefix_path.dsv
│   │           │   ├── ament_prefix_path.sh
│   │           │   ├── path.dsv
│   │           │   └── path.sh
│   │           ├── hook
│   │           │   ├── cmake_prefix_path.dsv
│   │           │   ├── cmake_prefix_path.ps1
│   │           │   └── cmake_prefix_path.sh
│   │           ├── local_setup.bash
│   │           ├── local_setup.dsv
│   │           ├── local_setup.sh
│   │           ├── local_setup.zsh
│   │           ├── package.bash
│   │           ├── package.dsv
│   │           ├── package.ps1
│   │           ├── package.sh
│   │           ├── package.xml
│   │           └── package.zsh
│   ├── local_setup.bash
│   ├── local_setup.ps1
│   ├── local_setup.sh
│   ├── _local_setup_util_ps1.py
│   ├── _local_setup_util_sh.py
│   ├── local_setup.zsh
│   ├── setup.bash
│   ├── setup.ps1
│   ├── setup.sh
│   └── setup.zsh
├── log
│   ├── build_2025-07-31_22-18-53
│   │   ├── events.log
│   │   ├── learning_node_cpp
│   │   │   ├── command.log
│   │   │   ├── stderr.log
│   │   │   ├── stdout.log
│   │   │   ├── stdout_stderr.log
│   │   │   └── streams.log
│   │   └── logger_all.log
│   ├── COLCON_IGNORE
│   ├── latest -> latest_build
│   └── latest_build -> build_2025-07-31_22-18-53
├── package.xml
└── src
    └── node_helloworld_class.cpp

在install 文件夹中,存在一个local_setup.sh,帮助我们设置Ros运行的相关功能包即可执行文件

5.设置exe及FuncPackage的环境变量

$ source install/local_setup.sh # 仅在当前终端生效
$ echo " source ~/dev_ws/install/local_setup.sh" >> ~/.bashrc # 所有终端均生效

至此,我们就完成了工作空间的创建、编译和配置。