virtual void onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) { wheelBody->GetCollisionModel()->ClearModel(); wheelBody->GetCollisionModel()->AddCylinder(0.46, 0.46, width / 2); wheelBody->GetCollisionModel()->BuildModel(); wheelBody->GetMaterialSurfaceDEM()->SetFriction(mu_t); wheelBody->GetMaterialSurfaceDEM()->SetYoungModulus(Y_t); wheelBody->GetMaterialSurfaceDEM()->SetRestitution(cr_t); }
virtual void onCallback(ChSharedPtr<ChBody> wheelBody, double radius, double width) { ChCollisionModelParallel* coll_model = (ChCollisionModelParallel*)wheelBody->GetCollisionModel(); coll_model->ClearModel(); // Assemble the tire contact from 15 segments, properly offset. // Each segment is further decomposed in convex hulls. for (int iseg = 0; iseg < 15; iseg++) { ChQuaternion<> rot = Q_from_AngAxis(iseg * 24 * CH_C_DEG_TO_RAD, VECT_Y); for (int ihull = 0; ihull < num_hulls; ihull++) { std::vector<ChVector<> > convexhull; lugged_convex.GetConvexHullResult(ihull, convexhull); coll_model->AddConvexHull(convexhull, VNULL, rot); } } // Add a cylinder to represent the wheel hub. coll_model->AddCylinder(0.223, 0.223, 0.126); coll_model->BuildModel(); wheelBody->GetMaterialSurfaceDEM()->SetFriction(mu_t); wheelBody->GetMaterialSurfaceDEM()->SetYoungModulus(Y_t); wheelBody->GetMaterialSurfaceDEM()->SetRestitution(cr_t); }
int main(int argc, char* argv[]) { // Set path to ChronoVehicle data files vehicle::SetDataPath(CHRONO_VEHICLE_DATA_DIR); // -------------------------- // Create output directories. // -------------------------- if (povray_output) { if (ChFileutils::MakeDirectory(out_dir.c_str()) < 0) { cout << "Error creating directory " << out_dir << endl; return 1; } if (ChFileutils::MakeDirectory(pov_dir.c_str()) < 0) { cout << "Error creating directory " << pov_dir << endl; return 1; } } // -------------- // Create system. // -------------- ChSystemParallelDEM* system = new ChSystemParallelDEM(); system->Set_G_acc(ChVector<>(0, 0, -9.81)); // ---------------------- // Enable debug log // ---------------------- ////system->SetLoggingLevel(LOG_INFO, true); ////system->SetLoggingLevel(LOG_TRACE, true); // ---------------------- // Set number of threads. // ---------------------- int max_threads = omp_get_num_procs(); if (threads > max_threads) threads = max_threads; system->SetParallelThreadNumber(threads); omp_set_num_threads(threads); cout << "Using " << threads << " threads" << endl; system->GetSettings()->perform_thread_tuning = thread_tuning; // --------------------- // Edit system settings. // --------------------- system->GetSettings()->solver.use_full_inertia_tensor = false; system->GetSettings()->solver.tolerance = tolerance; system->GetSettings()->solver.max_iteration_bilateral = max_iteration_bilateral; system->GetSettings()->solver.contact_force_model = contact_force_model; system->GetSettings()->solver.tangential_displ_mode = tangential_displ_mode; system->GetSettings()->collision.narrowphase_algorithm = NARROWPHASE_HYBRID_MPR; system->GetSettings()->collision.bins_per_axis = I3(20, 20, 10); // ------------------- // Create the terrain. // ------------------- // Ground body ChSharedPtr<ChBody> ground = ChSharedPtr<ChBody>(new ChBody(new collision::ChCollisionModelParallel, ChBody::DEM)); ground->SetIdentifier(-1); ground->SetMass(1000); ground->SetBodyFixed(true); ground->SetCollide(true); ground->GetMaterialSurfaceDEM()->SetFriction(mu_g); ground->GetMaterialSurfaceDEM()->SetYoungModulus(Y_g); ground->GetMaterialSurfaceDEM()->SetRestitution(cr_g); ground->GetMaterialSurfaceDEM()->SetCohesion(cohesion_g); ground->GetCollisionModel()->ClearModel(); // Bottom box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hdimX, hdimY, hthick), ChVector<>(0, 0, -hthick), ChQuaternion<>(1, 0, 0, 0), true); if (terrain_type == GRANULAR) { // Front box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hthick, hdimY, hdimZ + hthick), ChVector<>(hdimX + hthick, 0, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); // Rear box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hthick, hdimY, hdimZ + hthick), ChVector<>(-hdimX - hthick, 0, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); // Left box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hdimX, hthick, hdimZ + hthick), ChVector<>(0, hdimY + hthick, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); // Right box utils::AddBoxGeometry(ground.get_ptr(), ChVector<>(hdimX, hthick, hdimZ + hthick), ChVector<>(0, -hdimY - hthick, hdimZ - hthick), ChQuaternion<>(1, 0, 0, 0), visible_walls); } ground->GetCollisionModel()->BuildModel(); system->AddBody(ground); // Create the granular material. double vertical_offset = 0; if (terrain_type == GRANULAR) { vertical_offset = CreateParticles(system); } // ----------------------------------------- // Create and initialize the vehicle system. // ----------------------------------------- utils::VehicleSystem* vehicle; utils::TireContactCallback* tire_cb; // Create the vehicle assembly and the callback object for tire contact // according to the specified type of tire/wheel. switch (wheel_type) { case CYLINDRICAL: { vehicle = new utils::VehicleSystem(system, vehicle_file_cyl, simplepowertrain_file); tire_cb = new MyCylindricalTire(); } break; case LUGGED: { vehicle = new utils::VehicleSystem(system, vehicle_file_lug, simplepowertrain_file); tire_cb = new MyLuggedTire(); } break; } vehicle->SetTireContactCallback(tire_cb); // Set the callback object for driver inputs. Pass the hold time as a delay in // generating driver inputs. MyDriverInputs driver_cb(time_hold); vehicle->SetDriverInputsCallback(&driver_cb); // Initialize the vehicle at a height above the terrain. vehicle->Initialize(initLoc + ChVector<>(0, 0, vertical_offset), initRot); // Initially, fix the chassis and wheel bodies (will be released after time_hold). vehicle->GetVehicle()->GetChassis()->SetBodyFixed(true); for (int i = 0; i < 2 * vehicle->GetVehicle()->GetNumberAxles(); i++) { vehicle->GetVehicle()->GetWheelBody(i)->SetBodyFixed(true); } // ----------------------- // Perform the simulation. // ----------------------- #ifdef CHRONO_PARALLEL_HAS_OPENGL // Initialize OpenGL opengl::ChOpenGLWindow& gl_window = opengl::ChOpenGLWindow::getInstance(); gl_window.Initialize(1280, 720, "HMMWV", system); gl_window.SetCamera(ChVector<>(0, -10, 0), ChVector<>(0, 0, 0), ChVector<>(0, 0, 1)); gl_window.SetRenderMode(opengl::WIREFRAME); #endif // Run simulation for specified time. int out_steps = std::ceil((1.0 / time_step) / out_fps); double time = 0; int sim_frame = 0; int out_frame = 0; int next_out_frame = 0; double exec_time = 0; int num_contacts = 0; while (time < time_end) { // If enabled, output data for PovRay postprocessing. if (sim_frame == next_out_frame) { cout << endl; cout << "---- Frame: " << out_frame + 1 << endl; cout << " Sim frame: " << sim_frame << endl; cout << " Time: " << time << endl; cout << " Speed: " << vehicle->GetVehicle()->GetVehicleSpeed() << endl; cout << " Avg. contacts: " << num_contacts / out_steps << endl; cout << " Execution time: " << exec_time << endl; if (povray_output) { char filename[100]; sprintf(filename, "%s/data_%03d.dat", pov_dir.c_str(), out_frame + 1); utils::WriteShapesPovray(system, filename); } out_frame++; next_out_frame += out_steps; num_contacts = 0; } // Release the vehicle chassis at the end of the hold time. if (vehicle->GetVehicle()->GetChassis()->GetBodyFixed() && time > time_hold) { cout << endl << "Release vehicle t = " << time << endl; vehicle->GetVehicle()->GetChassis()->SetBodyFixed(false); for (int i = 0; i < 2 * vehicle->GetVehicle()->GetNumberAxles(); i++) { vehicle->GetVehicle()->GetWheelBody(i)->SetBodyFixed(false); } } // Update vehicle vehicle->Update(time); // Advance dynamics. #ifdef CHRONO_PARALLEL_HAS_OPENGL if (gl_window.Active()) { gl_window.DoStepDynamics(time_step); gl_window.Render(); } else break; #else system->DoStepDynamics(time_step); #endif ////progressbar(out_steps + sim_frame - next_out_frame + 1, out_steps); TimingOutput(system); // Periodically display maximum constraint violation if (monitor_bilaterals && sim_frame % bilateral_frame_interval == 0) { std::vector<double> cvec; ////vehicle->GetVehicle()->LogConstraintViolations(); cout << " Max. violation = " << system->CalculateConstraintViolation(cvec) << endl; } // Update counters. time += time_step; sim_frame++; exec_time += system->GetTimerStep(); num_contacts += system->GetNcontacts(); } // Final stats cout << "==================================" << endl; cout << "Simulation time: " << exec_time << endl; cout << "Number of threads: " << threads << endl; delete vehicle; delete tire_cb; return 0; }