00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <labust/control/ExecControl.hpp>
00038
00039 #include <boost/graph/graphviz.hpp>
00040 #include <boost/graph/dijkstra_shortest_paths.hpp>
00041
00042 #include <std_msgs/String.h>
00043
00044 #include <fstream>
00045 #include <iostream>
00046
00047 using namespace labust::control;
00048
00049 ExecControl::ExecControl():
00050 tnum(0),
00051 pnum(6),
00052 marking(pnum)
00053 {
00054 this->onInit();
00055 }
00056
00057 void ExecControl::onInit()
00058 {
00059 ros::NodeHandle nh,ph("~");
00060 depGraphPub = nh.advertise<std_msgs::String>("dependency_graph",1);
00061 pnGraphPub = nh.advertise<std_msgs::String>("petri_net_graph",1);
00062
00063 registerController = nh.advertiseService("register_controller",
00064 &ExecControl::onRegisterController, this);
00065
00066 activateController = nh.subscribe<std_msgs::String>("activate_cnt",1,
00067 &ExecControl::onActivateController, this);
00068
00069
00070 std::string dofs[]={"X","Y","Z","K","M","N"};
00071
00072 for (int i=X; i<=N;++i)
00073 {
00074 boost::add_vertex(VertexProperty(dofs[i],VertexProperty::p),graph);
00075 marking(i) = 1;
00076 pname[i] = dofs[i];
00077 }
00078 }
00079
00080 bool ExecControl::onRegisterController(
00081 navcon_msgs::RegisterController::Request& req,
00082 navcon_msgs::RegisterController::Response& resp)
00083 {
00084
00085 if (controllers.find(req.name) != controllers.end())
00086 {
00087 ROS_ERROR("The %s controller is already registered.", req.name.c_str());
00088 resp.accepted = false;
00089 return true;
00090 }
00091
00092
00093 for (int i=0; i<req.used_cnt.size(); ++i)
00094 {
00095 if (controllers.find(req.used_cnt[i]) == controllers.end())
00096 {
00097 ROS_ERROR("The controller %s is missing dependency %s.",
00098 req.name.c_str(),
00099 req.used_cnt[i].c_str());
00100 resp.unmet_cnt.push_back(req.used_cnt[i]);
00101 }
00102 }
00103
00104 if (resp.unmet_cnt.size())
00105 {
00106 resp.accepted = false;
00107 return true;
00108 }
00109
00110
00111 ROS_INFO("Adding controller %s.",req.name.c_str());
00112 resp.accepted = true;
00113 controllers[req.name].info = req;
00114 depGraph.addToGraph(req);
00115
00116
00117
00118 ros::Time now = ros::Time::now();
00119 pnCon.addToGraph(req);
00120 double addgraph_dT = (ros::Time::now() - now).toSec();
00121 now = ros::Time::now();
00122 pnCon.addToPNGraph(req);
00123 double addpngraph_dT = (ros::Time::now() - now).toSec();
00124
00125 double classic_dT = (ros::Time::now() - now).toSec();
00126 now = ros::Time::now();
00127
00128 pnCon.addToRGraph(req.name);
00129 double incremental_dT = (ros::Time::now() - now).toSec();
00130
00131
00132
00133 names.push_back(req.name);
00134
00135 std_msgs::String out;
00136 std::fstream dep_file("dep_graph.dot",std::ios::out);
00137 std::fstream pn_file("pn_graph.dot",std::ios::out);
00138 std::fstream r_file("r_graph.dot",std::ios::out);
00139 std::string temp;
00140 depGraph.getDotDesc(temp);
00141 dep_file<<temp;
00142 out.data = temp;
00143 depGraphPub.publish(out);
00144 pnCon.getDotDesc2(temp);
00145 pn_file<<temp;
00146 out.data = temp;
00147 pnGraphPub.publish(out);
00148 pnCon.getDotDesc(temp);
00149 r_file<<temp;
00150
00151 std::ofstream prof_file("profile.csv", std::ios::app);
00152 prof_file<<addgraph_dT<<","<<addpngraph_dT<<","<<classic_dT<<","<<incremental_dT<<std::endl;
00153
00154 return true;
00155 }
00156
00157 void ExecControl::addToMatrix(const std::string& name)
00158 {
00159
00160 using namespace boost;
00161 ControllerInfo& newcon = controllers[name];
00162 newcon.place_num = pnum++;
00163 pname[newcon.place_num] = name;
00164 marking.conservativeResize(pnum);
00165 marking(newcon.place_num) = 0;
00166 newcon.en_t_num = tnum++;
00167 newcon.dis_t_num = tnum++;
00168 std::cout<<"Resize matrix 2."<<std::endl;
00169 Dm.conservativeResize(pnum, tnum);
00170 Dp.conservativeResize(pnum, tnum);
00171 Dm.row(newcon.place_num) = Eigen::VectorXi::Zero(tnum);
00172 Dp.row(newcon.place_num) = Eigen::VectorXi::Zero(tnum);
00173 Dm.col(newcon.en_t_num)= Eigen::VectorXi::Zero(pnum);
00174 Dp.col(newcon.en_t_num)= Eigen::VectorXi::Zero(pnum);
00175 Dm.col(newcon.dis_t_num)= Eigen::VectorXi::Zero(pnum);
00176 Dp.col(newcon.dis_t_num)= Eigen::VectorXi::Zero(pnum);
00177
00178
00179 Dm(newcon.place_num, newcon.dis_t_num) = 1;
00180 Dp(newcon.place_num, newcon.en_t_num) = 1;
00181
00182 for (int i=0; i<newcon.info.used_dofs.size(); ++i)
00183 {
00184 if (newcon.info.used_dofs[i])
00185 {
00186 Dm(i, newcon.en_t_num) = 1;
00187 Dp(i, newcon.dis_t_num) = 1;
00188 }
00189 }
00190
00191
00192 for (int i=0; i<newcon.info.used_cnt.size(); ++i)
00193 {
00194 const std::string& dep = newcon.info.used_cnt[i];
00195 ControllerMap::iterator it = controllers.end();
00196 if ((it = controllers.find(dep)) != controllers.end())
00197 {
00198
00199
00200 Dm(it->second.place_num, newcon.en_t_num) = 1;
00201 Dp(it->second.place_num, newcon.dis_t_num) = 1;
00202 }
00203 }
00204
00205 std::cout<<"Current marking:"<<marking<<std::endl;
00206 std::cout<<"Current Dm matrix:"<<Dm<<std::endl;
00207 std::cout<<"Current Dp matrix:"<<Dp<<std::endl;
00208 std::cout<<"Current I matrix:"<<Dp-Dm<<std::endl;
00209
00210 reachability();
00211 }
00212
00213 void ExecControl::onActivateController(const std_msgs::String::ConstPtr& name)
00214 {
00215 if (controllers.find(name->data) != controllers.end())
00216 {
00217
00218
00219
00220
00221 pnCon.get_firing_pn(name->data);
00222 }
00223 else
00224 {
00225
00226 std::string dofs[]={"X","Y","Z","K","M","N"};
00227
00228 for (int i=X; i<=N;++i)
00229 {
00230 if (name->data == dofs[i])
00231 {
00232
00233 pnCon.get_firing_pn(name->data);
00234 break;
00235 }
00236 }
00237 }
00238 }
00239
00240 bool ExecControl::firing_rec2(int des_place, std::vector<int>& skip_transitions, std::vector<int>& visited_places)
00241 {
00242 visited_places.push_back(des_place);
00243
00244
00245 Eigen::VectorXi transitions = Dp.row(des_place);
00246 std::vector<int> activators;
00247 for (int i=0; i<transitions.size(); ++i)
00248 {
00249 if (transitions(i))
00250 {
00251 bool skipped = false;
00252
00253 for (int j=0; j< skip_transitions.size(); ++j)
00254 {
00255 if ((skipped = (skip_transitions[j] == i))) break;
00256 }
00257
00258 if (!skipped) activators.push_back(i);
00259 }
00260 }
00261
00262 std::cout<<"Place "<<pname[des_place]<<" depends on transitions:";
00263 for (int i=0; i<activators.size(); ++i)
00264 {
00265 std::cout<<activators[i]<<", ";
00266 }
00267 std::cout<<std::endl;
00268
00269
00270 if (activators.empty())
00271 {
00272 std::cout<<"Dead-end."<<std::endl;
00273 return false;
00274 }
00275
00276
00277 bool add_seq = false;
00278 for (int i=0; i<activators.size(); ++i)
00279 {
00280 Eigen::VectorXi t_en = Dm.col(activators[i]);
00281 std::vector<int> places;
00282 for (int j=0; j<t_en.size(); ++j)
00283 {
00284 if (t_en(j))
00285 {
00286
00287 bool skipped = false;
00288
00289 for (int k=0; k< visited_places.size(); ++k)
00290 {
00291 if ((skipped = (visited_places[k] == j))) break;
00292 }
00293
00294 if (!skipped) places.push_back(j);
00295 }
00296 }
00297
00298 std::cout<<"Transition "<<activators[i]<<" depends on places:";
00299 for (int j=0; j<places.size(); ++j)
00300 {
00301 std::cout<<pname[places[j]]<<", ";
00302 }
00303 std::cout<<std::endl;
00304
00305 bool add_cur_seq=true;
00306 for (int j=0; j<places.size(); ++j)
00307 {
00308
00309 if (!marking(places[j]))
00310 {
00311 if (!firing_rec2(places[j], skip_transitions, visited_places))
00312 {
00313 add_cur_seq = false;
00314 break;
00315 }
00316 }
00317 }
00318
00319 if (add_cur_seq && !places.empty())
00320 {
00321 bool add = true;
00322 for (int j=0; j<firing_seq.size(); ++j)
00323 {
00324 if (firing_seq[j] == activators[i])
00325 {
00326 add = false;
00327 break;
00328 }
00329 }
00330 if (add)
00331 {
00332 std::cout<<"Adding to firing sequence:"<<activators[i]<<std::endl;
00333 firing_seq.push_back(activators[i]);
00334 add_seq = true;
00335 if (activators[i]%2 == 0)
00336 {
00337 skip_transitions.push_back(activators[i]+1);
00338 }
00339 else
00340 {
00341 skip_transitions.push_back(activators[i]-1);
00342 }
00343 }
00344 }
00345 }
00346 return add_seq;
00347 }
00348
00349 bool ExecControl::firing_rec(int des_place, std::vector<int>& skip_transitions, std::vector<int>& visited_places){}
00350
00351 void ExecControl::get_firing(const std::string& name)
00352 {}
00353
00354 void ExecControl::get_firing2(const std::string& name)
00355 {
00356 std::vector<int> skip_transitions;
00357 std::vector<int> visited_places;
00358
00359
00360 int des_place = controllers[name].place_num;
00361 firing_rec2(des_place, skip_transitions, visited_places);
00362
00363 std::cout<<"The firing sequence is:";
00364 for (int i=0; i<firing_seq.size(); ++i)
00365 {
00366 std::cout<<firing_seq[i]<<" ,";
00367 }
00368 std::cout<<std::endl;
00369
00370
00371
00372
00373 for(int i=0; i<firing_seq.size(); ++i)
00374 {
00375 Eigen::VectorXi fire = Eigen::VectorXi::Zero(Dm.cols());
00376 fire(firing_seq[i]) = 1;
00377 marking = marking + (Dp-Dm)*fire;
00378 std::cout<<"Transition "<<firing_seq[i]<<" fired, new marking:"<<marking<<std::endl;
00379 if (marking(des_place)) break;
00380 }
00381 }
00382
00383
00384 void ExecControl::reachability()
00385 {
00386 rgraph.clear();
00387 Eigen::VectorXi trans = marking.transpose()*Dm;
00388
00389 std::cout<<"Transition matrix:"<<trans<<std::endl;
00390
00391 int last_m = boost::add_vertex(rgraph);
00392 rgraph[last_m].marking = marking;
00393
00394 Eigen::VectorXi fire = Eigen::VectorXi::Zero(trans.size());
00395 int tnum = -1;
00396 for (int i=0; i<trans.size(); ++i)
00397 {
00398 if (trans(i)>0)
00399 {
00400 std::cout<<"Transition "<<i<<" can fire."<<std::endl;
00401 fire(i) = 1;
00402 tnum = i;
00403 break;
00404 }
00405 }
00406
00407
00408
00409 int new_m = boost::add_vertex(rgraph);
00410 rgraph[new_m].marking = marking;
00411 REdgeProperty prop;
00412 prop.t = tnum;
00413 prop.weight = 1;
00414
00415 boost::add_edge(last_m, new_m, prop, rgraph);
00416 prop.t+=1;
00417
00418 boost::add_edge(new_m, last_m, prop, rgraph);
00419
00420
00421 std::cout<<"Transition fired, new marking:"<<marking<<std::endl;
00422 }
00423
00424 int main(int argc, char* argv[])
00425 {
00426 ros::init(argc,argv,"exec_control");
00427 labust::control::ExecControl exec;
00428 ros::spin();
00429 return 0;
00430 }