赞
踩
由于Chrono的官方教程在一些细节方面解释的并不清楚,自己做了一些尝试,做学习总结。
Vehicle Overview
Vehicle Mannel
Vehicle的官方demo
https://api.projectchrono.org/vehicle_overview.html#vehicle_simulation_loop
每一步仿真时,依次执行:获取系统输出、同步各个系统(synchronize system)、系统动力学仿真前进一步(advance system)。
正因为如此,在仿真代码中,每次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);
Vehicle的可视化与之前的整体仿真环境的可视化有些相同,但不完全相同。相同之处是,是选用irrlicht、还是OpenGL、还是离线POV-Ray可视化。我这里采用irrlicht。
除此之外,由于vehicle包括很多子模块,例如地盘、悬挂、轮胎等,在仿真时可以选择是否进行显示。一般显示方式为三种:不显示(VisualizationType::None
)、显示基础结构(PRIMITIVES
)、显示完整表面mesh(MESH
)。例如,地盘、悬挂、转向、轮胎、外壳,全部显示MESH和只显示基础结构分别是这样的:
车辆控制系统在chrono里面称作“driver”,ChDriver。
对于车辆的控制,主要控制量只有两个:油门throttle(和刹车brake)、转向(steering 左/右)。
控制系统包括:交互控制ChIteractiveDriver、闭环控制ChClosedLoopDriver、AI Driver等多种方式,每个模块的控制代码写法不同。这里暂不展开介绍。
这里采用较为简单的交互控制。交互控制通过可视化模块获取来自键盘的输入控制量,通过WSAD分别控制:加油门、刹车、左转向、右转向。需要注意,在开启交互控制前,需要按键j
启动键盘控制,否则无效(注意是否关闭了中文输入法)。
交互系统部分的代码是这样的:
DriverInputs driver_inputs = driver->GetInputs();
之后,在调用driver->Advance
函数时,即对车辆的控制量进行更新。
需要注意的是,在交互控制中,每次按键改变的是上述控制量的增量,即按一下油门,油门会增大一些。因此,并不是直接控制的速度,所以在操作时,需要练习手感。
在程序运行时,右上角会显示控制量和车辆状态:
可以看出,此时的油门是+88(油门控制量默认是0-100),刹车是0(通过按键S将油门在减为0后,刹车会上来),此时车速是8.51m/s,以及一些其他参数。
这次以官方例子进行介绍:
#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 = 50 int 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 path ChContactMethod 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 terrain double terrainHeight = 0; // terrain height (FLAT terrain only) double terrainLength = 200.0; // size in X direction double terrainWidth = 200.0; // size in Y direction std::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 +1 double braking_time = 0.3; // time to go from 0 to +1 std::shared_ptr<ChVehicleVisualSystem> vis; std::shared_ptr<ChDriver> driver; // Create the vehicle Irrlicht interface auto 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 events int render_steps = (int)std::ceil(render_step_size / step_size); // Initialize simulation frame counters int step_number = 0; int render_frame = 0; hmmwv.GetVehicle().EnableRealtime(true); while (vis->Run()) { double time = hmmwv.GetSystem()->GetChTime(); // End simulation if (time >= t_end) break; // Render scene and output post-processing data if (step_number % render_steps == 0) { vis->BeginScene(); vis->Render(); vis->EndScene(); render_frame++; } // Driver inputs DriverInputs 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 modules driver->Advance(step_size); terrain.Advance(step_size); hmmwv.Advance(step_size); vis->Advance(step_size); //~ 更新vis的trackpoint等。 // Increment frame number step_number++; std::cout << "Step: " << step_number << std::endl; } return 0; } }
运行这个例子,就可以用WASD控制悍马车在自定义的一个地形上开动了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。