高翔《自动驾驶中的SLAM技术》代码详解 — 第6章 2D SLAM

目录

6.2 扫描匹配算法

6.2.1 点到点的扫描匹配


6.2 扫描匹配算法

6.2.1 点到点的扫描匹配

// src/ch6/test_2dlidar_io.cc
// Created by xiang on 2022/3/15.
//
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <opencv2/highgui.hpp>#include "ch6/lidar_2d_utils.h"
#include "common/io_utils.h"// DEFINE_string定义ROS数据包的路径
DEFINE_string(bag_path, "./dataset/sad/2dmapping/test_2d_lidar.bag", "数据包路径");/// 测试从rosbag中读取2d scan并plot的结果
int main(int argc, char** argv) {// 来初始化Google日志记录库google::InitGoogleLogging(argv[0]);// 将日志级别设置为INFOFLAGS_stderrthreshold = google::INFO;// 将日志输出到标准错误流(stderr)并带有彩色显示FLAGS_colorlogtostderr = true;// 将日志输出到标准错误流(stderr)并带有彩色显示google::ParseCommandLineFlags(&argc, &argv, true);// 创建了一个sad::RosbagIO对象rosbag_io,用于从rosbag中读取数据sad::RosbagIO rosbag_io(fLS::FLAGS_bag_path);rosbag_io.AddScan2DHandle("/pavo_scan_bottom",[](Scan2d::Ptr scan) {cv::Mat image;     // 存储可视化的扫描图像sad::Visualize2DScan(scan, SE2(), image, Vec3b(255, 0, 0)); //生成可视化的图像cv::imshow("scan", image);cv::waitKey(20);return true;}).Go();  // 用于从rosbag中读取数据return 0;
}
#include "ch6/lidar_2d_utils.h"
#include <opencv2/imgproc.hpp>namespace sad {
// 扫描数据(scan)、位姿(pose)、图像(image)、
// 颜色(color)、图像大小(image_size)、分辨率(resolution)、子地图的位姿(pose_submap)
void Visualize2DScan(Scan2d::Ptr scan, const SE2& pose, cv::Mat& image, const Vec3b& color, int image_size,float resolution, const SE2& pose_submap) {// 如果图像的数据为空,如果图像(image)的数据为空if (image.data == nullptr) {image = cv::Mat(image_size, image_size, CV_8UC3, cv::Vec3b(255, 255, 255));}// 扫描数据中的每一个激光点,判断激光点的测量距离是否在有效范围内for (size_t i = 0; i < scan->ranges.size(); ++i) {if (scan->ranges[i] < scan->range_min || scan->ranges[i] > scan->range_max) {continue;}// 计算当前激光点的真实角度double real_angle = scan->angle_min + i * scan->angle_increment;// 通过角度计算出该点在二维空间中的坐标(x, y)double x = scan->ranges[i] * std::cos(real_angle);double y = scan->ranges[i] * std::sin(real_angle);// 如果当前激光点的真实角度是否在可视范围内if (real_angle < scan->angle_min + 30 * M_PI / 180.0 || real_angle > scan->angle_max - 30 * M_PI / 180.0) {continue;}// 计算出激光点在地图坐标系下的坐标Vec2d psubmap = pose_submap.inverse() * (pose * Vec2d(x, y));// 将激光点在地图坐标系下的坐标映射到图像坐标系中int image_x = int(psubmap[0] * resolution + image_size / 2);int image_y = int(psubmap[1] * resolution + image_size / 2);// 判断像素坐标是否在图像的有效范围内if (image_x >= 0 && image_x < image.cols && image_y >= 0 && image_y < image.rows) {image.at<cv::Vec3b>(image_y, image_x) = cv::Vec3b(color[0], color[1], color[2]);}}// 同时画出pose自身所在位置Vec2d pose_in_image =pose_submap.inverse() * (pose.translation()) * double(resolution) + Vec2d(image_size / 2, image_size / 2);cv::circle(image, cv::Point2f(pose_in_image[0], pose_in_image[1]), 5, cv::Scalar(color[0], color[1], color[2]), 2);
}}  // namespace s

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/60304.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【实测有效】朋友圈截图生成,制作朋友圈网页教程

使用教程可以自己看工具的使用手册。 Windows电脑版&#xff1a; https://imageio.jscs.top/zip/wxchat-moment-windows Mac电脑版&#xff1a; https://imageio.jscs.top/zip/wxchat-moment-mac 比如&#xff0c;你可以使用朋友圈评论生成器制作一段搞笑的评论回复&#…

