【Chrono Engine学习总结】4-vehicle-4.1-vehicle的基本概念

2024-02-13 13:12

本文主要是介绍【Chrono Engine学习总结】4-vehicle-4.1-vehicle的基本概念,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

1、基本介绍

Vehicle Overview
Vehicle Mannel
Vehicle的官方demo

1.1 Vehicle的构型

  • 一个车辆由许多子系统构成:悬挂、转向、轮子/履带、刹车/油门、动力传统系统(driverline)。
  • Chrono提供了一些典型的车辆模型,例如:悍马车、小型轿车等 vehicle models,只需要直接代码选定即可;
  • 如果不用官方的车型,就需要自己定义各种子系统。chono提供一些典型的子系统构型,例如悬挂包括:双横臂、前麦花臣支柱等 悬挂类型,转向包括:转向垂臂( Pitman arm)等转向类型。
  • 如果连官方的子系统都不想用,就需要自己定义一些弹簧/轴的连接,就复杂一些,一般采用JSON文件的方式,这样比较清晰明了。

1.2 Vehicle部分仿真的逻辑

https://api.projectchrono.org/vehicle_overview.html#vehicle_simulation_loop

每一步仿真时,依次执行:获取系统输出、同步各个系统(synchronize system)、系统动力学仿真前进一步(advance system)。

  • 在各个系统同步时,可能不仅包括vehicle的模块,还包括可视化等多个模块,同时vehicle部分需要同步:驾驶控制器、地型交互、车体、可视化等模块,如有。
  • 在同步之后,进行advance操作,前进一步。

正因为如此,在仿真代码中,每次loop最后会有这么两段:

// Update modules (process inputs from other modules
driver->Synchronize(time);
terrain.Synchronize(time);
hmmwv.Synchronize(time, driver_inputs, terrain);
vis->Synchronize(time, driver_inputs);
// Advance simulation for one timestep for all modules
driver->Advance(step_size);
terrain.Advance(step_size);
hmmwv.Advance(step_size);
vis->Advance(step_size);

1.3 vehicle的可视化

Vehicle的可视化与之前的整体仿真环境的可视化有些相同,但不完全相同。相同之处是,是选用irrlicht、还是OpenGL、还是离线POV-Ray可视化。我这里采用irrlicht。

除此之外,由于vehicle包括很多子模块,例如地盘、悬挂、轮胎等,在仿真时可以选择是否进行显示。一般显示方式为三种:不显示(VisualizationType::None)、显示基础结构(PRIMITIVES)、显示完整表面mesh(MESH)。例如,地盘、悬挂、转向、轮胎、外壳,全部显示MESH和只显示基础结构分别是这样的:
在这里插入图片描述
在这里插入图片描述

2. 车辆控制系统

2.1 控制系统基础概念

车辆控制系统在chrono里面称作“driver”,ChDriver。

对于车辆的控制,主要控制量只有两个:油门throttle(和刹车brake)、转向(steering 左/右)。

控制系统包括:交互控制ChIteractiveDriver、闭环控制ChClosedLoopDriver、AI Driver等多种方式,每个模块的控制代码写法不同。这里暂不展开介绍。

在这里插入图片描述

2.2 交互控制系统

这里采用较为简单的交互控制。交互控制通过可视化模块获取来自键盘的输入控制量,通过WSAD分别控制:加油门、刹车、左转向、右转向。需要注意,在开启交互控制前,需要按键j启动键盘控制,否则无效(注意是否关闭了中文输入法)。

交互系统部分的代码是这样的:

DriverInputs driver_inputs = driver->GetInputs();

之后,在调用driver->Advance函数时,即对车辆的控制量进行更新。

需要注意的是,在交互控制中,每次按键改变的是上述控制量的增量,即按一下油门,油门会增大一些。因此,并不是直接控制的速度,所以在操作时,需要练习手感。

在程序运行时,右上角会显示控制量和车辆状态:
在这里插入图片描述
可以看出,此时的油门是+88(油门控制量默认是0-100),刹车是0(通过按键S将油门在减为0后,刹车会上来),此时车速是8.51m/s,以及一些其他参数。

