ROS2 驱动思岚G4雷达(ydlidar)- Rviz显示

2023-10-29

记录G4雷达的配置


系统环境为:Ubuntu22.04

配置步骤

1、安装雷达SDK
2、构建 G4 雷达 ROS2 项目工程文件
3、使用Rviz可视化界面显示


1、安装雷达SDK

1.1 安装CMake

YDLidar SDK需要CMake 2.8.2+作为依赖项

  • Ubuntu 18.04或者Ubuntu 22.04
sudo apt install cmake pkg-config

如果使用python API,您需要安装python和swig(3.0或更高版本)

sudo apt-get install python swig
sudo apt-get install python-pip

1.2 构建YDLidar SDK

在YDLidar SDK目录中,运行以下命令来编译项目:

git clone https://github.com/YDLIDAR/YDLidar-SDK.git
cd YDLidar-SDK/build
cmake ..
make
sudo make install

注意:如果已经安装了python和swig,sudo make install命令也将安装python API,而无需执行以下操作,在这里建议大家还是使用一次 sudo make install 确认安装成功

至此,若在编译过程中未出现错误,即为SDK安装成功

2、构建 G4 雷达 ROS2 项目工程文件

2.1 编译和安装YDLidar SDK

ydlidar_ros2_driver依赖于ydlidar SDK库。如果从未安装过YDLidar SDK库,则必须首先安装YDLidar SDK库,具体的可以参考上一点:

2.2 Cylinder_ros2_driver克隆

(1)为github克隆ydlidar_ros2_driver包:

git clone https://github.com/YDLIDAR/ydlidar_ros2_driver.git ydlidar_ros2_ws/src/ydlidar_ros2_driver

(2)构建ydlidar_ros2_driver包

cd ydlidar_ros2_ws
colcon build --symlink-install

(3)程序包环境设置:
将工作空间添加到环境变量里面

source ./install/setup.bash

同样可以使用比较长久的方法:

echo "source ~/ydlidar_ros2_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc

在这里 “~/ydlidar_ros2_ws/install/setup.bash路径要对应上自己的工作空间当中的setup.bash位置。

(4)确认要确认包路径已设置,请打印grep-i ROS变量

printenv | grep -i ROS

应该看到类似的内容:OLDPWD=/home/tony/ydlidar_ros2_ws/install
(5)创建串行端口别名[可选]

