コード例 #1
0
ファイル: hmmwvDEM.cpp プロジェクト: rserban/chrono-projects
  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);
  }
コード例 #2
0
ファイル: hmmwvDEM.cpp プロジェクト: rserban/chrono-projects
  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);
  }
コード例 #3
0
ファイル: hmmwvDEM.cpp プロジェクト: rserban/chrono-projects
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;
}