3、官方例子

这次以官方例子进行介绍:


#include "chrono/core/ChStream.h"
#include "chrono/utils/ChUtilsInputOutput.h"
#include "chrono/utils/ChFilters.h"
#include "chrono_vehicle/ChConfigVehicle.h"
#include "chrono_vehicle/ChVehicleModelData.h"
#include "chrono_vehicle/terrain/RigidTerrain.h"
#include "chrono_vehicle/output/ChVehicleOutputASCII.h"
#include "chrono_models/vehicle/hmmwv/HMMWV.h"
#include "chrono_thirdparty/filesystem/path.h"
#include "chrono_vehicle/driver/ChInteractiveDriverIRR.h"
#include "chrono_vehicle/wheeled_vehicle/ChWheeledVehicleVisualSystemIrrlicht.h"
#include <iostream>using namespace chrono;
using namespace chrono::irrlicht;
using namespace chrono::vehicle;
using namespace chrono::vehicle::hmmwv;// Simulation step sizes
double step_size = 1e-3;
double tire_step_size = step_size;
double t_end = 1000;// Time interval between two render frames
double render_step_size = 1.0 / 50;  // FPS = 50int main(int argc, char* argv[]) {chrono::SetChronoDataPath("E:/codeGit/chrono/chrono/build/data/");              // change the default data loading path.chrono::vehicle::SetDataPath("E:/codeGit/chrono/chrono/build/data/vehicle/");              // change the vehicle data pathChContactMethod contact_method = ChContactMethod::SMC;	// 设定碰撞类型// Create the HMMWV vehicle, set parameters, and initialize// 创建一个HMMWV车,注意如果有vehicle模块,则不需要重新定义一个物理系统,这个vehicle自带一个系统,可以直接给别的模块调用。HMMWV_Full hmmwv;hmmwv.SetCollisionSystemType(ChCollisionSystem::Type::BULLET);hmmwv.SetContactMethod(contact_method);hmmwv.SetChassisCollisionType(CollisionType::NONE);hmmwv.SetChassisFixed(false);hmmwv.SetInitPosition(ChCoordsys<>({ 0, 0, 0.5 }, { 1, 0, 0, 0 }));hmmwv.SetEngineType(EngineModelType::SHAFTS);hmmwv.SetTransmissionType(TransmissionModelType::SHAFTS);hmmwv.SetDriveType(DrivelineTypeWV::AWD);hmmwv.UseTierodBodies(true);hmmwv.SetSteeringType(SteeringTypeWV::PITMAN_ARM);hmmwv.SetBrakeType(BrakeType::SHAFTS);hmmwv.SetTireType(TireModelType::PAC02);hmmwv.SetTireStepSize(tire_step_size);hmmwv.Initialize();// Visualization type for vehicle parts (PRIMITIVES, MESH, or NONE)// 设置车辆各个模块的可视化程度。VisualizationType chassis_vis_type = VisualizationType::PRIMITIVES;VisualizationType suspension_vis_type = VisualizationType::PRIMITIVES;VisualizationType steering_vis_type = VisualizationType::PRIMITIVES;VisualizationType wheel_vis_type = VisualizationType::PRIMITIVES;VisualizationType tire_vis_type = VisualizationType::PRIMITIVES;hmmwv.SetChassisVisualizationType(chassis_vis_type);hmmwv.SetSuspensionVisualizationType(suspension_vis_type);hmmwv.SetSteeringVisualizationType(steering_vis_type);hmmwv.SetWheelVisualizationType(wheel_vis_type);hmmwv.SetTireVisualizationType(tire_vis_type);// Create the terrain 创建地形,并设置地形的一些物理参数。RigidTerrain terrain(hmmwv.GetSystem());ChContactMaterialData minfo;minfo.mu = 0.9f;minfo.cr = 0.01f;minfo.Y = 2e7f;auto patch_mat = minfo.CreateMaterial(contact_method);// Rigid terraindouble terrainHeight = 0;      // terrain height (FLAT terrain only)double terrainLength = 200.0;  // size in X directiondouble terrainWidth = 200.0;   // size in Y directionstd::shared_ptr<RigidTerrain::Patch> patch;patch = terrain.AddPatch(patch_mat, CSYSNORM, terrainLength, terrainWidth);patch->SetTexture(vehicle::GetDataFile("terrain/textures/dirt.jpg"), 200, 200);patch->SetColor(ChColor(0.8f, 0.8f, 0.5f));terrain.Initialize();// 创建基于irrlicht的可视化,以及交互控制系统。定义每次控制量、可hi话等内容。// ------------------------------------------------------------------------------// Create the vehicle run-time visualization interface and the interactive driver// ------------------------------------------------------------------------------// Set the time response for steering and throttle keyboard inputs.double steering_time = 1.0;  // time to go from 0 to +1 (or from 0 to -1)double throttle_time = 1.0;  // time to go from 0 to +1double braking_time = 0.3;   // time to go from 0 to +1std::shared_ptr<ChVehicleVisualSystem> vis;std::shared_ptr<ChDriver> driver;// Create the vehicle Irrlicht interfaceauto vis_irr = chrono_types::make_shared<ChWheeledVehicleVisualSystemIrrlicht>();       //~ ChWheeled这个类继承了可视化的基类vis_irr->SetWindowTitle("HMMWV Demo");vis_irr->SetChaseCamera({ 0.0, 0.0, 1.75 }, 6.0, 0.5);		// 将可视化的“相机位置”和车底盘上一点绑定。vis_irr->Initialize();vis_irr->AddLightDirectional();vis_irr->AddSkyBox();vis_irr->AddLogo();vis_irr->AttachVehicle(&hmmwv.GetVehicle());			// 将可视化与vehicle绑定// Create the interactive Irrlicht driver system  自定义每次按键的增量auto driver_irr = chrono_types::make_shared<ChInteractiveDriverIRR>(*vis_irr);driver_irr->SetSteeringDelta(render_step_size / steering_time);driver_irr->SetThrottleDelta(render_step_size / throttle_time);driver_irr->SetBrakingDelta(render_step_size / braking_time);driver_irr->Initialize();vis = vis_irr;driver = driver_irr;// ---------------// Simulation loop// ---------------// Number of simulation steps between miscellaneous eventsint render_steps = (int)std::ceil(render_step_size / step_size);// Initialize simulation frame countersint step_number = 0;int render_frame = 0;hmmwv.GetVehicle().EnableRealtime(true);while (vis->Run()) {double time = hmmwv.GetSystem()->GetChTime();// End simulationif (time >= t_end)break;// Render scene and output post-processing dataif (step_number % render_steps == 0) {vis->BeginScene();vis->Render();vis->EndScene();render_frame++;}// Driver inputsDriverInputs driver_inputs = driver->GetInputs();// Update modules (process inputs from other modules)driver->Synchronize(time);terrain.Synchronize(time);hmmwv.Synchronize(time, driver_inputs, terrain);vis->Synchronize(time, driver_inputs);// Advance simulation for one timestep for all modulesdriver->Advance(step_size);terrain.Advance(step_size);hmmwv.Advance(step_size);vis->Advance(step_size);            //~ 更新vis的trackpoint等。// Increment frame numberstep_number++;std::cout << "Step: " << step_number << std::endl;}return 0;}
}

运行这个例子,就可以用WASD控制悍马车在自定义的一个地形上开动了。

这篇关于【Chrono Engine学习总结】4-vehicle-4.1-vehicle的基本概念的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/705611

相关文章

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

AOP编程的基本概念与idea编辑器的配合体验过程

《AOP编程的基本概念与idea编辑器的配合体验过程》文章简要介绍了AOP基础概念,包括Before/Around通知、PointCut切入点、Advice通知体、JoinPoint连接点等,说明它们... 目录BeforeAroundAdvise — 通知PointCut — 切入点Acpect — 切面

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta