CExporterDot.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2013, Institute for Artificial Intelligence,
00005  *  Universität Bremen.
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the Institute for Artificial Intelligence,
00019  *     Universität Bremen, nor the names of its contributors may be
00020  *     used to endorse or promote products derived from this software
00021  *     without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *********************************************************************/
00036 
00040 #include <plugins/dotexporter/CExporterDot.h>
00041 
00042 
00043 namespace beliefstate {
00044   CExporterDot::CExporterDot() {
00045   }
00046   
00047   CExporterDot::~CExporterDot() {
00048   }
00049   
00050   bool CExporterDot::runExporter(CKeyValuePair* ckvpConfigurationOverlay) {
00051     this->renewUniqueIDs();
00052     int nMaxDetailLevel = this->configuration()->floatValue("max-detail-level");
00053     
00054     if(this->outputFilename() != "") {
00055       std::string strGraphID = this->generateRandomIdentifier("plangraph_", 8);
00056       std::string strToplevelID = this->generateUniqueID("node_", 8);
00057       
00058       std::string strDot = "digraph " + strGraphID + " {\n";
00059       
00060       strDot += "  " + strToplevelID + " [shape=doublecircle, style=bold, label=\"top-level\"];\n";
00061       
00062       strDot += this->generateDotStringForNodes(this->nodes(), strToplevelID);
00063       
00064       strDot += "}\n";
00065       
00066       return this->writeToFile(strDot);
00067     }
00068     
00069     return false;
00070   }
00071   
00072   string CExporterDot::generateDotStringForDescription(std::list<CKeyValuePair*> lstDescription, int nTimeStart, int nTimeEnd) {
00073     std::string strDot = "";
00074     
00075     if(nTimeStart > -1) {
00076       strDot += "|{time-start | " + this->str(nTimeStart) + "}";
00077     }
00078     
00079     if(nTimeEnd > -1) {
00080       strDot += "|{time-end | " + this->str(nTimeEnd) + "}";
00081     }
00082     
00083     for(CKeyValuePair* ckvpCurrent : lstDescription) {
00084       if(ckvpCurrent->key().at(0) != '_') {
00085         std::string strValue = "?";
00086         bool bEscape = true;
00087         
00088         if(ckvpCurrent->type() == STRING) {
00089           strValue = ckvpCurrent->stringValue();
00090         } else if(ckvpCurrent->type() == FLOAT) {
00091           strValue = this->str(ckvpCurrent->floatValue());
00092         } else if(ckvpCurrent->type() == POSE) {
00093           bEscape = false;
00094           geometry_msgs::Pose psPose = ckvpCurrent->poseValue();
00095           std::stringstream stsPS;
00096           
00097           stsPS << "|{position |{{x | " << psPose.position.x << "} "
00098                 << "|{y | " << psPose.position.y << "} "
00099                 << "|{z | " << psPose.position.z << "}}} "
00100                 << "|{orientation |{{x | " << psPose.orientation.x << "} "
00101                 << "|{y | " <<psPose.orientation.y << "} "
00102                 << "|{z | " << psPose.orientation.z << "} "
00103                 << "|{w | " << psPose.orientation.w << "}}}}";
00104         
00105           strValue = stsPS.str();
00106         } else if(ckvpCurrent->type() == POSESTAMPED) {
00107           bEscape = false;
00108           geometry_msgs::PoseStamped psPoseStamped = ckvpCurrent->poseStampedValue();
00109           std::stringstream stsPS;
00110           
00111           stsPS << "{{frame-id | \\\"" << psPoseStamped.header.frame_id << "\\\"} "
00112                 << "|{position |{{x | " << psPoseStamped.pose.position.x << "} "
00113                 << "|{y | " << psPoseStamped.pose.position.y << "} "
00114                 << "|{z | " << psPoseStamped.pose.position.z << "}}} "
00115                 << "|{orientation |{{x | " << psPoseStamped.pose.orientation.x << "} "
00116                 << "|{y | " <<psPoseStamped.pose.orientation.y << "} "
00117                 << "|{z | " << psPoseStamped.pose.orientation.z << "} "
00118                 << "|{w | " << psPoseStamped.pose.orientation.w << "}}}}";
00119           
00120           strValue = stsPS.str();
00121         } else {
00122           // NOTE(winkler): This actually IS a valid warning. The only
00123           // issue is that we don't have a proper failure handling
00124           // mechanism here, yet. Also, it doesn't hurt the current
00125           // logs.
00126           
00127           /*stringstream sts;
00128           sts << (int)ckvpCurrent->type();
00129           this->warn("Careful: unknown type code for field (" + sts.str() + ")");*/
00130         }
00131         
00132         if(bEscape) {
00133           strValue = this->dotEscapeString(strValue);
00134         }
00135         
00136         strDot += "|{" + this->dotEscapeString(ckvpCurrent->key()) + " | " + strValue + "}";
00137       }
00138     }
00139   
00140     return strDot;
00141   }
00142 
00143   std::string CExporterDot::generateDotStringForNodes(std::list<Node*> lstNodes, std::string strParentID) {
00144     std::string strDot = "";
00145     
00146     for(Node* ndCurrent : lstNodes) {
00147       if(this->nodeDisplayable(ndCurrent)) {
00148         std::string strNodeID = ndCurrent->uniqueID();
00149         
00150         std::string strFillColor;
00151         std::string strEdgeColor;
00152         
00153         if(ndCurrent->metaInformation()->floatValue("success") == 1) {
00154           strFillColor = "#ddffdd";
00155           strEdgeColor = "green";
00156         } else {
00157           strFillColor = "#ffdddd";
00158           strEdgeColor = "red";
00159         }
00160         
00161         std::string strParameters = this->generateDotStringForDescription(ndCurrent->description(),
00162                                                                           ndCurrent->metaInformation()->floatValue("time-start"),
00163                                                                           ndCurrent->metaInformation()->floatValue("time-end"));
00164         std::string strLabel = "{" + this->dotEscapeString(ndCurrent->title()) + strParameters + "}";
00165         
00166         strDot += "\n  " + strNodeID + " [shape=Mrecord, style=filled, fillcolor=\"" + strFillColor + "\", label=\"" + strLabel + "\"];\n";
00167         strDot += "  edge [color=\"" + strEdgeColor + "\", label=\"\"];\n";
00168         strDot += "  " + strParentID + " -> " + strNodeID + ";\n";
00169         
00170         // Images
00171         strDot += this->generateDotImagesStringForNode(ndCurrent);
00172         
00173         // Objects
00174         strDot += this->generateDotObjectsStringForNode(ndCurrent);
00175         
00176         // Subnodes
00177         strDot += this->generateDotStringForNodes(ndCurrent->subnodes(), strNodeID);
00178       } else if(this->nodeHasValidDetailLevel(ndCurrent)) {
00179         // Node has valid detail level. So the failed displayability
00180         // was due to this and not due to a failed success/failure
00181         // check. Display its children and use this node's parent id
00182         // for their parent id.
00183         
00184         // Subnodes
00185         strDot += this->generateDotStringForNodes(ndCurrent->subnodes(), strParentID);
00186       }
00187     }
00188     
00189     return strDot;
00190   }
00191   
00192   std::string CExporterDot::generateDotImagesStringForNode(Node *ndImages) {
00193     std::string strDot = "";
00194     
00195     CKeyValuePair *ckvpImages = ndImages->metaInformation()->childForKey("images");
00196     
00197     if(ckvpImages) {
00198       list<CKeyValuePair*> lstChildren = ckvpImages->children();
00199       
00200       unsigned int unIndex = 0;
00201       for(CKeyValuePair* ckvpChild : lstChildren) {
00202         std::string strOrigin = ckvpChild->stringValue("origin");
00203         std::string strFilename = ckvpChild->stringValue("filename");
00204         
00205         std::stringstream sts;
00206         sts << ndImages->uniqueID() << "_image_" << unIndex;
00207         
00208         strDot += "  " + sts.str() + " [shape=box, label=\"" + strOrigin + "\", width=\"6cm\", height=\"6cm\", fixedsize=true, imagescale=true, image=\"" + strFilename + "\"];\n";
00209         strDot += "  edge [color=\"black\", label=\"camera image\"];\n";
00210         strDot += "  " + sts.str() + " -> " + ndImages->uniqueID() + ";\n";
00211       }
00212     }
00213     
00214     return strDot;
00215   }
00216 
00217   std::string CExporterDot::generateDotObjectsStringForNode(Node *ndObjects) {
00218     std::string strDot = "";
00219     
00220     CKeyValuePair *ckvpObjects = ndObjects->metaInformation()->childForKey("objects");
00221     
00222     if(ckvpObjects) {
00223       std::list<CKeyValuePair*> lstChildren = ckvpObjects->children();
00224       
00225       unsigned int unIndex = 0;
00226       for(CKeyValuePair* ckvpChild : lstChildren) {
00227         std::string strDefClass = ckvpChild->stringValue("_class");
00228         std::string strDefProperty = ckvpChild->stringValue("_property");
00229         
00230         if(strDefClass == "") {
00231           strDefClass = "object";
00232         }
00233         
00234         if(strDefProperty == "") {
00235           strDefProperty = "knowrob:objectActedOn";
00236         }
00237         
00238         std::string strObjectID = strDefClass + "_" + ckvpChild->stringValue("__id");
00239         
00240         // std::stringstream sts;
00241         // sts << ndObjects->uniqueID() << "_object_" << unIndex;
00242         
00243         std::string strParameters = this->generateDotStringForDescription(ckvpChild->children());
00244         std::string strTitle = strObjectID;
00245         std::string strLabel = "{" + this->dotEscapeString(strTitle) + strParameters + "}";
00246         
00247         strDot += "  " + strObjectID + " [shape=Mrecord, label=\"" + strLabel + "\"];\n";
00248         strDot += "  edge [color=\"black\", label=\"" + strDefProperty + "\"];\n";
00249         strDot += "  " + strObjectID + " -> " + ndObjects->uniqueID() + ";\n";
00250       }
00251     }
00252     
00253     return strDot;
00254   }
00255 
00256   string CExporterDot::dotEscapeString(std::string strValue) {
00257     strValue = this->replaceString(strValue, "\n", "\\n");
00258     strValue = this->replaceString(strValue, "{", "\\{");
00259     strValue = this->replaceString(strValue, "}", "\\}");
00260     strValue = this->replaceString(strValue, "<", "\\<");
00261     strValue = this->replaceString(strValue, ">", "\\>");
00262     strValue = this->replaceString(strValue, "\"", "\\\"");
00263     strValue = this->replaceString(strValue, "|", "\\|");
00264   
00265     return strValue;
00266   }
00267 }


beliefstate
Author(s): Jan Winkler
autogenerated on Sun Oct 5 2014 22:30:15