diagnosis_engine_controller.cpp
Go to the documentation of this file.
00001 /*
00002 * diagnosis_engine_controller.cpp is a client to use the java based diagnosis engine server.
00003 *
00004 * Copyright (c).2012. OWNER: Institute for Software Technology, TU Graz Austria.
00005 * Authors: Safdar Zaman, Gerald Steinbauer. (szaman@ist.tugraz.at, steinbauer@ist.tugraz.at)
00006 * All rights reserved.
00007 *    This program is free software: you can redistribute it and/or modify
00008 *    it under the terms of the GNU General Public License as published by
00009 *    the Free Software Foundation, either version 3 of the License, or
00010 *    (at your option) any later version.
00011 *
00012 *    This program is distributed in the hope that it will be useful,
00013 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 *    GNU General Public License for more details.
00016 *
00017 *    You should have received a copy of the GNU General Public License
00018 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include <sys/socket.h>
00022 #include <sys/types.h>
00023 #include <netinet/in.h>
00024 #include <iostream>
00025 #include <netdb.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <unistd.h>
00030 #include <errno.h>
00031 #include <algorithm>
00032 #include <ros/ros.h>
00033 #include <actionlib/client/simple_action_client.h>
00034 #include <actionlib/client/terminal_state.h>
00035 #include <tug_ist_diagnosis_msgs/SystemModelAction.h>
00036 #include <tug_ist_diagnosis_msgs/Observations.h>
00037 #include <tug_ist_diagnosis_msgs/Diagnosis.h>
00038 #include <tug_ist_diagnosis_msgs/DiagnosisResults.h>
00039 #include <time.h>
00040 
00041 #define POST_SD_HEADER "POST sessionA ADD_SENTENCES SD ATP\r\nNumber-Rules: "
00042 #define POST_REPLACE_SD_HEADER "POST sessionA REPLACE_SENTENCES SD ATP\r\nNumber-Rules: "
00043 #define POST_OBS_HEADER "POST sessionA ADD_SENTENCES OBS ATP\r\nNumber-Rules: "
00044 #define POST_REPLACE_OBS_HEADER "POST sessionA REPLACE_SENTENCES OBS ATP\r\nNumber-Rules: "
00045 
00046 const int NUM_SECONDS = 1;
00047 
00048 typedef actionlib::SimpleActionClient<tug_ist_diagnosis_msgs::SystemModelAction> modelClient;
00049 using std::vector;
00050 class Diagnosis_Client
00051 {
00052 
00053 protected:
00054          ros::NodeHandle nh_;
00055          ros::Subscriber mdl_sub,obs_sub;
00056          ros::Publisher diag_pub;
00057          int sock, bytes_recieved;
00058          char recv_data_buff[1024];  
00059          char recv_data[1024];
00060          struct hostent *host;
00061          struct sockaddr_in server_addr;  
00062          char *send_data;
00063          int no_of_rules;
00064          int no_of_props;
00065          int no_of_obs;
00066          std::string neg_prefix;
00067          vector<std::string> msg_list;
00068          vector<std::string> comp_list;
00069          std::string FALSE_RULES;
00070          int NUM_FALSE_RULES;
00071          clock_t this_time;
00072          clock_t last_time;
00073          int time_counter;
00074 
00075          
00076          
00077          
00078 public:
00079 
00080     Diagnosis_Client(ros::NodeHandle nh)
00081     {      nh_ = nh;
00082            diag_pub = nh_.advertise<tug_ist_diagnosis_msgs::Diagnosis>("/diagnosis", 100); 
00083            mdl_sub = nh_.subscribe("/diagnosis_model", 1, &Diagnosis_Client::modelCB, this);
00084            obs_sub = nh_.subscribe("/observations", 1, &Diagnosis_Client::observationsCB, this);
00085            ROS_INFO("\nWaiting for the Diagnosis Model Action Server.......");
00086            modelClient mc("diagnosis_model_server", true);
00087            tug_ist_diagnosis_msgs::SystemModelGoal goal;
00088            tug_ist_diagnosis_msgs::SystemModelResult result;
00089            goal.goal = 1;
00090            mc.waitForServer();
00091            mc.sendGoal(goal);
00092            printf("\nGetting model.....");
00093            mc.waitForResult(ros::Duration(5.0));
00094            if (mc.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00095                 printf("\nGot the model!\n");
00096            else
00097                 printf("\nCould not get the Model!");
00098            connect_to_Server();
00099            last_time = clock();
00100            time_counter = 0;
00101            
00102 
00103 
00104   }
00105   
00106   ~Diagnosis_Client(){
00107       disconnect_to_Server();
00108   }
00109       
00110 
00111   void set_port(int port) {
00112         server_addr.sin_family = AF_INET;     
00113         server_addr.sin_port = htons(port);   
00114         server_addr.sin_addr = *((struct in_addr *)host->h_addr);
00115         bzero(&(server_addr.sin_zero),8); 
00116   }
00117   void set_ip(char *ip) {
00118         host = gethostbyname(ip);
00119   }
00120   void send_SD_to_server(char *data) {
00121         int size_data = strlen(data);
00122         char buffer[50+size_data]; 
00123         char * ptr;
00124         strcpy(buffer, POST_REPLACE_SD_HEADER );
00125         ptr = strcat( buffer, data );
00126         ROS_INFO("SD:\n%s",buffer);
00127         send(sock,buffer,strlen(buffer), 0);
00128   }
00129 
00130   void send_OBS_to_server(char *data) {
00131         int size_data = strlen(data);
00132         char buffer[50+size_data]; 
00133         char * ptr;
00134         strcpy(buffer,POST_REPLACE_OBS_HEADER );
00135         ptr = strcat( buffer, data );
00136         send(sock,buffer,strlen(buffer), 0);
00137         ROS_INFO("OBS\n%s",buffer);
00138   }
00139 
00140 
00141   void send_QUERY_to_server(char *data) {
00142            
00143            send(sock,data,strlen(data), 0); 
00144   }
00145 
00146   void connect_to_Server() {
00147         set_ip("127.0.0.1");
00148         set_port(10000);
00149         if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
00150             perror("Socket Error!");
00151             exit(1);
00152         }
00153 
00154         if (connect(sock, (struct sockaddr *)&server_addr,
00155                     sizeof(struct sockaddr)) == -1) 
00156         {
00157             perror("Connection Error!");
00158             exit(1);
00159         }
00160         ROS_INFO("\nConnected to DiagTCP Server....");
00161   }
00162   void disconnect_to_Server() {
00163         send_QUERY_to_server("CLOSE\r\n\r\n\r\n");
00164         close(sock);
00165         ROS_INFO("\nDisconnected from DiagTCP Server....");
00166   }
00167   void recieve_from_server() {
00168         bool receive_end = false;
00169         int total_chunk = 0;
00170         do {    bytes_recieved=recv(sock,recv_data_buff,1024,0);
00171                 memcpy(recv_data, recv_data_buff, bytes_recieved);
00172                 total_chunk+=bytes_recieved;
00173                 if(recv_data[total_chunk-3]=='\n' && recv_data[total_chunk-1]=='\n'){
00174                         receive_end = true;
00175                         recv_data[total_chunk] = '\0';
00176                         ROS_INFO("%s",recv_data);               
00177                 }
00178         }while(!receive_end);
00179 
00180   }
00181 
00182   void make_false_rule(tug_ist_diagnosis_msgs::SystemModelResult model) {
00183            char a[32];
00184            FALSE_RULES = "";
00185            for(int p=0;p<no_of_props;p++){
00186               FALSE_RULES.append(model.props[p].c_str());
00187               FALSE_RULES.append(",");
00188               FALSE_RULES.append(model.neg_prefix.c_str());
00189               FALSE_RULES.append(model.props[p].c_str());
00190               FALSE_RULES.append("->false.\r\n");
00191            }
00192            NUM_FALSE_RULES = no_of_props;
00193          
00194   }
00195   
00196   void make_SD_rules(tug_ist_diagnosis_msgs::SystemModelResult model){
00197            char a[32];
00198            sprintf(a, "%d", no_of_rules);
00199            std::string str="";
00200            str.append(a);
00201            str.append("\r\n\r\n");
00202            for(int r=0;r<no_of_rules;r++){
00203               str.append(model.rules[r].c_str());
00204               str.append(".\r\n"); 
00205            }
00206            str.append("\r\n\r\n");
00207            
00208            char* c=const_cast<char*>(str.data());
00209            send_SD_to_server(c);
00210            recieve_from_server();
00211            
00212   }
00213    void observationsCB(const tug_ist_diagnosis_msgs::ObservationsConstPtr & obs_msg){
00214                 this_time = clock();
00215                 for(int o=0;o<obs_msg->obs.size();o++){
00216                    std::string s = obs_msg->obs[o].c_str();
00217                    std::string ns = "@";
00218                    if(s.at(0)=='~'){ 
00219                        ns = s.substr(1);
00220                        s = neg_prefix + s.substr(1);
00221                    }else
00222                        ns = neg_prefix + s;
00223                  if (std::find(msg_list.begin(), msg_list.end(), s) != msg_list.end()){
00224                         // DO NOTHING 
00225                  } 
00226                  else {
00227                        msg_list.push_back(s);
00228                        std::vector<std::string>::iterator iter=std::find(msg_list.begin(), msg_list.end(), ns);
00229                        if(iter != msg_list.end())
00230                              msg_list.erase(iter);
00231                                         
00232                  }
00233                }// for loop
00234               
00235       char a[32];
00236       std::string str="";
00237       no_of_obs = msg_list.size();
00238       sprintf(a, "%d", no_of_obs + NUM_FALSE_RULES );
00239       str.append(a);
00240       str.append("\r\n\r\n");
00241       str.append(FALSE_RULES);
00242       for(int b=0;b<no_of_obs;b++){
00243            str.append(msg_list[b].c_str());
00244            str.append(".\r\n");
00245       }
00246       str.append("\r\n\r\n");
00247       time_counter += (double)(this_time - last_time);
00248       last_time = this_time;
00249       if(time_counter > (double)(NUM_SECONDS * CLOCKS_PER_SEC)){
00250         char* c=const_cast<char*>(str.data());
00251         send_OBS_to_server(c);
00252         recieve_from_server();
00253         callDiag();
00254         time_counter = 0;
00255       }
00256   }
00257 
00258   void modelCB(const tug_ist_diagnosis_msgs::SystemModelResultConstPtr & mdl_msg){
00259            disconnect_to_Server();
00260            connect_to_Server();
00261            no_of_rules = mdl_msg->rules.size();
00262            no_of_props = mdl_msg->props.size();
00263            neg_prefix = mdl_msg->neg_prefix.c_str();
00264            
00265            make_SD_rules(*mdl_msg);
00266            make_false_rule(*mdl_msg);          
00267            ROS_INFO("model received.........");
00268            getCOMP(*mdl_msg);
00269   }
00270   
00271   void spin(){
00272       while( nh_.ok() ){
00273          ros::spinOnce();
00274       }
00275   }
00276 
00277   void getCOMP(tug_ist_diagnosis_msgs::SystemModelResult model){
00278       size_t found_start, found_end;
00279       for(int r=0;r<no_of_rules;r++){
00280               std::string rule = model.rules[r].c_str();
00281               found_start = rule.find("->");
00282               found_end = rule.find(")");
00283               int limit = int(found_start);
00284               for (size_t i=0; i < limit; i++){
00285                 if(rule.at(i)=='('){
00286                    std::string comp = "";
00287                    for (size_t j=i+1; j < limit; j++){
00288                       if(rule.at(j)==')')
00289                            break;
00290                       comp+=rule.at(j);
00291                    }
00292                    if (std::find(comp_list.begin(), comp_list.end(), comp) != comp_list.end()){
00293                         // DO NOTHING 
00294                    }else
00295                        comp_list.push_back(comp);
00296                    
00297                 }
00298               }
00299        }
00300   }
00301 
00302   void publishDiag(vector<std::string> diag_vec){
00303        vector<tug_ist_diagnosis_msgs::DiagnosisResults> diag_results;
00304        tug_ist_diagnosis_msgs::DiagnosisResults diag_result;
00305        tug_ist_diagnosis_msgs::Diagnosis diagnosis;
00306        vector<std::string> good,bad;
00307        bool diag_found = false;
00308        for (int v=0; v<diag_vec.size(); v++){
00309          std::string diag = diag_vec[v].c_str();
00310          if(diag.length()>3){
00311                 diag_found = true;
00312                 for (int i=0; i<comp_list.size(); i++){
00313                         size_t found = diag.find(comp_list[i].c_str());
00314                         if(int(found)>-1){
00315                                 bad.push_back(comp_list[i].c_str());
00316                         }
00317                         else{
00318                                 good.push_back(comp_list[i].c_str());
00319                         }
00320                 }
00321                 diag_result.bad  = bad;
00322                 diag_result.good = good;
00323                 diag_results.push_back(diag_result);
00324                 bad.clear();
00325                 good.clear();
00326          }
00327       }
00328       if(!diag_found){
00329            for (int i=0; i<comp_list.size(); i++)
00330                   good.push_back(comp_list[i].c_str());
00331            diag_result.good = good;
00332            diag_results.push_back(diag_result);
00333 
00334       }
00335       diagnosis.o_time = ros::Time::now().toSec();
00336       diagnosis.diag = diag_results;
00337       diag_pub.publish(diagnosis);
00338   }
00339   void callDiag(){
00340       char *send_data = "GET sessionA MIN_DIAG\r\nUse-Fault-Modes: true\r\n\r\n\r\n";
00341       send_QUERY_to_server(send_data);
00342       recieve_from_server();
00343       vector<std::string> diag_vec;
00344       std::string diag;
00345       int i = 50;
00346       while(i<(bytes_recieved-6)){
00347           while(recv_data[i++]=='\r' || recv_data[i++]=='\n');
00348           diag = "";
00349           while(recv_data[i++]!='\r' || recv_data[i++]!='\n')
00350                   diag+=recv_data[i];
00351           diag_vec.push_back(diag.c_str());
00352       }
00353      publishDiag(diag_vec);
00354   }
00355 
00356 };
00357 
00358 
00359 
00360 int main(int argc, char** argv)
00361 
00362 {
00363   ros::init(argc, argv, "Diagnosis_Client_Node");
00364   ros::NodeHandle n;
00365   Diagnosis_Client *c = new Diagnosis_Client(n);
00366   c->spin();
00367   return 0;
00368 }
00369 


tug_ist_diagnosis_engine
Author(s): Safdar Zaman, Gerald Steinbauer
autogenerated on Mon Jan 6 2014 11:51:16