planners/ik_mpep/SMGraph.cpp

Go to the documentation of this file.
00001 
00002 #include "SMGraph.h"
00003 #include <assert.h>
00004 #include <LEDA/shortest_path.h>
00005 #include <LEDA/templates/shortest_path.t>
00006 
00007 
00008 #define DATA_LEN_IN_NODE  1
00009 #define DATA_LEN_IN_EDGE  1
00010 
00011 //Construction function,
00012 //  where the ENTRY node will be set with A configuration.
00013 SMGraph::SMGraph(Configuration &entry):
00014                 G(DATA_LEN_IN_NODE, DATA_LEN_IN_EDGE)
00015 {
00016         G.make_undirected();
00017         node newNode = NewNode(entry);
00018 
00019         assert(newNode!=NULL);
00020 
00021         entryNode = newNode;
00022         exitNode = NULL;
00023 
00024         current = NULL;
00025         currentNode = NULL;
00026 }
00027 
00028 SMGraph::~SMGraph()
00029 {
00030         node v;
00031         Configuration *config;
00032         forall_nodes(v, G)
00033         {
00034                 config = (Configuration *)v->data(0);
00035                 delete config;
00036         }
00037         G.clear();
00038 }
00039 
00040 //Actually, the purpose letting this function here,
00041 //  is just to make it similiar with "SetExitConfig"
00042 //  maybe never get called.
00043 bool SMGraph::SetEntryConfig(Configuration &entry)
00044 {
00045         node v=Lookup(entry);
00046 
00047         if (v!=NULL)
00048         {
00049                 entryNode = v;
00050                 return true;
00051         }
00052         else
00053         {
00054                 return false;
00055         }
00056 }
00057 
00058 //Update the EXIT node for the Self-Motion Graph.
00059 bool SMGraph::SetExitConfig(Configuration &exit)
00060 {
00061         node v=Lookup(exit);
00062 
00063         if (v!=NULL)
00064         {
00065                 exitNode = v;
00066                 return true;
00067         }
00068         else
00069         {
00070                 return false;
00071         }
00072 }
00073 
00074 //Call the shortest path algorithm to get the shortest path from
00075 //  the ENTRY node to the EXIT node.
00076 bool SMGraph::GetPath()
00077 {
00078         if (entryNode==NULL)
00079                 return false;
00080         if (exitNode==NULL)
00081                 return false;
00082 
00083         edge_array<double>cost(G);
00084         edge ed;
00085         forall_edges(ed, G)
00086         {
00087                 cost[ed] = G.inf(ed);
00088         }
00089 
00090         node_array<double> dist(G);
00091         node_array<edge> pred(G);
00092 
00093         bool result = SHORTEST_PATH_T(G, entryNode, cost, dist, pred);
00094 
00095         if (result==false)
00096                 return false;
00097 
00098         //Got the shortest path, retrieve the corresponding configuration from the path.
00099         path.clear();
00100 
00101         node v;
00102         v=exitNode;
00103         path.append(G.inf(v));
00104         while(pred[v]!=NULL)
00105         {
00106                 edge e;
00107                 e = pred[v];
00108                 v=G.opposite(v, e);
00109                 path.append(G.inf(v));
00110         }
00111 
00112         return true;
00113 }
00114 
00115 void* SMGraph::FirstNode()
00116 {
00117         currentNode = G.first_node();
00118         return currentNode;
00119 }
00120 
00121 void* SMGraph::NextNode()
00122 {
00123         currentNode = G.succ_node(currentNode);
00124         return currentNode;
00125 }
00126 
00127 Configuration* SMGraph::GetConfiguration(void *v)
00128 {
00129         return (Configuration *)G.inf((node)v);
00130 }
00131 
00132 Configuration* SMGraph::FirstConfigInPath()
00133 {
00134         current = path.first();
00135         if (current != NULL)
00136                 return (Configuration *)path.inf(current);
00137         else
00138                 return NULL;
00139 }
00140 
00141 Configuration* SMGraph::NextConfigInPath()
00142 {
00143         current = path.succ(current);
00144         if (current != NULL)
00145                 return (Configuration *)path.inf(current);
00146         else
00147                 return NULL;
00148 }
00149 
00150 void *SMGraph::AddConnection(void* parent, Configuration &son)
00151 {
00152         node v=NewNode(son);
00153         double dist = Distance(*(G.inf((node)parent)), son);
00154         edge e=G.new_edge((node)parent, v, dist);
00155         exitNode = v;
00156         return v;
00157 }
00158 
00159 void *SMGraph::AddConnection(Configuration &parent, Configuration &son)
00160 {
00161         node v=Lookup(parent);
00162 
00163         if (v!=NULL)
00164         {
00165                 return AddConnection(v, son);
00166         }
00167         else
00168         {
00169                 return NULL;
00170         }
00171 }
00172 
00173 void SMGraph::Clear()
00174 {
00175         if ( !G.empty() )
00176         {
00177                 G.clear();
00178         }
00179 }
00180 
00181 bool SMGraph::OptimizeConnection()
00182 {
00183         //What is expected here is to optimize the structure of Graph, including
00184         //  - Make the Graph more compact.
00185         //  - Remove the cyclic connection, if there is
00186         //  - Remove independent vertex, if there is
00187         //  - Maybe some other operation
00188         //However, just forget about it at this moment.
00189         return true;
00190 }
00191 
00192 int SMGraph::Node_Num()
00193 {
00194         return G.number_of_nodes();
00195 }
00196 
00197 GRAPH<Configuration *, double> *SMGraph::GetSMGraph() 
00198 {
00199         return &G;
00200 }
00201 
00202 int SMGraph::Node_Edge()
00203 {
00204         return G.number_of_edges();
00205 }
00206 
00207 void SMGraph::GetConfig(const node& n, Configuration **conf)
00208 {
00209         *conf = (Configuration *)(G.inf(n));
00210 }
00211 
00212 void SMGraph::GetConfig(const edge& e, Configuration **conf1, Configuration **conf2)
00213 {
00214         node v = G.source(e);
00215         *conf1 = (Configuration *)(G.inf(v));
00216         v = G.target(e);
00217         *conf2 = (Configuration *)(G.inf(v));
00218 }
00219 
00220 node SMGraph::NewNode(Configuration &config)
00221 {
00222         Configuration *data = new Configuration(config);
00223         node v=G.new_node(data);
00224         return v;
00225 }
00226 
00227 node SMGraph::Lookup(Configuration &config)
00228 {
00229         node v;
00230         Configuration *inf;
00231         forall_nodes(v, G)
00232         {
00233                 inf = (Configuration *)(G.inf(v));
00234                 if ((*inf)==config)
00235                         break;
00236         }
00237         return v;
00238 }
00239 
00240 double SMGraph::Distance (const Configuration& a, const Configuration& b)
00241 {
00242         //Here, actually need to compute the distance between two configurations.
00243         //  However, computing this distance required the visibility of Collision Detection(C-D).
00244         //  So, I'm thinking to hang this in there.
00245         //    If someday we really need that, we can use callback or exporting C-D to make it happen.
00246         //    Before that Self-Motion Graph is actually a un-weighted graph.
00247         return 1;
00248 }
00249 

Generated on Sat Apr 1 21:30:43 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO