/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #include #include #include #include #include #include #include "ASMTAssembly.h" #include "CREATE.h" #include "ASMTRevoluteJoint.h" #include "ASMTCylindricalJoint.h" #include "ASMTRotationalMotion.h" #include "ASMTTranslationalMotion.h" #include "ASMTMarker.h" #include "ASMTPart.h" #include "ASMTTranslationalJoint.h" #include "ASMTSphericalJoint.h" #include "ASMTFixedJoint.h" #include "ASMTGeneralMotion.h" #include "ASMTAllowRotation.h" #include "ASMTUniversalJoint.h" #include "ASMTPointInPlaneJoint.h" #include "ASMTPrincipalMassMarker.h" #include "ASMTForceTorque.h" #include "ASMTConstantGravity.h" #include "ASMTSimulationParameters.h" #include "ASMTAnimationParameters.h" #include "Part.h" #include "ASMTTime.h" #include "ASMTItemIJ.h" #include "ASMTAngleJoint.h" #include "ASMTConstantVelocityJoint.h" #include "ASMTCylSphJoint.h" #include "ASMTGearJoint.h" #include "ASMTPointInLineJoint.h" #include "ASMTRevCylJoint.h" #include "ASMTSphSphJoint.h" #include "ASMTLineInPlaneJoint.h" #include "ASMTPlanarJoint.h" #include "ASMTNoRotationJoint.h" #include "ASMTParallelAxesJoint.h" #include "ASMTPerpendicularJoint.h" #include "ASMTRackPinionJoint.h" #include "ASMTScrewJoint.h" #include "SimulationStoppingError.h" #include "ASMTKinematicIJ.h" #include "ASMTRefPoint.h" #include "ASMTRefCurve.h" #include "ASMTRefSurface.h" #include "ExternalSystem.h" #include "SystemSolver.h" #include "ASMTRevRevJoint.h" #include "ASMTLimit.h" #include "ASMTRotationLimit.h" #include "ASMTTranslationLimit.h" #include "ExternalSystem.h" #if __GNUC__ >= 8 #include #endif using namespace MbD; MbD::ASMTAssembly::ASMTAssembly() : ASMTSpatialContainer() { externalSystem = std::make_shared(); times = std::make_shared>(); } std::shared_ptr MbD::ASMTAssembly::With() { auto asmt = std::make_shared(); asmt->initialize(); return asmt; } void MbD::ASMTAssembly::runSinglePendulumSuperSimplified() { // In this version we skip declaration of variables that don't need as they use default values. auto assembly = CREATE::With(); assembly->setName("Assembly1"); auto mkr = CREATE::With(); mkr->setName("Marker1"); assembly->addMarker(mkr); auto part = CREATE::With(); part->setName("Part1"); part->setPosition3D(-0.1, -0.1, -0.1); assembly->addPart(part); mkr = CREATE::With(); mkr->setName("Marker1"); mkr->setPosition3D(0.1, 0.1, 0.1); part->addMarker(mkr); auto joint = CREATE::With(); joint->setName("Joint1"); joint->setMarkerI("/Assembly1/Marker1"); joint->setMarkerJ("/Assembly1/Part1/Marker1"); assembly->addJoint(joint); auto simulationParameters = CREATE::With(); simulationParameters->settstart(0.0); simulationParameters->settend(0.0); // tstart == tend Initial Conditions only. simulationParameters->sethmin(1.0e-9); simulationParameters->sethmax(1.0); simulationParameters->sethout(0.04); simulationParameters->seterrorTol(1.0e-6); assembly->setSimulationParameters(simulationParameters); assembly->runKINEMATIC(); } void MbD::ASMTAssembly::runSinglePendulumSuperSimplified2() { // In this version we skip declaration of variables that don't need as they use default values. auto assembly = CREATE::With(); assembly->setName("OndselAssembly"); auto mkr = CREATE::With(); mkr->setName("marker1"); assembly->addMarker(mkr); auto part = CREATE::With(); part->setName("part1"); assembly->addPart(part); auto marker1 = CREATE::With(); marker1->setName("FixingMarker"); part->addMarker(marker1); auto marker2 = CREATE::With(); marker2->setName("marker2"); marker2->setPosition3D(20.0, 10.0, 0.0); part->addMarker(marker2); auto part2 = CREATE::With(); part2->setName("part2"); part2->setPosition3D(20.0, 10.0, 0.0); assembly->addPart(part2); auto marker3 = CREATE::With(); marker3->setName("marker2"); marker3->setPosition3D(50.0, 10.0, 0.0); part2->addMarker(marker3); /*Ground joint*/ auto joint = CREATE::With(); joint->setName("Joint1"); joint->setMarkerI("/OndselAssembly/marker1"); joint->setMarkerJ("/OndselAssembly/part1/FixingMarker"); assembly->addJoint(joint); auto joint2 = CREATE::With(); joint2->setName("Joint2"); joint2->setMarkerI("/OndselAssembly/part1/marker2"); joint2->setMarkerJ("/OndselAssembly/part2/marker2"); assembly->addJoint(joint2); auto simulationParameters = CREATE::With(); simulationParameters->settstart(0.0); simulationParameters->settend(0.0); // tstart == tend Initial Conditions only. simulationParameters->sethmin(1.0e-9); simulationParameters->sethmax(1.0); simulationParameters->sethout(0.04); simulationParameters->seterrorTol(1.0e-6); assembly->setSimulationParameters(simulationParameters); assembly->runKINEMATIC(); } void MbD::ASMTAssembly::runSinglePendulumSimplified() { auto assembly = CREATE::With(); assembly->setNotes(""); assembly->setName("Assembly1"); assembly->setPosition3D(0, 0, 0); assembly->setRotationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1); assembly->setVelocity3D(0, 0, 0); assembly->setOmega3D(0, 0, 0); auto massMarker = ASMTPrincipalMassMarker::With(); massMarker->setMass(0.0); massMarker->setDensity(0.0); massMarker->setMomentOfInertias(0, 0, 0); massMarker->setPosition3D(0, 0, 0); massMarker->setRotationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1); assembly->setPrincipalMassMarker(massMarker); auto mkr = CREATE::With(); mkr->setName("Marker1"); mkr->setPosition3D(0, 0, 0); mkr->setRotationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1); assembly->addMarker(mkr); auto part = CREATE::With(); part->setName("Part1"); part->setPosition3D(-0.1, -0.1, -0.1); part->setRotationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1); part->setVelocity3D(0, 0, 0); part->setOmega3D(0, 0, 0); assembly->addPart(part); massMarker = ASMTPrincipalMassMarker::With(); massMarker->setMass(0.2); massMarker->setDensity(10.0); massMarker->setMomentOfInertias(8.3333333333333e-4, 0.016833333333333, 0.017333333333333); massMarker->setPosition3D(0.5, 0.1, 0.05); massMarker->setRotationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1); part->setPrincipalMassMarker(massMarker); mkr = CREATE::With(); mkr->setName("Marker1"); mkr->setPosition3D(0.1, 0.1, 0.1); mkr->setRotationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1); part->addMarker(mkr); auto joint = CREATE::With(); joint->setName("Joint1"); joint->setMarkerI("/Assembly1/Marker1"); joint->setMarkerJ("/Assembly1/Part1/Marker1"); assembly->addJoint(joint); auto motion = CREATE::With(); motion->setName("Motion1"); motion->setMotionJoint("/Assembly1/Joint1"); motion->setRotationZ("0.0"); assembly->addMotion(motion); auto constantGravity = CREATE::With(); constantGravity->setg(0.0, 0.0, 0.0); assembly->setConstantGravity(constantGravity); auto simulationParameters = CREATE::With(); simulationParameters->settstart(0.0); simulationParameters->settend(0.0); // tstart == tend Initial Conditions only. simulationParameters->sethmin(1.0e-9); simulationParameters->sethmax(1.0); simulationParameters->sethout(0.04); simulationParameters->seterrorTol(1.0e-6); assembly->setSimulationParameters(simulationParameters); assembly->runKINEMATIC(); } void MbD::ASMTAssembly::runSinglePendulum() { auto assembly = CREATE::With(); std::string str = ""; assembly->setNotes(str); str = "Assembly1"; assembly->setName(str); auto pos3D = std::make_shared>(ListD {0, 0, 0}); assembly->setPosition3D(pos3D); auto rotMat = std::make_shared>(ListListD {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); assembly->setRotationMatrix(rotMat); auto vel3D = std::make_shared>(ListD {0, 0, 0}); assembly->setVelocity3D(vel3D); auto ome3D = std::make_shared>(ListD {0, 0, 0}); assembly->setOmega3D(ome3D); // auto massMarker = ASMTPrincipalMassMarker::With(); massMarker->setMass(0.0); massMarker->setDensity(0.0); auto aJ = std::make_shared>(ListD {0, 0, 0}); massMarker->setMomentOfInertias(aJ); pos3D = std::make_shared>(ListD {0, 0, 0}); massMarker->setPosition3D(pos3D); rotMat = std::make_shared>(ListListD {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); massMarker->setRotationMatrix(rotMat); assembly->setPrincipalMassMarker(massMarker); // auto mkr = CREATE::With(); str = "Marker1"; mkr->setName(str); pos3D = std::make_shared>(ListD {0, 0, 0}); mkr->setPosition3D(pos3D); rotMat = std::make_shared>(ListListD {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); mkr->setRotationMatrix(rotMat); assembly->addMarker(mkr); // auto part = CREATE::With(); str = "Part1"; part->setName(str); pos3D = std::make_shared>(ListD {-0.1, -0.1, -0.1}); part->setPosition3D(pos3D); rotMat = std::make_shared>(ListListD {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); part->setRotationMatrix(rotMat); vel3D = std::make_shared>(ListD {0, 0, 0}); part->setVelocity3D(vel3D); ome3D = std::make_shared>(ListD {0, 0, 0}); part->setOmega3D(ome3D); assembly->addPart(part); // massMarker = ASMTPrincipalMassMarker::With(); massMarker->setMass(0.2); massMarker->setDensity(10.0); aJ = std::make_shared>( ListD {8.3333333333333e-4, 0.016833333333333, 0.017333333333333}); massMarker->setMomentOfInertias(aJ); pos3D = std::make_shared>(ListD {0.5, 0.1, 0.05}); massMarker->setPosition3D(pos3D); rotMat = std::make_shared>(ListListD {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); massMarker->setRotationMatrix(rotMat); part->setPrincipalMassMarker(massMarker); // mkr = CREATE::With(); str = "Marker1"; mkr->setName(str); pos3D = std::make_shared>(ListD {0.1, 0.1, 0.1}); mkr->setPosition3D(pos3D); rotMat = std::make_shared>(ListListD {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); mkr->setRotationMatrix(rotMat); part->addMarker(mkr); // auto joint = CREATE::With(); str = "Joint1"; joint->setName(str); str = "/Assembly1/Marker1"; joint->setMarkerI(str); str = "/Assembly1/Part1/Marker1"; joint->setMarkerJ(str); assembly->addJoint(joint); // auto motion = CREATE::With(); str = "Motion1"; motion->setName(str); str = "/Assembly1/Joint1"; motion->setMotionJoint(str); str = "0.0"; motion->setRotationZ(str); assembly->addMotion(motion); // auto constantGravity = CREATE::With(); auto gAcceleration = std::make_shared>(ListD {0.0, 0.0, 0.0}); constantGravity->setg(gAcceleration); assembly->setConstantGravity(constantGravity); // auto simulationParameters = CREATE::With(); simulationParameters->settstart(0.0); simulationParameters->settend(0.0); // tstart == tend Initial Conditions only. simulationParameters->sethmin(1.0e-9); simulationParameters->sethmax(1.0); simulationParameters->sethout(0.04); simulationParameters->seterrorTol(1.0e-6); assembly->setSimulationParameters(simulationParameters); // assembly->runKINEMATIC(); } std::shared_ptr MbD::ASMTAssembly::assemblyFromFile(const std::string& fileName) { // https://stackoverflow.com/a/45867491 #if __GNUC__ >= 8 std::filesystem::path currentPath = std::filesystem::current_path(); std::cout << "Current directory: " << currentPath << std::endl; #endif std::ifstream stream(fileName); if (stream.fail()) { throw std::invalid_argument("File not found."); } std::string line; std::vector lines; while (std::getline(stream, line)) { lines.push_back(line); } auto assembly = ASMTAssembly::With(); auto str = assembly->popOffTop(lines); [[maybe_unused]] bool bool1 = str == "freeCAD: 3D CAD with Motion Simulation by askoh.com"; [[maybe_unused]] bool bool2 = str == "OndselSolver"; assert(bool1 || bool2); assert(assembly->readStringOffTop(lines) == "Assembly"); assembly->setFilename(fileName); assembly->parseASMT(lines); return assembly; } void MbD::ASMTAssembly::runFile(const std::string& fileName) { std::ifstream stream(fileName); if (stream.fail()) { throw std::invalid_argument("File not found."); } std::string line; std::vector lines; while (std::getline(stream, line)) { lines.push_back(line); } bool bool1 = lines[0] == "freeCAD: 3D CAD with Motion Simulation by askoh.com"; bool bool2 = lines[0] == "OndselSolver"; assert(bool1 || bool2); lines.erase(lines.begin()); if (lines[0] == "Assembly") { lines.erase(lines.begin()); auto assembly = CREATE::With(); assembly->setFilename(fileName); assembly->parseASMT(lines); assembly->runKINEMATIC(); } } void MbD::ASMTAssembly::runDraggingLogTest() { runDraggingTest(); auto assembly = ASMTAssembly::assemblyFromFile("runPreDrag.asmt"); assembly->runDraggingLog("dragging.log"); } void MbD::ASMTAssembly::runDraggingLogTest2() { runDraggingTest2(); auto assembly = ASMTAssembly::assemblyFromFile("runPreDrag.asmt"); assembly->runDraggingLog("dragging.log"); } void MbD::ASMTAssembly::runDraggingLogTest3() { runDraggingTest3(); auto assembly = ASMTAssembly::assemblyFromFile("runPreDrag.asmt"); assembly->runDraggingLog("dragging.log"); } void MbD::ASMTAssembly::runDraggingTest() { // auto assembly = ASMTAssembly::assemblyFromFile("../../testapp/pistonWithLimits.asmt"); auto assembly = ASMTAssembly::assemblyFromFile("../../testapp/dragCrankSlider.asmt"); assembly->setDebug(true); auto limit1 = ASMTRotationLimit::With(); limit1->setName("Limit1"); limit1->setMarkerI("/Assembly1/Marker2"); limit1->setMarkerJ("/Assembly1/Part1/Marker1"); limit1->settype("=>"); limit1->setlimit("30.0*pi/180.0"); limit1->settol("1.0e-9"); assembly->addLimit(limit1); auto limit2 = ASMTTranslationLimit::With(); limit2->setName("Limit2"); limit2->setMarkerI("/Assembly1/Part3/Marker2"); limit2->setMarkerJ("/Assembly1/Marker1"); limit2->settype("=<"); limit2->setlimit("1.2"); limit2->settol("1.0e-9"); assembly->addLimit(limit2); auto& dragPart = assembly->parts->at(0); auto dragParts = std::make_shared>>(); dragParts->push_back(dragPart); assembly->runPreDrag(); // Do this before first drag FColDsptr pos3D, delta; pos3D = dragPart->position3D; delta = std::make_shared>(ListD {0.1, 0.2, 0.3}); dragPart->setPosition3D(pos3D->plusFullColumn(delta)); assembly->runDragStep(dragParts); pos3D = dragPart->position3D; delta = std::make_shared>(ListD {0.3, 0.2, 0.1}); dragPart->setPosition3D(pos3D->plusFullColumn(delta)); assembly->runDragStep(dragParts); assembly->runPostDrag(); // Do this after last drag } void MbD::ASMTAssembly::runDraggingTest2() { // auto assembly = ASMTAssembly::assemblyFromFile("../../testapp/pistonWithLimits.asmt"); auto assembly = ASMTAssembly::assemblyFromFile("../../testapp/dragCrankSlider.asmt"); assembly->setDebug(true); auto limit1 = ASMTRotationLimit::With(); limit1->setName("Limit1"); limit1->setmotionJoint("/Assembly1/Joint1"); limit1->settype("=>"); limit1->setlimit("0.0*pi/180.0"); limit1->settol("1.0e-9"); assembly->addLimit(limit1); auto limit2 = ASMTTranslationLimit::With(); limit2->setName("Limit2"); limit2->setmotionJoint("/Assembly1/Joint4"); limit2->settype("=<"); limit2->setlimit("0.0"); limit2->settol("1.0e-9"); assembly->addLimit(limit2); assembly->outputFile("assembly.asmt"); auto& dragPart = assembly->parts->at(0); auto dragParts = std::make_shared>>(); dragParts->push_back(dragPart); assembly->runPreDrag(); // Do this before first drag FColDsptr pos3D, delta; pos3D = dragPart->position3D; delta = std::make_shared>(ListD {0.1, 0.2, 0.3}); dragPart->setPosition3D(pos3D->plusFullColumn(delta)); assembly->runDragStep(dragParts); pos3D = dragPart->position3D; delta = std::make_shared>(ListD {0.3, 0.2, 0.1}); dragPart->setPosition3D(pos3D->plusFullColumn(delta)); assembly->runDragStep(dragParts); assembly->runPostDrag(); // Do this after last drag } void MbD::ASMTAssembly::runDraggingTest3() { auto assembly = ASMTAssembly::assemblyFromFile("../../testapp/rackPinion3.asmt"); assembly->setDebug(true); auto dragPart = assembly->partNamed("/OndselAssembly/rackPinion#Box"); auto rotPart = assembly->partNamed("/OndselAssembly/rackPinion#Cylinder"); auto dragParts = std::make_shared>>(); dragParts->push_back(dragPart); FColDsptr dragPos3D, rotPos3D, delta; FMatDsptr rotMat; assembly->runPreDrag(); // Do this before first drag dragPos3D = dragPart->position3D; rotPos3D = rotPart->position3D; rotMat = rotPart->rotationMatrix; delta = std::make_shared>(ListD {0.5, 0.0, 0.0}); dragPart->setPosition3D(dragPos3D->plusFullColumn(delta)); assembly->runDragStep(dragParts); dragPos3D = dragPart->position3D; rotPos3D = rotPart->position3D; rotMat = rotPart->rotationMatrix; delta = std::make_shared>(ListD {0.5, 0.0, 0.0}); dragPart->setPosition3D(dragPos3D->plusFullColumn(delta)); assembly->runDragStep(dragParts); dragPos3D = dragPart->position3D; rotPos3D = rotPart->position3D; rotMat = rotPart->rotationMatrix; assembly->runPostDrag(); // Do this after last drag dragPos3D = dragPart->position3D; rotPos3D = rotPart->position3D; rotMat = rotPart->rotationMatrix; } void MbD::ASMTAssembly::readWriteFile(const std::string& fileName) { std::ifstream stream(fileName); if (stream.fail()) { throw std::invalid_argument("File not found."); } std::string line; std::vector lines; while (std::getline(stream, line)) { lines.push_back(line); } bool bool1 = lines[0] == "freeCAD: 3D CAD with Motion Simulation by askoh.com"; bool bool2 = lines[0] == "OndselSolver"; assert(bool1 || bool2); lines.erase(lines.begin()); if (lines[0] == "Assembly") { lines.erase(lines.begin()); auto assembly = CREATE::With(); assembly->parseASMT(lines); assembly->runKINEMATIC(); assembly->outputFile("assembly.asmt"); ASMTAssembly::runFile("assembly.asmt"); } } void MbD::ASMTAssembly::initialize() { ASMTSpatialContainer::initialize(); times = std::make_shared>(); } ASMTAssembly* MbD::ASMTAssembly::root() { return this; } void MbD::ASMTAssembly::setNotes(const std::string& str) { notes = str; } void MbD::ASMTAssembly::parseASMT(std::vector& lines) { readNotes(lines); readName(lines); readPosition3D(lines); readRotationMatrix(lines); readVelocity3D(lines); readOmega3D(lines); initprincipalMassMarker(); readRefPoints(lines); readRefCurves(lines); readRefSurfaces(lines); readParts(lines); readKinematicIJs(lines); readConstraintSets(lines); readForcesTorques(lines); readConstantGravity(lines); readSimulationParameters(lines); readAnimationParameters(lines); readTimeSeries(lines); readAssemblySeries(lines); readPartSeriesMany(lines); readJointSeriesMany(lines); readMotionSeriesMany(lines); } void MbD::ASMTAssembly::readNotes(std::vector& lines) { assert(lines[0] == "\tNotes"); lines.erase(lines.begin()); notes = readString(lines[0]); lines.erase(lines.begin()); } void MbD::ASMTAssembly::readParts(std::vector& lines) { assert(lines[0] == "\tParts"); lines.erase(lines.begin()); parts->clear(); auto it = std::find(lines.begin(), lines.end(), "\tKinematicIJs"); std::vector partsLines(lines.begin(), it); while (!partsLines.empty()) { readPart(partsLines); } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readPart(std::vector& lines) { assert(lines[0] == "\t\tPart"); lines.erase(lines.begin()); auto part = CREATE::With(); part->parseASMT(lines); parts->push_back(part); part->owner = this; } void MbD::ASMTAssembly::readKinematicIJs(std::vector& lines) { assert(lines[0] == "\tKinematicIJs"); lines.erase(lines.begin()); kinematicIJs->clear(); auto it = std::find(lines.begin(), lines.end(), "\tConstraintSets"); std::vector kinematicIJsLines(lines.begin(), it); while (!kinematicIJsLines.empty()) { readKinematicIJ(kinematicIJsLines); } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readKinematicIJ(std::vector&) { throw SimulationStoppingError("To be implemented."); } void MbD::ASMTAssembly::readConstraintSets(std::vector& lines) { assert(lines[0] == "\tConstraintSets"); lines.erase(lines.begin()); readJoints(lines); readMotions(lines); readLimits(lines); readGeneralConstraintSets(lines); } void MbD::ASMTAssembly::readJoints(std::vector& lines) { assert(lines[0] == "\t\tJoints"); lines.erase(lines.begin()); joints->clear(); auto it = std::find(lines.begin(), lines.end(), "\t\tMotions"); std::vector jointsLines(lines.begin(), it); std::shared_ptr joint; while (!jointsLines.empty()) { if (jointsLines[0] == "\t\t\tAngleJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tGearJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tNoRotationJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tParallelAxesJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tPerpendicularJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tRackPinionJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tScrewJoint") { joint = CREATE::With(); } // AtPointJoints else if (jointsLines[0] == "\t\t\tConstantVelocityJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tFixedJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tRevoluteJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tSphericalJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tUniversalJoint") { joint = CREATE::With(); } // CompoundJoints else if (jointsLines[0] == "\t\t\tSphSphJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tCylSphJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tRevCylJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tRevRevJoint") { joint = CREATE::With(); } // InLineJoints else if (jointsLines[0] == "\t\t\tCylindricalJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tPointInLineJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tTranslationalJoint") { joint = CREATE::With(); } // InPlaneJoints else if (jointsLines[0] == "\t\t\tLineInPlaneJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tPlanarJoint") { joint = CREATE::With(); } else if (jointsLines[0] == "\t\t\tPointInPlaneJoint") { joint = CREATE::With(); } else { throw SimulationStoppingError("To be implemented."); } jointsLines.erase(jointsLines.begin()); joint->parseASMT(jointsLines); joints->push_back(joint); joint->owner = this; } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readMotions(std::vector& lines) { assert(lines[0] == "\t\tMotions"); lines.erase(lines.begin()); motions->clear(); auto it = std::find(lines.begin(), lines.end(), "\t\tLimits"); if (it == lines.end()) { it = std::find(lines.begin(), lines.end(), "\t\tGeneralConstraintSets"); } std::vector motionsLines(lines.begin(), it); std::shared_ptr motion; while (!motionsLines.empty()) { if (motionsLines[0] == "\t\t\tRotationalMotion") { motion = CREATE::With(); } else if (motionsLines[0] == "\t\t\tTranslationalMotion") { motion = CREATE::With(); } else if (motionsLines[0] == "\t\t\tGeneralMotion") { motion = CREATE::With(); } else if (motionsLines[0] == "\t\t\tAllowRotation") { motion = CREATE::With(); } else { throw SimulationStoppingError("To be implemented."); } motionsLines.erase(motionsLines.begin()); motion->parseASMT(motionsLines); motions->push_back(motion); motion->owner = this; motion->initMarkers(); } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readLimits(std::vector& lines) { if (lines[0] != "\t\tLimits") { return; } lines.erase(lines.begin()); limits->clear(); auto it = std::find(lines.begin(), lines.end(), "\t\tGeneralConstraintSets"); std::vector limitsLines(lines.begin(), it); std::shared_ptr limit; while (!limitsLines.empty()) { if (limitsLines[0] == "\t\t\tRotationLimit") { limit = ASMTRotationLimit::With(); } else if (limitsLines[0] == "\t\t\tTranslationLimit") { limit = ASMTTranslationLimit::With(); } else { throw SimulationStoppingError("To be implemented."); } limitsLines.erase(limitsLines.begin()); limit->parseASMT(limitsLines); limits->push_back(limit); limit->owner = this; limit->initMarkers(); } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readGeneralConstraintSets(std::vector& lines) const { assert(lines[0] == "\t\tGeneralConstraintSets"); lines.erase(lines.begin()); constraintSets->clear(); auto it = std::find(lines.begin(), lines.end(), "\tForceTorques"); std::vector generalConstraintSetsLines(lines.begin(), it); while (!generalConstraintSetsLines.empty()) { throw SimulationStoppingError("To be implemented."); } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readForcesTorques(std::vector& lines) { assert(lines[0] == "\tForceTorques"); // Spelling is not consistent in asmt file. lines.erase(lines.begin()); forcesTorques->clear(); auto it = std::find(lines.begin(), lines.end(), "\tConstantGravity"); std::vector forcesTorquesLines(lines.begin(), it); while (!forcesTorquesLines.empty()) { if (forcesTorquesLines[0] == "\t\tForceTorque") { forcesTorquesLines.erase(forcesTorquesLines.begin()); auto forceTorque = CREATE::With(); forceTorque->parseASMT(forcesTorquesLines); forcesTorques->push_back(forceTorque); forceTorque->owner = this; } else { throw SimulationStoppingError("To be implemented."); } } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readConstantGravity(std::vector& lines) { assert(lines[0] == "\tConstantGravity"); lines.erase(lines.begin()); constantGravity = CREATE::With(); constantGravity->parseASMT(lines); constantGravity->owner = this; } void MbD::ASMTAssembly::readSimulationParameters(std::vector& lines) { assert(lines[0] == "\tSimulationParameters"); lines.erase(lines.begin()); simulationParameters = CREATE::With(); simulationParameters->parseASMT(lines); simulationParameters->owner = this; } void MbD::ASMTAssembly::readAnimationParameters(std::vector& lines) { assert(lines[0] == "\tAnimationParameters"); lines.erase(lines.begin()); animationParameters = CREATE::With(); animationParameters->parseASMT(lines); animationParameters->owner = this; } void MbD::ASMTAssembly::readTimeSeries(std::vector& lines) { if (lines.empty()) { return; } assert(lines[0] == "TimeSeries"); lines.erase(lines.begin()); assert(lines[0].find("Number\tInput") != std::string::npos); lines.erase(lines.begin()); readTimes(lines); } void MbD::ASMTAssembly::readTimes(std::vector& lines) { if (lines.empty()) { return; } std::string str = lines[0]; std::string substr = "Time\tInput"; auto pos = str.find(substr); assert(pos != std::string::npos); str.erase(0, pos + substr.length()); times = readRowOfDoubles(str); if (times->empty()) { times->insert(times->begin(), 0.0); // The first element is the input state. } else { times->insert(times->begin(), times->at(0)); // The first element is the input state. } lines.erase(lines.begin()); } void MbD::ASMTAssembly::readPartSeriesMany(std::vector& lines) { if (lines.empty()) { return; } assert(lines[0].find("PartSeries") != std::string::npos); auto it = std::find_if(lines.begin(), lines.end(), [](const std::string& s) { return s.find("JointSeries") != std::string::npos; }); std::vector partSeriesLines(lines.begin(), it); while (!partSeriesLines.empty()) { readPartSeries(partSeriesLines); } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readJointSeriesMany(std::vector& lines) { if (lines.empty()) { return; } assert(lines[0].find("JointSeries") != std::string::npos); auto it = std::find_if(lines.begin(), lines.end(), [](const std::string& s) { return s.find("tionSeries") != std::string::npos; }); std::vector jointSeriesLines(lines.begin(), it); while (!jointSeriesLines.empty()) { readJointSeries(jointSeriesLines); } lines.erase(lines.begin(), it); } void MbD::ASMTAssembly::readAssemblySeries(std::vector& lines) { if (lines.empty()) { return; } std::string str = lines[0]; std::string substr = "AssemblySeries"; auto pos = str.find(substr); assert(pos != std::string::npos); str.erase(0, pos + substr.length()); auto seriesName = readString(str); assert(fullName("") == seriesName); lines.erase(lines.begin()); // xs, ys, zs, bryxs, bryys, bryzs readXs(lines); readYs(lines); readZs(lines); readBryantxs(lines); readBryantys(lines); readBryantzs(lines); readVXs(lines); readVYs(lines); readVZs(lines); readOmegaXs(lines); readOmegaYs(lines); readOmegaZs(lines); readAXs(lines); readAYs(lines); readAZs(lines); readAlphaXs(lines); readAlphaYs(lines); readAlphaZs(lines); } void MbD::ASMTAssembly::readPartSeries(std::vector& lines) { if (lines.empty()) { return; } std::string str = lines[0]; std::string substr = "PartSeries"; auto pos = str.find(substr); assert(pos != std::string::npos); str.erase(0, pos + substr.length()); auto seriesName = readString(str); auto it = std::find_if(parts->begin(), parts->end(), [&](const std::shared_ptr& prt) { return prt->fullName("") == seriesName; }); auto& part = *it; part->readPartSeries(lines); } void MbD::ASMTAssembly::readJointSeries(std::vector& lines) { if (lines.empty()) { return; } std::string str = lines[0]; std::string substr = "JointSeries"; auto pos = str.find(substr); assert(pos != std::string::npos); str.erase(0, pos + substr.length()); auto seriesName = readString(str); auto it = std::find_if(joints->begin(), joints->end(), [&](const std::shared_ptr& jt) { return jt->fullName("") == seriesName; }); auto& joint = *it; joint->readJointSeries(lines); } void MbD::ASMTAssembly::readMotionSeriesMany(std::vector& lines) { while (!lines.empty()) { assert(lines[0].find("tionSeries") != std::string::npos); readMotionSeries(lines); } } void MbD::ASMTAssembly::readMotionSeries(std::vector& lines) { if (lines.empty()) { return; } std::string str = lines[0]; std::string substr = "tionSeries"; auto pos = str.find(substr); assert(pos != std::string::npos); str.erase(0, pos + substr.length()); auto seriesName = readString(str); auto it = std::find_if(motions->begin(), motions->end(), [&](const std::shared_ptr& jt) { return jt->fullName("") == seriesName; }); auto& motion = *it; motion->readMotionSeries(lines); } void MbD::ASMTAssembly::runDraggingLog(const std::string& fileName) { std::ifstream stream(fileName); if (stream.fail()) { throw std::invalid_argument("File not found."); } std::string line; std::vector lines; while (std::getline(stream, line)) { lines.push_back(line); } assert(readStringOffTop(lines) == "runPreDrag"); runPreDrag(); while (lines[0].find("runDragStep") != std::string::npos) { assert(readStringOffTop(lines) == "runDragStep"); auto dragParts = std::make_shared>>(); while (lines[0].find("Name") != std::string::npos) { assert(readStringOffTop(lines) == "Name"); auto dragPartName = readStringOffTop(lines); std::string longerName = "/" + name + "/" + dragPartName; auto dragPart = partAt(longerName); dragParts->push_back(dragPart); assert(readStringOffTop(lines) == "Position3D"); auto dragPartPosition3D = readColumnOfDoublesOffTop(lines); dragPart->setPosition3D(dragPartPosition3D); assert(readStringOffTop(lines) == "RotationMatrix"); auto dragPartRotationMatrix = std::make_shared>(3); for (size_t i = 0; i < 3; i++) { auto row = readRowOfDoublesOffTop(lines); dragPartRotationMatrix->atiput(i, row); } dragPart->setRotationMatrix(dragPartRotationMatrix); } runDragStep(dragParts); } assert(readStringOffTop(lines) == "runPostDrag"); runPostDrag(); } void MbD::ASMTAssembly::outputFor(AnalysisType) { throw SimulationStoppingError("To be implemented."); } void MbD::ASMTAssembly::preMbDrun(std::shared_ptr mbdSys) { calcCharacteristicDimensions(); deleteMbD(); createMbD(mbdSys, mbdUnits); std::static_pointer_cast(mbdObject)->asFixed(); } void MbD::ASMTAssembly::preMbDrunDragStep(std::shared_ptr mbdSys, std::shared_ptr>> /*dragParts*/) { for (auto& part : *parts) { part->preMbDrunDragStep(mbdSys, mbdUnits); } } void MbD::ASMTAssembly::postMbDrun() { throw SimulationStoppingError("To be implemented."); } void MbD::ASMTAssembly::calcCharacteristicDimensions() { auto unitTime = this->calcCharacteristicTime(); auto unitMass = this->calcCharacteristicMass(); auto unitLength = this->calcCharacteristicLength(); auto unitAngle = 1.0; this->mbdUnits = std::make_shared(unitTime, unitMass, unitLength, unitAngle); this->mbdUnits = std::make_shared(1.0, 1.0, 1.0, 1.0); // for debug } double MbD::ASMTAssembly::calcCharacteristicTime() const { return std::abs(simulationParameters->hout); } double MbD::ASMTAssembly::calcCharacteristicMass() const { auto n = parts->size(); double sumOfSquares = 0.0; for (size_t i = 0; i < n; i++) { auto mass = parts->at(i)->principalMassMarker->mass; sumOfSquares += mass * mass; } auto unitMass = std::sqrt(sumOfSquares / n); if (unitMass <= 0) { unitMass = 1.0; } return unitMass; } double MbD::ASMTAssembly::calcCharacteristicLength() const { auto markerMap = this->markerMap(); auto lengths = std::make_shared>(); auto connectorList = this->connectorList(); for (auto& connector : *connectorList) { auto& mkrI = markerMap->at(connector->markerI); lengths->push_back(mkrI->rpmp()->length()); auto& mkrJ = markerMap->at(connector->markerJ); lengths->push_back(mkrJ->rpmp()->length()); } auto n = lengths->size(); double sumOfSquares = std::accumulate(lengths->begin(), lengths->end(), 0.0, [](double sum, double l) { return sum + l * l; }); auto unitLength = std::sqrt(sumOfSquares / std::max(n, size_t(1))); if (unitLength <= 0) { unitLength = 1.0; } return unitLength; } std::shared_ptr>> MbD::ASMTAssembly::connectorList() const { auto list = std::make_shared>>(); list->insert(list->end(), joints->begin(), joints->end()); list->insert(list->end(), motions->begin(), motions->end()); list->insert(list->end(), kinematicIJs->begin(), kinematicIJs->end()); list->insert(list->end(), forcesTorques->begin(), forcesTorques->end()); return list; } std::shared_ptr>> MbD::ASMTAssembly::markerMap() const { auto answer = std::make_shared>>(); for (auto& refPoint : *refPoints) { for (auto& marker : *refPoint->markers) { answer->insert(std::make_pair(marker->fullName(""), marker)); } } for (auto& part : *parts) { for (auto& refPoint : *part->refPoints) { for (auto& marker : *refPoint->markers) { answer->insert(std::make_pair(marker->fullName(""), marker)); } } } return answer; } void MbD::ASMTAssembly::deleteMbD() { ASMTSpatialContainer::deleteMbD(); constantGravity->deleteMbD(); asmtTime->deleteMbD(); for (auto& part : *parts) { part->deleteMbD(); } for (auto& joint : *joints) { joint->deleteMbD(); } for (auto& motion : *motions) { motion->deleteMbD(); } for (auto& limit : *limits) { limit->deleteMbD(); } for (auto& forceTorque : *forcesTorques) { forceTorque->deleteMbD(); } } void MbD::ASMTAssembly::createMbD(std::shared_ptr mbdSys, std::shared_ptr mbdUnits) { ASMTSpatialContainer::createMbD(mbdSys, mbdUnits); constantGravity->createMbD(mbdSys, mbdUnits); asmtTime->createMbD(mbdSys, mbdUnits); std::sort(parts->begin(), parts->end(), [](std::shared_ptr a, std::shared_ptr b) { return a->name < b->name; }); auto jointsMotions = std::make_shared>>(); jointsMotions->insert(jointsMotions->end(), joints->begin(), joints->end()); jointsMotions->insert(jointsMotions->end(), motions->begin(), motions->end()); std::sort(jointsMotions->begin(), jointsMotions->end(), [](std::shared_ptr a, std::shared_ptr b) { return a->name < b->name; }); std::sort(limits->begin(), limits->end(), [](std::shared_ptr a, std::shared_ptr b) { return a->name < b->name; }); std::sort(forcesTorques->begin(), forcesTorques->end(), [](std::shared_ptr a, std::shared_ptr b) { return a->name < b->name; }); for (auto& part : *parts) { part->createMbD(mbdSys, mbdUnits); } for (auto& joint : *jointsMotions) { joint->createMbD(mbdSys, mbdUnits); } for (auto& limit : *limits) { limit->createMbD(mbdSys, mbdUnits); } for (auto& forceTorque : *forcesTorques) { forceTorque->createMbD(mbdSys, mbdUnits); } auto& mbdSysSolver = mbdSys->systemSolver; mbdSysSolver->errorTolPosKine = simulationParameters->errorTolPosKine; mbdSysSolver->errorTolAccKine = simulationParameters->errorTolAccKine; mbdSysSolver->iterMaxPosKine = simulationParameters->iterMaxPosKine; mbdSysSolver->iterMaxAccKine = simulationParameters->iterMaxAccKine; mbdSysSolver->tstart = simulationParameters->tstart / mbdUnits->time; mbdSysSolver->tend = simulationParameters->tend / mbdUnits->time; mbdSysSolver->hmin = simulationParameters->hmin / mbdUnits->time; mbdSysSolver->hmax = simulationParameters->hmax / mbdUnits->time; mbdSysSolver->hout = simulationParameters->hout / mbdUnits->time; mbdSysSolver->corAbsTol = simulationParameters->corAbsTol; mbdSysSolver->corRelTol = simulationParameters->corRelTol; mbdSysSolver->intAbsTol = simulationParameters->intAbsTol; mbdSysSolver->intRelTol = simulationParameters->intRelTol; mbdSysSolver->iterMaxDyn = simulationParameters->iterMaxDyn; mbdSysSolver->orderMax = simulationParameters->orderMax; mbdSysSolver->translationLimit = simulationParameters->translationLimit / mbdUnits->length; mbdSysSolver->rotationLimit = simulationParameters->rotationLimit; // animationParameters = nullptr; } void MbD::ASMTAssembly::outputFile(const std::string& filename) { std::ofstream os(filename); os << std::setprecision(std::numeric_limits::max_digits10); // try { os << "OndselSolver" << std::endl; storeOnLevel(os, 0); os.close(); // } // catch (...) { // os.close(); // } } void MbD::ASMTAssembly::storeOnLevel(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "Assembly"); storeOnLevelNotes(os, level + 1); storeOnLevelName(os, level + 1); ASMTSpatialContainer::storeOnLevel(os, level); storeOnLevelParts(os, level + 1); storeOnLevelKinematicIJs(os, level + 1); storeOnLevelConstraintSets(os, level + 1); storeOnLevelForceTorques(os, level + 1); constantGravity->storeOnLevel(os, level + 1); simulationParameters->storeOnLevel(os, level + 1); animationParameters->storeOnLevel(os, level + 1); storeOnTimeSeries(os); } size_t MbD::ASMTAssembly::numberOfFrames() { return times->size(); } void MbD::ASMTAssembly::solve() { auto simulationParameters = CREATE::With(); simulationParameters->settstart(0.0); simulationParameters->settend(0.0); // tstart == tend Initial Conditions only. simulationParameters->sethmin(1.0e-9); simulationParameters->sethmax(1.0); simulationParameters->sethout(0.04); simulationParameters->seterrorTol(1.0e-6); setSimulationParameters(simulationParameters); runKINEMATIC(); } void MbD::ASMTAssembly::runPreDrag() { if (debug) { outputFile("runPreDrag.asmt"); std::ofstream os("dragging.log"); os << "runPreDrag" << std::endl; os.close(); } mbdSystem = std::make_shared(); mbdSystem->externalSystem->asmtAssembly = this; mbdSystem->runPreDrag(mbdSystem); } void MbD::ASMTAssembly::runDragStep( std::shared_ptr>> dragASMTParts) { if (debug) { std::ofstream os("dragging.log", std::ios_base::app); os << "runDragStep" << std::endl; os.close(); } auto dragMbDParts = std::make_shared>>(); auto crO1 = std::make_shared>(); auto crO2 = std::make_shared>(); auto cqEO1 = std::make_shared>>>(); auto cqEO2 = std::make_shared>>>(); for (auto& dragASMTPart : *dragASMTParts) { if (debug) { std::ofstream os("dragging.log", std::ios_base::app); os << std::setprecision(std::numeric_limits::max_digits10); dragASMTPart->storeOnLevelName(os, 1); dragASMTPart->storeOnLevelPositionRaw(os, 1); dragASMTPart->storeOnLevelRotationMatrixRaw(os, 1); os.close(); } auto dragMbDPart = std::static_pointer_cast(dragASMTPart->mbdObject); dragMbDParts->push_back(dragMbDPart); crO1->push_back(dragASMTPart->oldPos3D); crO2->push_back(dragASMTPart->position3D); cqEO1->push_back(dragASMTPart->oldRotMat->asEulerParameters()); cqEO2->push_back(dragASMTPart->rotationMatrix->asEulerParameters()); } bool success = false; for (int i = 0; i < 5; i++) { if (i > 0) { double factor = std::pow(2.0, -i); for (size_t j = 0; j < dragASMTParts->size(); j++) { auto& dragASMTPart = dragASMTParts->at(j); auto rO1 = crO1->at(j); auto rO2 = crO2->at(j); auto rOMid = rO1->times(1.0 - factor)->plusFullColumn(rO2->times(factor)); dragASMTPart->setPosition3D(rOMid); auto qEO1 = cqEO1->at(j); auto qEO2 = cqEO2->at(j); std::shared_ptr> qEOmid; auto cosHalfTheta = qEO1->dot(qEO2); if (std::abs(cosHalfTheta) >= 1.0) { qEOmid = qEO1->copy(); } else { auto halfTheta = std::acos(cosHalfTheta); auto sinHalfTheta = std::sin(halfTheta); double ratio1 = std::sin((1.0 - factor) * halfTheta) / sinHalfTheta; double ratio2 = std::sin(factor * halfTheta) / sinHalfTheta; qEOmid = qEO1->times(ratio1)->plusFullColumn(qEO2->times(ratio2)); } qEOmid->calcABC(); dragASMTPart->setRotationMatrix(qEOmid->aA); } } if (debug) { outputFile("runDragStep.asmt"); } try { mbdSystem->runDragStep(mbdSystem, dragMbDParts); success = true; break; } catch (std::exception const& e) { // Do not use // runPreDrag(); // Assembly breaks up too easily because of redundant constraint removal. noop(); } } if (!success) restorePosRot(); } void MbD::ASMTAssembly::runPostDrag() { if (debug) { // outputFile("runPostDrag.asmt"); std::ofstream os("dragging.log", std::ios_base::app); os << "runPostDrag" << std::endl; os.close(); } mbdSystem = std::make_shared(); mbdSystem->externalSystem->asmtAssembly = this; mbdSystem->runPreDrag(mbdSystem); } void MbD::ASMTAssembly::restorePosRot() { for (auto& part : *parts) { part->restorePosRot(); } } void MbD::ASMTAssembly::runKINEMATIC() { mbdSystem = std::make_shared(); mbdSystem->externalSystem->asmtAssembly = this; try { mbdSystem->runKINEMATIC(mbdSystem); } catch (const SimulationStoppingError& ex) { } } void MbD::ASMTAssembly::initprincipalMassMarker() { principalMassMarker = ASMTPrincipalMassMarker::With(); principalMassMarker->mass = 0.0; principalMassMarker->density = 0.0; principalMassMarker->momentOfInertias = std::make_shared>(3, 0); // principalMassMarker->position3D = std::make_shared>(3, 0); // principalMassMarker->rotationMatrix = FullMatrix>::identitysptr(3); } std::shared_ptr MbD::ASMTAssembly::spatialContainerAt(std::shared_ptr self, std::string& longname) const { if ((self->fullName("")) == longname) { return self; } auto it = std::find_if(parts->begin(), parts->end(), [&](const std::shared_ptr& prt) { return prt->fullName("") == longname; }); auto& part = *it; return part; } std::shared_ptr MbD::ASMTAssembly::partAt(const std::string& longname) const { for (auto& part : *parts) { if (part->fullName("") == longname) { return part; } } return nullptr; } std::shared_ptr MbD::ASMTAssembly::markerAt(const std::string& longname) const { for (auto& refPoint : *refPoints) { for (auto& marker : *refPoint->markers) { if (marker->fullName("") == longname) { return marker; } } } for (auto& part : *parts) { for (auto& refPoint : *part->refPoints) { for (auto& marker : *refPoint->markers) { if (marker->fullName("") == longname) { return marker; } } } } return nullptr; } std::shared_ptr MbD::ASMTAssembly::jointAt(const std::string& longname) const { auto it = std::find_if(joints->begin(), joints->end(), [&](const std::shared_ptr& jt) { return jt->fullName("") == longname; }); auto& joint = *it; return joint; } std::shared_ptr MbD::ASMTAssembly::motionAt(const std::string& longname) const { auto it = std::find_if(motions->begin(), motions->end(), [&](const std::shared_ptr& mt) { return mt->fullName("") == longname; }); auto& motion = *it; return motion; } std::shared_ptr MbD::ASMTAssembly::forceTorqueAt(const std::string& longname) const { auto it = std::find_if(forcesTorques->begin(), forcesTorques->end(), [&](const std::shared_ptr& mt) { return mt->fullName("") == longname; }); auto& forceTorque = *it; return forceTorque; } FColDsptr MbD::ASMTAssembly::vOcmO() { return std::make_shared>(3, 0.0); } FColDsptr MbD::ASMTAssembly::omeOpO() { return std::make_shared>(3, 0.0); } std::shared_ptr MbD::ASMTAssembly::geoTime() const { return asmtTime; } void MbD::ASMTAssembly::updateFromMbD() { ASMTSpatialContainer::updateFromMbD(); auto time = asmtTime->getValue(); times->push_back(time); std::cout << "Time = " << time << std::endl; for (auto& part : *parts) { part->updateFromMbD(); } for (auto& joint : *joints) { joint->updateFromMbD(); } for (auto& motion : *motions) { motion->updateFromMbD(); } for (auto& forceTorque : *forcesTorques) { forceTorque->updateFromMbD(); } } void MbD::ASMTAssembly::compareResults(AnalysisType type) { ASMTSpatialContainer::compareResults(type); for (auto& part : *parts) { part->compareResults(type); } for (auto& joint : *joints) { joint->compareResults(type); } for (auto& motion : *motions) { motion->compareResults(type); } for (auto& forceTorque : *forcesTorques) { forceTorque->compareResults(type); } } void MbD::ASMTAssembly::outputResults(AnalysisType type) { (void) type; //ASMTSpatialContainer::outputResults(type); //for (auto& part : *parts) part->outputResults(type); //for (auto& joint : *joints) joint->outputResults(type); //for (auto& motion : *motions) motion->outputResults(type); //for (auto& forceTorque : *forcesTorques) forceTorque->outputResults(type); } void MbD::ASMTAssembly::addPart(std::shared_ptr part) { parts->push_back(part); part->owner = this; } void MbD::ASMTAssembly::addJoint(std::shared_ptr joint) { joints->push_back(joint); joint->owner = this; } void MbD::ASMTAssembly::addMotion(std::shared_ptr motion) { motions->push_back(motion); motion->owner = this; motion->initMarkers(); } void MbD::ASMTAssembly::addLimit(std::shared_ptr limit) { limits->push_back(limit); limit->owner = this; limit->initMarkers(); } void MbD::ASMTAssembly::setConstantGravity(std::shared_ptr gravity) { constantGravity = gravity; gravity->owner = this; } void MbD::ASMTAssembly::setSimulationParameters( std::shared_ptr parameters) { simulationParameters = parameters; parameters->owner = this; } std::shared_ptr MbD::ASMTAssembly::partNamed(const std::string& partName) const { auto it = std::find_if(parts->begin(), parts->end(), [&](const std::shared_ptr& prt) { return prt->fullName("") == partName; }); auto& part = *it; return part; } std::shared_ptr MbD::ASMTAssembly::partPartialNamed(const std::string& partialName) const { auto it = std::find_if(parts->begin(), parts->end(), [&](const std::shared_ptr& prt) { auto fullName = prt->fullName(""); return fullName.find(partialName) != std::string::npos; }); auto& part = *it; return part; } void MbD::ASMTAssembly::storeOnLevelNotes(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "Notes"); storeOnLevelString(os, level + 1, notes); } void MbD::ASMTAssembly::storeOnLevelParts(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "Parts"); for (auto& part : *parts) { part->storeOnLevel(os, level + 1); } } void MbD::ASMTAssembly::storeOnLevelKinematicIJs(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "KinematicIJs"); for (auto& kinematicIJ : *kinematicIJs) { kinematicIJ->storeOnLevel(os, level); } } void MbD::ASMTAssembly::storeOnLevelConstraintSets(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "ConstraintSets"); storeOnLevelJoints(os, level + 1); storeOnLevelMotions(os, level + 1); storeOnLevelLimits(os, level + 1); storeOnLevelGeneralConstraintSets(os, level + 1); } void MbD::ASMTAssembly::storeOnLevelForceTorques(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "ForceTorques"); for (auto& forceTorque : *forcesTorques) { forceTorque->storeOnLevel(os, level + 1); } } void MbD::ASMTAssembly::storeOnLevelJoints(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "Joints"); for (auto& joint : *joints) { joint->storeOnLevel(os, level + 1); } } void MbD::ASMTAssembly::storeOnLevelMotions(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "Motions"); for (auto& motion : *motions) { motion->storeOnLevel(os, level + 1); } } void MbD::ASMTAssembly::storeOnLevelLimits(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "Limits"); for (auto& limit : *limits) { limit->storeOnLevel(os, level + 1); } } void MbD::ASMTAssembly::storeOnLevelGeneralConstraintSets(std::ofstream& os, size_t level) { storeOnLevelString(os, level, "GeneralConstraintSets"); // for (auto& generalConstraintSet : *generalConstraintSets) { // generalConstraintSet->storeOnLevel(os, level); // } } void MbD::ASMTAssembly::storeOnTimeSeries(std::ofstream& os) { if (times->empty()) { return; } os << "TimeSeries" << std::endl; os << "Number\tInput\t"; for (size_t i = 1; i < times->size(); i++) { os << i << '\t'; } os << std::endl; os << "Time\tInput\t"; for (size_t i = 1; i < times->size(); i++) { os << times->at(i) << '\t'; } os << std::endl; os << "AssemblySeries\t" << fullName("") << std::endl; ASMTSpatialContainer::storeOnTimeSeries(os); for (auto& part : *parts) { part->storeOnTimeSeries(os); } for (auto& joint : *joints) { joint->storeOnTimeSeries(os); } for (auto& motion : *motions) { motion->storeOnTimeSeries(os); } } void MbD::ASMTAssembly::setFilename(const std::string& str) { std::stringstream ss; ss << "FileName = " << str << std::endl; auto str2 = ss.str(); logString(str2); filename = str; } void MbD::ASMTAssembly::setDebug(bool todebug) { debug = todebug; } void MbD::ASMTAssembly::updateForFrame(size_t index) { ASMTSpatialContainer::updateForFrame(index); for (auto& part : *parts) { part->updateForFrame(index); } //for (auto& joint : *joints) { // joint->updateForFrame(index); //} //for (auto& motion : *motions) { // motion->updateForFrame(index); //} //for (auto& forceTorque : *forcesTorques) { // forceTorque->updateForFrame(index); //} }