RobotInstanceFactory.cpp
Go to the documentation of this file.
00001 #include "robot_instance/RobotInstanceFactory.h"
00002 
00003 using namespace std;
00004 using namespace log4cpp;
00005 
00012 void RobotInstanceFactory::populateRobotInstanceFromFile(RobotInstancePtr instance, const std::string& configPath, const std::string& configSafetyPath, const std::string& filenameNoPath)
00013 {
00014     if (not instance)
00015     {
00016         instance = boost::make_shared<RobotInstance>();
00017     }
00018 
00019     instance->nodeTokenMap.clear();
00020     instance->mechanismRegisterMap.clear();
00021     instance->mechanismClassFileMap.clear();
00022     instance->mechanismJointFileMap.clear();
00023     instance->mechanismClassSafetyFileMap.clear();
00024     instance->mechanismCommandMap.clear();
00025     instance->mechanismControlMap.clear();
00026     instance->mechanisms.clear();
00027     instance->devices.clear();
00028     instance->commandableJoints.clear();
00029     instance->channelTypeMap.clear();
00030     instance->mechanismTypeMap.clear();
00031     instance->mechanismJointsMap.clear();
00032     instance->mechanismActuatorsMap.clear();
00033     instance->mechanismNodeMap.clear();
00034     instance->mechanismScheduleMap.clear();
00035     instance->jointScheduleNodeMap.clear();
00036     instance->actuatorScheduleNodeMap.clear();
00037     instance->deviceNodeMap.clear();
00038     instance->deviceScheduleMap.clear();
00039     instance->deviceRegisterMap.clear();
00040     instance->jointTypeMap.clear();
00041     instance->jointCommandPathMap.clear();
00042     instance->componentCpfsMap.clear();
00043     instance->deviceCalFileMap.clear();
00044     instance->deviceTypeMap.clear();
00045     instance->crew.clear();
00046 
00047     instance->configurationBasePath = configPath + "/";
00048     instance->configurationSafetyBasePath = configSafetyPath + "/";
00049 
00050     std::string filename = instance->configurationSafetyBasePath + RobotInstance::INSTANCE_PATH + filenameNoPath;
00051 
00052     // Load File
00053     TiXmlDocument file(filename.c_str());
00054     bool loadOkay = file.LoadFile();
00055 
00056     if (!loadOkay)
00057     {
00058         stringstream err;
00059         err << "Failed to load file [" << filename << "]";
00060         NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::FATAL, err.str());
00061         throw runtime_error(err.str());
00062     }
00063 
00064     TiXmlHandle doc(&file);
00065     NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::INFO, "RobotInstance file [" + filename + "] successfully loaded.");
00066 
00067     // Check for RobotInstance
00068     TiXmlHandle robotInstanceElement(doc.FirstChildElement("RobotInstance"));
00069 
00070     if (robotInstanceElement.ToElement())
00071     {
00072         instance->robotInstance = Private::getAttribute(robotInstanceElement, "id");
00073     }
00074     else
00075     {
00076         stringstream err;
00077         err << "The file " << filename << " has no element named [RobotInstance]";
00078         NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00079         throw runtime_error(err.str());
00080     }
00081 
00082     // Check for ComponentProperties
00083     TiXmlHandle componentPropertiesElement(robotInstanceElement.FirstChildElement("ComponentProperties"));
00084 
00085     if (componentPropertiesElement.ToElement())
00086     {
00087         TiXmlHandle currentComponentElement = 0;
00088         TiXmlHandle currentCpfElement       = 0;
00089         string      currentComponentName;
00090 
00091         std::vector< std::pair<std::string, std::string> > cpfFiles;
00092 
00093         // Iterate over components
00094         currentComponentElement = componentPropertiesElement.FirstChild("ComponentCpfs");
00095 
00096         while (currentComponentElement.ToElement())
00097         {
00098             currentComponentName = Private::getAttribute(currentComponentElement, "id");
00099 
00100             // Iterate over CPF files
00101             cpfFiles.clear();
00102             currentCpfElement = currentComponentElement.FirstChild("ComponentCpf");
00103 
00104             while (currentCpfElement.ToElement())
00105             {
00106                 cpfFiles.push_back(std::make_pair(Private::getAttribute(currentCpfElement, "value"), Private::getAttribute(currentCpfElement, "type")));
00107 
00108                 currentCpfElement = currentCpfElement.ToElement()->NextSiblingElement("ComponentCpf");
00109             }
00110 
00111             // Store the file set in the map
00112             instance->componentCpfsMap[currentComponentName] = cpfFiles;
00113 
00114             currentComponentElement = currentComponentElement.ToElement()->NextSiblingElement("ComponentCpfs");
00115         }
00116     }
00117 
00118     // Check for MachineName
00119     TiXmlHandle machineNameElement(robotInstanceElement.FirstChildElement("MachineName"));
00120 
00121     if (machineNameElement.ToElement())
00122     {
00123         instance->machineName = Private::getAttribute(machineNameElement, "id");
00124     }
00125     else
00126     {
00127         stringstream err;
00128         err << "The file " << filename << " has no element named [MachineName]";
00129         NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00130         throw runtime_error(err.str());
00131     }
00132 
00133     // Check for Friends
00134     TiXmlHandle crewElement(robotInstanceElement.FirstChildElement("Crew"));
00135 
00136     if (crewElement.ToElement())
00137     {
00138         TiXmlHandle currentMemberElement = 0;
00139         string currentMemberName;
00140 
00141         // Iterate over Friends
00142         currentMemberElement = crewElement.FirstChild("Member");
00143 
00144         while (currentMemberElement.ToElement())
00145         {
00146             currentMemberName = Private::getAttribute(currentMemberElement, "id");
00147             //cout << currentNodeName << endl;
00148 
00149             instance->crew.push_back(currentMemberName);
00150 
00151             currentMemberElement = currentMemberElement.ToElement()->NextSiblingElement("Member");
00152         }
00153     }
00154 
00155     // Check for KinematicModelFile
00156     TiXmlHandle kinematicModelElement(robotInstanceElement.FirstChildElement("KinematicModelFile"));
00157 
00158     if (kinematicModelElement.ToElement())
00159     {
00160         instance->kinematicModelFile = Private::getAttribute(kinematicModelElement, "id");
00161     }
00162 
00163     // Check for DynamicModelFile
00164     TiXmlHandle dynamicModelElement(robotInstanceElement.FirstChildElement("DynamicModelFile"));
00165 
00166     if (dynamicModelElement.ToElement())
00167     {
00168         instance->dynamicModelFile = Private::getAttribute(dynamicModelElement, "id");
00169     }
00170 
00171     // Check for MasterTokenFile
00172     TiXmlHandle masterTokenFileElement(robotInstanceElement.FirstChildElement("MasterTokenFile"));
00173 
00174     if (masterTokenFileElement.ToElement())
00175     {
00176         instance->masterTokenFile = Private::getAttribute(masterTokenFileElement, "id");
00177         //cout << instance->masterTokenFile << endl;
00178     }
00179 
00180     // Check for Nodes
00181     TiXmlHandle nodesElement(robotInstanceElement.FirstChildElement("Nodes"));
00182 
00183     if (nodesElement.ToElement())
00184     {
00185         TiXmlHandle currentNodeElement = 0;
00186         string      currentNodeName;
00187         string      currentNodeToken;
00188 
00189         // Iterate over joints
00190         currentNodeElement = nodesElement.FirstChild("Node");
00191 
00192         while (currentNodeElement.ToElement())
00193         {
00194             currentNodeName = Private::getAttribute(currentNodeElement, "id");
00195 
00196             instance->nodeTokenMap[currentNodeName] = Private::getAttribute(currentNodeElement, "token");
00197 
00198             currentNodeElement = currentNodeElement.ToElement()->NextSiblingElement("Node");
00199         }
00200     }
00201 
00202     // Check for Active Channels
00203     TiXmlHandle channelsElement(robotInstanceElement.FirstChildElement("ChannelModes"));
00204 
00205     if (nodesElement.ToElement())
00206     {
00207         TiXmlHandle currentChannelElement = 0;
00208         string      currentChannelName;
00209         string      currentChannelType;
00210 
00211         // Iterate over joints
00212         currentChannelElement = channelsElement.FirstChild("Channel");
00213 
00214         while (currentChannelElement.ToElement())
00215         {
00216             currentChannelName = Private::getAttribute(currentChannelElement, "id");
00217 
00218             currentChannelType = Private::getAttribute(currentChannelElement, "type");
00219             instance->channelTypeMap[currentChannelName] = currentChannelType;
00220 
00221             currentChannelElement = currentChannelElement.ToElement()->NextSiblingElement("Channel");
00222         }
00223     }
00224 
00225     // Check for Mechanisms
00226     TiXmlHandle mechanismsElement(robotInstanceElement.FirstChildElement("Mechanisms"));
00227 
00228     if (mechanismsElement.ToElement())
00229     {
00230         TiXmlHandle currentMechanismElement = 0;
00231         TiXmlHandle jointsElement           = 0;
00232         TiXmlHandle currentJointElement     = 0;
00233         TiXmlHandle actuatorsElement        = 0;
00234         TiXmlHandle currentActuatorElement  = 0;
00235         TiXmlHandle schedulesElement        = 0;
00236         TiXmlHandle currentScheduleElement  = 0;
00237         string      currentMechanismName;
00238         string      currentMechanismType;
00239         string      currentJointName;
00240         string      currentJointNameFQ;
00241         string      currentJointType;
00242         string      currentActuatorName;
00243         string      currentActuatorNameFQ;
00244         string      currentActuatorNode;
00245         string      currentActuatorSchedule;
00246 
00247         // Iterate over channels
00248         currentMechanismElement = mechanismsElement.FirstChild("Mechanism");
00249 
00250         while (currentMechanismElement.ToElement())
00251         {
00252             currentMechanismName = Private::getAttribute(currentMechanismElement, "id");
00253             instance->mechanisms.push_back(currentMechanismName);
00254 
00255             currentMechanismType = Private::getAttribute(currentMechanismElement, "type");
00256             instance->mechanismTypeMap[currentMechanismName] = currentMechanismType;
00257 
00258             instance->mechanismRegisterMap[currentMechanismName]    = Private::getSubelementAttribute(currentMechanismElement, "RegisterFile",    "id", false);
00259 
00260             if (instance->mechanismRegisterMap[currentMechanismName] == "")
00261             {
00262                 instance->mechanismRegisterMap.erase(currentMechanismName);
00263             }
00264 
00265             instance->mechanismClassFileMap[currentMechanismName]       = Private::getSubelementAttribute(currentMechanismElement, "ClassFile",         "id");
00266             instance->mechanismJointFileMap[currentMechanismName]       = Private::getSubelementAttribute(currentMechanismElement, "JointFile",         "id");
00267             instance->mechanismClassSafetyFileMap[currentMechanismName] = Private::getSubelementAttribute(currentMechanismElement, "ClassSafetyFile",   "id");
00268             instance->mechanismJointSafetyFileMap[currentMechanismName] = Private::getSubelementAttribute(currentMechanismElement, "JointSafetyFile",   "id");
00269             instance->mechanismCommandMap[currentMechanismName]         = Private::getSubelementAttribute(currentMechanismElement, "CommandApiMapFile", "id");
00270             instance->mechanismControlMap[currentMechanismName]         = Private::getSubelementAttribute(currentMechanismElement, "ControlApiMapFile", "id");
00271             instance->mechanismSetpointMap[currentMechanismName]        = Private::getSubelementAttribute(currentMechanismElement, "SetpointFile",      "id", false);
00272 
00273             if (instance->mechanismSetpointMap[currentMechanismName] == "")
00274             {
00275                 instance->mechanismSetpointMap.erase(currentMechanismName);
00276             }
00277 
00278             if (currentMechanismType == "simple")
00279             {
00280                 instance->mechanismNodeMap[currentMechanismName]     = Private::getSubelementAttribute(currentMechanismElement, "Node",         "id");
00281                 instance->mechanismScheduleMap[currentMechanismName] = Private::getSubelementAttribute(currentMechanismElement, "ScheduleFile", "id");
00282                 instance->jointTypeMap[currentMechanismName]         = "active";
00283                 instance->jointCommandPathMap[currentMechanismName]  = Private::getAttribute(currentMechanismElement, "commandPath");
00284                 instance->commandableJoints.push_back(currentMechanismName);
00285                 instance->mechanismJointsMap[currentMechanismName].push_back(currentMechanismName);
00286             }
00287             else if (currentMechanismType == "complex")
00288             {
00289                 // Check for Joints
00290                 jointsElement = currentMechanismElement.FirstChildElement("Joints");
00291 
00292                 if (jointsElement.ToElement())
00293                 {
00294                     // Iterate over joints
00295                     currentJointElement = jointsElement.FirstChild("Joint");
00296 
00297                     while (currentJointElement.ToElement())
00298                     {
00299                         currentJointName = Private::getAttribute(currentJointElement, "id");
00300 
00301                         currentJointNameFQ = currentMechanismName + StringUtilities::TOKEN_DELIMITER + currentJointName;
00302 
00303                         currentJointType = Private::getAttribute(currentJointElement, "type");
00304                         instance->jointTypeMap[currentJointNameFQ] = currentJointType;
00305 
00306                         if (currentJointType == "active")
00307                         {
00308                             instance->mechanismJointsMap[currentMechanismName].push_back(currentJointNameFQ);
00309                             instance->commandableJoints.push_back(currentJointNameFQ);
00310                         }
00311                         else if (currentJointType != "passive")
00312                         {
00313                             stringstream err;
00314                             err << "Joint " << currentJointNameFQ << " has unknown type [" << currentJointType << "]. Defaulting to passive.";
00315                             NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::WARN, err.str());
00316                         }
00317 
00318                         instance->mechanismAllJointsMap[currentMechanismName].push_back(currentJointNameFQ);
00319                         instance->allJoints.push_back(currentJointNameFQ);
00320 
00321                         instance->jointCommandPathMap[currentJointNameFQ]  = Private::getAttribute(currentMechanismElement, "commandPath");
00322 
00323                         schedulesElement = currentJointElement.FirstChildElement("ScheduleFiles");
00324 
00325                         if (schedulesElement.ToElement())
00326                         {
00327                             currentScheduleElement = schedulesElement.FirstChild("ScheduleFile");
00328 
00329                             while (currentScheduleElement.ToElement())
00330                             {
00331                                 instance->jointScheduleNodeMap[currentJointNameFQ].push_back(make_pair(Private::getAttribute(currentScheduleElement, "id"), Private::getAttribute(currentScheduleElement, "node")));
00332 
00333                                 currentScheduleElement = currentScheduleElement.ToElement()->NextSiblingElement("ScheduleFile");
00334                             }
00335                         }
00336                         else
00337                         {
00338                             stringstream err;
00339                             err << "The file " << filename << " has no element named [ScheduleFiles]";
00340                             NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00341                             throw runtime_error(err.str());
00342                         }
00343 
00344                         currentJointElement = currentJointElement.ToElement()->NextSiblingElement("Joint");
00345                     }
00346                 }
00347                 else
00348                 {
00349                     stringstream err;
00350                     err << "The file " << filename << " has no element named [Joints]";
00351                     NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00352                     throw runtime_error(err.str());
00353                 }
00354 
00355                 // Check for Actuators
00356                 actuatorsElement = currentMechanismElement.FirstChildElement("Actuators");
00357 
00358                 if (actuatorsElement.ToElement())
00359                 {
00360                     // Iterate over actuators
00361                     currentActuatorElement = actuatorsElement.FirstChild("Actuator");
00362 
00363                     while (currentActuatorElement.ToElement())
00364                     {
00365                         currentActuatorName = Private::getAttribute(currentActuatorElement, "id");
00366 
00367                         currentActuatorNameFQ = currentMechanismName + StringUtilities::TOKEN_DELIMITER + currentActuatorName;
00368 
00369                         instance->mechanismActuatorsMap[currentMechanismName].push_back(currentActuatorNameFQ);
00370 
00371                         schedulesElement = currentActuatorElement.FirstChildElement("ScheduleFiles");
00372 
00373                         if (schedulesElement.ToElement())
00374                         {
00375                             currentScheduleElement = schedulesElement.FirstChild("ScheduleFile");
00376 
00377                             while (currentScheduleElement.ToElement())
00378                             {
00379                                 instance->actuatorScheduleNodeMap[currentActuatorNameFQ].push_back(make_pair(Private::getAttribute(currentScheduleElement, "id"), Private::getAttribute(currentScheduleElement, "node")));
00380 
00381                                 currentScheduleElement = currentScheduleElement.ToElement()->NextSiblingElement("ScheduleFile");
00382                             }
00383                         }
00384                         else
00385                         {
00386                             stringstream err;
00387                             err << "The file " << filename << " has no element named [ScheduleFiles]";
00388                             NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00389                             throw runtime_error(err.str());
00390                         }
00391 
00392                         currentActuatorElement = currentActuatorElement.ToElement()->NextSiblingElement("Actuator");
00393                     }
00394                 }
00395                 else
00396                 {
00397                     stringstream err;
00398                     err << "The file " << filename << " has no element named [Actuators]";
00399                     NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00400                     throw runtime_error(err.str());
00401                 }
00402             }
00403 
00404             currentMechanismElement = currentMechanismElement.ToElement()->NextSiblingElement("Mechanism");
00405         }
00406     }
00407 
00408     // Check for Devices
00409     TiXmlHandle devicesElement(robotInstanceElement.FirstChildElement("Devices"));
00410 
00411     if (devicesElement.ToElement())
00412     {
00413         TiXmlHandle currentDeviceElement = 0;
00414         string      currentDeviceName;
00415         string      currentDeviceNode;
00416         string      currentDeviceSchedule;
00417 
00418         // Iterate over joints
00419         currentDeviceElement = devicesElement.FirstChild("Device");
00420 
00421         while (currentDeviceElement.ToElement())
00422         {
00423             currentDeviceName = Private::getAttribute(currentDeviceElement, "id");
00424 
00425             instance->devices.push_back(currentDeviceName);
00426 
00427             instance->deviceNodeMap[currentDeviceName]     = Private::getAttribute(currentDeviceElement, "node");
00428             instance->deviceScheduleMap[currentDeviceName] = Private::getAttribute(currentDeviceElement, "schedule");
00429             instance->deviceRegisterMap[currentDeviceName]  = Private::getAttribute(currentDeviceElement, "register", false);
00430 
00431             if (instance->deviceRegisterMap[currentDeviceName] == "")
00432             {
00433                 instance->deviceRegisterMap.erase(currentDeviceName);
00434             }
00435 
00436             instance->deviceCalFileMap[currentDeviceName] = Private::getAttribute(currentDeviceElement, "calFile", false);
00437 
00438             if (instance->deviceCalFileMap[currentDeviceName] == "")
00439             {
00440                 instance->deviceCalFileMap.erase(currentDeviceName);
00441             }
00442 
00443             instance->deviceTypeMap[currentDeviceName] = Private::getAttribute(currentDeviceElement, "type", false);
00444 
00445             if (instance->deviceTypeMap[currentDeviceName] == "")
00446             {
00447                 instance->deviceTypeMap.erase(currentDeviceName);
00448             }
00449 
00450             currentDeviceElement = currentDeviceElement.ToElement()->NextSiblingElement("Device");
00451         }
00452     }
00453 
00454     NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::NOTICE, "RobotInstance file [" + filename + "] successfully parsed.");
00455 }
00456 
00462 RobotInstancePtr RobotInstanceFactory::createRobotInstanceFromFile(const std::string& configPath, const std::string& configSafetyPath, const string& filename)
00463 {
00464     RobotInstancePtr instance = boost::make_shared<RobotInstance>();
00465 
00466     populateRobotInstanceFromFile(instance, configPath, configSafetyPath, filename);
00467 
00468     return instance;
00469 }
00470 
00478 const string RobotInstanceFactory::Private::getAttribute(TiXmlHandle handle, const string& attribute, bool required)
00479 {
00480     if (handle.ToElement()->Attribute(attribute))
00481     {
00482         return *(handle.ToElement()->Attribute(attribute));
00483     }
00484     else
00485     {
00486         if (required)
00487         {
00488             stringstream err;
00489             err << "The attribute [" << attribute << "] was not found for element [" << handle.ToElement()->ValueStr() << "]";
00490             NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00491             throw runtime_error(err.str());
00492         }
00493 
00494         return "";
00495     }
00496 }
00497 
00505 const string RobotInstanceFactory::Private::getSubelementAttribute(TiXmlHandle handle, const string& subelementName, const string& attribute, bool required)
00506 {
00507     if (handle.FirstChildElement(subelementName).ToElement())
00508     {
00509         return Private::getAttribute(handle.FirstChildElement(subelementName), attribute, required);
00510     }
00511     else
00512     {
00513         if (required)
00514         {
00515             stringstream err;
00516             err << "No [" << subelementName << "] subelement found for element [" << handle.ToElement()->ValueStr() << "]";
00517             NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::INFO, err.str());
00518             throw runtime_error(err.str());
00519         }
00520 
00521         return "";
00522     }
00523 }
00524 
00525 const string RobotInstanceFactory::Private::getNodeFile(TiXmlHandle handle, const string& subelementName, const string& defaultFileName)
00526 {
00527     try
00528     {
00529         return Private::getSubelementAttribute(handle, subelementName, "id");
00530     }
00531     catch (runtime_error& e)
00532     {
00533         if (defaultFileName.size() > 0)
00534         {
00535             NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::INFO, "No [" + subelementName + "] element found for [" + getAttribute(handle, "id") + "], using default value.");
00536             return defaultFileName;
00537         }
00538         else
00539         {
00540             stringstream err;
00541             err << "No [" << subelementName << "] element found and no default value to use";
00542             NasaCommonLogging::Logger::log("gov.nasa.configuration.RobotInstanceFactory", Priority::ERROR, err.str());
00543             throw runtime_error(err.str());
00544         }
00545     }
00546 }


robot_instance
Author(s):
autogenerated on Sat Jun 8 2019 20:43:12