当前位置: 首页 > news >正文

【Chrono Engine学习总结】5-sensor-5.1-sensor基础并创建一个lidar

由于Chrono的官方教程在一些细节方面解释的并不清楚,自己做了一些尝试,做学习总结。

1、Sensor模块

Sensor模块是附加模块,需要单独安装。参考:【Chrono Engine学习总结】1-安装配置与程序运行

Sensor Module Tutorial
Sensor Overview

Sensor模块包括的内容如下:
在这里插入图片描述
其中:

  • Sensors模块是核心,包括各种传感器(IMU、GPS、相机、Lidar、Radar等),以及传感器管理器等;
  • Sensor Filters是对sensor原始数据进行滤波(我认为更准确说应该是“处理方式”),即从原始数据得到我们想要的数据。https://api.projectchrono.org/group__sensor__filters.html
  • Scene是和camera相关的场景设置,例如背景色、光照等;
  • 其他内容不展开介绍。

传感器当中,“光学”传感器,例如相机、lidar、radar等,依赖OptiX这个库。具体的依赖关系如下:
在这里插入图片描述

2、创建Sensor的流程

这里全部以lidar为例,进行介绍。

2.0 创建传感器管理器

在chrono中,所有传感器需要注册在sensor manager当中,由其统一进行管理。

管理器的创建、添加一个具体的sensor、仿真时数据更新,3行代码如下:

// 创建管理器
auto manager = chrono_types::make_shared<ChSensorManager>(&sys);
// 添加一个sensor:AddSensor(std::shared_ptr<ChSensor> sensor)
manager->AddSensor(lidar);
// 在仿真循环中,更新所有传感器数据:
manager->Update();

2.1 从JSON文件载入预定义好的sensor

官方提供了一些已经定义好的sensor,包括:通用相机、VLP16雷达、HDL32雷达、通用GPS、通用IMU等,这些的调用只需要一行代码即可实现创建。例如,直接创建一个VLP16的雷达:

auto vlp16 = Sensor::CreateFromJSON(GetChronoDataFile("sensor/json/Velodyne/VLP-16.json"), box_body, offset_pose);
manager->AddSensor(vlp16);

我们可以打开这个JSON文件,查看VLP16的具体参数:
在这里插入图片描述

2.2 通过代码方式逐步创建一个sensor

通过代码方式创建,就是通过代码将JSON中的格式,完全自己配置一遍,例如:

