ROS1代码向ROS2移植

2023-10-29

前言

由于ros2的种种优点,特别是通信和节点去中心化的优点,我们团队决定将我们的代码从ros1移植到ros2,我们选择的ros2版本为foxy,ubuntu环境为20.04,现在记录以下移植大概过程。本博客内容将不定期更新。
这里列举一些ros2的学习教程:
鱼香ros B站教学视频.
ros2官方文档.
ros2功能包
创客制造ros2教程
古月居ros2代码移植

安装ros2 foxy

可以使用鱼香ros一键配置ros环境,配置前记得将系统的源设置为国内源(清华源、中科大、阿里云等),鱼香ros一键安装ros2.
安装完后可以用小乌龟测试一下安装效果:

ros2 run turtlesim turtlesim_node 
ros2 run turtlesim turtle_teleop_key

小乌龟

配置vscode

这里就不将怎么安装vscode了,正常下载安装即可。使用vscode的目的只是为了写代码时可以有提示,更方便,不使用vscode也可以。
配置vscode主要包括安装插件,主要安装以下插件:

python;c/c++:对应编程语言解释器
Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code:汉化插件
ros:ros1插件
这里不推荐安装ros2插件,不太好用。

ros2基本操作

创建工作空间

mkdir -p ~/my_workspace/src
cd ~/my_workspace
colcon build

用上面的三句话就可以初始化一个工作空间,在ros2中,没有了catkin功能包。ros2的编译工具是colcon,但安装ros2时默认是不安装colcon的,因此要安装colcon:

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

只编译一个功能包:

colcon build --packages-select easy_planner

添加工作空间环境变量

和ros1不同,ros2添加环境变量是用下面的命令:

cd ~/my_workspace
source install/setup.bash

创建ros2功能包

创建功能包用以下命令:

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

安装第三方功能包

sudo apt install ros-[版本]-[功能包名]

这里的版本用系统当前环境变量ros版本代替,功能包名就是要安装的功能包的名字,比如我想安装ros2版本foxy的gazebo-ros功能包,则用下面的语句:

sudo apt install ros-foxy-gazebo-ros

节点相关指令

ros2 node list  //查看节点列表

功能包内相关文件注解

cmakelist.txt文件注解

先通过注释的方式解释一下功能包cmakelist.txt文件里的代码功能。

cmake_minimum_required(VERSION 3.5)    //指定cmake版本
project(easy_planner)              //指定功能包名称

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(nav_msgs REQUIRED)
find_package(tf2 REQUIRED)
find_package(tf2_ros REQUIRED)           //这些都是当前功能包依赖的其他外部功能包,
                                         //编译时,如果A功能包依赖了B功能包,
                                         //那就会先编译B功能包

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # uncomment the line when a copyright and license is not present in all source files
  #set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # uncomment the line when this package is not in a git repo
  #set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

include_directories(                     //指定头文件目录,当前头文件目录为功能包下的include目录
  include
)

add_executable(easy_planner1 src/easy_planner.cpp src/DStarPlanner.cpp)     //重点是下面这几个语句,这个语句是将cpp文件编译成为一个可执行文件,第一个参数即为可执行文件名,第二三个参数是互相关联的两个cpp文件,编译时,它们将编译成一个文件。
ament_target_dependencies(easy_planner1 rclcpp std_msgs geometry_msgs nav_msgs tf2 tf2_ros)  //指定可执行文件的依赖,比如说这里说的是easy_planner1依赖rclcpp、std_msgs等文件

add_executable(easy_planner2 src/easy_planner1.cpp src/DStarPlanner.cpp)  //同上
ament_target_dependencies(easy_planner2 rclcpp std_msgs geometry_msgs nav_msgs tf2 tf2_ros)

install(TARGETS
  easy_planner1
  DESTINATION lib/${PROJECT_NAME})        //这里是将编译完的可执行文件放到工作空间install目录下
                                         //如果没放到这个目录下,导入工作空间环境变量之后就可能找不到这个可执行文件。


install(TARGETS
  easy_planner2
  DESTINATION lib/${PROJECT_NAME})

ament_package()   

package.xml文件注解

再通过注释的方式讲一下package.xml文件的代码功能:

<?xml version="1.0"?>       //xml版本
<package format="2">
  <name>ugvc_planner</name>    //功能包名
  <version>0.0.0</version>
  <description>The ugvc_planner package</description>      //功能包描述

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="u5@todo.todo">u5</maintainer>
                    //记录作者等信息

  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>


  <!-- Url tags are optional, but multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/ugvc_localplanner</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->


  <!-- The *depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>   //对于这个文件,这些才是重点,当前功能包依赖了哪些其他功能包,都应该在这里列出来
  <depend>roscpp</depend>
  <depend>std_msgs</depend>
  <depend>geometry_msgs</depend>
  <depend>nav_msgs</depend>
  <depend>tf</depend>

  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

