泉州快速建站模板,微信网页版登陆,网站开发需要的技术人才,网站开发有哪些竞赛由于Chrono的官方教程在一些细节方面解释的并不清楚#xff0c;自己做了一些尝试#xff0c;做学习总结。
1、Sensor模块
Sensor模块是附加模块#xff0c;需要单独安装。参考#xff1a;【Chrono Engine学习总结】1-安装配置与程序运行
Sensor Module Tutorial Sensor …由于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.htmlScene是和camera相关的场景设置例如背景色、光照等其他内容不展开介绍。
传感器当中“光学”传感器例如相机、lidar、radar等依赖OptiX这个库。具体的依赖关系如下
2、创建Sensor的流程
这里全部以lidar为例进行介绍。
2.0 创建传感器管理器
在chrono中所有传感器需要注册在sensor manager当中由其统一进行管理。
管理器的创建、添加一个具体的sensor、仿真时数据更新3行代码如下
// 创建管理器
auto manager chrono_types::make_sharedChSensorManager(sys);
// 添加一个sensorAddSensor(std::shared_ptrChSensor 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_sharedChLidarSensor(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_sharedChFilterDIAccess()); // 允许后续获取depth和intensity的filter
lidar-PushFilter(chrono_types::make_sharedChFilterVisualize(horizontal_samples / 2, vertical_samples * 5, Raw Lidar Depth Data)); // 将雷达数据可视化为深度图像的可视化filter
lidar-PushFilter(chrono_types::make_sharedChFilterPCfromDepth()); // 通过深度获取点云的filter
lidar-PushFilter(chrono_types::make_sharedChFilterLidarNoiseXYZI(0.01f, 0.001f, 0.001f, 0.01f)); // 对XYZI增加噪声的filter
lidar-PushFilter(chrono_types::make_sharedChFilterVisualizePointCloud(640, 480, 2, Lidar Point Cloud)); // 点云可视化的filter
lidar-PushFilter(chrono_types::make_sharedChFilterXYZIAccess()); // 获取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.husing 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_sharedChBodyEasyBox(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_sharedChBodyEasyBox(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_sharedChBodyEasyBox(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_sharedChSensorManager(sys);manager-SetVerbose(false);// -----------------------------------------------// Create a lidar and add it to the sensor manager// -----------------------------------------------// 自定义代码方式创建一个lidarauto offset_pose chrono::ChFramedouble({ -4, 0, 1 }, Q_from_AngAxis(0, { 0, 1, 0 }));auto lidar chrono_types::make_sharedChLidarSensor(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_sharedChFilterVisualize(horizontal_samples / 2, vertical_samples * 5, Raw Lidar Depth Data));// Convert Depth,Intensity data to XYZI pointlidar-PushFilter(chrono_types::make_sharedChFilterPCfromDepth());// Add a noise model filter to the lidar sensorswitch (noise_model) {case CONST_NORMAL_XYZI:lidar-PushFilter(chrono_types::make_sharedChFilterLidarNoiseXYZI(0.1f, 0.001f, 0.001f, 0.01f));break;case NONE:// Dont add any noise modelsbreak;} Render the point cloudlidar-PushFilter(chrono_types::make_sharedChFilterVisualizePointCloud(640, 480, 2, Lidar Point Cloud));// Access the lidar data as an XYZI bufferlidar-PushFilter(chrono_types::make_sharedChFilterXYZIAccess());// 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;
}