ROS学习笔记

| 参考:

  1. Autolabor Ros

  2. linux命令行代理神器-proxychains

  3. 中科院软件所-机器人操作系统入门(ROS入门教程)

1 安装ROS

1.1 更换国内源

sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'

1.2 设置 key

sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654

1.3 安装操作

sudo apt update

sudo apt install ros-noetic-desktop-full

sudo apt remove ros-noetic-*  # 卸载 ros

1.4 配置环境变量

echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc

1.5 安装依赖项

sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential

sudo apt install python3-rosdep

sudo rosdep init

# 终端代理 proxychains
sudo apt install proxychains

sudo vim /etc/proxychains.conf

# 添加代理,以 socks5 为例
socks5 127.0.0.1 9999 username password

# 使用方法:在需要用到代理的命令行前加上 proxychains
proxychains curl cip.cc


rosdep update # # 这一步需要访问外网资源,所以需要设置一下终端代理,命令如下

proxychains rosdep update

2 HelloWorld 实例演示

2.1 创建空间并初始化

mkdir -p test/src && cd test
catkin_make

2.2 添加依赖性

cd src

catkin_create_pkg helloworld(自定义ROS包名) roscpp rospy std_msgs

2.3 编程实现

# 该目录下 test/src/helloworld/src
touch helloworld_c.cpp
sudo vim helloworld_c.cpp  # 编写源码文件

#############################
# 文件内容如下:
// 1. 包含 ros 头文件
#include "ros/ros.h"

// 2. 编写 main 函数
int main(int argc, char *argv[]) {
	// 3. 初始化 ros 节点
	ros::init(argc, argv, "hello_node");
	// 4. 输出日志
	ROS_INFO("hello world");
	return 0;
}

2.4 编辑 CMakeList.txt 文件

# vim 显示行号
:set number

add_executable(源文件名 src/源文件名.cpp) # 第一个参数可随意起名,映射到第二个参数指定的文件
add_executable(hello src/helloworld_c.cpp)

target_link_libraries(源文件名 ${catkin_LIBRARIES})
target_link_libraries(hello ${catkin_LIBRARIES})

2.5 编译运行

# 在工作空间下 /home/sebas/projects/ros-projects/test 编译
catkin_make

# 启动,另起一个窗口
roscore

# 在工作空间下 /home/sebas/projects/ros-projects/test 编译
source ./devel/setup.bash
rosrun helloworld(包名) hello

编译和运行截图如下:
运行截图

3 VSCode开发环境配置

3.1 terminator 使用

sudo apt install terminator

# 快捷键
Ctrl+Shift+O                    //水平分割终端
Ctrl+Shift+E                    //垂直分割终端
Ctrl+Shift+F                    //搜索
Ctrl+Shift+C                    //复制选中的内容到剪贴板
Ctrl+Shift+V                    //粘贴剪贴板的内容到此处
Ctrl+Shift+W                    //关闭当前终端
Ctrl+Shift+Q                    //退出当前窗口,当前窗口的所有终端都将被关闭
Ctrl+Shift+X                    //最大化显示当前终端
Ctrl+Shift+Z                    //最大化显示当前终端并使字体放大
Ctrl+Shift+N or Ctrl+Tab        //移动到下一个终端
Ctrl+Shift+P or Ctrl+Shift+Tab  //Crtl+Shift+Tab 移动到之前的一个终端

4 中国科学院软件所 ROS 入门

ROS 工程结构
在这里插入图片描述

4.1 package

ROS软件的基本组织形式,catkin编译的基本单元,一个package可以包含多个可执行文件(节点)。基本组成:CMakeList.txt 和 package.xml

  • CMakeList.txt : 规定 catkin 编译的规则,例如源文件、依赖项、目标文件
    在这里插入图片描述

  • package.xml : 定义了 package 的属性,例如包名、版本号、作者、依赖等。
    在这里插入图片描述

  • manifest.xml:rosbuild 编译系统采用的包信息清单,类似 catkin 的 package.xml

  • 自定义通信格式:消息(msg)、服务(srv)、动作(action)

  • launch 以及配置文件: launch 文件(一次性运行多个可执行文件)、配置文件(yaml)

  • 常用的包管理指令
    在这里插入图片描述

4.2 基本流程

# 安装 tree,以树形结构展示目录
sudo apt install tree

mkdir -p catkin_ws/src && cd catkin_ws
tree
catkin_make  # 初始化
tree

cd src
catkin_create_pkg test1	 # 最基础的 package