ros1代码向ros2移植技巧

下面我将通过我的移植经验向大家展示移植过程中的经验。

1、首先是现在ros2中文教程比较少,英文论坛里的内容也没有很多。很多ros2的中文教程都是英文直译而来,如果能看懂英文教程还是尽量区看英文教程: ros2官方文档.

2、有些功能我们如果没有找到对应教程,可以采用以下方法解决,这里举TF的例子。
在ros2中,TF的有些函数用法和ros1不太一样,比如下面的语句:

       tf::StampedTransform transformB2O;
       try
       {
           plistener.waitForTransform("/odom", "/base_link",
           ros::Time::now(), ros::Duration(10.0));
           plistener.lookupTransform("/odom", "/base_link",
           ros::Time(0), transformB2O);   // Global image
       }
       catch(tf::TransformException &ex) 
       {
           ROS_ERROR("%s",ex.what());
           ros::Duration(1.0).sleep();
           continue;
       }

这个语句就是用来订阅odom坐标系和base_link坐标系的TF的,但参考ros2官方教程,例程中只用了下面的语句:

        geometry_msgs::msg::TransformStamped transformStamped;

        // Look up for the transformation between target_frame and turtle2 frames
        // and send velocity commands for turtle2 to reach target_frame
        try {
          transformStamped = tf_buffer_->lookupTransform(
            toFrameRel, fromFrameRel,
            tf2::TimePointZero);
        } catch (tf2::TransformException & ex) {
          RCLCPP_INFO(
            this->get_logger(), "Could not transform %s to %s: %s",
            toFrameRel.c_str(), fromFrameRel.c_str(), ex.what());
          return;
        }

没有了waitForTransform函数。我试了一下,将这段代码替换原来的ros1的代码,发现终端总是会报下面的错误:

[turtle_tf2_listener_debug-4] [INFO] [1630223454.942322623] [listener_debug]: Could not transform odom to base_link: "odom" passed to lookupTransform argument target_frame does not exist

意思就是没收到odom到base_link的坐标转换,这就让我很迷惑,后面我又用了官方教程给的tf debug的教程:tf_debug,用

ros2 run tf2_ros tf2_echo odom base_link

终端显示可以有数据输出,即odom到base_link的转换是存在的。
在这里插入图片描述
我找了好久,终于在一个论坛里找到了答案,原来是因为接受时间序不对。但找到了问题怎么解决呢。我想到了一个办法,既然tf2_ros功能包的tf2_echo工具可以接收TF,那就看一下tf2_echo的源码是怎么写的,学习一下就行了。

于是我就去找到了它的源码,寻找过程如下:
先进入ros wiki中,找到packages并进入:
在这里插入图片描述
再在红线上的区域选择foxy,就可以找到foxy版本下的所有功能包,
在这里插入图片描述再在右上角的搜索栏输入tf2_ros就可以找到各个版本对应的tf2_ros功能包,选择foxy版本的进入:
在这里插入图片描述进入后在右边栏可以看到一个browse code,这个就是元源码入口,双击进入就可以看到tf2_ros功能包源码,我们找到tf2_echo实现代码,发现源码多了这部分,加入之后移植代码就可以接受TF数据了:
在这里插入图片描述
上面是第二个经验。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS1代码向ROS2移植 的相关文章

