| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include <sstream> |
| | | #include <fstream> |
| | | #include <iostream> |
| | | |
| | | // åä¾è·å |
| | | RecipeManager& RecipeManager::getInstance() { |
| | | static RecipeManager instance; |
| | | return instance; |
| | | } |
| | | |
| | | // æé 彿° |
| | | RecipeManager::RecipeManager() : m_recipeFolder("Recipe") {} |
| | | |
| | | // 设置é
æ¹æä»¶å¤¹ |
| | | void RecipeManager::setRecipeFolder(const std::string& folderPath) { |
| | | m_recipeFolder = folderPath; |
| | | } |
| | | |
| | | // å è½½é
æ¹ï¼å¦ææä»¶ä¸åå¨ï¼å è½½é»è®¤æ°æ®ï¼ |
| | | bool RecipeManager::loadRecipe(const std::string& recipeName) { |
| | | std::string filePath = m_recipeFolder + "/" + recipeName + ".xml"; |
| | | pugi::xml_document doc; |
| | | |
| | | if (!doc.load_file(filePath.c_str())) { |
| | | std::cerr << "Recipe file not found: " << filePath << ". Loading default recipe." << std::endl; |
| | | generateDefaultRecipe(); |
| | | return false; // æä»¶ä¸åå¨ï¼ä½å è½½äºé»è®¤æ°æ® |
| | | } |
| | | |
| | | m_axes.clear(); |
| | | |
| | | auto recipe = doc.child("Recipe"); |
| | | for (auto axisNode : recipe.child("Axes").children("Axis")) { |
| | | AxisInfo axisInfo; |
| | | axisInfo.id = axisNode.attribute("id").as_int(); |
| | | axisInfo.number = axisNode.attribute("number").value(); |
| | | axisInfo.description = axisNode.attribute("description").value(); |
| | | axisInfo.startAddress = axisNode.attribute("start_address").value(); |
| | | axisInfo.jogDistance = axisNode.attribute("jog_distance").as_double(); |
| | | axisInfo.manualSpeed = axisNode.attribute("manual_speed").as_double(); |
| | | axisInfo.autoSpeed = axisNode.attribute("auto_speed").as_double(); |
| | | axisInfo.accelerationTime = axisNode.attribute("acceleration_time").as_double(); |
| | | axisInfo.decelerationTime = axisNode.attribute("deceleration_time").as_double(); |
| | | |
| | | for (auto positionNode : axisNode.child("Positions").children("Position")) { |
| | | std::string description = positionNode.attribute("description").value(); |
| | | double positionValue = positionNode.attribute("value").as_double(); |
| | | axisInfo.positions.emplace_back(description, positionValue); |
| | | } |
| | | |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // ä¿åé
æ¹ |
| | | bool RecipeManager::saveRecipe(const std::string& recipeName) { |
| | | // çææä»¶è·¯å¾ |
| | | std::string filePath = m_recipeFolder + "/" + recipeName + ".xml"; |
| | | |
| | | // å建 XML ææ¡£å¯¹è±¡ |
| | | pugi::xml_document doc; |
| | | |
| | | // å¦æè½´æ°æ®ä¸ºç©ºï¼çæé»è®¤é
æ¹ |
| | | if (m_axes.empty()) { |
| | | generateDefaultRecipe(); |
| | | } |
| | | |
| | | // æ·»å é
æ¹æ ¹èç¹ |
| | | auto recipe = doc.append_child("Recipe"); |
| | | |
| | | // æ·»å è½´å表èç¹ |
| | | auto axesNode = recipe.append_child("Axes"); |
| | | |
| | | // éåææè½´æ°æ®å¹¶åå
¥ XML |
| | | for (const auto& axisEntry : m_axes) { |
| | | const AxisInfo& axisInfo = axisEntry.second; |
| | | |
| | | auto axisNode = axesNode.append_child("Axis"); |
| | | axisNode.append_attribute("id") = axisInfo.id; |
| | | axisNode.append_attribute("number") = axisInfo.number.c_str(); |
| | | axisNode.append_attribute("description") = axisInfo.description.c_str(); |
| | | axisNode.append_attribute("start_address") = axisInfo.startAddress.c_str(); |
| | | axisNode.append_attribute("jog_distance") = axisInfo.jogDistance; |
| | | axisNode.append_attribute("manual_speed") = axisInfo.manualSpeed; |
| | | axisNode.append_attribute("auto_speed") = axisInfo.autoSpeed; |
| | | axisNode.append_attribute("acceleration_time") = axisInfo.accelerationTime; |
| | | axisNode.append_attribute("deceleration_time") = axisInfo.decelerationTime; |
| | | |
| | | // æ·»å å®ä½ç¹å表 |
| | | auto positionsNode = axisNode.append_child("Positions"); |
| | | for (const auto& position : axisInfo.positions) { |
| | | auto positionNode = positionsNode.append_child("Position"); |
| | | positionNode.append_attribute("description") = position.first.c_str(); |
| | | positionNode.append_attribute("value") = position.second; |
| | | } |
| | | } |
| | | |
| | | // ä¿å XML æä»¶ |
| | | return doc.save_file(filePath.c_str()); |
| | | } |
| | | |
| | | // çæé»è®¤é
æ¹ |
| | | void RecipeManager::generateDefaultRecipe() { |
| | | m_axes.clear(); |
| | | |
| | | for (int axisId = 1; axisId <= 12; ++axisId) { |
| | | AxisInfo axisInfo; |
| | | axisInfo.id = axisId; |
| | | axisInfo.number = "M100-M" + std::to_string(axisId); |
| | | axisInfo.description = "Default_Axis" + std::to_string(axisId); |
| | | axisInfo.startAddress = "D" + std::to_string(5000 + axisId * 10); |
| | | axisInfo.jogDistance = 0.5; |
| | | axisInfo.manualSpeed = 10.0; |
| | | axisInfo.autoSpeed = 15.0; |
| | | axisInfo.accelerationTime = 0.2; |
| | | axisInfo.decelerationTime = 0.3; |
| | | |
| | | for (int posId = 1; posId <= 25; ++posId) { |
| | | axisInfo.positions.emplace_back("Position " + std::to_string(posId), posId * 10.0); |
| | | } |
| | | |
| | | m_axes[axisId] = axisInfo; |
| | | } |
| | | } |
| | | |
| | | // è·åææè½´ä¿¡æ¯ |
| | | const std::map<int, AxisInfo>& RecipeManager::getAxes() const { |
| | | return m_axes; |
| | | } |
| | | |
| | | // è·ååä¸ªè½´ä¿¡æ¯ |
| | | AxisInfo RecipeManager::getAxis(int axisId) const { |
| | | auto it = m_axes.find(axisId); |
| | | if (it != m_axes.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | // è¿åä¸ä¸ªæ æç AxisInfo |
| | | return AxisInfo{ -1, "", "", "", 0.0, 0.0, 0.0, 0.0, 0.0, {}}; |
| | | } |
| | | |
| | | // æ´æ°è½´ä¿¡æ¯ |
| | | bool RecipeManager::updateAxis(const AxisInfo& axisInfo) { |
| | | if (m_axes.find(axisInfo.id) == m_axes.end()) { |
| | | return false; // è½´ä¸åå¨ |
| | | } |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | return true; |
| | | } |
| | | |
| | | // æ·»å æ°çè½´ä¿¡æ¯ |
| | | bool RecipeManager::addAxis(const AxisInfo& axisInfo) { |
| | | if (m_axes.find(axisInfo.id) != m_axes.end()) { |
| | | return false; // è½´å·²åå¨ |
| | | } |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | return true; |
| | | } |
| | | |
| | | // å é¤è½´ä¿¡æ¯ |
| | | bool RecipeManager::deleteAxis(int axisId) { |
| | | return m_axes.erase(axisId) > 0; |
| | | } |
| | | |
| | | // è·åææè½´ç¼å· |
| | | std::vector<int> RecipeManager::getAllAxisID() const { |
| | | std::vector<int> axisNumbers; |
| | | for (const auto& axis : m_axes) { |
| | | int axisId = axis.first; |
| | | axisNumbers.push_back(axisId); |
| | | } |
| | | |
| | | return axisNumbers; |
| | | } |
| | | |
| | | // è·åæå®é¡µçå®ä½ç¹ |
| | | std::vector<std::pair<std::string, double>> RecipeManager::getPositions(int axisId, int pageNumber, int pageSize) const { |
| | | std::vector<std::pair<std::string, double>> result; |
| | | |
| | | // æ£æ¥è½´æ¯å¦åå¨ |
| | | auto it = m_axes.find(axisId); |
| | | if (it == m_axes.end()) { |
| | | return result; // å¦æè½´ ID ä¸åå¨ï¼è¿åç©ºç»æ |
| | | } |
| | | |
| | | // è·åæå®è½´çææå®ä½ç¹ |
| | | const auto& positions = it->second.positions; |
| | | |
| | | // ç¡®å®å页èå´ |
| | | int startIndex = (pageNumber - 1) * pageSize; |
| | | int endIndex = startIndex + pageSize; |
| | | |
| | | // éåå®ä½ç¹ï¼æå页æåæ°æ® |
| | | int index = 0; |
| | | for (const auto& pos : positions) { |
| | | const std::string& description = pos.first; // é®ï¼æè¿° |
| | | double value = pos.second; // å¼ï¼ä½ç½®å¼ |
| | | |
| | | if (index >= startIndex && index < endIndex) { |
| | | result.emplace_back(description, value); |
| | | } |
| | | |
| | | ++index; |
| | | if (index >= endIndex) { |
| | | break; // è¾¾å°åé¡µç»æç¹ |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |