int main(int argc, char* argv[]) { GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n"; // Create a ChronoENGINE physical system ChSystemNSC mphysicalSystem; // Create the Irrlicht visualization (open the Irrlicht device, // bind a simple user interface, etc. etc.) ChIrrApp application(&mphysicalSystem, L"Conveyor belt", core::dimension2d<u32>(800, 600), false); // Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene: ChIrrWizard::add_typical_Logo(application.GetDevice()); ChIrrWizard::add_typical_Sky(application.GetDevice()); ChIrrWizard::add_typical_Lights(application.GetDevice()); ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df((f32)1.5, (f32)0.4, -1), core::vector3df((f32)0.5, 0, 0)); // This is for GUI tweaking of system parameters.. MyEventReceiver receiver(&application); // note how to add the custom event receiver to the default interface: application.SetUserEventReceiver(&receiver); // Set small collision envelopes for objects that will be created from now on.. ChCollisionModel::SetDefaultSuggestedEnvelope(0.002); ChCollisionModel::SetDefaultSuggestedMargin(0.002); // Create two conveyor fences auto mfence1 = std::make_shared<ChBodyEasyBox>(2, 0.11, 0.04, 1000, true, true); mphysicalSystem.Add(mfence1); mfence1->SetPos(ChVector<>(0, 0, -0.325)); mfence1->SetBodyFixed(true); mfence1->GetMaterialSurfaceNSC()->SetFriction(0.1f); auto mfence2 = std::make_shared<ChBodyEasyBox>(2, 0.11, 0.04, 1000, true, true); mphysicalSystem.Add(mfence2); mfence2->SetPos(ChVector<>(0, 0, 0.325)); mfence2->SetBodyFixed(true); mfence2->GetMaterialSurfaceNSC()->SetFriction(0.1f); // Create the conveyor belt (this is a pure Chrono::Engine object, // because an Irrlicht 'SceneNode' wrapper is not yet available, so it is invisible - no 3D preview) auto mconveyor = std::make_shared<ChConveyor>(2, 0.05, 0.6); mconveyor->SetBodyFixed(true); mconveyor->GetMaterialSurfaceNSC()->SetFriction(0.35f); mconveyor->SetConveyorSpeed(STATIC_speed); mconveyor->SetPos(ChVector<>(0, 0, 0)); mphysicalSystem.Add(mconveyor); // Use this function for adding a ChIrrNodeAsset to all items // Otherwise use application.AssetBind(myitem); on a per-item basis. application.AssetBindAll(); // Use this function for 'converting' assets into Irrlicht meshes application.AssetUpdateAll(); // // THE SOFT-REAL-TIME CYCLE // application.SetStepManage(true); application.SetTimestep(0.005); while (application.GetDevice()->run()) { application.BeginScene(true, true, SColor(255, 140, 161, 192)); application.DrawAll(); application.DoStep(); if (!application.GetPaused()) { // Continuosly create debris that fall on the conveyor belt create_debris(application, application.GetTimestep(), STATIC_flow); // Limit the max number of debris particles on the scene, deleting the oldest ones, for performance purge_debris(application, 300); // Maybe the user played with the slider and changed STATIC_speed... mconveyor->SetConveyorSpeed(STATIC_speed); } application.EndScene(); } return 0; }
void create_some_falling_items(ChSystemNSC& mphysicalSystem) { // From now on, all created collision models will have a large outward envelope (needed // to allow some compliance with the plastic deformation of cohesive bounds ChCollisionModel::SetDefaultSuggestedEnvelope(0.3); for (int bi = 0; bi < 400; bi++) { // Create a bunch of ChronoENGINE rigid bodies which will fall.. auto mrigidBody = std::make_shared<ChBodyEasySphere>(0.81, // radius 1000, // density true, // collide enable? true); // visualization? mrigidBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10)); mrigidBody->GetMaterialSurfaceNSC()->SetFriction(0.3f); mphysicalSystem.Add(mrigidBody); // optional, attach a texture for better visualization auto mtexture = std::make_shared<ChTexture>(); mtexture->SetTextureFilename(GetChronoDataFile("rock.jpg")); mrigidBody->AddAsset(mtexture); } // Create the five walls of the rectangular container, using // fixed rigid bodies of 'box' type: auto floorBody = std::make_shared<ChBodyEasyBox>(20, 1, 20, // x,y,z size 1000, // density true, // collide enable? true); // visualization? floorBody->SetPos(ChVector<>(0, -5, 0)); floorBody->SetBodyFixed(true); mphysicalSystem.Add(floorBody); auto wallBody1 = std::make_shared<ChBodyEasyBox>(1, 10, 20.99, // x,y,z size 1000, // density true, // collide enable? true); // visualization? wallBody1->SetPos(ChVector<>(-10, 0, 0)); wallBody1->SetBodyFixed(true); mphysicalSystem.Add(wallBody1); auto wallBody2 = std::make_shared<ChBodyEasyBox>(1, 10, 20.99, // x,y,z size 1000, // density true, // collide enable? true); // visualization? wallBody2->SetPos(ChVector<>(10, 0, 0)); wallBody2->SetBodyFixed(true); mphysicalSystem.Add(wallBody2); auto wallBody3 = std::make_shared<ChBodyEasyBox>(20.99, 10, 1, // x,y,z size 1000, // density true, // collide enable? true); // visualization? wallBody3->SetPos(ChVector<>(0, 0, -10)); wallBody3->SetBodyFixed(true); mphysicalSystem.Add(wallBody3); auto wallBody4 = std::make_shared<ChBodyEasyBox>(20.99, 10, 1, // x,y,z size 1000, // density true, // collide enable? true); // visualization? wallBody4->SetPos(ChVector<>(0, 0, 10)); wallBody4->SetBodyFixed(true); mphysicalSystem.Add(wallBody4); // optional, attach textures for better visualization auto mtexturewall = std::make_shared<ChTexture>(); mtexturewall->SetTextureFilename(GetChronoDataFile("concrete.jpg")); wallBody1->AddAsset(mtexturewall); // note: most assets can be shared wallBody2->AddAsset(mtexturewall); wallBody3->AddAsset(mtexturewall); wallBody4->AddAsset(mtexturewall); floorBody->AddAsset(mtexturewall); // Add the rotating mixer auto rotatingBody = std::make_shared<ChBodyEasyBox>(10, 5, 1, // x,y,z size 4000, // density true, // collide enable? true); // visualization? rotatingBody->SetPos(ChVector<>(0, -1.6, 0)); rotatingBody->GetMaterialSurfaceNSC()->SetFriction(0.4f); mphysicalSystem.Add(rotatingBody); // .. an engine between mixer and truss auto my_motor = std::make_shared<ChLinkEngine>(); my_motor->Initialize(rotatingBody, floorBody, ChCoordsys<>(ChVector<>(0, 0, 0), Q_from_AngAxis(CH_C_PI_2, VECT_X))); my_motor->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); if (auto mfun = std::dynamic_pointer_cast<ChFunction_Const>(my_motor->Get_spe_funct())) mfun->Set_yconst(CH_C_PI / 2.0); // speed w=90°/s mphysicalSystem.AddLink(my_motor); }
int main(int argc, char* argv[]) { GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n"; // Create a ChronoENGINE physical system ChSystemNSC mphysicalSystem; // Create the Irrlicht visualization (open the Irrlicht device, // bind a simple user interface, etc. etc.) ChIrrApp application(&mphysicalSystem, L"Gears and pulleys", core::dimension2d<u32>(800, 600), false); // Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene: ChIrrWizard::add_typical_Logo(application.GetDevice()); ChIrrWizard::add_typical_Sky(application.GetDevice()); ChIrrWizard::add_typical_Lights(application.GetDevice()); ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(12, 15, -20)); // Create all the rigid bodies. double radA = 2; double radB = 4; // ...the truss auto mbody_truss = std::make_shared<ChBodyEasyBox>(20, 10, 2, 1000, false, true); mphysicalSystem.Add(mbody_truss); mbody_truss->SetBodyFixed(true); mbody_truss->SetPos(ChVector<>(0, 0, 3)); // ...a texture asset that will be shared among the four wheels auto cylinder_texture = std::make_shared<ChTexture>(GetChronoDataFile("pinkwhite.png")); // ...the rotating bar support for the two epicycloidal wheels auto mbody_train = std::make_shared<ChBodyEasyBox>(8, 1.5, 1.0, 1000, false, true); mphysicalSystem.Add(mbody_train); mbody_train->SetPos(ChVector<>(3, 0, 0)); // ...which must rotate respect to truss along Z axis, in 0,0,0, auto link_revoluteTT = std::make_shared<ChLinkLockRevolute>(); link_revoluteTT->Initialize(mbody_truss, mbody_train, ChCoordsys<>(ChVector<>(0, 0, 0), QUNIT)); mphysicalSystem.AddLink(link_revoluteTT); // ...the first gear auto mbody_gearA = std::make_shared<ChBodyEasyCylinder>(radA, 0.5, 1000, false, true); mphysicalSystem.Add(mbody_gearA); mbody_gearA->SetPos(ChVector<>(0, 0, -1)); mbody_gearA->SetRot(Q_from_AngAxis(CH_C_PI / 2, VECT_X)); mbody_gearA->AddAsset(cylinder_texture); // for aesthetic reasons, also add a thin cylinder only as a visualization: auto mshaft_shape = std::make_shared<ChCylinderShape>(); mshaft_shape->GetCylinderGeometry().p1 = ChVector<>(0,-3,0); mshaft_shape->GetCylinderGeometry().p2 = ChVector<>(0, 10,0); mshaft_shape->GetCylinderGeometry().rad = radA*0.4; mbody_gearA->AddAsset(mshaft_shape); // ...impose rotation between the first gear and the fixed truss auto link_engine = std::make_shared<ChLinkEngine>(); link_engine->Initialize(mbody_gearA, mbody_truss, ChCoordsys<>(ChVector<>(0, 0, 0), QUNIT)); link_engine->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); // also works as revolute support link_engine->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); if (auto mfun = std::dynamic_pointer_cast<ChFunction_Const>(link_engine->Get_spe_funct())) mfun->Set_yconst(6); // rad/s angular speed mphysicalSystem.AddLink(link_engine); // ...the second gear double interaxis12 = radA + radB; auto mbody_gearB = std::make_shared<ChBodyEasyCylinder>(radB, 0.4, 1000, false, true); mphysicalSystem.Add(mbody_gearB); mbody_gearB->SetPos(ChVector<>(interaxis12, 0, -1)); mbody_gearB->SetRot(Q_from_AngAxis(CH_C_PI / 2, VECT_X)); mbody_gearB->AddAsset(cylinder_texture); // ... the second gear is fixed to the rotating bar auto link_revolute = std::make_shared<ChLinkLockRevolute>(); link_revolute->Initialize(mbody_gearB, mbody_train, ChCoordsys<>(ChVector<>(interaxis12, 0, 0), QUNIT)); mphysicalSystem.AddLink(link_revolute); // ...the gear constraint between the two wheels A and B. // As transmission ratio (=speed of wheel B / speed of wheel A) to enter in Set_tau(), we // could use whatever positive value we want: the ChLinkGear will compute the two radii of the // wheels for its 'hidden' computations, given the distance between the two axes. However, since // we already build two '3D cylinders' bodies -just for visualization reasons!- with radA and radB, // we must enter Set_tau(radA/radB). // Also, note that the initial position of the constraint has no importance (simply use CSYSNORM), // but we must set where the two axes are placed in the local coordinates of the two wheels, so // we use Set_local_shaft1() and pass some local ChFrame. Note that, since the Z axis of that frame // will be considered the axis of the wheel, we must rotate the frame 90° with Q_from_AngAxis(), because // we created the wheel with ChBodyEasyCylinder() which created a cylinder with Y as axis. auto link_gearAB = std::make_shared<ChLinkGear>(); link_gearAB->Initialize(mbody_gearA, mbody_gearB, CSYSNORM); link_gearAB->Set_local_shaft1(ChFrame<>(VNULL, chrono::Q_from_AngAxis(-CH_C_PI / 2, VECT_X))); link_gearAB->Set_local_shaft2(ChFrame<>(VNULL, chrono::Q_from_AngAxis(-CH_C_PI / 2, VECT_X))); link_gearAB->Set_tau(radA / radB); link_gearAB->Set_checkphase(true); mphysicalSystem.AddLink(link_gearAB); // ...the gear constraint between the second wheel B and a large wheel C with inner teeth, that // does not necessarily need to be created as a new body because it is the 'fixed' part of the // epicycloidal reducer, so, as wheel C, we will simply use the ground object 'mbody_truss'. double radC = 2 * radB + radA; auto link_gearBC = std::make_shared<ChLinkGear>(); link_gearBC->Initialize(mbody_gearB, mbody_truss, CSYSNORM); link_gearBC->Set_local_shaft1(ChFrame<>(VNULL, chrono::Q_from_AngAxis(-CH_C_PI / 2, VECT_X))); link_gearBC->Set_local_shaft2(ChFrame<>(ChVector<>(0, 0, -4), QUNIT)); link_gearBC->Set_tau(radB / radC); link_gearBC->Set_epicyclic(true); // <-- this means: use a wheel with internal teeth! mphysicalSystem.AddLink(link_gearBC); // ...the bevel gear at the side, double radD = 5; auto mbody_gearD = std::make_shared<ChBodyEasyCylinder>(radD, 0.8, 1000, false, true); mphysicalSystem.Add(mbody_gearD); mbody_gearD->SetPos(ChVector<>(-10, 0, -9)); mbody_gearD->SetRot(Q_from_AngAxis(CH_C_PI / 2, VECT_Z)); mbody_gearD->AddAsset(cylinder_texture); // ... it is fixed to the truss using a revolute joint with horizontal axis (must rotate // default ChLink creation coordys 90° on the Y vertical, since the revolute axis is the Z axis). auto link_revoluteD = std::make_shared<ChLinkLockRevolute>(); link_revoluteD->Initialize(mbody_gearD, mbody_truss, ChCoordsys<>(ChVector<>(-10, 0, -9), Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); mphysicalSystem.AddLink(link_revoluteD); // ... Let's make a 1:1 gear between wheel A and wheel D as a bevel gear: chrono::engine does not require // special info for this case -the position of the two shafts and the transmission ratio are enough- auto link_gearAD = std::make_shared<ChLinkGear>(); link_gearAD->Initialize(mbody_gearA, mbody_gearD, CSYSNORM); link_gearAD->Set_local_shaft1(ChFrame<>(ChVector<>(0, -7, 0), chrono::Q_from_AngAxis(-CH_C_PI / 2, VECT_X))); link_gearAD->Set_local_shaft2(ChFrame<>(ChVector<>(0, -7, 0), chrono::Q_from_AngAxis(-CH_C_PI / 2, VECT_X))); link_gearAD->Set_tau(1); mphysicalSystem.AddLink(link_gearAD); // ...the pulley at the side, double radE = 2; auto mbody_pulleyE = std::make_shared<ChBodyEasyCylinder>(radE, 0.8, 1000, false, true); mphysicalSystem.Add(mbody_pulleyE); mbody_pulleyE->SetPos(ChVector<>(-10, -11, -9)); mbody_pulleyE->SetRot(Q_from_AngAxis(CH_C_PI / 2, VECT_Z)); mbody_pulleyE->AddAsset(cylinder_texture); // ... it is fixed to the truss using a revolute joint with horizontal axis (must rotate // default ChLink creation coordys 90° on the Y vertical, since the revolute axis is the Z axis). auto link_revoluteE = std::make_shared<ChLinkLockRevolute>(); link_revoluteE->Initialize(mbody_pulleyE, mbody_truss, ChCoordsys<>(ChVector<>(-10, -11, -9), Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); mphysicalSystem.AddLink(link_revoluteE); // ... Let's make a synchro belt constraint between pulley D and pulley E. The user must be // sure that the two shafts are parallel in absolute space. Also, interaxial distance should not change. auto link_pulleyDE = std::make_shared<ChLinkPulley>(); link_pulleyDE->Initialize(mbody_gearD, mbody_pulleyE, CSYSNORM); link_pulleyDE->Set_local_shaft1(ChFrame<>(VNULL, chrono::Q_from_AngAxis(-CH_C_PI / 2, VECT_X))); link_pulleyDE->Set_local_shaft2(ChFrame<>(VNULL, chrono::Q_from_AngAxis(-CH_C_PI / 2, VECT_X))); link_pulleyDE->Set_r1(radD); link_pulleyDE->Set_r2(radE); link_pulleyDE->Set_checkphase(true); // synchro belts don't tolerate slipping: this avoids it as numerical errors accumulate. mphysicalSystem.AddLink(link_pulleyDE); // Use this function for adding a ChIrrNodeAsset to all items // Otherwise use application.AssetBind(myitem); on a per-item basis. application.AssetBindAll(); // Use this function for 'converting' assets into Irrlicht meshes application.AssetUpdateAll(); // Prepare the physical system for the simulation mphysicalSystem.SetTimestepperType(ChTimestepper::Type::EULER_IMPLICIT_PROJECTED); // // THE SOFT-REAL-TIME CYCLE // application.SetStepManage(true); application.SetTimestep(0.01); application.SetTryRealtime(true); while (application.GetDevice()->run()) { application.BeginScene(true, true, SColor(255, 140, 161, 192)); application.DrawAll(); // .. draw also some circle lines representing gears - just for aesthetical reasons ChIrrTools::drawCircle(application.GetVideoDriver(), link_gearBC->Get_r2(), (link_gearBC->Get_local_shaft2() >> *link_gearBC->GetBody2()).GetCoord(), video::SColor(255, 255, 0, 0), 50, true); ChIrrTools::drawCircle(application.GetVideoDriver(), link_gearAD->Get_r1(), (link_gearAD->Get_local_shaft1() >> *link_gearAD->GetBody1()).GetCoord(), video::SColor(255, 255, 0, 0), 30, true); ChIrrTools::drawCircle(application.GetVideoDriver(), link_gearAD->Get_r2(), (link_gearAD->Get_local_shaft2() >> *link_gearAD->GetBody2()).GetCoord(), video::SColor(255, 255, 0, 0), 30, true); ChIrrTools::drawCircle(application.GetVideoDriver(), 0.1, ChCoordsys<>(link_gearAB->GetMarker2()->GetAbsCoord().pos, QUNIT)); ChIrrTools::drawCircle(application.GetVideoDriver(), 0.1, ChCoordsys<>(link_gearAD->GetMarker2()->GetAbsCoord().pos, QUNIT)); ChIrrTools::drawCircle(application.GetVideoDriver(), 0.1, ChCoordsys<>(link_gearBC->GetMarker2()->GetAbsCoord().pos, QUNIT)); // ..draw also some segments for a simplified representation of pulley ChIrrTools::drawSegment(application.GetVideoDriver(), link_pulleyDE->Get_belt_up1(), link_pulleyDE->Get_belt_up2(), video::SColor(255, 0, 255, 0), true); ChIrrTools::drawSegment(application.GetVideoDriver(), link_pulleyDE->Get_belt_low1(), link_pulleyDE->Get_belt_low2(), video::SColor(255, 0, 255, 0), true); // ADVANCE THE SIMULATION FOR ONE STEP application.DoStep(); application.EndScene(); } return 0; }
int main(int argc, char* argv[]) { GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n"; // Create the system // Set gravitational acceleration to zero ChSystemNSC system; system.Set_G_acc(ChVector<>(0, 0, 0)); // Create the ground body auto ground = std::make_shared<ChBodyEasyBox>(3, 2, 0.1, 10, false, true); system.AddBody(ground); ground->SetBodyFixed(true); // Create the sliding body // Give an initial angular velocity auto body = std::make_shared<ChBodyEasyBox>(0.5, 0.5, 0.5, 10, false, true); system.AddBody(body); body->SetBodyFixed(false); body->SetPos(ChVector<>(-1.25, -0.75, 0.1)); body->SetWvel_loc(ChVector<>(0.1, 0.1, 0.1)); auto body_col = std::make_shared<ChColorAsset>(); body_col->SetColor(ChColor(0.6f, 0, 0)); body->AddAsset(body_col); // Create the plane-plane constraint // Constrain the sliding body to move and rotate in the x-y plane // (i.e. the plane whose normal is the z-axis of the specified coord sys) auto plane_plane = std::make_shared<ChLinkLockPlanePlane>(); plane_plane->Initialize(ground, body, ChCoordsys<>(ChVector<>(-1.25, -0.75, 0), ChQuaternion<>(1, 0, 0, 0))); system.AddLink(plane_plane); // Create a linear spring (with default spring & damping coefficients) auto spring = std::make_shared<ChLinkSpring>(); spring->Initialize(ground, body, true, ChVector<>(0, 0, 2), ChVector<>(0, 0, 0), false, 1.9); system.AddLink(spring); // Create the Irrlicht application ChIrrApp application(&system, L"ChLinkLockPlanePlane", irr::core::dimension2d<irr::u32>(800, 600), false, true); application.AddTypicalLogo(); application.AddTypicalSky(); application.AddTypicalLights(); application.AddTypicalCamera(irr::core::vector3df(3, 0, 3)); application.AssetBindAll(); application.AssetUpdateAll(); // Simulation loop application.SetTimestep(0.005); while (application.GetDevice()->run()) { application.BeginScene(); application.DrawAll(); ChIrrTools::drawSpring(application.GetVideoDriver(), 0.05, spring->GetEndPoint1Abs(), spring->GetEndPoint2Abs(), irr::video::SColor(0, 255, 255, 100), 80, 15, true); ChIrrTools::drawAllCOGs(system, application.GetVideoDriver(), 2); application.EndScene(); application.DoStep(); } return 0; }
void create_wall_bodies(ChSystemNSC& mphysicalSystem) { // Create a material that will be shared between bricks auto mmaterial = std::make_shared<ChMaterialSurfaceNSC>(); mmaterial->SetFriction(0.4f); mmaterial->SetCompliance(0.0000005f); mmaterial->SetComplianceT(0.0000005f); mmaterial->SetDampingF(0.2f); // Create bricks for (int ai = 0; ai < 1; ai++) // N. of walls { for (int bi = 0; bi < 10; bi++) // N. of vert. bricks { for (int ui = 0; ui < 15; ui++) // N. of hor. bricks { auto mrigidBody = std::make_shared<ChBodyEasyBox>(3.96, 2, 4, // x,y,z size 100, // density true, // collide enable? true); // visualization? mrigidBody->SetPos(ChVector<>(-8 + ui * 4.0 + 2 * (bi % 2), 1.0 + bi * 2.0, ai * 9)); mrigidBody->SetMaterialSurface(mmaterial); // use shared surface properties mphysicalSystem.Add(mrigidBody); // optional, attach a texture for better visualization auto mtexture = std::make_shared<ChTexture>(); mtexture->SetTextureFilename(GetChronoDataFile("cubetexture_borders.png")); mrigidBody->AddAsset(mtexture); } } } // Create the floor using // fixed rigid body of 'box' type: auto mrigidFloor = std::make_shared<ChBodyEasyBox>(250, 4, 250, // x,y,z size 1000, // density true, // collide enable? true); // visualization? mrigidFloor->SetPos(ChVector<>(0, -2, 0)); mrigidFloor->SetMaterialSurface(mmaterial); mrigidFloor->SetBodyFixed(true); mphysicalSystem.Add(mrigidFloor); // Create a ball that will collide with wall auto mrigidBall = std::make_shared<ChBodyEasySphere>(4, // radius 8000, // density true, // collide enable? true); // visualization? mrigidBall->SetPos(ChVector<>(0, -2, 0)); mrigidBall->SetMaterialSurface(mmaterial); mrigidBall->SetPos(ChVector<>(0, 3, -8)); mrigidBall->SetPos_dt(ChVector<>(0, 0, 16)); // set initial speed mrigidBall->GetMaterialSurfaceNSC()->SetFriction(0.4f); // use own (not shared) matrial properties mrigidBall->GetMaterialSurfaceNSC()->SetCompliance(0.0); mrigidBall->GetMaterialSurfaceNSC()->SetComplianceT(0.0); mrigidBall->GetMaterialSurfaceNSC()->SetDampingF(0.2f); mphysicalSystem.Add(mrigidBall); // optional, attach a texture for better visualization auto mtextureball = std::make_shared<ChTexture>(); mtextureball->SetTextureFilename(GetChronoDataFile("bluwhite.png")); mrigidBall->AddAsset(mtextureball); }
int main(int argc, char* argv[]) { GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n"; // Create a ChronoENGINE physical system ChSystemNSC mphysicalSystem; // Create the Irrlicht visualization (open the Irrlicht device, // bind a simple user interface, etc. etc.) ChIrrApp application(&mphysicalSystem, L"Bricks test", core::dimension2d<u32>(800, 600), false, true); // Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene: ChIrrWizard::add_typical_Logo(application.GetDevice()); ChIrrWizard::add_typical_Sky(application.GetDevice()); ChIrrWizard::add_typical_Lights(application.GetDevice(), core::vector3df(70.f, 120.f, -90.f), core::vector3df(30.f, 80.f, 60.f), 290, 190); ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(-15, 14, -30), core::vector3df(0, 5, 0)); // // HERE YOU POPULATE THE MECHANICAL SYSTEM OF CHRONO... // // Create all the rigid bodies. create_wall_bodies(mphysicalSystem); // create_jengatower_bodies (mphysicalSystem); // Use this function for adding a ChIrrNodeAsset to all items // If you need a finer control on which item really needs a visualization proxy in // Irrlicht, just use application.AssetBind(myitem); on a per-item basis. application.AssetBindAll(); // Use this function for 'converting' into Irrlicht meshes the assets // into Irrlicht-visualizable meshes application.AssetUpdateAll(); // Prepare the physical system for the simulation mphysicalSystem.SetSolverType(ChSolver::Type::SOR_MULTITHREAD); //mphysicalSystem.SetUseSleeping(true); mphysicalSystem.SetMaxPenetrationRecoverySpeed(1.6); // used by Anitescu stepper only mphysicalSystem.SetMaxItersSolverSpeed(40); mphysicalSystem.SetMaxItersSolverStab(20); // unuseful for Anitescu, only Tasora uses this mphysicalSystem.SetSolverWarmStarting(true); mphysicalSystem.SetParallelThreadNumber(4); // // THE SOFT-REAL-TIME CYCLE // application.SetStepManage(true); application.SetTimestep(0.02); while (application.GetDevice()->run()) { application.BeginScene(true, true, SColor(255, 140, 161, 192)); ChIrrTools::drawGrid(application.GetVideoDriver(), 5, 5, 20, 20, ChCoordsys<>(ChVector<>(0, 0.04, 0), Q_from_AngAxis(CH_C_PI / 2, VECT_X)), video::SColor(50, 90, 90, 150), true); application.DrawAll(); application.DoStep(); application.EndScene(); } return 0; }
void create_jengatower_bodies(ChSystemNSC& mphysicalSystem) { // Create a material that will be shared between bricks auto mmaterial = std::make_shared<ChMaterialSurfaceNSC>(); mmaterial->SetFriction(0.4f); mmaterial->SetCompliance(0.0000005f); mmaterial->SetComplianceT(0.0000005f); mmaterial->SetDampingF(0.2f); // Create bricks for (int bi = 0; bi < 12; bi += 2) { auto mrigidBody1 = std::make_shared<ChBodyEasyBox>(2, 2, 14, // x,y,z size 100, // density true, // collide enable? true); // visualization? mrigidBody1->SetPos(ChVector<>(-5, 1.0 + bi * 2.0, 0)); mrigidBody1->SetMaterialSurface(mmaterial); // use shared surface properties mphysicalSystem.Add(mrigidBody1); auto mrigidBody2 = std::make_shared<ChBodyEasyBox>(2, 2, 14, // x,y,z size 100, // density true, // collide enable? true); // visualization? mrigidBody2->SetPos(ChVector<>(5, 1.0 + bi * 2.0, 0)); mrigidBody2->SetMaterialSurface(mmaterial); // use shared surface properties mphysicalSystem.Add(mrigidBody2); auto mrigidBody3 = std::make_shared<ChBodyEasyBox>(14, 2, 2, // x,y,z size 100, // density true, // collide enable? true); // visualization? mrigidBody3->SetPos(ChVector<>(0, 3.0 + bi * 2.0, 5)); mrigidBody3->SetMaterialSurface(mmaterial); // use shared surface properties mphysicalSystem.Add(mrigidBody3); auto mrigidBody4 = std::make_shared<ChBodyEasyBox>(14, 2, 2, // x,y,z size 100, // density true, // collide enable? true); // visualization? mrigidBody4->SetPos(ChVector<>(0, 3.0 + bi * 2.0, -5)); mrigidBody4->SetMaterialSurface(mmaterial); // use shared surface properties mphysicalSystem.Add(mrigidBody4); } // Create the floor using // fixed rigid body of 'box' type: auto mrigidFloor = std::make_shared<ChBodyEasyBox>(250, 4, 250, // x,y,z size 1000, // density true, // collide enable? true); // visualization? mrigidFloor->SetPos(ChVector<>(0, -2, 0)); mrigidFloor->SetMaterialSurface(mmaterial); mrigidFloor->SetBodyFixed(true); mphysicalSystem.Add(mrigidFloor); // Create a ball that will collide with tower auto mrigidBall = std::make_shared<ChBodyEasySphere>(4, // radius 1000, // density true, // collide enable? true); // visualization? mrigidBall->SetMaterialSurface(mmaterial); mrigidBall->SetPos(ChVector<>(0, 3, -8)); mrigidBall->SetPos_dt(ChVector<>(0, 0, 2)); // set initial speed mrigidBall->GetMaterialSurfaceNSC()->SetFriction(0.4f); // use own (not shared) matrial properties mrigidBall->GetMaterialSurfaceNSC()->SetCompliance(0.0); mrigidBall->GetMaterialSurfaceNSC()->SetComplianceT(0.0); mrigidBall->GetMaterialSurfaceNSC()->SetDampingF(0.2f); mphysicalSystem.Add(mrigidBall); // optional, attach a texture for better visualization auto mtextureball = std::make_shared<ChTexture>(); mtextureball->SetTextureFilename(GetChronoDataFile("bluwhite.png")); mrigidBall->AddAsset(mtextureball); }
int main(int argc, char* argv[]) { GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n"; // Create a ChronoENGINE physical system ChSystemNSC mphysicalSystem; // ** user input double wheelMass = 5.0; // mass of wheel double suspMass = 10.0; // mass of suspended weight // Create the Irrlicht visualization (open the Irrlicht device, // bind a simple user interface, etc. etc.) ChIrrApp application(&mphysicalSystem, L"Soil bin demo", core::dimension2d<u32>(1024, 768), false); ChIrrWizard::add_typical_Logo(application.GetDevice()); ChIrrWizard::add_typical_Sky(application.GetDevice()); ChIrrWizard::add_typical_Lights(application.GetDevice(), irr::core::vector3df(20., 30., 25.), irr::core::vector3df(25., 25., -25.), 65.0, 75.); ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(3.5f, 2.5f, -2.4f)); // ******* SOIL BIN WHEEL // Create the wheel ChVector<> wheelCMpos = ChVector<>(0, 0.5, 0); ChVector<> wheelInertia = ChVector<>(1.0, 1.0, 1.0); SoilbinWheel* mwheel = new SoilbinWheel(&mphysicalSystem, wheelCMpos, wheelMass, wheelInertia); // ***** TESTING MECHANISM // now, create the testing mechanism and attach the wheel to it double binWidth = 1.0; double binLen = 2.4; TestMech* mTestMechanism = new TestMech(&mphysicalSystem, mwheel->wheel, binWidth, binLen, suspMass, 2500., 10.); // ***** PARTICLE GENERATOR // make a particle generator, that the sceneManager can use to easily dump a bunch of dirt in the bin ParticleGenerator* mParticleGen = new ParticleGenerator(&application, &mphysicalSystem, binWidth, binLen); // Bind visualization assets. application.AssetBindAll(); application.AssetUpdateAll(); // ***** Create the User - GUI double torqueMax = 50.; MyEventReceiver receiver(&application, mwheel, mTestMechanism, mParticleGen, 0.02, 0.02, torqueMax); // add a custom event receiver to the default interface: application.SetUserEventReceiver(&receiver); // Set some integrator settings // mphysicalSystem.SetSolverType(ChSolver::Type::APGD); mphysicalSystem.SetSolverType(ChSolver::Type::SOR_MULTITHREAD); mphysicalSystem.SetMaxItersSolverSpeed(70); mphysicalSystem.SetMaxItersSolverStab(15); mphysicalSystem.SetParallelThreadNumber(4); // Use real-time step of the simulation, OR... application.SetStepManage(true); application.SetTimestep(0.01); application.SetTryRealtime(true); while (application.GetDevice()->run()) { application.BeginScene(true, true, SColor(255, 140, 161, 192)); application.DrawAll(); // draw the custom links receiver.drawSprings(); receiver.drawGrid(); // output relevant soil, wheel data if the tab is selected if (receiver.gad_tab_soil->isVisible()) receiver.drawSoilOutput(); if (receiver.gad_tab_wheel->isVisible()) receiver.drawWheelOutput(); receiver.drawWheelOutput(); // apply torque to the wheel mTestMechanism->applyTorque(); application.DoStep(); if (!application.GetPaused()) { // add bodies to the system? if (receiver.createParticles()) { receiver.genParticles(); } } application.EndScene(); } return 0; }
void create_some_falling_items(ChSystemNSC& mphysicalSystem, ISceneManager* msceneManager, IVideoDriver* driver) { for (int bi = 0; bi < 29; bi++) { // Create a bunch of ChronoENGINE rigid bodies (spheres and // boxes etc.) which will fall.. auto msphereBody = std::make_shared<ChBodyEasySphere>(1.1, // radius size 1000, // density true, // collide enable? true); // visualization? msphereBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10)); msphereBody->GetMaterialSurfaceNSC()->SetFriction(0.2f); mphysicalSystem.Add(msphereBody); // optional, attach a texture for better visualization auto mtexture = std::make_shared<ChTexture>(); mtexture->SetTextureFilename(GetChronoDataFile("bluwhite.png")); msphereBody->AddAsset(mtexture); auto mboxBody = std::make_shared<ChBodyEasyBox>(1.5, 1.5, 1.5, // x,y,z size 100, // density true, // collide enable? true); // visualization? mboxBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10)); mphysicalSystem.Add(mboxBody); // optional, attach a texture for better visualization auto mtexturebox = std::make_shared<ChTexture>(); mtexturebox->SetTextureFilename(GetChronoDataFile("cubetexture_bluwhite.png")); mboxBody->AddAsset(mtexturebox); auto mcylBody = std::make_shared<ChBodyEasyCylinder>(0.75, 0.5, // radius, height 100, // density true, // collide enable? true); // visualization? mcylBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10)); mphysicalSystem.Add(mcylBody); // optional, attach a texture for better visualization auto mtexturecyl = std::make_shared<ChTexture>(); mtexturecyl->SetTextureFilename(GetChronoDataFile("pinkwhite.png")); mcylBody->AddAsset(mtexturecyl); } // Create the five walls of the rectangular container, using // fixed rigid bodies of 'box' type: auto floorBody = std::make_shared<ChBodyEasyBox>(20, 1, 20, 1000, true, true); floorBody->SetPos(ChVector<>(0, -5, 0)); floorBody->SetBodyFixed(true); mphysicalSystem.Add(floorBody); auto wallBody1 = std::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true); wallBody1->SetPos(ChVector<>(-10, 0, 0)); wallBody1->SetBodyFixed(true); mphysicalSystem.Add(wallBody1); auto wallBody2 = std::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true); wallBody2->SetPos(ChVector<>(10, 0, 0)); wallBody2->SetBodyFixed(true); mphysicalSystem.Add(wallBody2); auto wallBody3 = std::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true); wallBody3->SetPos(ChVector<>(0, 0, -10)); wallBody3->SetBodyFixed(true); mphysicalSystem.Add(wallBody3); auto wallBody4 = std::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true); wallBody4->SetPos(ChVector<>(0, 0, 10)); wallBody4->SetBodyFixed(true); mphysicalSystem.Add(wallBody4); // optional, attach textures for better visualization auto mtexturewall = std::make_shared<ChTexture>(); mtexturewall->SetTextureFilename(GetChronoDataFile("concrete.jpg")); wallBody1->AddAsset(mtexturewall); // note: most assets can be shared wallBody2->AddAsset(mtexturewall); wallBody3->AddAsset(mtexturewall); wallBody4->AddAsset(mtexturewall); floorBody->AddAsset(mtexturewall); // Add the rotating mixer auto rotatingBody = std::make_shared<ChBodyEasyBox>(10, 5, 1, // x,y,z size 4000, // density true, // collide enable? true); // visualization? rotatingBody->SetPos(ChVector<>(0, -1.6, 0)); rotatingBody->GetMaterialSurfaceNSC()->SetFriction(0.4f); mphysicalSystem.Add(rotatingBody); // .. a motor between mixer and truss auto my_motor = std::make_shared<ChLinkMotorRotationSpeed>(); my_motor->Initialize(rotatingBody, floorBody, ChFrame<>(ChVector<>(0, 0, 0), Q_from_AngAxis(CH_C_PI_2, VECT_X))); auto mfun = std::make_shared<ChFunction_Const>(CH_C_PI / 2.0); // speed w=90°/s my_motor->SetSpeedFunction(mfun); mphysicalSystem.AddLink(my_motor); /* /// NOTE: Instead of creating five separate 'box' bodies to make /// the walls of the bowl, you could have used a single body /// made of five box shapes, which build a single collision description, /// as in the alternative approach: // create a plain ChBody (no colliding shape nor visualization mesh is used yet) auto mrigidBody = std::make_shared<ChBody>(); // set the ChBodySceneNode as fixed body, and turn collision ON, otherwise no collide by default mrigidBody->SetBodyFixed(true); mrigidBody->SetCollide(true); // Clear model. The colliding shape description MUST be between ClearModel() .. BuildModel() pair. mrigidBody->GetCollisionModel()->ClearModel(); // Describe the (invisible) colliding shape by adding five boxes (the walls and floor) mrigidBody->GetCollisionModel()->AddBox(20,1,20, ChVector<>( 0,-10, 0)); mrigidBody->GetCollisionModel()->AddBox(1,40,20, ChVector<>(-11, 0, 0)); mrigidBody->GetCollisionModel()->AddBox(1,40,20, ChVector<>( 11, 0, 0)); mrigidBody->GetCollisionModel()->AddBox(20,40,1, ChVector<>( 0, 0,-11)); mrigidBody->GetCollisionModel()->AddBox(20,40,1, ChVector<>( 0, 0, 11)); // Complete the description of collision shape. mrigidBody->GetCollisionModel()->BuildModel(); // Attach some visualization shapes if needed: auto vshape = std::make_shared<ChBoxShape>(); vshape->GetBoxGeometry().SetLengths( ChVector<> (20,1,20) ); vshape->GetBoxGeometry().Pos = ChVector<> (0,-5,0); this->AddAsset( vshape ); // etc. for other 4 box shapes.. */ }