sudo chmod 0777 src/ydlidar_ros2_driver/startup/*
sudo sh src/ydlidar_ros2_driver/startup/initenv.sh

3、使用Rviz可视化界面显示

使用启动文件运行ydlidar_ros2_driver

3.1 运行雷达启动launch文件

ros2 launch ydlidar_ros2_driver ydlidar_launch.py 

或者

ros2 launch $(ros2 pkg prefix ydlidar_ros2_driver)/share/ydlidar_ros2_driver/launch/ydlidar.py 

3.2运行可视化界面

如果想要运行可视化界面的话可以使用一下命令,单独在终端里运行即可

ros2 launch ydlidar_ros2_driver ydlidar_launch_view.py 

在这里插入图片描述
在这里插入图片描述
3、查看一下雷达扫描话题信息

ros2 run ydlidar_ros2_driver ydlidar_ros2_driver_client or ros2 topic echo /scan

在这里插入图片描述

问题解决

1、launch文件修改

在编译过程当中,出现了ydlidar_launch_view.py文件或者ydlidar_launch.py文件中的
[ERROR] [launch]: Caught exception in launch LifecycleNode: __init__() missing 1 required keyword-only argument: 'node_executable'
这样的错误警告,将两个文件当中含有node_[后缀名称]更改为[后缀名称即可]
例如,在本次报错当中,需要将LifecycleNode这个节点的node_executable更改为executable即可,其他的node_name同样的更改为 name

#!/usr/bin/python3
# Copyright 2020, EAIBOT
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from ament_index_python.packages import get_package_share_directory

from launch import LaunchDescription
from launch_ros.actions import LifecycleNode
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.actions import LogInfo

import lifecycle_msgs.msg
import os


def generate_launch_description():
    share_dir = get_package_share_directory('ydlidar_ros2_driver')
    rviz_config_file = os.path.join(share_dir, 'config','ydlidar.rviz')
    parameter_file = LaunchConfiguration('params_file')
    # node_name = 'ydlidar_ros2_driver_node'

    params_declare = DeclareLaunchArgument('params_file',
                                           default_value=os.path.join(
                                               share_dir, 'params', 'ydlidar.yaml'),
                                           description='FPath to the ROS2 parameters file to use.')

    driver_node = LifecycleNode(package='ydlidar_ros2_driver',
                                executable='ydlidar_ros2_driver_node',
                                name='ydlidar_ros2_driver_node',
                                output='screen',
                                emulate_tty=True,
                                parameters=[parameter_file],
                                namespace='/',
                                )
    tf2_node = Node(package='tf2_ros',
                    executable='static_transform_publisher',
                    name='static_tf_pub_laser',
                    arguments=['0', '0', '0.02','0', '0', '0', '1','base_link','laser_frame'],
                    )
    rviz2_node = Node(package='rviz2',
                    executable='rviz2',
                    name='rviz2',
                    arguments=['-d', rviz_config_file],
                    )

    return LaunchDescription([
        params_declare,
        driver_node,
        tf2_node,
        rviz2_node,
    ])

上图对应的是 "ydlidar_launch_view.py"文件,然后ydlidar_launch.py文件中对应的两个参数,也就是node_executable和node_name 两个变量名字做出修改,修改后如下代码所示:

#!/usr/bin/python3
# Copyright 2020, EAIBOT
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from ament_index_python.packages import get_package_share_directory

from launch import LaunchDescription
from launch_ros.actions import LifecycleNode
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.actions import LogInfo

import lifecycle_msgs.msg
import os


def generate_launch_description():
    share_dir = get_package_share_directory('ydlidar_ros2_driver')
    parameter_file = LaunchConfiguration('params_file')
    # node_name = 'ydlidar_ros2_driver_node'

    params_declare = DeclareLaunchArgument('params_file',
                                           default_value=os.path.join(
                                               share_dir, 'params', 'ydlidar.yaml'),
                                           description='FPath to the ROS2 parameters file to use.')

    driver_node = LifecycleNode(package='ydlidar_ros2_driver',
                                executable='ydlidar_ros2_driver_node',
                                name='ydlidar_ros2_driver_node',
                                output='screen',
                                emulate_tty=True,
                                parameters=[parameter_file],
                                namespace='/',
                                )
    tf2_node = Node(package='tf2_ros',
                    executable='static_transform_publisher',
                    name='static_tf_pub_laser',
                    arguments=['0', '0', '0.02','0', '0', '0', '1','base_link','laser_frame'],
                    )

    return LaunchDescription([
        params_declare,
        driver_node,
        tf2_node,
    ])

建议使用 vscode 编辑器对文本进行更改,以便可以重复撤回和更加便携式的文本切换

2、如果出现node节点链接错误

然后就是在编译过程(colcon build --symlink-install)中,如果出现node节点链接错误的情况,需要更改当前目录下的
ydlidar_ros2_driver/src/ydlidar_ros2_driver_node.cpp 这个文件内容(直接复制替换即可)

/*
 *  YDLIDAR SYSTEM
 *  YDLIDAR ROS 2 Node
 *
 *  Copyright 2017 - 2020 EAI TEAM
 *  http://www.eaibot.com
 *
 */

/* Modified for Humble by @lghrainbow  10/2022 */

#ifdef _MSC_VER
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#endif

#include "src/CYdLidar.h"
#include <math.h>
#include <chrono>
#include <iostream>
#include <memory>