随机推荐

  • 基于Docker Desktop的PHP学习环境搭建(文科生笔记)

    目录 引言 一 学习设备 系统 1 设备 2 系统 3 工具 1 Docker Desktop for Windows 官网下载 2 VS Code 官网下载 3 Navicat Premium 二 PHP环境方案 nginx php 1
  • [Qt教程] 第2篇 在Ubuntu14.04上创建Qt 5.4.0开发环境

    导语 上一篇安装好了Ubuntu系统 在正式进行嵌入式开发之前 我们先在Ubuntu上安装Qt开发环境 确保可以正常进行桌面程序的开发 毕竟程序首先是要在桌面上测试的 这里我们使用最新的Qt 5 4 0版本 正文 一 下载并安装Qt 1 下
  • Matplotlib数据可视化基础

    一 了解绘图基础语法与常用参数 import matplotlib pyplot as plt import numpy as np 画图流程 1 创建画布 2 选定子图 3 绘制图形 4 添加图形 5 保存图形 6 显示图形 plt fi
  • python语法-面向对象(类的基本使用)

    python语法 面向对象 类的基本使用 1 设计一个类 class 类名称 类的属性 成员变量 类的行为 成员方法 class Student name None 记录学生姓名 gender None 记录学生性别 age None 记录
  • AI坦克-unity3D

    2 坦克对战游戏 AI 设计 从商店下载游戏 Kawaii Tank 或 其他坦克模型 构建 AI 对战坦克 具体要求 使用 感知 思考 行为 模型 建模 AI 坦克 场景中要放置一些障碍阻挡对手视线 坦克需要放置一个矩阵包围盒触发器 以保
  • Java 集合类 接口

    List Set Map Arrays Collection接口 Iterator 迭代器 接口 Iterator接口 Iterator 迭代器 接口并不是一种集合类型 用来遍历并有选择地删除集合中的元素 通过Collection接口定义的
  • 常用停用词表整理(哈工大停用词表,百度停用词表等)

    辣鸡CSDN https github com goto456 stopwords https zhuanlan zhihu com p 30002654 转载于 https www cnblogs com 0n the way p 105
  • 智能优化算法之萤火虫算法(FA)的实现(Python附源码)

    一 萤火虫算法的实现思路 萤火虫算法 Firefly Algorithm FA 是由Yang于2010年提出的一种群智能优化算法 在自然界中 萤火虫之间通过自身发光来吸引异性前来交配以及吸引猎物进行捕猎 而该算法主要仿照自然界中萤火虫之间受
  • gin获取用户请求IP

    nginx配置 作用就是在反向代理的时候 将用户ip设置到请求头中 location proxy set header X Forward For remote addr proxy set header X real ip remote
  • GCTA 报错信息: XtWX is not invertible。

    报错信息 XtWX is not invertible 1 在输入以下命令时 报错 gcta64 mbfile geno chrs txt grm sparse sp grm joint covar fastGWA mlm binary p
  • OpenDDS自学

    前言 最近做毕设要做一个DDS系统和TISA系统的网关 完全没有基础 只好对着OpenDDS的Developers Guide和 分布式系统实时发布 订阅数据分发技术 这本书一点一点学 顺便吐槽这本书就是guide的翻译版 很多语句不通 遇
  • Springboot整合Shiro

    目录 1 springboot整合shiro 认证 登录 1 1 创建springboot项目 1 2 引依赖 1 3 修改application配置文件 1 4 创建实体类 1 5 创建dao层 1 6 创建service层 1 7 编写
  • MMDetection 系列之(自定义数据管道处理增强管道)

    数据管道设计 遵循典型约定 我们使用Dataset和DataLoader对多个worker进行数据加载 数据集返回与模型的forward方法的参数相对应的数据项字典 由于目标检测中的数据可能不相同大小 图像大小 gt box大小等 我们在M
  • Linux下 Redis集群搭建详解(主从+哨兵)

    文章目录 前言 文章重点 一 Redis 入门简介 二 Redis 安装部署 1 下载安装包 2 安装 3 部署 4 启动redis服务 5 关闭redis服务 三 Redis 集群整体架构 四 Redis 主从配置及数据同步 1 主机配置
  • Windows消息机制

    一 简介 Windows程序设计是一种事件驱动的程序设计模式 主要是基于消息的 一个消息从产生到被一个窗口响应 其中有5个步骤 系统中发生了某个事件 Windows把这个事件翻译为消息 然后把它放到消息队列中 应用程序从消息队列中接收到这个
  • T-Kernel 内核介绍

    本文译至 http www t engine org ja what is t kernel t kernel T 内核是一个实时操作系统 它是T Engine的心脏 T Kernel 通过和称为T Kerneel扩展的中间件的组合 能够配
  • python输出结果换行_python输出时如何换行

    在我们常用的print 方法进行输出时 通常输出结果是整行显示出来的 这时候我们需要考虑一下 我们输出的结果需不需要换行 不需要换行的方法也是so esay的 这里就不多赘述了 来说说如何做到输出换行 常用的转义符方式 n coding u
  • Flink java wordcount

    Flnk java wordcount 前言 项目的目录结构 pom文件 WindowWordCount java helloword txt文件 运行结果 注意 前言 各位好 欢迎浏览我的博客 后面将持续更新小编在flink上学习的心得体
  • 21年广东计算机考研分数线,21年考研国家线公布_中国研究生招生信息网官方

    21年考研国家线公布 中国研究生招生信息网官方由广东研究生考试网考试快讯栏目由提供 更多关于考研成绩查询时间 考研国家线 广东研究生考试快讯的内容 请关注广东研究生考试频道 广东人事考试网 2020年下半年全国大学英语四 六级考试成绩 和2
  • ROS1代码向ROS2移植

    ROS1代码向ROS2移植 前言 安装ros2 foxy 配置vscode ros2基本操作 创建工作空间 添加工作空间环境变量 创建ros2功能包 安装第三方功能包 节点相关指令 功能包内相关文件注解 cmakelist txt文件注解