// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- void ChTrackTestRig::AddVisualize_post(std::shared_ptr<ChBody> post_body, std::shared_ptr<ChBody> chassis_body, double length, double width, double height, const ChColor& color) { // Platform (on post body) auto base_box = std::make_shared<ChBoxShape>(); base_box->GetBoxGeometry().SetLengths(ChVector<>(length, width, height)); post_body->AddAsset(base_box); auto col = std::make_shared<ChColorAsset>(); col->SetColor(color); post_body->AddAsset(col); // Piston (on post body) auto piston = std::make_shared<ChCylinderShape>(); piston->GetCylinderGeometry().rad = width / 6.0; piston->GetCylinderGeometry().p1 = ChVector<>(0, 0, -height / 2.0); piston->GetCylinderGeometry().p2 = ChVector<>(0, 0, -height * 12.0); post_body->AddAsset(piston); // add asset to post body // Post sleeve (on chassis/ground body) auto cyl = std::make_shared<ChCylinderShape>(); cyl->GetCylinderGeometry().rad = width / 4.0; cyl->GetCylinderGeometry().p1 = post_body->GetPos() - ChVector<>(0, 0, 8 * height); cyl->GetCylinderGeometry().p2 = post_body->GetPos() - ChVector<>(0, 0, 16 * height); chassis_body->AddAsset(cyl); }
void ChTrackShoeBandBushing::AddWebVisualization(std::shared_ptr<ChBody> segment) { segment->AddAsset(std::make_shared<ChColorAsset>(GetColor(m_index))); auto box = std::make_shared<ChBoxShape>(); box->GetBoxGeometry().SetLengths(ChVector<>(m_seg_length, GetBeltWidth(), GetWebThickness())); segment->AddAsset(box); auto cyl = std::make_shared<ChCylinderShape>(); double radius = GetWebThickness() / 4; cyl->GetCylinderGeometry().rad = radius; cyl->GetCylinderGeometry().p1 = ChVector<>(m_seg_length / 2, -GetBeltWidth() / 2 - 2 * radius, 0); cyl->GetCylinderGeometry().p2 = ChVector<>(m_seg_length / 2, +GetBeltWidth() / 2 + 2 * radius, 0); segment->AddAsset(cyl); }
void AddWall(std::shared_ptr<ChBody> body, const ChVector<>& dim, const ChVector<>& loc) { body->GetCollisionModel()->AddBox(dim.x(), dim.y(), dim.z(), loc); auto box = std::make_shared<ChBoxShape>(); box->GetBoxGeometry().Size = dim; box->GetBoxGeometry().Pos = loc; box->SetColor(ChColor(1, 0, 0)); box->SetFading(0.6f); body->AddAsset(box); }
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- void ChDoubleWishboneReduced::AddVisualizationUpright(std::shared_ptr<ChBody> upright, const ChVector<> pt_C, const ChVector<> pt_U, const ChVector<> pt_L, const ChVector<> pt_T, double radius) { static const double threshold2 = 1e-6; // Express hardpoint locations in body frame. ChVector<> p_C = upright->TransformPointParentToLocal(pt_C); ChVector<> p_U = upright->TransformPointParentToLocal(pt_U); ChVector<> p_L = upright->TransformPointParentToLocal(pt_L); ChVector<> p_T = upright->TransformPointParentToLocal(pt_T); if ((p_L - p_C).Length2() > threshold2) { auto cyl_L = std::make_shared<ChCylinderShape>(); cyl_L->GetCylinderGeometry().p1 = p_L; cyl_L->GetCylinderGeometry().p2 = p_C; cyl_L->GetCylinderGeometry().rad = radius; upright->AddAsset(cyl_L); } if ((p_U - p_C).Length2() > threshold2) { auto cyl_U = std::make_shared<ChCylinderShape>(); cyl_U->GetCylinderGeometry().p1 = p_U; cyl_U->GetCylinderGeometry().p2 = p_C; cyl_U->GetCylinderGeometry().rad = radius; upright->AddAsset(cyl_U); } if ((p_T - p_C).Length2() > threshold2) { auto cyl_T = std::make_shared<ChCylinderShape>(); cyl_T->GetCylinderGeometry().p1 = p_T; cyl_T->GetCylinderGeometry().p2 = p_C; cyl_T->GetCylinderGeometry().rad = radius; upright->AddAsset(cyl_T); } auto col = std::make_shared<ChColorAsset>(); col->SetColor(ChColor(0.2f, 0.2f, 0.6f)); upright->AddAsset(col); }
void AddContainerWall(std::shared_ptr<ChBody> body, const ChVector<>& pos, const ChVector<>& size, bool visible = true) { ChVector<> hsize = 0.5 * size; body->GetCollisionModel()->AddBox(hsize.x(), hsize.y(), hsize.z(), pos); if (visible) { auto box = std::make_shared<ChBoxShape>(); box->GetBoxGeometry().Pos = pos; box->GetBoxGeometry().Size = hsize; box->SetColor(ChColor(1, 0, 0)); box->SetFading(0.6f); body->AddAsset(box); } }
// Use convex decomposition for collision detection with the Trelleborg tire SoilbinWheel(ChSystemNSC* system, ChVector<> mposition, double mass, ChVector<>& inertia) { ChCollisionModel::SetDefaultSuggestedEnvelope(0.005); ChCollisionModel::SetDefaultSuggestedMargin(0.004); // Create the wheel body wheel = std::make_shared<ChBody>(); wheel->SetPos(mposition); wheel->SetMass(mass); wheel->SetInertiaXX(inertia); wheel->GetMaterialSurfaceNSC()->SetFriction(0.4f); wheel->SetCollide(true); // Visualization mesh auto tireMesh = std::make_shared<ChTriangleMeshConnected>(); tireMesh->LoadWavefrontMesh(GetChronoDataFile("tractor_wheel.obj"), true, true); auto tireMesh_asset = std::make_shared<ChTriangleMeshShape>(); tireMesh_asset->SetMesh(tireMesh); wheel->AddAsset(tireMesh_asset); // Contact mesh wheel->GetCollisionModel()->ClearModel(); // Describe the (invisible) colliding shape by adding the 'carcass' decomposed shape and the // 'knobs'. Since these decompositions are only for 1/15th of the wheel, use for() to pattern them. for (double mangle = 0; mangle < 360.; mangle += (360. / 15.)) { ChQuaternion<> myrot; ChStreamInAsciiFile myknobs(GetChronoDataFile("tractor_wheel_knobs.chulls").c_str()); ChStreamInAsciiFile myslice(GetChronoDataFile("tractor_wheel_slice.chulls").c_str()); myrot.Q_from_AngAxis(mangle * (CH_C_PI / 180.), VECT_X); ChMatrix33<> mm(myrot); wheel->GetCollisionModel()->AddConvexHullsFromFile(myknobs, ChVector<>(0, 0, 0), mm); wheel->GetCollisionModel()->AddConvexHullsFromFile(myslice, ChVector<>(0, 0, 0), mm); } wheel->GetCollisionModel()->BuildModel(); // Add wheel body to system system->AddBody(wheel); }
// Build and initialize the forklift, creating all bodies corresponding to // the various parts and adding them to the physical system - also creating // and adding constraints to the system. MySimpleForklift(ChIrrAppInterface* app, ChVector<> offset = ChVector<>(0, 0, 0)) { throttle = 0; // initially, gas throttle is 0. steer = 0; lift = 0; ChVector<> COG_truss(0, 0.4, 0.5); ChVector<> COG_wheelRF(-0.566, 0.282, 1.608); ChVector<> COG_wheelLF(0.566, 0.282, 1.608); ChVector<> COG_arm(0, 1.300, 1.855); ChVector<> COG_fork(0, 0.362, 2.100); ChVector<> COG_wheelB(0, 0.282, 0.003); ChVector<> POS_pivotarm(0, 0.150, 1.855); ChVector<> POS_prismatic(0, 0.150, 1.855); double RAD_back_wheel = 0.28; double RAD_front_wheel = 0.28; forkliftTiremap = app->GetVideoDriver()->getTexture(GetChronoDataFile("tire_truck.png").c_str()); // --- The car body --- truss = std::make_shared<ChBody>(); app->GetSystem()->Add(truss); truss->SetPos(COG_truss); truss->SetMass(200); truss->SetInertiaXX(ChVector<>(100, 100, 100)); // collision properties: truss->GetCollisionModel()->ClearModel(); truss->GetCollisionModel()->AddBox(1.227 / 2., 1.621 / 2., 1.864 / 2., ChVector<>(-0.003, 1.019, 0.192)); truss->GetCollisionModel()->AddBox(0.187 / 2., 0.773 / 2., 1.201 / 2., ChVector<>(0.486, 0.153, -0.047)); truss->GetCollisionModel()->AddBox(0.187 / 2., 0.773 / 2., 1.201 / 2., ChVector<>(-0.486, 0.153, -0.047)); truss->GetCollisionModel()->BuildModel(); truss->SetCollide(true); // visualization properties: auto truss_asset_assembly = std::make_shared<ChAssetLevel>(); truss_asset_assembly->GetFrame().SetPos(-COG_truss); truss->AddAsset(truss_asset_assembly); auto truss_mesh = std::make_shared<ChObjShapeFile>(); truss_mesh->SetFilename(GetChronoDataFile("forklift_body.obj")); truss_asset_assembly->AddAsset(truss_mesh); auto truss_texture = std::make_shared<ChTexture>(GetChronoDataFile("tire_truck.png")); truss_asset_assembly->AddAsset(truss_texture); // ..the right-front wheel wheelRF = std::make_shared<ChBody>(); app->GetSystem()->Add(wheelRF); wheelRF->SetPos(COG_wheelRF); wheelRF->SetMass(20); wheelRF->SetInertiaXX(ChVector<>(2, 2, 2)); // collision properties: ChMatrix33<> Arot(chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Z)); wheelRF->GetCollisionModel()->ClearModel(); wheelRF->GetCollisionModel()->AddCylinder(RAD_front_wheel, RAD_front_wheel, 0.1, ChVector<>(0, 0, 0), Arot); wheelRF->GetCollisionModel()->BuildModel(); wheelRF->SetCollide(true); // visualization properties: auto wheelRF_asset_assembly = std::make_shared<ChAssetLevel>(); wheelRF_asset_assembly->GetFrame().SetPos(-COG_wheelRF); wheelRF->AddAsset(wheelRF_asset_assembly); auto wheelRF_mesh = std::make_shared<ChObjShapeFile>(); wheelRF_mesh->SetFilename(GetChronoDataFile("wheel.obj")); wheelRF_asset_assembly->AddAsset(wheelRF_mesh); auto wheelRF_texture = std::make_shared<ChTexture>(GetChronoDataFile("tire_truck.png")); wheelRF_asset_assembly->AddAsset(wheelRF_texture); // .. create the revolute joint between the wheel and the truss link_revoluteRF = std::make_shared<ChLinkLockRevolute>(); // right, front, upper, 1 link_revoluteRF->Initialize(wheelRF, truss, ChCoordsys<>(COG_wheelRF, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); app->GetSystem()->AddLink(link_revoluteRF); // ..the left-front wheel wheelLF = std::make_shared<ChBody>(); app->GetSystem()->Add(wheelLF); wheelLF->SetPos(COG_wheelLF); wheelLF->SetRot(chrono::Q_from_AngAxis(CH_C_PI, VECT_Y)); // reuse RF wheel shape, flipped wheelLF->SetMass(20); wheelLF->SetInertiaXX(ChVector<>(2, 2, 2)); // collision properties: wheelLF->GetCollisionModel()->ClearModel(); wheelLF->GetCollisionModel()->AddCylinder(RAD_front_wheel, RAD_front_wheel, 0.1, ChVector<>(0, 0, 0), Arot); wheelLF->GetCollisionModel()->BuildModel(); wheelLF->SetCollide(true); // visualization properties: auto wheelLF_asset_assembly = std::make_shared<ChAssetLevel>(); wheelLF_asset_assembly->GetFrame().SetPos(-COG_wheelRF); wheelLF->AddAsset(wheelLF_asset_assembly); auto wheelLF_mesh = std::make_shared<ChObjShapeFile>(); wheelLF_mesh->SetFilename(GetChronoDataFile("wheel.obj")); wheelLF_asset_assembly->AddAsset(wheelLF_mesh); auto wheelLF_texture = std::make_shared<ChTexture>(GetChronoDataFile("tire_truck.png")); wheelLF_asset_assembly->AddAsset(wheelLF_texture); // .. create the revolute joint between the wheel and the truss link_revoluteLF = std::make_shared<ChLinkLockRevolute>(); // right, front, upper, 1 link_revoluteLF->Initialize(wheelLF, truss, ChCoordsys<>(COG_wheelLF, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); app->GetSystem()->AddLink(link_revoluteLF); // ..the back steering spindle (invisible, no mesh) spindleB = std::make_shared<ChBody>(); app->GetSystem()->Add(spindleB); spindleB->SetPos(COG_wheelB); spindleB->SetMass(10); spindleB->SetInertiaXX(ChVector<>(1, 1, 1)); // .. create the vertical steering link between the spindle structure and the truss link_steer_engineB = std::make_shared<ChLinkEngine>(); link_steer_engineB->Initialize( spindleB, truss, ChCoordsys<>(COG_wheelB, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_X))); // vertical axis link_steer_engineB->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); link_steer_engineB->Set_eng_mode(ChLinkEngine::ENG_MODE_ROTATION); app->GetSystem()->AddLink(link_steer_engineB); // ..the back wheel wheelB = std::make_shared<ChBody>(); app->GetSystem()->Add(wheelB); wheelB->SetPos(COG_wheelB); wheelB->SetRot(chrono::Q_from_AngAxis(CH_C_PI, VECT_Y)); // reuse RF wheel shape, flipped wheelB->SetMass(20); wheelB->SetInertiaXX(ChVector<>(2, 2, 2)); // collision properties: wheelB->GetCollisionModel()->ClearModel(); wheelB->GetCollisionModel()->AddCylinder(RAD_back_wheel, RAD_back_wheel, 0.1, ChVector<>(0, 0, 0), Arot); wheelB->GetCollisionModel()->BuildModel(); wheelB->SetCollide(true); // visualization properties: auto wheelB_asset_assembly = std::make_shared<ChAssetLevel>(); wheelB_asset_assembly->GetFrame().SetPos(-COG_wheelRF); wheelB->AddAsset(wheelB_asset_assembly); auto wheelB_mesh = std::make_shared<ChObjShapeFile>(); wheelB_mesh->SetFilename(GetChronoDataFile("wheel.obj")); wheelB_asset_assembly->AddAsset(wheelB_mesh); auto wheelB_texture = std::make_shared<ChTexture>(GetChronoDataFile("tire_truck.png")); wheelB_asset_assembly->AddAsset(wheelB_texture); // .. create the motor between the back wheel and the steering spindle structure link_engineB = std::make_shared<ChLinkEngine>(); link_engineB->Initialize(wheelB, spindleB, ChCoordsys<>(COG_wheelB, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); link_engineB->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); link_engineB->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED); app->GetSystem()->AddLink(link_engineB); // ..the arm arm = std::make_shared<ChBody>(); app->GetSystem()->Add(arm); arm->SetPos(COG_arm); arm->SetMass(100); arm->SetInertiaXX(ChVector<>(30, 30, 30)); // visualization properties: auto arm_asset_assembly = std::make_shared<ChAssetLevel>(); arm_asset_assembly->GetFrame().SetPos(-COG_arm); arm->AddAsset(arm_asset_assembly); auto arm_mesh = std::make_shared<ChObjShapeFile>(); arm_mesh->SetFilename(GetChronoDataFile("forklift_arm.obj")); arm_asset_assembly->AddAsset(arm_mesh); // .. create the revolute joint between the arm and the truss link_engineArm = std::make_shared<ChLinkEngine>(); // right, front, upper, 1 link_engineArm->Initialize(arm, truss, ChCoordsys<>(POS_pivotarm, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); link_engineArm->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); link_engineArm->Set_eng_mode(ChLinkEngine::ENG_MODE_ROTATION); app->GetSystem()->AddLink(link_engineArm); // ..the fork fork = std::make_shared<ChBody>(); app->GetSystem()->Add(fork); fork->SetPos(COG_fork); fork->SetMass(60); fork->SetInertiaXX(ChVector<>(15, 15, 15)); // collision properties: fork->GetCollisionModel()->ClearModel(); fork->GetCollisionModel()->AddBox(0.1 / 2., 0.032 / 2., 1.033 / 2.,ChVector<>(-0.352, -0.312, 0.613)); fork->GetCollisionModel()->AddBox(0.1 / 2., 0.032 / 2., 1.033 / 2., ChVector<>(0.352, -0.312, 0.613)); fork->GetCollisionModel()->AddBox(0.344 / 2., 1.134 / 2., 0.101 / 2., ChVector<>(-0.000, 0.321, -0.009)); fork->GetCollisionModel()->BuildModel(); fork->SetCollide(true); // visualization properties: auto fork_asset_assembly = std::make_shared<ChAssetLevel>(); fork_asset_assembly->GetFrame().SetPos(-COG_fork); fork->AddAsset(fork_asset_assembly); auto fork_mesh = std::make_shared<ChObjShapeFile>(); fork_mesh->SetFilename(GetChronoDataFile("forklift_forks.obj")); fork_asset_assembly->AddAsset(fork_mesh); // .. create the prismatic joint between the fork and arm link_prismaticFork = std::make_shared<ChLinkLockPrismatic>(); link_prismaticFork->Initialize( fork, arm, ChCoordsys<>( POS_prismatic, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_X))); // set prism as vertical (default would be aligned to z, horizontal app->GetSystem()->AddLink(link_prismaticFork); // .. create the linear actuator that pushes upward the fork link_actuatorFork = std::make_shared<ChLinkLinActuator>(); link_actuatorFork->Initialize(fork, arm, false, ChCoordsys<>(POS_prismatic + ChVector<>(0, 0.01, 0), QUNIT), ChCoordsys<>(POS_prismatic, QUNIT)); app->GetSystem()->AddLink(link_actuatorFork); // ..a pallet auto pallet = std::make_shared<ChBodyEasyMesh>( GetChronoDataFile("pallet.obj"), // mesh .OBJ file 300, // density true, // compute mass, inertia & COG from the mesh (must be a closed watertight mesh!) true, // enable collision with mesh 0.001, // sphere swept inflate of mesh - improves robustness of collision detection true); // enable visualization of mesh app->GetSystem()->Add(pallet); pallet->SetPos(ChVector<>(0, 0.4, 3)); // apply also a texture to the pallet: auto pallet_texture = std::make_shared<ChTexture>(); pallet_texture->SetTextureFilename(GetChronoDataFile("cubetexture.png")); pallet->AddAsset(pallet_texture); // // Move the forklift to initial offset position // // pallet->GetBody()->Move(offset); truss->Move(offset); wheelRF->Move(offset); wheelLF->Move(offset); wheelB->Move(offset); spindleB->Move(offset); arm->Move(offset); fork->Move(offset); }
// functions TestMech(ChSystemNSC* system, std::shared_ptr<ChBody> wheelBody, double binWidth = 1.0, double binLength = 2.0, double weightMass = 100.0, double springK = 25000, double springD = 100) { ChCollisionModel::SetDefaultSuggestedEnvelope(0.003); ChCollisionModel::SetDefaultSuggestedMargin(0.002); ChQuaternion<> rot; rot.Q_from_AngAxis(ChRandom() * CH_C_2PI, VECT_Y); // ******* // Create a soil bin with planes. bin width = x-dir, bin length = z-dir // Note: soil bin depth will always be ~ 1m // ******* double binHeight = 1.0; double wallWidth = std::min<double>(binWidth, binLength) / 10.0; // wall width = 1/10 of min of bin dims // create the floor auto cubeMap = std::make_shared<ChTexture>(); cubeMap->SetTextureFilename(GetChronoDataFile("concrete.jpg")); floor = std::make_shared<ChBodyEasyBox>(binWidth + wallWidth / 2.0, wallWidth, binLength + wallWidth / 2.0, 1.0, true, true); floor->SetPos(ChVector<>(0, -0.5 - wallWidth / 2.0, 0)); floor->SetBodyFixed(true); floor->GetMaterialSurfaceNSC()->SetFriction(0.5); floor->AddAsset(cubeMap); system->AddBody(floor); // add some transparent walls to the soilBin, w.r.t. width, length of bin wall1 = std::make_shared<ChBodyEasyBox>(wallWidth, binHeight, binLength, 1.0, true, true); wall1->SetPos(ChVector<>(-binWidth / 2.0 - wallWidth / 2.0, 0, 0)); wall1->SetBodyFixed(true); system->AddBody(wall1); wall2 = std::make_shared<ChBodyEasyBox>(wallWidth, binHeight, binLength, 1.0, true, false); wall2->SetPos(ChVector<>(binWidth / 2.0 + wallWidth / 2.0, 0, 0)); wall2->SetBodyFixed(true); system->AddBody(wall2); wall3 = std::make_shared<ChBodyEasyBox>(binWidth + wallWidth / 2.0, binHeight, wallWidth, 1.0, true, false); wall3->SetPos(ChVector<>(0, 0, -binLength / 2.0 - wallWidth / 2.0)); wall3->SetBodyFixed(true); system->AddBody(wall3); // wall 4 wall4 = std::make_shared<ChBodyEasyBox>(binWidth + wallWidth / 2.0, binHeight, wallWidth, 1.0, true, true); wall4->SetPos(ChVector<>(0, 0, binLength / 2.0 + wallWidth / 2.0)); wall4->SetBodyFixed(true); system->AddBody(wall4); // ****** // make a truss, connect it to the wheel via revolute joint // single rotational DOF will be driven with a user-input for torque // ***** auto bluMap = std::make_shared<ChTexture>(); bluMap->SetTextureFilename(GetChronoDataFile("blu.png")); ChVector<> trussCM = wheelBody->GetPos(); truss = std::make_shared<ChBodyEasyBox>(0.2, 0.2, 0.4, 300.0, false, true); truss->SetPos(trussCM); truss->SetMass(5.0); truss->AddAsset(bluMap); system->AddBody(truss); // create the revolute joint between the wheel and spindle spindle = std::make_shared<ChLinkLockRevolute>(); spindle->Initialize(truss, wheelBody, ChCoordsys<>(trussCM, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); system->AddLink(spindle); // create a torque between the truss and wheel torqueDriver = std::make_shared<ChLinkEngine>(); torqueDriver->Initialize(truss, wheelBody, ChCoordsys<>(trussCM, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y))); torqueDriver->Set_eng_mode(ChLinkEngine::ENG_MODE_TORQUE); system->AddLink(torqueDriver); // ****** // create a body that will be used as a vehicle weight ChVector<> weightCM = ChVector<>(trussCM); weightCM.y() += 1.0; // note: this will determine the spring free length suspweight = std::make_shared<ChBodyEasyBox>(0.2, 0.4, 0.2, 5000.0, false, true); suspweight->SetPos(weightCM); suspweight->SetMass(weightMass); suspweight->AddAsset(bluMap); system->AddBody(suspweight); // create the translational joint between the truss and weight load auto translational = std::make_shared<ChLinkLockPrismatic>(); translational->Initialize(truss, suspweight, ChCoordsys<>(trussCM, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_X))); system->AddLink(translational); // create a spring between spindle truss and weight spring = std::make_shared<ChLinkSpring>(); spring->Initialize(truss, suspweight, false, trussCM, suspweight->GetPos()); spring->Set_SpringK(springK); spring->Set_SpringR(springD); system->AddLink(spring); // create a prismatic constraint between the weight and the ground auto weightLink = std::make_shared<ChLinkLockOldham>(); weightLink->Initialize(suspweight, floor, ChCoordsys<>(weightCM, chrono::Q_from_AngAxis(CH_C_PI / 2.0, VECT_Y))); system->AddLink(weightLink); }