#include "rclcpp/clock.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/time_source.hpp"
#include "sensor_msgs/msg/laser_scan.hpp"
#include "std_srvs/srv/empty.hpp"
#include <vector>
#include <iostream>
#include <string>
#include <signal.h>

#define ROS2Verision "1.0.2"   /* 1.0.1 modified */


int main(int argc, char *argv[]) {
  rclcpp::init(argc, argv);

  auto node = rclcpp::Node::make_shared("ydlidar_ros2_driver_node");

  RCLCPP_INFO(node->get_logger(), "[YDLIDAR INFO] Current ROS Driver Version: %s\n", ((std::string)ROS2Verision).c_str());

  CYdLidar laser;
  std::string str_optvalue = "/dev/ydlidar";
  node->declare_parameter<std::string>("port");
  node->get_parameter("port", str_optvalue);
  ///lidar port
  laser.setlidaropt(LidarPropSerialPort, str_optvalue.c_str(), str_optvalue.size());

  ///ignore array
  str_optvalue = "";
  node->declare_parameter<std::string>("ignore_array");
  node->get_parameter("ignore_array", str_optvalue);
  laser.setlidaropt(LidarPropIgnoreArray, str_optvalue.c_str(), str_optvalue.size());

  std::string frame_id = "laser_frame";
  node->declare_parameter<std::string>("frame_id");
  node->get_parameter("frame_id", frame_id);

  //int property/
  /// lidar baudrate
  int optval = 230400;
  node->declare_parameter<int>("baudrate");
  node->get_parameter("baudrate", optval);
  laser.setlidaropt(LidarPropSerialBaudrate, &optval, sizeof(int));
  /// tof lidar
  optval = TYPE_TRIANGLE;
  node->declare_parameter<int>("lidar_type");
  node->get_parameter("lidar_type", optval);
  laser.setlidaropt(LidarPropLidarType, &optval, sizeof(int));
  /// device type
  optval = YDLIDAR_TYPE_SERIAL;
  node->declare_parameter<int>("device_type");
  node->get_parameter("device_type", optval);
  laser.setlidaropt(LidarPropDeviceType, &optval, sizeof(int));
  /// sample rate
  optval = 9;
  node->declare_parameter<int>("sample_rate");
  node->get_parameter("sample_rate", optval);
  laser.setlidaropt(LidarPropSampleRate, &optval, sizeof(int));
  /// abnormal count
  optval = 4;
  node->declare_parameter<int>("abnormal_check_count");
  node->get_parameter("abnormal_check_count", optval);
  laser.setlidaropt(LidarPropAbnormalCheckCount, &optval, sizeof(int));
     

  //bool property/
  /// fixed angle resolution
  bool b_optvalue = false;
  node->declare_parameter<bool>("fixed_resolution");
  node->get_parameter("fixed_resolution", b_optvalue);
  laser.setlidaropt(LidarPropFixedResolution, &b_optvalue, sizeof(bool));
  /// rotate 180
  b_optvalue = true;
  node->declare_parameter<bool>("reversion");
  node->get_parameter("reversion", b_optvalue);
  laser.setlidaropt(LidarPropReversion, &b_optvalue, sizeof(bool));
  /// Counterclockwise
  b_optvalue = true;
  node->declare_parameter<bool>("inverted");
  node->get_parameter("inverted", b_optvalue);
  laser.setlidaropt(LidarPropInverted, &b_optvalue, sizeof(bool));
  b_optvalue = true;
  node->declare_parameter<bool>("auto_reconnect");
  node->get_parameter("auto_reconnect", b_optvalue);
  laser.setlidaropt(LidarPropAutoReconnect, &b_optvalue, sizeof(bool));
  /// one-way communication
  b_optvalue = false;
  node->declare_parameter<bool>("isSingleChannel");
  node->get_parameter("isSingleChannel", b_optvalue);
  laser.setlidaropt(LidarPropSingleChannel, &b_optvalue, sizeof(bool));
  /// intensity
  b_optvalue = false;
  node->declare_parameter<bool>("intensity");
  node->get_parameter("intensity", b_optvalue);
  laser.setlidaropt(LidarPropIntenstiy, &b_optvalue, sizeof(bool));
  /// Motor DTR
  b_optvalue = false;
  node->declare_parameter<bool>("support_motor_dtr");
  node->get_parameter("support_motor_dtr", b_optvalue);
  laser.setlidaropt(LidarPropSupportMotorDtrCtrl, &b_optvalue, sizeof(bool));

  //float property/
  /// unit: °
  float f_optvalue = 180.0f;
  node->declare_parameter<float>("angle_max");
  node->get_parameter("angle_max", f_optvalue);
  laser.setlidaropt(LidarPropMaxAngle, &f_optvalue, sizeof(float));
  f_optvalue = -180.0f;
  node->declare_parameter<float>("angle_min");
  node->get_parameter("angle_min", f_optvalue);
  laser.setlidaropt(LidarPropMinAngle, &f_optvalue, sizeof(float));
  /// unit: m
  f_optvalue = 64.f;
  node->declare_parameter<float>("range_max");
  node->get_parameter("range_max", f_optvalue);
  laser.setlidaropt(LidarPropMaxRange, &f_optvalue, sizeof(float));
  f_optvalue = 0.1f;
  node->declare_parameter<float>("range_min");
  node->get_parameter("range_min", f_optvalue);
  laser.setlidaropt(LidarPropMinRange, &f_optvalue, sizeof(float));
  /// unit: Hz
  f_optvalue = 10.f;
  node->declare_parameter<float>("frequency");
  node->get_parameter("frequency", f_optvalue);
  laser.setlidaropt(LidarPropScanFrequency, &f_optvalue, sizeof(float));

  bool invalid_range_is_inf = false;
  node->declare_parameter<bool>("invalid_range_is_inf");
  node->get_parameter("invalid_range_is_inf", invalid_range_is_inf);


  bool ret = laser.initialize();
  if (ret) {
    ret = laser.turnOn();
  } else {
    RCLCPP_ERROR(node->get_logger(), "%s\n", laser.DescribeError());
  }
  
  auto laser_pub = node->create_publisher<sensor_msgs::msg::LaserScan>("scan", rclcpp::QoS(rclcpp::SensorDataQoS()));

  auto stop_scan_service =
    [&laser](const std::shared_ptr<rmw_request_id_t> request_header,
  const std::shared_ptr<std_srvs::srv::Empty::Request> req,
  std::shared_ptr<std_srvs::srv::Empty::Response> response) -> bool
  {
    return laser.turnOff();
  };

  auto stop_service = node->create_service<std_srvs::srv::Empty>("stop_scan",stop_scan_service);

  auto start_scan_service =
    [&laser](const std::shared_ptr<rmw_request_id_t> request_header,
  const std::shared_ptr<std_srvs::srv::Empty::Request> req,
  std::shared_ptr<std_srvs::srv::Empty::Response> response) -> bool
  {
    return laser.turnOn();
  };

  auto start_service = node->create_service<std_srvs::srv::Empty>("start_scan",start_scan_service);

  rclcpp::WallRate loop_rate(20);

  while (ret && rclcpp::ok()) {

    LaserScan scan;//

    if (laser.doProcessSimple(scan)) {

      auto scan_msg = std::make_shared<sensor_msgs::msg::LaserScan>();

      scan_msg->header.stamp.sec = RCL_NS_TO_S(scan.stamp);
      scan_msg->header.stamp.nanosec =  scan.stamp - RCL_S_TO_NS(scan_msg->header.stamp.sec);
      scan_msg->header.frame_id = frame_id;
      scan_msg->angle_min = scan.config.min_angle;
      scan_msg->angle_max = scan.config.max_angle;
      scan_msg->angle_increment = scan.config.angle_increment;
      scan_msg->scan_time = scan.config.scan_time;
      scan_msg->time_increment = scan.config.time_increment;
      scan_msg->range_min = scan.config.min_range;
      scan_msg->range_max = scan.config.max_range;
      
      int size = (scan.config.max_angle - scan.config.min_angle)/ scan.config.angle_increment + 1;
      scan_msg->ranges.resize(size);
      scan_msg->intensities.resize(size);
      for(size_t i=0; i < scan.points.size(); i++) {
        int index = std::ceil((scan.points[i].angle - scan.config.min_angle)/scan.config.angle_increment);
        if(index >=0 && index < size) {
          scan_msg->ranges[index] = scan.points[i].range;
          scan_msg->intensities[index] = scan.points[i].intensity;
        }
      }

      laser_pub->publish(*scan_msg);


    } else {
      RCLCPP_ERROR(node->get_logger(), "Failed to get scan");
    }
    if(!rclcpp::ok()) {
      break;
    }
    rclcpp::spin_some(node);
    loop_rate.sleep();
  }


  RCLCPP_INFO(node->get_logger(), "[YDLIDAR INFO] Now YDLIDAR is stopping .......");
  laser.turnOff();
  laser.disconnecting();
  rclcpp::shutdown();

  return 0;
}

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