catkin_create_pkg test2 roscpp rospy std_msgs nav_msgs  # 安装所需要的依赖项
tree

proxychains git clone https://github.com/DroidAITech/ROS-Academy-for-Beginners.git

cd ..
rosdep install --from-paths src --ignore-src --rosdistro=noetic -y

5 lingyun_ros

5.1 目录结构

catkin_ws   
- build(保存编译完成后的二进制可执行文件)
- devel
- map_data (数据文件)
- src (该目录存放功能包等要实现的文件)
    - lingyun_subscriber (订阅图像和点云)
    	- CMakeLists.txt(需要自行编辑 需要的库、要编译的源文件等)
    	- src
       	 	- image_subscriber.cc
        	- pointCloud_subscriber.cc
    - lingyun_launch(启动多个ros节点)
    	- launch
        	- lingyun.launch

5.2 详细步骤

  • 创建工作空间并配置环境变量
# 创建一个工作空间并初始化
mkdir -p catkin_ws/src
cd catkin_ws/src
catkin_init_workspace

# 编译工作空间
cd catkin_ws/
catkin_make

# 环境变量
# 每次编译(catkin_make)完成后,需要更新一下环境变量
source devel/setup.bash
# 也可以把这句写到 ~/.bashrc 中,这样就不用每次都更新

# 检查环境变量
echo $ROS_PACKAGE_PATH 
  • 创建功能包
cd catkin_ws/src
catkin_create_pkg lingyun_subscriber std_msgs rospy roscpp

# 创建功能包 lingyun_subscriber 后,该目录下会自动生成 CMakeLists.txt 和 package 等文件,CMakeLists.txt 文件需要自己配置,具体参考附件 。src 目录下存放要实现的源码文件
# 例如实现订阅图像和点云的功能,具体代码参考附件
touch image_subscriber.cc
touch pointCloud_subscriber.cc

# 编译功能包,在 catkin_ws 目录下执行以下命令
catkin_make

# 编译完成后在build目录下会生成对应的二进制可执行文件

source catkin_ws/devel/setup.bash


自己编写的定位建图等代码也可以直接放到 src 目录下,将 code 复制到 src 目录下,配置好 CMakeList.txt 文件,使用 catkin_make 也可以编译成功

  • roslaunch文件的编写
# roslaunch
cd catkin_ws/src

# 在 catkin_ws/src 目录下创建 roslaunch 的功能包
catkin_create_pkg lingyun_launch

# 创建一个 launch 目录用于存放 launch 文件
cd lingyun_launch
mkdir launch && cd launch
touch lingyun.launch

# lingyun.launch 文件内容
# pkg:节点所在功能包名称
# name:节点的可执行文件名称
# type:节点运行时的名称

<launch>
    <node pkg="tlingyun_subscriber" name="image_subscriber" type="image_subscriber"/>
    <node pkg="lingyun_subscriber" name="pointCloud_subscriber" type="pointCloud_subscriber"/>
    <node pkg="code" name="test_lattest" type="test_lattest"/>
</launch>

# 编写完 launch 文件后,回到 catkin_ws 目录执行编译操作并更新环境变量
catkin_make
source devel/setup.bash # 如果在 ~/.bashrc 文件中配置了就不需要这一步

# 使用 launch 文件启动多个 ros 节点
roslaunch lingyun_launch lingyun.launch

使用 roslaunch 命令启动节点的时候,可能会报错找不到可执行的二进制文件,需要把 catkin_ws/build/code 和 catkin_ws/build/lingyun_subscriber 目录下的二进制可执行文件分别复制到 catkin_ws/src/code 和 catkin_ws/src/lingyun_subscribe 目录下。

附件

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)

IF(NOT ROS_BUILD_TYPE)
  SET(ROS_BUILD_TYPE Release)
ENDIF()

MESSAGE("Build type: " ${ROS_BUILD_TYPE})

project(lidar_relocalization)

set(CMAKE_C_FLAGS_RELEASE "-O3")

add_definitions(-w)
################################
# OpenCV
################################
find_package(OpenCV 3)
if(NOT OpenCV_FOUND)
   find_package(OpenCV 2.4.3 QUIET)
   if(NOT OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
   endif()
endif()


find_package(Eigen3 3.1.0 REQUIRED)
find_package(PCL REQUIRED COMPONENT common io visualization filters)

find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   geometry_msgs
   nav_msgs
   tf
   cv_bridge   
)

# include_directories(${CATKIN_INCLUDE_DIRS})
include_directories(${catkin_INCLUDE_DIRS})

