[足式机器人]Part5 ROS2学习笔记-CH00-1-基础入门部分

本文仅供学习使用
本文参考:
基础部分 : 古月居-ROS2入门21讲 , 鱼香ROS

ROS2学习笔记-Ch00 - 基础入门部分part1

  • 1. 前言
    • 1.1 Linux 使用
      • 1.1.1 更改分辨率
      • 1.1.2 常用快捷键
      • 1.1.3 小鱼做的一键安装ROS等常用指令合集
      • 1.1.4 安装软件
      • 1.1.5 常用指令
    • 1.2 编程调用
      • 1.2.1 Python
      • 1.2.2 C++
      • 1.2.3 手动安装g++
    • 1.3 常用软件
      • 1.3.1 VsCode
      • 1.3.2 搜狗拼音
      • 1.3.3 QQ与微信
    • 1.4 ROS介绍
      • 1.4.1 核心概念
      • 1.4.2 安装ROS2
      • 1.4.3 ROS2卸载
      • 1.4.4 ROS2初体验
  • 2. 编程基础
    • 2.1 使用gcc编译ROS2节点
      • 2.1.1 动态链接库
      • 2.1.2 用g++编译ROS2的C++节点
    • 2.2 使用make编译ROS2节点
      • 2.2.1 安装make
      • 2.2.2 编写Makefile
    • 2.3 使用CMakeLists.txt编译ROS2节点
      • 2.3.1 安装Cmake
      • 2.3.2 编译CMakeLists.txt
    • 2.4 CMake依赖查找流程
      • 2.4.1 优化CMakeList.txt
      • 2.4.2 find_package查找路径
    • 2.5 Python依赖查找流程
      • 2.5.1 编写ROS2的Python节点
    • 2.6 Python打包工具之Setup
      • 2.6.1 为什么需要对项目分发打包?
      • 2.6.2 包分发的始祖:distutils
      • 2.6.3 分发工具升级:setuptools
      • 2.6.4 超详细讲解 setup.py 的编写
  • 3. 节点
    • 3.1 ROS2节点是什么
    • 3.2 节点之间如何交互?
    • 3.3 如何启动一个节点?
    • 3.4 通过命令行界面查看节点信息
      • 3.4.1 ROS2命令行
      • 3.4.2 节点相关的CLI
  • 4. ROS2工作空间
    • 4.1 工作空间
      • 4.1.1 创建工作空间
      • 4.1.2 自动安装依赖
      • 4.1.3 编译工作空间
      • 4.1.4 设置环境变量
    • 4.2 功能包是什么
    • 4.3 功能包获取的两种方式
      • 4.3.1 安装获取
      • 4.3.2 手动编译获取
    • 4.4 与功能包相关的指令 ros2 pkg(package)
  • 5. ROS2构建工具—Colcon
    • 5.1 Colcon是个啥
    • 5.2 安装colcon
    • 5.3 编个东西测试一下
    • 5.4 运行一个自己编的节点
    • 5.5 本节学习指令
      • 5.5.1 只编译一个包
      • 5.5.2 不编译测试单元
      • 5.5.3 运行编译的包的测试
      • 5.5.4 允许通过更改src下的部分文件来改变install(重要)
    • 5.6 练习-小乌龟求偶大作战
      • 5.6.1 游戏介绍
      • 5.6.2 创建工作空间编译功能包


1. 前言

ROS2使用:Humble版本 + Linux系统(22.04)

1.1 Linux 使用

1.1.1 更改分辨率

在桌面空白处右击,选择Display Settings(显示设置)——修改Resolution(分辨率)——右上角点Apply(应用)

1.1.2 常用快捷键

Ctrl + Alt + T:打开终端窗口。
复制文本:Ctrl+Shift+C
粘贴文本:Ctrl+Shift+V

Ctrl + C:终止当前运行的命令。

Ctrl + D:退出当前的终端会话。
Ctrl + A:将光标移动到行首。
Ctrl + E:将光标移动到行尾。

1.1.3 小鱼做的一键安装ROS等常用指令合集

wget http://fishros.com/install -O fishros && . fishros

1.1.4 安装软件

更换掉系统源为国内镜像源 —— 5

安装指令 :sudo apt install git , 指令详解:
apt指令是Ubuntu中的包管理工具,可以用于安装、卸载、升级软件包。
apt前加上sudo,表示使用以管理员(root)权限执行apt指令。
apt后的install代表安装
install后的git是软件名字

