#include #include #include #include #include #include #include "MBDynSystem.h" #include "CREATE.h" #include "FullColumn.h" #include "MBDynInitialValue.h" #include "MBDynData.h" #include "MBDynControlData.h" #include "ASMTAssembly.h" #include "ASMTConstantGravity.h" #include "ASMTTime.h" #include "MBDynBody.h" #include "MBDynJoint.h" #include "MBDynStructural.h" #include "SymbolicParser.h" #include "BasicUserFunction.h" #include "MBDynReference.h" #include "MBDynDrive.h" using namespace MbD; void MbD::MBDynSystem::runFile(const char* filename) { std::ifstream stream(filename); std::string line; std::vector lines; while (std::getline(stream, line)) { lines.push_back(line); } eraseComments(lines); auto statements = collectStatements(lines); auto system = std::make_shared(); system->setFilename(filename); system->parseMBDyn(statements); system->runKINEMATIC(); } void MbD::MBDynSystem::parseMBDyn(std::vector& lines) { readDataBlock(lines); readInitialValueBlock(lines); readControlDataBlock(lines); readLabels(lines); readVariables(lines); readReferences(lines); readNodesBlock(lines); readElementsBlock(lines); assert(lines.empty()); } std::shared_ptr>> MbD::MBDynSystem::mbdynNodes() { return nodes; } std::shared_ptr>> MbD::MBDynSystem::mbdynBodies() { return bodies; } std::shared_ptr>> MbD::MBDynSystem::mbdynJoints() { return joints; } std::shared_ptr>> MbD::MBDynSystem::mbdynDrives() { return drives; } std::shared_ptr> MbD::MBDynSystem::mbdynVariables() { return variables; } std::shared_ptr>> MbD::MBDynSystem::mbdynReferences() { return references; } void MbD::MBDynSystem::createASMT() { auto asmtAsm = std::make_shared(); asmtAsm->mbdynItem = this; asmtItem = asmtAsm; asmtItem->setName("Assembly"); initialValue->createASMT(); for (auto& node : *nodes) node->createASMT(); for (auto& body : *bodies) body->createASMT(); for (auto& joint : *joints) joint->createASMT(); } std::shared_ptr MbD::MBDynSystem::nodeAt(std::string nodeName) { for (auto& node : *nodes) { if (node->name == nodeName) return node; } return nullptr; } int MbD::MBDynSystem::nodeidAt(std::string nodeName) { return labels->at(nodeName); } std::shared_ptr MbD::MBDynSystem::bodyWithNode(std::string nodeName) { for (auto& body : *bodies) { if (body->nodeName == nodeName) return body; } return nullptr; } std::shared_ptr MbD::MBDynSystem::asmtAssembly() { return std::static_pointer_cast(asmtItem); } std::vector MbD::MBDynSystem::nodeNames() { auto nodeNames = std::vector(); for (auto& node : *nodes) { nodeNames.push_back(node->name); } return nodeNames; } void MbD::MBDynSystem::runKINEMATIC() { createASMT(); asmtAssembly()->outputFile("assembly.asmt"); std::static_pointer_cast(asmtItem)->runKINEMATIC(); outputFiles(); asmtAssembly()->outputFile("assembly2.asmt"); } void MbD::MBDynSystem::outputFiles() { auto movFile = filename.substr(0, filename.find_last_of('.')) + ".mov"; auto asmtAsm = asmtAssembly(); auto asmtTimes = asmtAsm->times; auto asmtParts = asmtAsm->parts; auto asmtJoints = asmtAsm->joints; auto asmtMotions = asmtAsm->motions; std::ofstream os(movFile); os << std::setprecision(std::numeric_limits::digits10 + 1); for (int i = 1; i < asmtTimes->size(); i++) { for (auto& node : *nodes) { node->outputLine(i, os); } } os.close(); } void MbD::MBDynSystem::setFilename(std::string str) { filename = str; } void MbD::MBDynSystem::readDataBlock(std::vector& lines) { std::vector tokens{ "begin:", "data" }; auto beginit = findLineWith(lines, tokens); std::vector tokens1{ "end:", "data" }; auto endit = findLineWith(lines, tokens1); std::vector blocklines = { beginit, endit + 1 }; parseMBDynData(blocklines); lines.erase(beginit, endit + 1); } void MbD::MBDynSystem::readInitialValueBlock(std::vector& lines) { std::vector tokens{ "begin:", "initial", "value" }; auto beginit = findLineWith(lines, tokens); std::vector tokens1{ "end:", "initial", "value" }; auto endit = findLineWith(lines, tokens1); std::vector blocklines = { beginit, endit + 1 }; initialValue = std::make_shared(); initialValue->owner = this; initialValue->parseMBDyn(blocklines); lines.erase(beginit, endit + 1); } void MbD::MBDynSystem::readControlDataBlock(std::vector& lines) { std::vector tokens{ "begin:", "control", "data" }; auto beginit = findLineWith(lines, tokens); std::vector tokens1{ "end:", "control", "data" }; auto endit = findLineWith(lines, tokens1); std::vector blocklines = { beginit, endit + 1 }; controlData = std::make_shared(); controlData->owner = this; controlData->parseMBDyn(blocklines); lines.erase(beginit, endit + 1); } void MbD::MBDynSystem::readLabels(std::vector& lines) { parseMBDynLabels(lines); } void MbD::MBDynSystem::readVariables(std::vector& lines) { parseMBDynVariables(lines); } void MbD::MBDynSystem::readReferences(std::vector& lines) { parseMBDynReferences(lines); } void MbD::MBDynSystem::readNodesBlock(std::vector& lines) { std::vector tokens{ "begin:", "nodes" }; auto beginit = findLineWith(lines, tokens); std::vector tokens1{ "end:", "nodes" }; auto endit = findLineWith(lines, tokens1); std::vector blocklines = { beginit, endit + 1 }; parseMBDynNodes(blocklines); lines.erase(beginit, endit + 1); } void MbD::MBDynSystem::readElementsBlock(std::vector& lines) { std::vector tokens{ "begin:", "elements" }; auto beginit = findLineWith(lines, tokens); std::vector tokens1{ "end:", "elements" }; auto endit = findLineWith(lines, tokens1); std::vector blocklines = { beginit, endit + 1 }; parseMBDynElements(blocklines); lines.erase(beginit, endit + 1); } void MbD::MBDynSystem::eraseComments(std::vector& lines) { for (int i = 0; i < lines.size(); i++) { auto line = lines[i]; auto it = line.find('#'); if (it != std::string::npos) { lines[i] = line.substr(0, it); } } for (int i = lines.size() - 1; i >= 0; i--) { auto& line = lines[i]; auto it = std::find_if(line.begin(), line.end(), [](unsigned char ch) { return !std::isspace(ch); }); if (it == line.end()) lines.erase(lines.begin() + i); } } std::vector MbD::MBDynSystem::collectStatements(std::vector& lines) { auto statements = std::vector(); while (!lines.empty()) { std::stringstream ss; while (!lines.empty()) { auto line = lines[0]; lines.erase(lines.begin()); auto i = line.find(';'); if (i != std::string::npos) { ss << line.substr(0, i); if (line.size() > i + 1) { auto remainder = line.substr(i + 1); auto it = std::find_if(remainder.begin(), remainder.end(), [](unsigned char ch) { return !std::isspace(ch); }); if (it != remainder.end()) lines.insert(lines.begin(), remainder); } break; } else { ss << line; } } statements.push_back(ss.str()); } return statements; } void MbD::MBDynSystem::initialize() { } void MbD::MBDynSystem::parseMBDynData(std::vector& lines) { assert(lines.size() == 3); std::vector tokens{ "problem:", "initial", "value" }; auto problemit = findLineWith(lines, tokens); assert(problemit != lines.end()); data = *problemit; } void MbD::MBDynSystem::parseMBDynNodes(std::vector& lines) { nodes = std::make_shared>>(); std::vector tokens{ "structural:" }; while (true) { auto it = findLineWith(lines, tokens); if (it != lines.end()) { auto structural = std::make_shared(); structural->owner = this; structural->parseMBDyn(*it); nodes->push_back(structural); lines.erase(it); } else { break; } } } void MbD::MBDynSystem::parseMBDynElements(std::vector& lines) { assert(lines[0].find("begin: elements") != std::string::npos); lines.erase(lines.begin()); bodies = std::make_shared>>(); joints = std::make_shared>>(); drives = std::make_shared>>(); std::vector bodyTokens{ "body:" }; std::vector jointTokens{ "joint:" }; std::vector driveTokens{ "drive", "caller:" }; std::vector::iterator it; while (true) { it = findLineWith(lines, bodyTokens); if (it != lines.end()) { auto body = std::make_shared(); body->owner = this; body->parseMBDyn(*it); bodies->push_back(body); lines.erase(it); continue; } it = findLineWith(lines, jointTokens); if (it != lines.end()) { auto joint = std::make_shared(); joint->owner = this; joint->parseMBDyn(*it); joints->push_back(joint); lines.erase(it); continue; } it = findLineWith(lines, driveTokens); if (it != lines.end()) { auto drive = std::make_shared(); drive->owner = this; drive->parseMBDyn(*it); drives->push_back(drive); lines.erase(it); continue; } break; } assert(lines[0].find("end: elements") != std::string::npos); lines.erase(lines.begin()); } void MbD::MBDynSystem::parseMBDynVariables(std::vector& lines) { variables = std::make_shared>(); std::string str, variable; double doubleValue; std::vector tokens{ "set:", "real" }; while (true) { auto it = findLineWith(lines, tokens); if (it != lines.end()) { std::istringstream iss(*it); iss >> str; iss >> str; iss >> variable; iss >> str; iss >> str; auto parser = std::make_shared(); parser->variables = variables; auto userFunc = std::make_shared(str, 1.0); parser->parseUserFunction(userFunc); auto sym = parser->stack->top(); auto val = sym->getValue(); variables->insert(std::make_pair(variable, sym)); lines.erase(it); } else { break; } } } void MbD::MBDynSystem::parseMBDynLabels(std::vector& lines) { labels = std::make_shared>(); std::string str, label; int intValue; std::vector tokens{ "set:", "integer" }; while (true) { auto it = findLineWith(lines, tokens); if (it != lines.end()) { std::istringstream iss(*it); iss >> str; iss >> str; iss >> label; iss >> str; iss >> intValue; labels->insert(std::make_pair(label, intValue)); lines.erase(it); } else { break; } } } void MbD::MBDynSystem::parseMBDynReferences(std::vector& lines) { references = std::make_shared>>(); std::string str, refName; double doubleValue; std::vector tokens{ "reference:" }; while (true) { auto it = findLineWith(lines, tokens); if (it != lines.end()) { auto reference = std::make_shared(); reference->owner = this; reference->parseMBDyn(*it); references->insert(std::make_pair(reference->name, reference)); lines.erase(it); } else { break; } } }