00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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 }
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
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