1.1.5 常用指令

  • ls命令: list 的缩写,通过 ls 命令不仅可以查看 linux 文件夹包含的文件,而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息等
    ls -a 列出目录所有文件,包含以.开始的隐藏文件
    ls -l 除了文件名之外,还将文件的权限、所有者、文件大小等信息详细列出来

  • cd 命令: cd(changeDirectory) 命令语法
    cd / 进入要目录
    cd ~ 进入 “home” 目录

  • pwd 命令: 用于查看当前工作目录路径。
    pwd查看当前路径
    pwd -P查看软链接的实际路径

  • mkdir 命令: 用于创建文件夹
    mkdir t当前工作目录下创建名为 t 的文件夹
    mkdir -p /tmp/test/t1/t在 tmp 目录下创建路径为 test/t1/t 的目录,若不存在,则创建(-p: 可以是一个路径名称。此时若路径中的某些目录尚不存在,加上此选项后,系统将自动建立好那些尚不在的目录,即一次可以建立多个目录。-m: 对新建目录设置存取权限,也可以用 chmod 命令设置)

  • rm 命令: 删除一个目录中的一个或多个文件或目录,如果没有使用 -r 选项,则 rm 不会删除目录。如果使用 rm 来删除文件,通常仍可以将该文件恢复原状。rm [选项] 文件…
    rm -i *.log删除任何 .log 文件,删除前逐一询问确认
    rm -rf test删除 test 子目录及子目录中所有档案删除,并且不用一一确认
    rm -- -f*删除以 -f 开头的文件

  • mv命令: 移动文件或修改文件名,根据第二参数类型(如目录,则移动文件;如为文件则重命令该文件)。当第二个参数为目录时,第一个参数可以是多个以空格分隔的文件或目录,然后移动第一个参数指定的多个文件到第二个参数指定的目录中。
    mv test.log test1.txt将文件 test.log 重命名为 test1.txt
    mv log1.txt log2.txt log3.txt /test3将文件 log1.txt,log2.txt,log3.txt 移动到根的 test3 目录中
    mv -i log1.txt log2.txt将文件 file1 改名为 file2,如果 file2 已经存在,则询问是否覆盖
    mv * ../移动当前文件夹下的所有文件到上一级目录

  • cp 命令: 将源文件复制至目标文件,或将多个源文件复制至目标目录。
    cp a.txt b.txt复制 a.txt 到 test 目录下,保持原文件时间,如果原文件存在提示是否覆盖。

1.2 编程调用

1.2.1 Python

  1. 打开终端,创建一个d2lros2文件夹接着在文件夹下创建chapt1文件夹。
mkdir d2lros2
cd d2lros2
mkdir chapt1
  1. 接着输入下面的指令打开gedit并创建文件
gedit hello_fishros.py
  1. 接着你应该看到一个类似于记事本的东西,在里面输入下面一段代码,打印一句话
print("Hello FishRos!")
  1. 使用Ctrl+S保存代码
  2. 关掉gedit,接着在终端输入下面的指令运行这段脚本
python3 hello_fishros.py