Android Camera预览画面变形问题

csdn 问题 安卓camera1在预览时&#xff0c;预览画面看起来被拉伸了&#xff0e; 如图&#xff0c;圆形的盖子&#xff0c;变成椭圆形了&#xff0e; 代码 默认流程&#xff0c;如下为大致的打开摄像头并进行预览显示的代码 private Camera mCamera null; private Surfa…

sentinel客户端和dashboard交互

回顾 在前面的章节中&#xff1a;通过阐述sentinel简单使用、滑动窗口、核心流程源码分析把sentinel限流、熔断等主要功能说明清楚了&#xff0c;但我们在实际使用的过程中&#xff0c;不可能通过硬编码的方式设置规则&#xff0c;且规则也没法直观的维护&#xff0c;为此肯定…

图像的缩放之c++实现(qt + 不调包)

1.基本原理 图像的缩放一般使用插值算法&#xff0c;而本章将介绍两种常用插值算法&#xff1a;最临近插值法和双线性插值法 1.最临近插值法 将浮点数的位置坐标&#xff0c;进行四舍五入找到原图像的整型坐标即可&#xff0c;具体操作可见下面的公式&#xff0c;其中原图像坐标…

Java培训出来的好找工作吗?能拿多少工资?

作为编程界“泰斗”级别的语言&#xff0c;Java进可攻前端、后可守后端&#xff0c;还是很受市场青睐的&#xff0c;那为什么很多程序员抱怨太卷了&#xff0c;找工作难&#xff1f;这其实是企业业务需求的原因&#xff0c;产品更新、迭代速度极快&#xff0c;企业需要的是“来…

贝叶斯深度学习的温和介绍

一、说明 欢迎来到令人兴奋的概率编程世界&#xff01;本文是对这个领域的温和介绍&#xff0c;你只需要对深度学习和贝叶斯统计有一个基本的了解。如果像我一样&#xff0c;你听说过贝叶斯深度学习&#xff0c;并且你猜它涉及贝叶斯统计&#xff0c;但你不知道它是如何使用的&…

现代C++中的从头开始深度学习【1/8】:基础知识

一、说明 提及机器学习框架与研究和工业的相关性。现在很少有项目不使用Google TensorFlow或Meta PyTorch&#xff0c;在于它们的可扩展性和灵活性。也就是说&#xff0c;花时间从头开始编码机器学习算法似乎违反直觉&#xff0c;即没有任何基本框架。然而&#xff0c;事实并非…

汽车及汽车零部件行业云MES解决方案

汽配行业现状&#xff1a; 随着经济全球化进程加快&#xff0c;一直走在智能化改造&#xff0c;数字化转型前沿的汽车行业企业&#xff0c;面临的信息化需求也日益增加&#xff0c;不管德系&#xff0c;美系还是日系供应链的各大厂商&#xff0c;均将企业信息化&#xff0c;数字…

HTTP代理与HTTPS代理请求的方式揭秘

今天&#xff0c;我们要一起来揭秘HTTP代理与HTTPS代理请求的方式&#xff0c;帮助大家更好地理解和使用这两种代理。我们将分析它们的不同之处&#xff0c;并提供一些实际的例子和操作经验&#xff0c;让你轻松玩转网络请求&#xff01; HTTP代理请求方式&#xff1a; HTTP代…

linux程序保护机制gcc编译选项

预备知识&#xff1a; 计算机内存的结构通常包括以下几个主要部分&#xff1a; 1.代码段(Code Segment)&#xff1a;也称为文本段&#xff0c;存储程序的可执行指令。代码段是被标记为可执行的&#xff0c;程序从代码段中获取指令并执行。 2.数据段(Data Segment)&#xff1a…

AD19 基础应用技巧(PCB设置快捷键)

众所周知&#xff0c;学会一个软件的快捷键操作可以大大提高我们的工作效率。 那么&#xff0c;Altium Designer软件如何设置快捷键&#xff1f; 以设置走线/放置过孔为例。 菜单栏 - 【放置】- 然后【Ctrl 鼠标左键 单击过孔】进入【Edit Command】界面。 在快捷方式一栏…

发布属于自己的 npm 包

1 创建文件夹&#xff0c;并创建 index.js 在文件中声明函数&#xff0c;使用module.exports 导出 2 npm 初始化工具包&#xff0c;package.json 填写包的信息&#xff08;包的名字是唯一的&#xff09; npm init 可在这里写包的名字&#xff0c;或者一路按回车&#xff0c;后…