//--------------------------------------------------------------------------------- // Time Slice all wheels //--------------------------------------------------------------------------------- void CGroundSuspension::Timeslice (float dT) { nWonG = 0; // No wheels on ground SumGearForces.x = SumGearMoments.x = 0.0; SumGearForces.y = SumGearMoments.y = 0.0; SumGearForces.z = SumGearMoments.z = 0.0; if (type == TRICYCLE) {;} else {;} // \todo different kind of train std::vector<CSuspension *>::const_iterator it_whel; for (it_whel = whl_susp.begin (); it_whel != whl_susp.end (); it_whel++) { // is it a steering wheel ? CSuspension *ssp = (CSuspension*)(*it_whel); SGearData *gdt = ssp->GetGearData(); if (ssp->IsSteerWheel ()) mveh->GetGearChannel(gdt); // is it a braking wheel ? /// \todo .../... // ... and finally timeslice ssp->Timeslice (dT); // sum all gear forces const SVector gf = (*it_whel)->GetBodyForce_ISU (); SumGearForces.x += gf.x; SumGearForces.y += gf.y; SumGearForces.z += gf.z; // sum all gear moments const SVector gm = (*it_whel)->GetBodyMoment_ISU (); SumGearMoments.x += gm.x; SumGearMoments.y += gm.y; SumGearMoments.z += gm.z; //--- update wheels on ground -------------------- if (ssp->IsOnGround()) nWonG++; } }
//--------------------------------------------------------------------------------- // Set ABS feature //--------------------------------------------------------------------------------- void CGroundSuspension::SetABS(char p) { std::vector<CSuspension *>::const_iterator wi; for (wi = whl_susp.begin (); wi != whl_susp.end (); wi++) { CSuspension *ssp = (CSuspension*)(*wi); ssp->SetABS(p); } return; }
//--------------------------------------------------------------------------------- // Reset crash //--------------------------------------------------------------------------------- void CGroundSuspension::ResetForce() { std::vector<CSuspension *>::const_iterator wi; for (wi = whl_susp.begin (); wi != whl_susp.end (); wi++) { CSuspension *ssp = (CSuspension*)(*wi); ssp->ResetForce(); } return; }
//------------------------------------------------------------------------ // All parameters are read. Finalize //------------------------------------------------------------------------- void COpalGroundSuspension::ReadFinished (void) { #ifdef _DEBUG DEBUGLOG ("COpalGroundSuspension::ReadFinished"); #endif CGroundSuspension::ReadFinished (); double base = FeetToMetres(wheel_base); std::vector<CSuspension *>::const_iterator it_whel; for (it_whel = whl_susp.begin (); it_whel != whl_susp.end (); it_whel++) { CSuspension *ssp = (CSuspension *)(*it_whel); ssp->SetWheelBase(base); ssp->InitGearJoint (type,this); } //------------------------------------------------------------------------ //JS note: This table is used to modulate the Brake force versus // ground speed. Brake force must decrease with speed //------------------------------------------------------------------------ if (0 == mbtbl) { // Brake force turn table CFmt1Map *map = new CFmt1Map(); mbtbl = map; map->Add(00.0f, 1.0f); map->Add(30.0f, 0.7f); map->Add(45.0f, 0.5f); map->Add(60.0f, 0.3f); map->Add(90.0f, 0.1f); } //------------------------------------------------------------------------ //JS note: This table is used to modulate the steering force versus // ground speed. steering must decrease with speed //------------------------------------------------------------------------ if (0 == mstbl) { // Ground speed turn table CFmt1Map *map = new CFmt1Map(); mstbl = map; map->Add(00.0f, 5.00f); map->Add(05.0f, 2.00f); map->Add(10.0f, 1.50f); map->Add(20.0f, 0.50f); map->Add(90.0f, 0.01f); } return; }
//--------------------------------------------------------------------------------- // Compute main gear axe barycenter // Compute steering gear axe center in Legacy coordinate (Z is up) //--------------------------------------------------------------------------------- void CGroundSuspension::ReadFinished (void) { #ifdef _DEBUG DEBUGLOG ("CGroundSuspension::ReadFinished"); #endif wheels_num = whl_susp.size (); //---Compute wheel parameters --(Z is forward direction)--------- CSuspension *str = 0; // Steering wheel max_gear = 0.0, min_gear = 0.0, mWPos = 0.0; double wheel_min_h = -1000.0; int nbw = 0; std::vector<CSuspension *>::const_iterator it_whel; for (it_whel = whl_susp.begin (); it_whel != whl_susp.end (); it_whel++) { CSuspension *s = (CSuspension *) *it_whel; max_gear = max (s->GetGearPosZ (), max_gear); // max forward min_gear = min (s->GetGearPosZ (), min_gear); // min forward mWPos = min (s->GetGearPosY (), mWPos); // lower point wheel_min_h = max (s->GetGearPosY (), wheel_min_h ); // LH //---Compute main gear barycenter --------------------- if (s->IsSteerWheel()) {str = s; continue; } nbw++; mainW.x += s->GetGearPosX(); mainW.z += s->GetGearPosY(); mainW.y += s->GetGearPosZ(); mainR += s->GetGearRadius(); } //-------------------------------------------------------- // The barycenter is the center of all main gear axis // -mainW is the average contact point of all main // gears in feet coordinates. To get the average axis // point , we just add the average radius. (as the // contact point is a negative position, we must add // the wheel radius //-------------------------------------------------------- double fac = (nbw)?(double(1) / nbw):(0); mainW.Times(fac); mainR *= fac; mainW.z += mainR; //-------------------------------------------------------- sterR = str->GetGearRadius(); //-------------------------------------------------------- // We also compute the bAGL (body above ground level) // bAGL is used to set the aircraft level above a given terrain // bAGL is what that must be added to ground to set // the aircraft correctly on ground // One foot is added for rounding up // (relative to aircraft visual model) // For physical model, the Cog offset must be accounted //-------------------------------------------------------- // Wheel_base is the longitudinal amplitude of the gear // (all wheels accounted). It is used to compute mass // repartition over the gear //-------------------------------------------------------- bAGL = mainR - mainW.z + 1; //--- Compute Wheel base --------------------------------- wheel_base = max_gear - min_gear; //-------------------------------------------------------- if (TRICYCLE == type) max_wheel_height = - mWPos; else if (TAIL_DRAGGER == type) max_wheel_height = - (mWPos - wheel_min_h); else max_wheel_height = - mWPos; }
//------------------------------------------------------------------------ // JS to LC: Removed brake force from wheel definition as it is // only used in Suspension TimeSlice. //------------------------------------------------------------------------- void COpalGroundSuspension::Timeslice (float dT) { /// very important ! be sure to compute only during /// engine & aerodynamics cycle if (!globals->simulation) return; nWonG = 0; // No wheels on ground SumGearMoments.x = 0.0; SumGearMoments.y = 0.0; SumGearMoments.z = 0.0; //--- Compute velocity in Miles per Hours --------- double vt = (mveh->GetBodyVelocityVector ())->z; double velocity = NMILE_PER_METRE_SEC(vt); float fstbl = mstbl->Lookup (velocity); // 1.0f; float fbtbl = mbtbl->Lookup (velocity); // 1.0f; std::vector<CSuspension *>::const_iterator it_whel; //-- Check for gear position ---------------------- if (mveh->lod->AreGearRetracted()) { max_wheel_height_backup = max_wheel_height; max_wheel_height = 0.0; } if (mveh->lod->AreGearDown()) { max_wheel_height = max_wheel_height_backup; } // for (it_whel = whl_susp.begin (); it_whel != whl_susp.end (); it_whel++) { // is it a steering wheel ? CSuspension *ssp = (CSuspension*)(*it_whel); SGearData *gdt = ssp->GetGearData(); gdt->stbl = fstbl; gdt->btbl = fbtbl; if (mveh->lod->AreGearDown()) { /// this is the completely extended gear position if (ssp->IsSteerWheel ()) mveh->GetGearChannel(gdt); // ... and finally timeslice ssp->Timeslice (dT); if (ssp->IsOnGround()) nWonG++; } } /// All the computation below is LH // verify if this test is useful // // add mass moment related to main gear // JS NOTE: The main_pos is in fact the distance between the Cg and the steering // wheel. // On a tricyle, the steering is in positive direction while on a Tail Dragger // the steering is in negative direction. // So I made the following modifications // The steering distance (in meters) is computed in the // CGroundSuspension::InitJoint() when wheels positions are computed // This vector is stored into mainVM and the massCF is the coeeficent // that modulate the mass supported by the wheel. // Also, the mass_force is modified so that the force applied is in the // vertical direction (Z) and is negative. // { CVector mass_moment; CVector mass_force (0, 0, -mveh->GetMassInKgs() * GRAVITY_MTS * massCF); //, 0.0); CVector mass_pos, main_gear; // main_gear.Set (0.0, FeetToMetres (-max_wheel_height), FeetToMetres (max_gear)); // mass_pos = *mveh->svh->GetNewCG_ISU () - main_gear; // VectorCrossProduct (mass_moment, mass_pos, mass_force); VectorCrossProduct (mass_moment, mainVM, mass_force); /// add gear moment to the CG moment SumGearMoments = VectorSum (SumGearMoments, mass_moment); #ifdef _DEBUG_suspension { FILE *fp_debug; if((fp_debug = fopen("__DDEBUG_suspension.txt", "a")) != NULL) { fprintf(fp_debug, "---------------------------------------------------------\n"); fprintf(fp_debug, "COpalGroundSuspension::Timeslice nWOW=%d SumF(%f %f %f) SumM(%f %f %f)\n", nWOW, SumGearForces.x, SumGearForces.y, SumGearForces.z, SumGearMoments.x, SumGearMoments.y, SumGearMoments.z ); fprintf(fp_debug, " cg(%f %f %f) mg(%f %f %f) mp(%f %f %f)\n mf(%f %f %f) mm(%f %f %f) (mwh%f Mg%f mg%f)\n", globals->sit->user->svh->GetNewCG_ISU ()->x, globals->sit->user->svh->GetNewCG_ISU ()->y, globals->sit->user->svh->GetNewCG_ISU ()->z, main_gear.x, main_gear.y, main_gear.z, mass_pos.x, mass_pos.y, mass_pos.z, mass_force.x, mass_force.y, mass_force.z, mass_moment.x, mass_moment.y, mass_moment.z, max_wheel_height, max_gear, min_gear ); fprintf(fp_debug, "---------------------------------------------------------\n"); fclose(fp_debug); } } #endif } }