1.2.2 C++

  1. 进入终端,用gedit再次编辑一个叫做hello_fishros.cpp的文件。(如果还是在当前目录d2lros2/chapt1/,则无效-'bash: cd: d2lros2/chapt1/: 没有那个文件或目录)
cd d2lros2/chapt1/
gedit hello_fishros.cpp
  1. gedit中输入下面的内容
#include"iostream"

int main(){
    std::cout<<"Hello FishRos!"<<std::endl;
    return 0;
}
  1. 保存代码,关闭gedit。
  2. 终端输入下面的指令对刚刚的代码进行编译
g++ hello_fishros.cpp
  1. 使用ls指令,应该可以看到一个叫做a.out的文件
  2. 输入下面的指令即可运行
./a.out

1.2.3 手动安装g++

C++代码必须经过编译构建之后才能运行。C++的编译工具使用的是g++,默认是不安装的

sudo apt install g++

1.3 常用软件

1.3.1 VsCode

左边是文件目录,Ctrl+B即可打开隐藏侧边栏。
中间是编辑器
下面可以显示终端,Ctrl+Shift+~即可打开终端

常用的是Python和C++插件

1.3.2 搜狗拼音

根据上述命令,查询官网学会安装软件吧!

1.3.3 QQ与微信

根据上述命令,查询官网学会安装软件吧!

1.4 ROS介绍

ROS(Robot Operating System)机器人操作系统,但ROS本身并不是一个操作系统,而是可以安装在现在已有的操作系统上(Linux、Windows、Mac)上的软件库工具集

机器人,我们对其进行拆解。可以分为感知(激光雷达、深度相机、IMU、里程计、碰撞感知、建图)、决策(路径规划(navigation)算法、定位算法)、控制(轮子驱动)三个部分。

ROS为此设计了一整套通信机制(话题、服务、参数、动作)。

1.4.1 核心概念

工作空间(Woekspace):开发过程的大本营
功能包(Package):功能源码的聚集地
节点(Node):机器人的工作细胞
话题(Topic): 节点间传递数据的桥梁
服务(Service):节点间的你问我答
通信接口(Interface):数据传递的标准结构
参数(Parameter):机器人系统的全局字典
动作(Action):完整行为的流程管理
分布式通信(Distributed Communication):多计算平台的任务分配
DDS(Date Distribution Service):机器人的神经网络(Data Distribution Service 数据分发服务)

1.4.2 安装ROS2

wget http://fishros.com/install -O fishros && . fishros

1.4.3 ROS2卸载

sudo apt remove ros-humble-*
sudo apt autoremove

1.4.4 ROS2初体验

  • 你听我说:启动两个节点,一个节点负责发消息(说),一个节点负责收消息(听)
  1. 启动一个终端Ctrl+Alt+T
  2. 启动倾听者
ros2 run demo_nodes_py listener
  1. 启动一个新终端Ctrl+Alt+T
  2. 启动说话者
ros2 run demo_nodes_cpp talker

观察一下现象,talker节点每数一个输,倾听节点每一次都能听到一个

  • 涂鸦乌龟:启动海龟模拟器,启动海龟遥控器,控制海龟在地图上画出任意轨迹
  1. 打开终端Ctrl+Alt+T
  2. 输入下面的指令
ros2 run turtlesim turtlesim_node
  1. 点一下原来的终端输入Ctrl+Shift+T
  2. 打开一个新的标签页输入
ros2 run turtlesim turtle_teleop_key

这个时候你就可以使用上下左右(方向键)去遥控海龟了

  • RQT可视化
  1. 保持前面两个游戏在运行状态,打新的终端,输入rqt
  2. Plugins——Introspection——Node Graph

2. 编程基础

2.1 使用gcc编译ROS2节点

2.1.1 动态链接库

程序编译一般需要经预处理、编译、汇编和链接几个步骤。在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为 “库”文件

在链接步骤中,链接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态(链接)库,其特点是可执行文件中包含了库代码的一份完整拷贝,缺点是被多次使用就会多份冗余拷贝。——(编写子函数)

还有一种库,就是程序在开始运行后调用库函数时才被载入,这种库独立于现有的程序,其本身不可执行,但包含着程序需要调用的一些函数,这种库称为动态(链接)库(Dynamic Link Library)——(调用函数包)

在widows平台下,静态链接库是.lib文件,动态库文件是.dll文件。在linux平台下,静态链接库是.a文件,动态链接库是.so文件。

2.1.2 用g++编译ROS2的C++节点

编写节点:打开终端,创建chapt2/basic目录,用VSCODE打开d2lros2目录

mkdir -p d2lros2/chapt2/basic/
code d2lros2

接着在左侧chapt2上新建first_ros2_node.cpp,然后在first_ros2_node.cpp中输入下面的代码。

// 包含rclcpp头文件,如果Vscode显示红色的波浪线也没关系
// 我们只是把VsCode当记事本而已,谁会在意记事本对代码的看法呢,不是吗?
#include "rclcpp/rclcpp.hpp"

int main(int argc, char **argv)
{
    // 调用rclcpp的初始化函数
    rclcpp::init(argc, argv);
    // 调用rclcpp的循环运行我们创建的first_node节点
    rclcpp::spin(std::make_shared<rclcpp::Node>("first_node"));
    return 0;
}

接着我们使用g++来编译first_ros2_node节点。正常的话一定会报错

g++ first_ros2_node.cpp 

一定要记住这个错误 No such file or directory,这将是你接下来机器人学习工作生涯中最常见的错误之一。

原因我们在代码里包含了"rclcpp/rclcpp.hpp"头文件,但是g++找不到这个头文件,解决方法就是告诉g++这个头文件的目录。

首先我们要找到这个头文件在哪里,这个头文件是ROS2的客户端库,其地址肯定在ROS2的安装目录下,即/opt/ros/humble/include/rclcppls指令列出命令 | grep rclcpp.h 是对列出的结果进行过滤,只显示包含rclcpp.h的行

cd /opt/ros/humble/include/rclcpp
ls rclcpp/* | grep rclcpp.h

使用上面的指令,可以看到这个文件确实在这里

接着我们可以用-I(大写i)来为g++指定这个目录,然后再次运行,你会发现依然报错 (需在代码路径cd /home/wjh/d2lros2/chapt2/basic下运行)

g++ first_ros2_node.cpp -I /opt/ros/humble/include/rclcpp/ 

/opt/ros/humble/include/rclcpp/rclcpp/executors/multi_threaded_executor.hpp:25这个位置,包含了rcl/guard_condition.h发现找不到这个头文件。

既然错误一样,那么解决方案也是相同的,rcl/guard_condition.h所在的路径是/opt/ros/humble/include/rcl/我们再次指定后运行。

g++ first_ros2_node.cpp -I /opt/ros/humble/include/rclcpp/ -I /opt/ros/humble/include/rcl/

会发现还是相同错误,因为头文件的包含是类似于套娃形式的,一层层加下去,总有终点,…发现报的错误变了

请记住上面错误中的undefined reference to xxxxx,这将是你接下来机器人学习工作生涯中另一个最常见的错误。

原因在于g++找不到库文件,解决方法就是我们帮助它定位到库文件的位置,并通过-L参数指定库目录,-l(小写L)指定库的名字。

ROS2相关的库的地址都在/opt/ros/humble/lib下,你可以使用下面的指定看到rclcpp的动态链接库。

ls /opt/ros/humble/lib | grep rclcpp
-L /opt/ros/humble/lib/ \
-lrclcpp -lrcutils

2.2 使用make编译ROS2节点

没搞明白

g++编译节点无比的麻烦,的确是这样子,为此先行者们发明了一个叫做make的批处理工具,我们可以将g++的指令写成脚本,就可以通过make自动的调用脚本完成操作。

2.2.1 安装make

sudo apt install make

2.2.2 编写Makefile

d2lros2/d2lros2/chapt2/basic下新建Makefile,然后将g++编译指令用下面的形式写到Makefile里。

build:
    g++ first_ros2_node.cpp \
    -I/opt/ros/humble/include/rclcpp/ \
    -I /opt/ros/humble/include/rcl/ \
    -I /opt/ros/humble/include/rcutils/ \
    -I /opt/ros/humble/include/rmw \
    -I /opt/ros/humble/include/rcl_yaml_param_parser/ \
    -I /opt/ros/humble/include/rosidl_runtime_c \
    -I /opt/ros/humble/include/rosidl_typesupport_interface \
    -I /opt/ros/humble/include/rcpputils \
    -I /opt/ros/humble/include/builtin_interfaces \
    -I /opt/ros/humble/include/rosidl_runtime_cpp \
    -I /opt/ros/humble/include/tracetools \
    -I /opt/ros/humble/include/rcl_interfaces \
    -I /opt/ros/humble/include/libstatistics_collector \
    -I /opt/ros/humble/include/statistics_msgs \
    -L /opt/ros/humble/lib/ \
    -lrclcpp -lrcutils \
    -o first_node
    
# 顺便小鱼加个clean指令,用来删掉first_node
clean:
    rm first_node

Makefile同级目录输入

make build
 g++ first_ros2_node.cpp \
    -I/opt/ros/humble/include/rclcpp/ \
    -I /opt/ros/humble/include/rcl/ \
    -I /opt/ros/humble/include/rcutils/ \
    -I /opt/ros/humble/include/rmw \
    -I /opt/ros/humble/include/rcl_yaml_param_parser/ \
    -I /opt/ros/humble/include/rosidl_runtime_c \
    -I /opt/ros/humble/include/rosidl_typesupport_interface \
    -I /opt/ros/humble/include/rcpputils \
    -I /opt/ros/humble/include/builtin_interfaces \
    -I /opt/ros/humble/include/rosidl_runtime_cpp \
    -I /opt/ros/humble/include/tracetools \
    -I /opt/ros/humble/include/rcl_interfaces \
    -I /opt/ros/humble/include/libstatistics_collector \
    -I /opt/ros/humble/include/statistics_msgs \
    -L /opt/ros/humble/lib/ \
    -lrclcpp -lrcutils \
    -o first_node

可以看到make指令调用了脚本里的build下的指令,对代码进行了编译。同级目录下也产生了first_node可执行文件(绿色代表可执行)。使用make clean指令即可删掉first_node节点。

make clean
rm first_node

2.3 使用CMakeLists.txt编译ROS2节点

虽然通过make调用Makefile编译代码非常的方便,但是还是需要我们手写gcc指令来编译,那有没有什么办法可以自动生成Makefile呢?

答案是有的,那就是cmake工具。cmake通过调用CMakeLists.txt直接生成Makefile

2.3.1 安装Cmake

sudo apt install cmake

2.3.2 编译CMakeLists.txt

d2lros2/d2lros2/chapt2/basic新建CMakeLists.txt,输入下面内容。

cmake_minimum_required(VERSION 3.22)

project(first_node)

#include_directories 添加特定的头文件搜索路径 ,相当于指定g++编译器的-I参数
include_directories(/opt/ros/humble/include/rclcpp/)
include_directories(/opt/ros/humble/include/rcl/)
include_directories(/opt/ros/humble/include/rcutils/)
include_directories(/opt/ros/humble/include/rcl_yaml_param_parser/)
include_directories(/opt/ros/humble/include/rosidl_runtime_c/)
include_directories(/opt/ros/humble/include/rosidl_typesupport_interface/)
include_directories(/opt/ros/humble/include/rcpputils/)
include_directories(/opt/ros/humble/include/builtin_interfaces/)
include_directories(/opt/ros/humble/include/rmw/)
include_directories(/opt/ros/humble/include/rosidl_runtime_cpp/)
include_directories(/opt/ros/humble/include/tracetools/)
include_directories(/opt/ros/humble/include/rcl_interfaces/)
include_directories(/opt/ros/humble/include/libstatistics_collector/)
include_directories(/opt/ros/humble/include/statistics_msgs/)

# link_directories - 向工程添加多个特定的库文件搜索路径,相当于指定g++编译器的-L参数
link_directories(/opt/ros/humble/lib/)

# add_executable - 生成first_node可执行文件
add_executable(first_node first_ros2_node.cpp)

# target_link_libraries - 为first_node(目标) 添加需要动态链接库,相同于指定g++编译器-l参数
# 下面的语句代替 -lrclcpp -lrcutils
target_link_libraries(first_node rclcpp rcutils)

一般会创建一个新的目录,运行cmake并进行编译,这样的好处是不会显得那么乱。

mkdir build
cd build

创建好文件夹,接着运行cmake指令,..代表到上级目录找CMakeLists.txt。

cmake ..

运行完cmake你应该可以在build目录下看到cmake自动生成的Makefile了,接着就可以运行make指令进行编译

make

运行完上面的指令,就可以在build目录下发现first_node节点了。

2.4 CMake依赖查找流程

上面我们用g++makecmake三种方式来编译ros2的C++节点。用cmake虽然成功了,但是CMakeLists.txt的内容依然非常的臃肿,我们需要将其进一步的简化。

2.4.1 优化CMakeList.txt

cmake_minimum_required(VERSION 3.22)
project(first_node)

find_package(rclcpp REQUIRED)
add_executable(first_node first_ros2_node.cpp)
target_link_libraries(first_node rclcpp::rclcpp)

接着继续生成和编译(在build文件夹路径下)

cmake ..
make

为什么可以浓缩成那么短的几句指令呢?

2.4.2 find_package查找路径

<package>_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
PATH

2.5 Python依赖查找流程

python的打包和引入依赖的方式相比C++要容易太多

没搞明白

2.5.1 编写ROS2的Python节点

d2lros2/d2lros2/chapt2/basic新建second_ros2_node.py,输入下面的内容

# 导入rclpy库,如果Vscode显示红色的波浪线也没关系
# 我们只是把VsCode当记事本而已,谁会在意记事本对代码的看法呢,不是吗?
import rclpy
from rclpy.node import Node
# 调用rclcpp的初始化函数
rclpy.init() 
# 调用rclcpp的循环运行我们创建的second_node节点
rclpy.spin(Node("second_node"))

2.6 Python打包工具之Setup

本部分只做了解即可,我们平时用的并不多,因为python的依赖并不是靠setup来查找的,但是C++却靠着CmakeLists.txt进行查找。

2.6.1 为什么需要对项目分发打包?

平常我们习惯了使用 pip 来安装一些第三方模块,这个安装过程之所以简单,是因为模块开发者为我们默默地为我们做了所有繁杂的工作,而这个过程就是 打包

打包,就是将你的源代码进一步封装,并且将所有的项目部署工作都事先安排好,这样使用者拿到后即装即用,不用再操心如何部署的问题(如果你不想对照着一堆部署文档手工操作的话)。

不管你是在工作中,还是业余准备自己写一个可以上传到 PyPI 的项目,你都要学会如何打包你的项目。

Python 发展了这么些年了,项目打包工具也已经很成熟了。他们都有哪些呢?

你可能听过 distutilsdistutils2setuptools等等,好像很熟悉,却又很陌生,他们都是什么关系呢?

2.6.2 包分发的始祖:distutils

distutils 是 Python 的一个标准库,从命名上很容易看出它是一个分发(distribute)工具(utlis),它是 Python 官方开发的一个分发打包工具,所有后续的打包工具,全部都是基于它进行开发的。

distutils 的精髓在于编写 setup.py,它是模块分发与安装的指导文件。经常用它来进行模块的安装

python setup.py install

2.6.3 分发工具升级:setuptools

setuptoolsdistutils 增强版,不包括在标准库中。其扩展了很多功能,能够帮助开发者更好的创建和分发 Python 包。大部分 Python 用户都会使用更先进的 setuptools 模块。

distributesetuptools 一个分支版本,分支的原因可能是有一部分开发者认为 setuptools 开发太慢了。但现在,distribute 又合并回了 setuptools 中。因此,我们可以认为它们是同一个东西。

还有一个大包分发工具是 distutils2,其试图尝试充分利用distutils,detuptools 和 distribute 并成为 Python 标准库中的标准工具。但该计划并没有达到预期的目的,且已经是一个废弃的项目。

因此,setuptools 是一个优秀的,可靠的 Python 包安装与分发工具。

2.6.4 超详细讲解 setup.py 的编写

打包分发最关键的一步是编写 setup.py 文件。

from setuptools import setup, find_packages

setup(
    # 指定项目名称,我们在后期打包时,这就是打包的包名称,当然打包时的名称可能还会包含下面的版本号哟~
    name="mytest",
    # 指定版本号
    version="1.0",
    author="flp",
    author_email="[email protected]",
    # 这是对当前项目的一个描述
    description="这只是一次测试",

    # 项目主页
    url="http://iswbm.com/", 

    # 你要安装的包,通过 setuptools.find_packages 找到当前目录下有哪些包
    packages=find_packages()
    
    # 指定包名,即你需要打包的包名称,要实际在你本地存在哟,它会将指定包名下的所有"*.py"文件进行打包哟,但不会递归去拷贝所有的子包内容。
    # 综上所述,我们如果想要把一个包的所有"*.py"文件进行打包,应该在packages列表写下所有包的层级关系哟~这样就开源将指定包路径的所有".py"文件进行打包!
    packages=['devops', "devops.dev", "devops.ops"],
)

3. 节点

3.1 ROS2节点是什么

ROS2中每一个节点也是只负责一个单独的模块化的功能(比如一个节点负责控制车轮转动,一个节点负责从激光雷达获取数据、一个节点负责处理激光雷达的数据、一个节点负责定位等等)
[足式机器人]Part5 ROS2学习笔记-CH00-1-基础入门部分_第1张图片

3.2 节点之间如何交互?

上面举了一个激光雷达的例子,一个节点负责获取激光雷达的扫描数据,一个节点负责处理激光雷达数据,比如去除噪点。

那节点与节点之间就必须要通信了,那他们之间该如何通信呢?ROS2早已为你准备好了一共四种通信方式:

  • 话题-topics : 单向传递,多端接受
  • 服务-services : 双向信息传递
  • 动作-action
  • 参数-parameters
    [足式机器人]Part5 ROS2学习笔记-CH00-1-基础入门部分_第2张图片

3.3 如何启动一个节点?

节点对应一个功能模块,及相当于启动一个工作空间和包:

ros2 run
启动包下的中的节点

这里运行一个节点,感受一下

ros2 run turtlesim turtlesim_node

运行之后可以看到一只小乌龟

3.4 通过命令行界面查看节点信息

3.4.1 ROS2命令行

ROS2的CLI,就是和ROS2相关的命令行操作。

CLI(Command-Line Interface)命令行
GUI(Graphical User Interface)可视化

GUI(Graphical User Interface)就是平常我们说的图形用户界面,大家用的Windows是就是可视化的,我们可以通过鼠标点击按钮等图形化交互完成任务。
CLI(Command-Line Interface)就是命令行界面了,我们所用的终端,黑框框就是命令行界面,没有图形化。

很久之前电脑还是没有图形化界面的,所有的交互都是通过命令行实现,就学习机器人而言,命令行操作相对于图形化优势更加明显。

ROS2为我们提供了一系列指令,通过这些指令,可以实现对ROS2相关模块信息的获取设置等操作。

如果你学过ansys apdl的话这里的概念就很明显了

3.4.2 节点相关的CLI

ros2 run <package_name> <executable_name>  # 启动包下的中的节点
ros2 node list  # 查看节点列表(常用)
ros2 node info <node_name>  # 查看节点信息(常用)

ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtle  # 重映射节点名称为/my_turtle _ 用于启用相同节点

ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=10  # 运行节点时设置参数  ??

4. ROS2工作空间

运行一个节点的时候使用的是:

ros2 run # 启动包下的中的节点 # 包名字 可执行文件名字

我们想找到一个节点(可执行文件),就必须要先知道它在哪个包,那问题就来了,想要找到某个包,该去哪里找?——工作空间

注意:一个工作空间下可以有多个功能包,一个功能包可以有多个节点存在

在文件夹构成的空间下执行命令,专门用于执行命令的文件夹——工作空间

4.1 工作空间

大家在之前的学习和开发中,应该有接触过某些集成开发环境,比如Visual Studio、Eclipse、Qt Creator等,当我们想要编写程序之前,都会在这些开发环境的工具栏中,点击一个“创建新工程”的选项,此时就产生一个文件夹,后续所有工作产生的文件,都会放置在这个文件夹中,这个文件夹以及里边的内容,就叫做是工程。

类似的,在ROS机器人开发中,我们针对机器人某些功能进行代码开始时,各种编写的代码、参数、脚本等文件,也需要放置在某一个文件夹里进行管理,这个文件夹在ROS系统中就叫做工作空间

工作空间是包含若干个功能包的目录,一开始大家把工作空间理解成一个文件夹就行了。这个文件夹包含下有src。所以一般新建一个工作空间的操作就像下面一样

cd d2lros2/chapt2/
mkdir -p chapt2_ws/src

其实就是创建一个目录,将所需的功能包放在workspace(chapt2_ws)的src下

ROS系统中一个典型的工作空间结构包括四个子目录,或者叫做四个子空间:build , install , log , src

  • src代码空间,未来编写的代码、脚本,都需要人为的放置到这里;
  • build编译空间,保存编译过程中产生的中间文件;
  • install安装空间,放置编译得到的可执行文件和脚本;
  • log日志空间,编译和运行过程中,保存各种警告、错误、信息等日志。

总体来讲,这四个空间的文件夹,我们绝大部分操作都是在src中进行的,编译成功后,就会执行install里边的结果,buildlog两个文件夹用的很少。

工作空间的名称我们可以自己定义,数量也并不是唯一的,比如:

  • 工作空间1:dev_w_a,用于A机器人的开发;
  • 工作空间2:dev_ws_b,用于B机器人的一部分功能;
  • 工作空间3:dev_ws_b2,用于开发B机器人另外一些功能。

4.1.1 创建工作空间

mkdir -p ~/dev_ws/src
cd ~/dev_ws/src
git clone https://gitee.com/guyuehome/ros2_21_tutorials.git

4.1.2 自动安装依赖

sudo apt install -y python3-pip  # 安装phython包pip3的工具
sudo pip3 install rosdepc  # 国内用于解决网络访问的问题
sudo rosdepc init
rosdepc update
cd ..
rosdepc install -i --from-path src --rosdistro humble -y  # 安装基本依赖

4.1.3 编译工作空间

sudo apt install python3-colcon-ros
cd ~/dev_ws/
colcon build

编译成功后,就可以在工作空间中看到自动生产的build、log、install文件夹了。
[足式机器人]Part5 ROS2学习笔记-CH00-1-基础入门部分_第3张图片

4.1.4 设置环境变量

编译成功后,为了让系统能够找到我们的功能包和可执行文件,还需要设置环境变量:

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

4.2 功能包是什么

功能包可以理解为存放节点的地方,ROS2中功能包根据编译方式的不同分为三种类型。

  • ament_python,适用于python程序
  • cmake,适用于C++
  • ament_cmake,适用于C++程序,是cmake的增强版

4.3 功能包获取的两种方式

4.3.1 安装获取

安装一般使用:

sudo apt install ros--package_name

安装获取会自动放置到系统目录,不用再次手动source

/POT/ROS/HUMBLE # 需要记住的路径-ros包安装位置,版本为humble

4.3.2 手动编译获取

手动编译相对麻烦一些,需要下载源码然后进行编译生成相关文件。

什么时候需要手动编译呢?
一般我们能安装的功能包都是作者编译好程序将可执行文件上传到仓库中,然后我们才能够通过apt进行安装,如果作者还没来得及测试上传,或者忘记了测试上传,就会找不到对应的包,这时候就需要手动编译安装了。
另外一种就是我们需要对包的源码进行修改,这个时候也需要自己编译修改。

手动编译之后,需要手动source工作空间的install目录,才可运行。

4.4 与功能包相关的指令 ros2 pkg(package)

  1. 创建功能包 create Create a new ROS2 package

ros2 pkg create --build-type {cmake,ament_cmake,ament_python} --dependencies <依赖名字>

  1. 列出可执行文件 executables Output a list of package specific executables
ros2 pkg executables  # 列出所有
ros2 pkg executables turtlesim  # 列出`turtlesim`功能包的所有可执行文件 
# 可以进行运行 ros2 run turtlesim turtlesim_nod
  1. 列出所有的包 list Output a list of available packages
ros2 pkg list
  1. 输出某个包所在路径的前缀 prefix Output the prefix path of a package

ros2 pkg prefix

ros2 pkg prefix turtlesim  # 比如小乌龟
  1. 列出包的清单描述文件 xml Output the XML of the package manifest or a specific tag
    每一个功能包都有一个标配的manifest.xml文件,用于记录这个包的名字,构建工具,编译信息,拥有者,干啥用的等信息。通过这个信息,就可以自动为该功能包安装依赖,构建时确定编译顺序等
ros2 pkg xml turtlesim   # 查看小乌龟模拟器功能包的信息

5. ROS2构建工具—Colcon

ROS2编译工具colcon

5.1 Colcon是个啥

colcon其实是一个功能包构建工具用来编译代码,ROS2默认是没有安装colcon的(colcon想当于ros1中的catkin工具)

5.2 安装colcon

sudo apt-get install python3-colcon-common-extensions

安装完成后,打开终端输入colcon即可看到其使用方法。

5.3 编个东西测试一下

  1. 创建一个工作区文件夹colcon_test_ws
cd d2lros2/chapt2/
mkdir colcon_test_ws && cd colcon_test_ws
  1. 下载个ROS2示例源码测试一下(需要科学上网)-b 用于指定github中的分支为humble
git clone https://github.com/ros2/examples src/examples -b humble
https://portal.s.au/knowledgebase/160/
sudo ./trojan # 需在安装路径下的终端运行
pkill -f trojan
  1. 编译工程
colcon build
  1. 编完之后的目录结构
    ROS系统中一个典型的工作空间结构如图所示,这个d2lros2/chapt2/colcon_test_ws 就是工作空间的根目录,里边会有四个子目录,或者叫做四个子空间: 在src放置源码)同级目录我们应该会看到 buildinstalllog 目录:
  • build 目录存储的是中间文件。对于每个包,将创建一个子文件夹,在其中调用例如CMake(编译产生的文件)
  • install 目录是每个软件包将安装到的位置。默认情况下,每个包都将安装到单独的子目录中(重要的安装目录)。
  • log 目录包含有关每个colcon调用的各种日志信息。
    [足式机器人]Part5 ROS2学习笔记-CH00-1-基础入门部分_第4张图片

5.4 运行一个自己编的节点

  1. 打开一个终端(d2lros2/chapt2/colcon_test_ws )进入我们刚刚创建的工作空间,先source 一下资源(以找到功能包)
source install/setup.bash
  1. 运行一个订者节点,你将看不到任何打印,因为没有发布者
ros2 run examples_rclcpp_minimal_subscriber subscriber_member_function
  1. 打开一个新的终端(d2lros2/chapt2/colcon_test_ws ),先source,再运行一个发行者节点
source install/setup.bash
ros2 run examples_rclcpp_minimal_publisher publisher_member_function

5.5 本节学习指令

5.5.1 只编译一个包

d2lros2/chapt2/colcon_test_ws

colcon build --packages-select YOUR_PKG_NAME 

5.5.2 不编译测试单元

d2lros2/chapt2/colcon_test_ws

colcon build --packages-select YOUR_PKG_NAME  --cmake-args -DBUILD_TESTING=0

5.5.3 运行编译的包的测试

d2lros2/chapt2/colcon_test_ws

colcon test

5.5.4 允许通过更改src下的部分文件来改变install(重要)

d2lros2/chapt2/colcon_test_ws
每次调整 python 脚本时都不必重新build了——colcon build 只是进行了拷贝,src的文件更改不会影响build文件夹中的内容

colcon build --symlink-install

5.6 练习-小乌龟求偶大作战

项目开源地址:fishros/turtle_battle: 追逐你喜欢的那个小乌龟,满100分奖励教学视频哦 (github.com)

5.6.1 游戏介绍

游戏内容很简单,画面中会出现两只小乌龟,一个乌龟是可以被控制的,玩家控制这只小乌龟去找自己的配偶乌龟,找到后配偶乌龟会随机出现在其他位置。每找到一次,好感度加10分,如果满100分就会跳出一个神秘网页

5.6.2 创建工作空间编译功能包

  • 创建工作空间
mkdir -p turtle_ws/src
cd turtle_ws/src
  • 下载源码功能包到工作空间的src文件夹下
git clone https://github.com/fishros/turtle_battle.git
  • 进入工作空间——目录上一级进行编译
cd ..
colcon build

你可能感兴趣的:(ros2,学习笔记)