include_directories(${roscpp_INCLUDE_DIRS})
include_directories(${PCL_INCLUDE_DIRS})
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(src)
message(${PCL_INCLUDE_DIRS})


# add_definitions(-DLOG_OUT)



# target_include_directories(reloc PUBLIC 
# orbslam_lib/include
# orbslam_lib/include/CameraModels
# orbslam_lib/Thirdparty/Sophus 
# orbslam_lib)


# Node for monocular camera
# rosbuild_add_executable(Test test_ros.cc)
# target_link_libraries(Test reloc ${OpenCV_LIBRARIES} ${PCL_LIBRARIES})

# add_executable(test_ros test_ros.cc)
# target_link_libraries(test_ros reloc ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${PCL_LIBRARIES})

# add_executable(test1 test.cc)
# target_link_libraries(test1 reloc ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${PCL_LIBRARIES})

add_executable(image_subscriber src/image_subscriber.cc)
target_link_libraries(image_subscriber ${OpenCV_LIBRARIES} ${roscpp_LIBRARIES} ${catkin_LIBRARIES})

add_executable(pointCloud_subscriber src/pointCloud_subscriber.cc)
target_link_libraries(pointCloud_subscriber ${OpenCV_LIBRARIES} ${PCL_LIBRARIES} ${roscpp_LIBRARIES} ${catkin_LIBRARIES})

# add_executable(main main.cc)
# target_link_libraries(main reloc ${OpenCV_LIBRARIES} ${PCL_LIBRARIES})


#add_executable(test test.cc)
# target_include_directories(test PUBLIC 
# orbslam_lib/include
# orbslam_lib/include/CameraModels
# orbslam_lib/Thirdparty/Sophus 
# orbslam_lib)
#target_link_libraries(test reloc ${OpenCV_LIBRARIES} ${PCL_LIBRARIES})

订阅图像和点云

  • image_subscriber.cc
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/mat.hpp>
#include <time.h>

#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>

using namespace std;

string cam0_path = "./SaveImgAndPCD/cam0/";

void ImageCallback(const sensor_msgs::ImageConstPtr& img_msg)
{
    
    ROS_INFO("image: ",img_msg -> data);

    // // Copy the ros image message to cv::Mat.
    // cv_bridge::CvImageConstPtr cv_ptr;
    // try
    // {
    //     cv_ptr = cv_bridge::toCvShare(msg);
    // }
    // catch (cv_bridge::Exception& e)
    // {
    //     ROS_ERROR("cv_bridge exception: %s", e.what());
    //     return;
    // }

    
    //double timestamps = img_msg -> header.stamp.toSec();
    //image_times.push_back(timestamps);
    cv_bridge::CvImageConstPtr ptr;
    ptr = cv_bridge::toCvCopy(img_msg, img_msg -> encoding);
    cv::Mat show_image = ptr -> image;

    double timestamps = img_msg -> header.stamp.toSec();
    string image_name = to_string(timestamps) + ".jpg";

    cv::imwrite(cam0_path + image_name, show_image); // 保存
    cv::imshow("img", show_image);
    //images.push_back(show_image);

}

int main(int argc, char **argv) {
    ros::init(argc, argv, "RGBD");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/usb_cam_30s/image_raw", 10, ImageCallback);
    ros::spin();

    return 0;
}
  • pointCloud_subscriber.cc
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/mat.hpp>
#include <time.h>

#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>


#include "pcl/io/pcd_io.h"
#include "pcl/point_cloud.h"
#include "pcl/point_types.h"
#include "pcl_conversions/pcl_conversions.h"
#include "ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
 
static size_t counter = 0;
std::string PCD_PATH = "./SaveImgAndPCD/PCD/";
 
void PointCloudCallback(const sensor_msgs::PointCloud2ConstPtr& lidar_message) {
  pcl::PointCloud<pcl::PointXYZI> point_cloud;
  pcl::fromROSMsg(*lidar_message, point_cloud);
  
  counter++;
  std::string file_name = "point_cloud_" + std::to_string(counter) + ".pcd";
  pcl::io::savePCDFile(PCD_PATH + file_name, point_cloud);
}
 
int main(int argc, char **argv) {
  ros::init(argc, argv, "point_cloud_subscriber");
  ros::NodeHandle node_handle;
  ros::Subscriber point_cloud_sub = node_handle.subscribe("/benewake_ros_driver_node/benewake_pointcloud", 1, PointCloudCallback);
  ros::spin();
 
  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值