auto lidar =chrono_types::make_shared<ChLidarSensor>(box_body,                               // body lidar is attached toupdate_rate,                            // scanning rate in Hzoffset_pose,                            // offset pose900,                                    // number of horizontal samples30,                                     // number of vertical channelshorizontal_fov,                         // horizontal field of viewmax_vert_angle, min_vert_angle, 100.0f  // vertical field of view);
lidar->SetName("Lidar Sensor 1");
lidar->SetLag(lag);
lidar->SetCollectionWindow(collection_time);lidar->PushFilter(chrono_types::make_shared<ChFilterDIAccess>());			// 允许后续获取depth和intensity的filter
lidar->PushFilter(chrono_types::make_shared<ChFilterVisualize>(horizontal_samples / 2, vertical_samples * 5, "Raw Lidar Depth Data"));			// 将雷达数据可视化为深度图像的可视化filter
lidar->PushFilter(chrono_types::make_shared<ChFilterPCfromDepth>());		// 通过深度获取点云的filter
lidar->PushFilter(chrono_types::make_shared<ChFilterLidarNoiseXYZI>(0.01f, 0.001f, 0.001f, 0.01f));	// 对XYZI增加噪声的filter
lidar->PushFilter(chrono_types::make_shared<ChFilterVisualizePointCloud>(640, 480, 2, "Lidar Point Cloud"));		// 点云可视化的filter
lidar->PushFilter(chrono_types::make_shared<ChFilterXYZIAccess>());		// 获取XYZI数据的filter
manager->AddSensor(lidar);		// 添加lidar到管理器

可以看出,设置了一些列的filter。当然,在上面的JSON中,也有许多filter,有些filter有参数,例如ChFilterLidarNoiseXYZI,有些没有例如ChFilterPCfromDepth。这些filter是干什么的呢?我个人理解,这些光学传感器获得的原始数据,需要加上这些filter之后,才具备我们平常使用这些sensor的数据格式。

例如,对于lidar来说,设置了ChFilterXYZIAccess后,才可以获取XYZI的数据;设置ChFilterLidarNoiseXYZI后,可以对XYZI增加高斯噪声;设置ChFilterVisualizePointCloud和ChFilterVisualize后,会出现三维点云和二位深度图的可视化(如下图)。所以,filter认为是“功能实现途径”比较合适。
在这里插入图片描述
所以:sensor的原始数据只是从光学系统中获得的特性,并没有转化成我们希望的“传感器数据格式”,需要通过filter进行实现。这些filter(对于lidar)负责添加噪声、二维图像可视化、三维点云可视化、获取点云XYZI格式、获取深度信息,(对于camera)转灰度图、像素噪声等。详细参考:【chrono::sensor::ChFilter Class Reference】

2.3 通过JSON方式自定义创建sensor

除了官方自定义的两个lidar的JSON外,还可以自定义lidar的配置。就创建对应的JSON并修改配置即可,无需多言。

3、参考代码

#include <cmath>
#include <cstdio>
#include <iomanip>
#include "chrono/assets/ChVisualShapeTriangleMesh.h"
#include "chrono/assets/ChVisualMaterial.h"
#include "chrono/assets/ChVisualShape.h"
#include "chrono/geometry/ChTriangleMeshConnected.h"
#include "chrono/physics/ChBodyEasy.h"
#include "chrono/physics/ChSystemNSC.h"
#include "chrono/utils/ChUtilsCreators.h"
#include "chrono_thirdparty/filesystem/path.h"#include "chrono_sensor/sensors/ChLidarSensor.h"
#include "chrono_sensor/ChSensorManager.h"
#include "chrono_sensor/filters/ChFilterAccess.h"
#include "chrono_sensor/filters/ChFilterPCfromDepth.h"
#include "chrono_sensor/filters/ChFilterVisualize.h"
#include "chrono_sensor/filters/ChFilterVisualizePointCloud.h"
#include "chrono_sensor/filters/ChFilterLidarReduce.h"
#include "chrono_sensor/filters/ChFilterLidarNoise.h"
#include "chrono_sensor/filters/ChFilterSavePtCloud.h"
#include "chrono_sensor/sensors/Sensor.h"using namespace chrono;
using namespace chrono::geometry;
using namespace chrono::sensor;// Noise model attached to the sensor
enum NoiseModel {CONST_NORMAL_XYZI,  // Gaussian noise with constant mean and standard deviationNONE                // No noise model
};
NoiseModel noise_model = CONST_NORMAL_XYZI;// Lidar return mode
// Either STRONGEST_RETURN, MEAN_RETURN, FIRST_RETURN, LAST_RETURN
LidarReturnMode return_mode = LidarReturnMode::STRONGEST_RETURN;// Update rate in Hz
float update_rate = 5.f;// Number of horizontal and vertical samples
unsigned int horizontal_samples = 4500;
unsigned int vertical_samples = 32;// Horizontal and vertical field of view (radians)
float horizontal_fov = (float)(2 * CH_C_PI);  // 360 degree scan
float max_vert_angle = (float)CH_C_PI / 12;   // 15 degrees up
float min_vert_angle = (float)-CH_C_PI / 6;   // 30 degrees down// Lag time
float lag = 0.f;// Collection window for the lidar
float collection_time = 1 / update_rate;  // typically 1/update rate// Simulation step size
double step_size = 1e-3;
// Simulation end time
float end_time = 2000.0f;
// Save lidar point clouds
bool save = false;
// Render lidar point clouds
bool vis = false;int main(int argc, char* argv[]) {GetLog() << "Copyright (c) 2019 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n";chrono::SetChronoDataPath("E:/codeGit/chrono/chrono/build/data/");              // change the default data loading path.// 创建物理仿真环境// -----------------// Create the system// -----------------ChSystemNSC sys;// 在左、右、下方各创建一面墙// --------------------------------------------// add a few box bodies to be sensed by a lidar// --------------------------------------------auto box_body = chrono_types::make_shared<ChBodyEasyBox>(100, 100, 1, 1000, true, false);box_body->SetPos({ 0, 0, -1 });box_body->SetBodyFixed(true);sys.Add(box_body);auto box_body_1 = chrono_types::make_shared<ChBodyEasyBox>(100, 1, 100, 1000, true, false);box_body_1->SetPos({ 0, -10, -3 });box_body_1->SetBodyFixed(true);sys.Add(box_body_1);auto box_body_2 = chrono_types::make_shared<ChBodyEasyBox>(100, 1, 100, 1000, true, false);box_body_2->SetPos({ 0, 10, -3 });box_body_2->SetBodyFixed(true);sys.Add(box_body_2);// 创建sensor管理器// -----------------------// Create a sensor manager// -----------------------auto manager = chrono_types::make_shared<ChSensorManager>(&sys);manager->SetVerbose(false);// -----------------------------------------------// Create a lidar and add it to the sensor manager// -----------------------------------------------// 自定义代码方式,创建一个lidarauto offset_pose = chrono::ChFrame<double>({ -4, 0, 1 }, Q_from_AngAxis(0, { 0, 1, 0 }));auto lidar =chrono_types::make_shared<ChLidarSensor>(box_body,                               // body lidar is attached toupdate_rate,                            // scanning rate in Hzoffset_pose,                            // offset pose900,                                    // number of horizontal samples30,                                     // number of vertical channelshorizontal_fov,                         // horizontal field of viewmax_vert_angle, min_vert_angle, 100.0f  // vertical field of view);lidar->SetName("Lidar Sensor 1");lidar->SetLag(lag);lidar->SetCollectionWindow(collection_time);// 添加相应的滤波器filter// Renders the raw lidar datalidar->PushFilter(chrono_types::make_shared<ChFilterVisualize>(horizontal_samples / 2, vertical_samples * 5, "Raw Lidar Depth Data"));// Convert Depth,Intensity data to XYZI pointlidar->PushFilter(chrono_types::make_shared<ChFilterPCfromDepth>());// Add a noise model filter to the lidar sensorswitch (noise_model) {case CONST_NORMAL_XYZI:lidar->PushFilter(chrono_types::make_shared<ChFilterLidarNoiseXYZI>(0.1f, 0.001f, 0.001f, 0.01f));break;case NONE:// Don't add any noise modelsbreak;} Render the point cloudlidar->PushFilter(chrono_types::make_shared<ChFilterVisualizePointCloud>(640, 480, 2, "Lidar Point Cloud"));// Access the lidar data as an XYZI bufferlidar->PushFilter(chrono_types::make_shared<ChFilterXYZIAccess>());// add sensor to the managermanager->AddSensor(lidar);// 从JSON文件直接载入VLP16雷达配置// Lidar from JSON file - Velodyne VLP-16auto vlp16 = Sensor::CreateFromJSON(GetChronoDataFile("sensor/json/Velodyne/VLP-16.json"), box_body, offset_pose);manager->AddSensor(vlp16);float ch_time = 0.0;std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();while (ch_time < end_time) {// 传感器数据更新// Will render/save/filter automaticallymanager->Update();// 系统动力学更新sys.DoStepDynamics(step_size);// Get the current time of the simulationch_time = (float)sys.GetChTime();}return 0;
}

相关文章:

【Chrono Engine学习总结】5-sensor-5.1-sensor基础并创建一个lidar

由于Chrono的官方教程在一些细节方面解释的并不清楚&#xff0c;自己做了一些尝试&#xff0c;做学习总结。 1、Sensor模块 Sensor模块是附加模块&#xff0c;需要单独安装。参考&#xff1a;【Chrono Engine学习总结】1-安装配置与程序运行 Sensor Module Tutorial Sensor …...

springboot/ssm学生信息管理系统Java学生在线选课考试管理系统

springboot/ssm学生信息管理系统Java学生在线选课考试管理系统 开发语言&#xff1a;Java 框架&#xff1a;springboot&#xff08;可改ssm&#xff09; vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.…...

three.js 箭头ArrowHelper的实践应用

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div></div></el-main></…...

力扣hot2--哈希

推荐博客&#xff1a; for(auto i : v)遍历容器元素_for auto 遍历-CSDN博客 字母异位词都有一个特点&#xff1a;也就是对这个词排序之后结果会相同。所以将排序之后的string作为key&#xff0c;将排序之后能变成key的单词组vector<string>作为value。 class Solution …...

【正在更新】从零开始认识语音识别:DNN-HMM混合系统语音识别(ASR)原理

摘要 | Abstract 这是一篇对语音识别中的一种热门技术——DNN-HMM混合系统原理的透彻介绍。本文自2月10日开始撰写&#xff0c;计划一星期内写完。 1.前言 | Introduction 近期想深入了解语音识别(ASR)中隐马尔可夫模型(HMM)和深度神经网络-隐马尔可夫(DNN-HMM)混合模型&#…...

thinkphp+vue企业产品展示网站f7enu

本文首先介绍了企业产品展示网站管理技术的发展背景与发展现状&#xff0c;然后遵循软件常规开发流程&#xff0c;首先针对系统选取适用的语言和开发平台&#xff0c;根据需求分析制定模块并设计数据库结构&#xff0c;再根据系统总体功能模块的设计绘制系统的功能模块图&#…...

在Ubuntu22.04上部署ComfyUI

ComfyUI 是 一个基于节点流程的 Stable Diffusion 操作界面&#xff0c;可以通过流程&#xff0c;实现了更加精准的工作流定制和完善的可复现性。每一个模块都有特定的的功能&#xff0c;我们可以通过调整模块连接达到不同的出图效果&#xff0c;特点如下&#xff1a; 1.对显存…...

Springboot+vue的社区养老服务平台(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的社区养老服务平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的社区养老服务平台&#xff0c;采用M&#xff08;model&…...

计算机设计大赛 深度学习+opencv+python实现车道线检测 - 自动驾驶

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &am…...

机器学习2---逻辑回归(基础准备)

逻辑回归是基于线性回归是直线分的也可以做多分类 ## 数学基础 import numpy as np np.pi # 三角函数 np.sin() np.cos() np.tan() # 指数 y3**x # 对数 np.log10(10) np.log2(2) np.e np.log(np.e) #ln(e)# 对数运算 # log(AB) log(A) logB np.log(3*4)np.log(3)np.log(4) #…...

JVM体系

JVM是一种虚拟的计算机&#xff0c;它模拟了一个完整的硬件系统&#xff0c;并运行在一个完全隔离的环境中。这意味着JVM可以看作是一个在操作系统之上的计算机系统&#xff0c;与VMware、Virtual Box等虚拟机类似。JVM的设计目标是提供一个安全、可靠、高效且跨平台的运行环境…...

.NET命令行(CLI)常用命令

本文用于记录了.NET软件开发全生命周期各阶段常用的一些CLI命令&#xff0c;用于开发速查。 .NET命令行&#xff08;CLI&#xff09;常用命令 项目创建&#xff08;1&#xff09;查看本机SDK&#xff08;2&#xff09;查看本机可以使用的.NET版本&#xff08;3&#xff09;生成…...

六、Redis之数据持久化及高频面试题

6.1 数据持久化 官网文档地址&#xff1a;https://redis.io/docs/manual/persistence/ Redis提供了主要提供了 2 种不同形式的持久化方式&#xff1a; RDB&#xff08;Redis数据库&#xff09;&#xff1a;RDB 持久性以指定的时间间隔执行数据集的时间点快照。AOF&#xff0…...

爬虫——ajax和selenuim总结

为什么要写这个博客呢&#xff0c;这个代码前面其实都有&#xff0c;就是结束了。明天搞个qq登录&#xff0c;这个就结束了。 当然也会更新小说爬取&#xff0c;和百度翻译&#xff0c;百度小姐姐的爬取&#xff0c;的对比爬取。总结嘛&#xff01;&#xff01;&#xff01;加…...

【Python】单元测试unittest框架

note 使用unittest框架进行单元测试是Python标准库的一部分&#xff0c;提供了编写测试用例、测试套件以及运行测试的能力。测试用例是继承自unittest.TestCase的类。在这个类中&#xff0c;你可以定义一系列的方法来测试不同的行为。每个测试方法都应该以test开头。 文章目录…...

(三十七)大数据实战——Solr服务的部署安装

前言 Solr是一个基于Apache Lucene的开源搜索平台&#xff0c;它提供了强大的全文搜索、分布式搜索和数据分析功能。Solr 可以用于构建高性能的搜索应用程序&#xff0c;支持从海量数据中快速检索和分析信息。Solr 使用倒排索引和先进的搜索算法&#xff0c;可实现快速而准确的…...

在Ubuntu22.04上部署FoooCUS2.1

Fooocus 是一款基于 Gradio的图像生成软件&#xff0c;Fooocus 是对 Stable Diffusion 和 Midjourney 设计的重新思考&#xff1a; 1、从 Stable Diffusion 学习&#xff0c;该软件是离线的、开源的和免费的。 2、从 Midjourney 中学到&#xff0c;不需要手动调整&#xff0c;…...

详解C语言中的野指针和assert断言

目录 1.野指针1.1 野指针成因1.1.1 指针未初始化1.1.2 指针越界访问1.1.3 指针指向的空间释放 1.2 如何规避野指针1.2.1 指针初始化1.2.2 小心指针越界1.2.3 指针变量不再使用时&#xff0c;及时置为NULL&#xff0c;指针使用之前检查1.2.4 避免返回局部变量的地址 2.assert断言…...

Vue源码系列讲解——模板编译篇【四】(文本解析器)

1. 前言 在上篇文章中我们说了&#xff0c;当HTML解析器解析到文本内容时会调用4个钩子函数中的chars函数来创建文本型的AST节点&#xff0c;并且也说了在chars函数中会根据文本内容是否包含变量再细分为创建含有变量的AST节点和不包含变量的AST节点&#xff0c;如下&#xff…...

微信小程序开发学习笔记《17》uni-app框架-tabBar

微信小程序开发学习笔记《17》uni-app框架-tabBar 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、创建tabBar分支 运行如下的命令&#xff0c;基于master分支在本地创建tabBar子分支&#x…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...