ROS2 驱动思岚G4雷达(ydlidar)- Rviz显示 的相关文章

随机推荐

  • 高通平台环境搭建,编译,系统引导流程分析

    1 高通平台android开发总结 1 1 搭建高通平台环境开发环境 在高通开发板上烧录文件系统 建立高通平台开发环境 高通平台 android和 modem 编译流程分析 高通平台 7620 启动流程分析 qcril 流程分析 设置sim
  • 永磁同步电机矢量控制(八)——弱磁控制(超前角弱磁)

    注 1 此为永磁同步控制系列文章之一 应大家的要求 关于永磁同步矢量控制的系列文章已经在主页置顶 大家可以直接去主页里面查阅 希望能给大家带来帮助 谢谢 2 矢量控制的六篇文章后 弱磁 MTPA 位置控制系列讲解已经补充 也放在主页了 请大
  • Mac 下安装PIL

    记python学习处理图片 Mac环境 大家都知道Mac自带python环境 但是在处理特殊需求的时候需要安装额外的模块 直接上干货 1 安装PIL http effbot org media downloads Imaging 1 1 7
  • python while、try、continue、break综合使用 简单演示

    python 的 while try continue break综合使用 简单演示 作为一个超级小白 由于我只是用python来辅助做些重复性工作 并不是编程人员 大多数时间并不搞程序 很多不常用的功能很容易忘掉 以后会逐渐记录一些实际操
  • QT对话框去掉帮助和关闭按钮

    建了一个对话框 我不想把边框去掉 只想去掉关闭按钮 setWindowFlags windowFlags Qt WindowCloseButtonHint Qt WindowContextHelpButtonHint 结果那个问号的按钮去掉
  • 使用ExcelJS快速处理Node.js爬虫数据

    什么是ExcelJS ExcelJS是一个用于处理Excel文件的JavaScript库 它可以让你使用JavaScript创建 读取和修改Excel文件 以下是ExcelJS的一些主要特点 支持xlsx xlsm xlsb xls格式的E
  • 【剑指Offer59 - I】滑动窗口的最大值

    题目描述 2021 3 26 给定一个数组 nums 和滑动窗口的大小 k 请找出所有滑动窗口里的最大值 示例 输入 nums 1 3 1 3 5 3 6 7 和 k 3 输出 3 3 5 5 6 7 解释 滑动窗口的位置 最大值 1 3
  • Laravel collection break continue

    背景 Laravel框架中循环我们都推荐使用 collect 进行循环 但是如果我们想要在循环中 break 或者 continue 直接break或者continue 语法层面会直接报错 那么怎么才能实现上述所要的效果呢 其实在循环中 r
  • 基于MIV的神经网络变量筛选----基于BP神经网络的变量筛选

    基于MIV的神经网络变量筛选 基于BP神经网络的变量筛选 清空环境变量 clc clear 产生输入 输出数据 设置步长 interval 0 01 产生x1 x2 x1 1 5 interval 1 5 x2 1 5 interval 1
  • 黑苹果不能收到系统更新通知修复

    问题现象 最近黑苹果12 6 升级到 13 1 后 13 2 系统发布后 检查系统更新 显示当前系统为最新版本 没有收到系统更新通知 解决方案 OpenCore Configurator 编辑器 把misc security secureB
  • 动态规划python实现

    什么叫动态规划问题 考虑一个场景 当你有去沙漠旅行 你有一个背包和一些物品 背包有最大承受重量 物品也有重量和价值 而物品种类很多 不可能全都装在背包里 如何去选取价值总量最高的物品组合呢 物品价值表 物品名 价值 water 10 boo
  • Scala基础介绍

    Scala是一门主要以Java虚拟机 JVM 为目标运行环境 并将面向对象和函数式编程有机的结合在一起 因为Scala运行于JVM上 所以Scala可以访问任何Java类库 并且能够与Java框架进行互操作 Scala既有动态语言的灵活简洁
  • Javacv在Windows下正常运行,在Linux上报异常~Could not initialize class org.bytedeco.javacv.FFmpegFrameGrabber

    1 问题描述 今天来分享一个违背Java跨平台的问题 在学习Java第一课老师肯定就是吹嘘Java如何强大 如何跨平台 如何一次编译 到处执行 本文就遇见了在本地windows环境开发没有问题 在Linux的服务器上运行各种异常 这不是有点
  • NodeJs session中间件 及应用(简单的登录与登出)

    session中间件用于为了保存用户数据提供一个session管理器 虽然session中的数据与cookie分开保存 但是session中的数据经过加密处理后默认保存在一个cookie中 因此 在使用session中间件之前必须使用cok
  • layui 中的一些问题

    使用layui 版本号2 4 5 在引入js css之后 1 水平导航栏二级菜单一直不能显示 解决办法 最后发现layui all js引入不能放
  • 有趣的数据结构算法2——快速排序

    有趣的数据结构算法2 快速排序 题目复述 题目分析 具体实现代码 GITHUB下载连接 题目复述 数据排序算法是一类常见算法 其适用范围深入编程的方方面面 常见的数据排序算法有冒泡排序 堆排序 简单选择排序等等 各个适用范围不同 快速排序由
  • 13-Error接口错误处理以及go Module

    Error接口和错误处理 Go语言中的错误处理和其他语言不一样 它把错误当成一种值来处理 更强调判断错误 处理错误 而不是一股脑的catch错误 error接口 Go语言中把错误当成一种特殊的值来处理 不支持其他语言的try catch 捕
  • 【matlab】常用快捷键汇总

    记录自己常用的快捷键 冲冲冲 命令行窗口的常用快捷键 上下光标键 调用Matlab最近使用过的历史命令 便于快速重新执行 编辑器的常用快捷键 Ctrl R 快速注释代码段 拖动鼠标选中需要注释的代码行 Ctrl T 快速取消注释代码段 ht
  • Linux命令之tftp常用参数说明

    tftp 文件传输 实际操作 put 上传 get 下载 mode 文件传输模式 connect 连接 quit 退出 参数 g 下载文件 p 上传文件 l 本地文件名 r 远程主机文件名 常用命令 tftp g r a 10 0 0 1
  • ROS2 驱动思岚G4雷达(ydlidar)- Rviz显示

    记录G4雷达的配置 系统环境为 Ubuntu22 04 配置步骤 1 安装雷达SDK 2 构建 G4 雷达 ROS2 项目工程文件 3 使用Rviz可视化界面显示 1 安装雷达SDK 1 1 安装CMake YDLidar SDK需要CMa