people_detection_action_client.cpp
Go to the documentation of this file.
00001 /****************************************************************
00002  *
00003  * Copyright (c) 2010
00004  *
00005  * Fraunhofer Institute for Manufacturing Engineering
00006  * and Automation (IPA)
00007  *
00008  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00009  *
00010  * Project name: care-o-bot
00011  * ROS stack name: cob_vision
00012  * ROS package name: cob_people_detection
00013  * Description:
00014  *
00015  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00016  *
00017  * Author: Richard Bormann, email:richard.bormann@ipa.fhg.de
00018  * Supervised by:
00019  *
00020  * Date of creation: 03/2011
00021  * ToDo:
00022  *
00023  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00024  *
00025  * Redistribution and use in source and binary forms, with or without
00026  * modification, are permitted provided that the following conditions are met:
00027  *
00028  *     * Redistributions of source code must retain the above copyright
00029  *       notice, this list of conditions and the following disclaimer.
00030  *     * Redistributions in binary form must reproduce the above copyright
00031  *       notice, this list of conditions and the following disclaimer in the
00032  *       documentation and/or other materials provided with the distribution.
00033  *     * Neither the name of the Fraunhofer Institute for Manufacturing
00034  *       Engineering and Automation (IPA) nor the names of its
00035  *       contributors may be used to endorse or promote products derived from
00036  *       this software without specific prior written permission.
00037  *
00038  * This program is free software: you can redistribute it and/or modify
00039  * it under the terms of the GNU Lesser General Public License LGPL as
00040  * published by the Free Software Foundation, either version 3 of the
00041  * License, or (at your option) any later version.
00042  *
00043  * This program is distributed in the hope that it will be useful,
00044  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00045  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00046  * GNU Lesser General Public License LGPL for more details.
00047  *
00048  * You should have received a copy of the GNU Lesser General Public
00049  * License LGPL along with this program.
00050  * If not, see <http://www.gnu.org/licenses/>.
00051  *
00052  ****************************************************************/
00053 
00054 //##################
00055 //#### includes ####
00056 
00057 // ROS includes
00058 #include <ros/ros.h>
00059 
00060 // Actions
00061 #include <actionlib/client/simple_action_client.h>
00062 #include <cob_people_detection/addDataAction.h>
00063 #include <cob_people_detection/updateDataAction.h>
00064 #include <cob_people_detection/deleteDataAction.h>
00065 #include <cob_people_detection/loadModelAction.h>
00066 #include <cob_people_detection/getDetectionsAction.h>
00067 
00068 // services
00069 #include <cob_people_detection/captureImage.h>
00070 #include <cob_people_detection/finishRecording.h>
00071 #include <cob_people_detection/recognitionTrigger.h>
00072 #include <std_srvs/Empty.h>
00073 
00074 // standard includes
00075 #ifdef __LINUX__
00076 #include <termios.h>
00077 
00078 int getch();
00079 
00080 int getch()
00081 {
00082         static int ch = -1, fd = 0;
00083         struct termios neu, alt;
00084         fd = fileno(stdin);
00085         tcgetattr(fd, &alt);
00086         neu = alt;
00087         neu.c_lflag &= ~(ICANON|ECHO);
00088         tcsetattr(fd, TCSANOW, &neu);
00089         ch = getchar();
00090         tcsetattr(fd, TCSANOW, &alt);
00091         return ch;
00092 }
00093 #endif
00094 
00095 //####################
00096 //#### node class ####
00097 
00098 typedef actionlib::SimpleActionClient<cob_people_detection::addDataAction> AddDataClient;
00099 typedef actionlib::SimpleActionClient<cob_people_detection::updateDataAction> UpdateDataClient;
00100 typedef actionlib::SimpleActionClient<cob_people_detection::deleteDataAction> DeleteDataClient;
00101 typedef actionlib::SimpleActionClient<cob_people_detection::loadModelAction> LoadModelClient;
00102 typedef actionlib::SimpleActionClient<cob_people_detection::getDetectionsAction> GetDetectionsClient;
00103 
00104 void addData(AddDataClient& add_data_client, ros::ServiceClient& capture_image_client, ros::ServiceClient& finish_recording_client)
00105 {
00106         cob_people_detection::addDataGoal goal;
00107 
00108         std::cout << "Input the label of the captured person: ";
00109         std::cin >> goal.label;
00110 
00111         std::cout << "Mode of data capture: 0=manual, 1=continuous: ";
00112         std::cin >> goal.capture_mode;
00113 
00114         if (goal.capture_mode == 1)
00115         {
00116                 std::cout << "How many images shall be captured automatically? ";
00117                 std::cin >> goal.continuous_mode_images_to_capture;
00118 
00119                 std::cout << "What is the desired delay time in seconds between two recordings? ";
00120                 std::cin >> goal.continuous_mode_delay;
00121         }
00122 
00123         // send goal to server
00124         add_data_client.sendGoal(goal);
00125         std::cout << "Recording job was sent to the server ..." << std::endl;
00126 
00127         // enable control in manual mode
00128         if (goal.capture_mode == 0)
00129         {
00130                 // wait for server to provide the capture and finish service
00131                 std::cout << "Waiting for the capture service to become available ..." << std::endl;
00132                 capture_image_client.waitForExistence();
00133                 finish_recording_client.waitForExistence();
00134 
00135                 // capture
00136                 std::cout << "Hit 'q' key to quit or 'c' key to capture an image.\n";
00137                 cob_people_detection::captureImageRequest capture_image_request;
00138                 cob_people_detection::captureImageResponse capture_image_response;
00139                 char key;
00140                 while ((key = getch()) != 'q')
00141                 {
00142                         if (key == 'c')
00143                         {
00144                                 printf("Image capture initiated ... \n");
00145                                 if (capture_image_client.call(capture_image_request, capture_image_response) == true)
00146                                         printf("   image %d successfully captured.\n", capture_image_response.number_captured_images);
00147                                 else
00148                                         printf("   image capture not successful.\n");
00149                         }
00150                 }
00151 
00152                 printf("Finishing recording ...\n");
00153 
00154                 // tell server to finish recording
00155                 cob_people_detection::finishRecording finish_recording;
00156                 finish_recording_client.call(finish_recording);
00157         }
00158 
00159         add_data_client.waitForResult();
00160 
00161         if (add_data_client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00162                 printf("Data recording finished successfully.\n");
00163         else
00164                 printf("Data recording did not finish successfully.\n");
00165 
00166         printf("Current State: %s   Message: %s\n", add_data_client.getState().toString().c_str(), add_data_client.getState().getText().c_str());
00167 }
00168 
00169 void updateData(UpdateDataClient& update_data_client)
00170 {
00171         cob_people_detection::updateDataGoal goal;
00172 
00173         std::cout << "Choose a mode for data update: 1=by index (changes exactly one entry), 2=by label (changes all entries with that label): ";
00174         std::cin >> goal.update_mode;
00175 
00176         if (goal.update_mode == 1)
00177         {
00178                 std::cout << "Enter the index of the database entry that shall be updated: ";
00179                 std::cin >> goal.update_index;
00180         }
00181         else if (goal.update_mode == 2)
00182         {
00183                 std::cout << "Enter the label of the database entries that shall be updated: ";
00184                 std::cin >> goal.old_label;
00185         }
00186         else
00187         {
00188                 std::cout << "Error: updateData: Wrong update_mode." << std::endl;
00189                 return;
00190         }
00191 
00192         std::cout << "Enter the new label that shall be assigned to the chosen data: ";
00193         std::cin >> goal.new_label;
00194 
00195         // send goal to server
00196         update_data_client.sendGoal(goal);
00197         std::cout << "Update job was sent to the server ..." << std::endl;
00198         update_data_client.waitForResult();
00199 
00200         if (update_data_client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00201                 printf("Data update finished successfully.\n");
00202         else
00203                 printf("Data update did not finish successfully.\n");
00204 
00205         printf("Current State: %s   Message: %s\n", update_data_client.getState().toString().c_str(), update_data_client.getState().getText().c_str());
00206 }
00207 
00208 void deleteData(DeleteDataClient& delete_data_client)
00209 {
00210         cob_people_detection::deleteDataGoal goal;
00211 
00212         std::cout << "Choose a mode for data deletion: 1=by index (deletes exactly one entry), 2=by label (deletes all entries with that label): ";
00213         std::cin >> goal.delete_mode;
00214 
00215         if (goal.delete_mode == 1)
00216         {
00217                 std::cout << "Enter the index of the database entry that shall be deleted: ";
00218                 std::cin >> goal.delete_index;
00219         }
00220         else if (goal.delete_mode == 2)
00221         {
00222                 std::cout << "Enter the label of the database entries that shall be deleted: ";
00223                 std::cin >> goal.label;
00224         }
00225         else
00226         {
00227                 std::cout << "Error: deleteData: Wrong delete_mode." << std::endl;
00228                 return;
00229         }
00230 
00231         // send goal to server
00232         delete_data_client.sendGoal(goal);
00233         std::cout << "Delete job was sent to the server ..." << std::endl;
00234         delete_data_client.waitForResult();
00235 
00236         if (delete_data_client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00237                 printf("Data deletion finished successfully.\n");
00238         else
00239                 printf("Data deletion did not finish successfully.\n");
00240 
00241         printf("Current State: %s   Message: %s\n", delete_data_client.getState().toString().c_str(), delete_data_client.getState().getText().c_str());
00242 }
00243 
00244 void loadRecognitionModel(LoadModelClient& load_model_client)
00245 {
00246         cob_people_detection::loadModelGoal goal;
00247 
00248         std::cout << "Enter the labels that should occur in the recognition model. By sending an empty list, all available data will be used." << std::endl;
00249         while (true)
00250         {
00251                 std::cout << "Enter label (finish by entering 'q'): ";
00252                 std::string label;
00253                 std::cin >> label;
00254 
00255                 if (label.compare("q") == 0)
00256                         break;
00257                 else
00258                         goal.labels.push_back(label);
00259         }
00260 
00261         // send goal to server
00262         load_model_client.sendGoal(goal);
00263         std::cout << "Recognition model is loaded by the server ..." << std::endl;
00264         std::cout << "\nA new recognition model is currently loaded or generated by the server. The following labels will be covered: " << std::endl;
00265         for (int i = 0; i < (int)goal.labels.size(); i++)
00266                 std::cout << "   - " << goal.labels[i] << std::endl;
00267 
00268         load_model_client.waitForResult();
00269 
00270         if (load_model_client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00271                 printf("The new recognition model has been successfully loaded.\n");
00272         else
00273                 printf("Loading a new recognition model was not successful.\n");
00274 
00275         printf("Current State: %s   Message: %s\n", load_model_client.getState().toString().c_str(), load_model_client.getState().getText().c_str());
00276 }
00277 
00278 void activateSensorMessageGateway(ros::ServiceClient& sensor_message_gateway_open_client, ros::ServiceClient& sensor_message_gateway_close_client)
00279 {
00280         int open_close = 0;
00281         std::cout << "Type 1 to activate or 2 to deactivate the sensor message gateway: ";
00282         std::cin >> open_close;
00283 
00284         if (open_close == 1)
00285         {
00286                 // activate
00287                 cob_people_detection::recognitionTriggerRequest req;
00288                 cob_people_detection::recognitionTriggerResponse res;
00289                 std::cout << "At which target frame rate (Hz) shall the sensor message gateway operate: ";
00290                 std::cin >> req.target_frame_rate;
00291 
00292                 if (sensor_message_gateway_open_client.call(req, res) == true)
00293                         printf("Gateway successfully opened.\n");
00294                 else
00295                         printf("Opening gateway was not successful.\n");
00296         }
00297         else if (open_close == 2)
00298         {
00299                 // deactivate
00300                 std_srvs::Empty rec;
00301                 if (sensor_message_gateway_close_client.call(rec) == true)
00302                         printf("Gateway successfully closed.\n");
00303                 else
00304                         printf("Closing gateway was not successful.\n");
00305         }
00306 }
00307 
00308 void getDetections(GetDetectionsClient& get_detections_client)
00309 {
00310         cob_people_detection::getDetectionsGoal goal;
00311 
00312         std::cout << "Enter a maximum age of the detection message (in seconds): ";
00313         std::cin >> goal.maximum_message_age;
00314 
00315         std::cout << "Enter the maximum waiting time to receive the message (in seconds): ";
00316         std::cin >> goal.timeout;
00317 
00318         // send goal to server
00319         get_detections_client.sendGoal(goal);
00320         std::cout << "Waiting for the server to send the detections ..." << std::endl;
00321         get_detections_client.waitForResult();
00322 
00323         if (get_detections_client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00324         {
00325                 cob_people_detection::getDetectionsResultConstPtr result = get_detections_client.getResult();
00326                 std::cout << "Received a detection message with " << result->detections.detections.size() << " detections.\nThe labels are" << std::endl;
00327                 for (int i = 0; i < (int)result->detections.detections.size(); i++)
00328                         std::cout << "   - " << result->detections.detections[i].label << std::endl;
00329         }
00330         else
00331                 std::cout << "No detections received.\n";
00332 
00333         printf("Current State: %s   Message: %s\n", get_detections_client.getState().toString().c_str(), get_detections_client.getState().getText().c_str());
00334 }
00335 
00336 int main(int argc, char** argv)
00337 {
00338         ros::init(argc, argv, "cob_people_detection_client");
00339 
00340         ros::NodeHandle nh;
00341 
00342         AddDataClient add_data_client("/cob_people_detection/face_capture/add_data_server", true); // true -> don't need ros::spin()
00343         ros::ServiceClient capture_image_client = nh.serviceClient<cob_people_detection::captureImage>("/cob_people_detection/face_capture/capture_image");
00344         ros::ServiceClient finish_recording_client = nh.serviceClient<cob_people_detection::finishRecording>("/cob_people_detection/face_capture/finish_recording");
00345         UpdateDataClient update_data_client("/cob_people_detection/face_capture/update_data_server", true);
00346         DeleteDataClient delete_data_client("/cob_people_detection/face_capture/delete_data_server", true);
00347         LoadModelClient load_model_client("/cob_people_detection/face_recognizer/load_model_server", true);
00348         GetDetectionsClient get_detections_client("/cob_people_detection/coordinator/get_detections_server", true);
00349         ros::ServiceClient sensor_message_gateway_open_client = nh.serviceClient<cob_people_detection::recognitionTrigger>("/cob_people_detection/coordinator/start_recognition");
00350         ros::ServiceClient sensor_message_gateway_close_client = nh.serviceClient<std_srvs::Empty>("/cob_people_detection/coordinator/stop_recognition");
00351 
00352         if (!add_data_client.waitForServer(ros::Duration(2.0)))
00353         {
00354                 std::cout << "No connection to server 'add_data_server'.\n";
00355                 return 0;
00356         }
00357         if (!update_data_client.waitForServer(ros::Duration(2.0)))
00358         {
00359                 std::cout << "No connection to server 'update_data_server'.\n";
00360                 return 0;
00361         }
00362         if (!delete_data_client.waitForServer(ros::Duration(2.0)))
00363         {
00364                 std::cout << "No connection to server 'delete_data_server'.\n";
00365                 return 0;
00366         }
00367         if (!load_model_client.waitForServer(ros::Duration(2.0)))
00368         {
00369                 std::cout << "No connection to server 'load_model_server'.\n";
00370                 return 0;
00371         }
00372         if (!get_detections_client.waitForServer(ros::Duration(2.0)))
00373         {
00374                 std::cout << "No connection to server 'get_detections_server'.\n";
00375                 return 0;
00376         }
00377 
00378         std::cout << "Connected to servers.\n";
00379 
00380         char key = 'q';
00381         do
00382         {
00383                 std::cout
00384                                 << "\n\nChoose an option:\n1 - capture face images\n2 - update database labels\n3 - delete database entries\n4 - load recognition model (necessary if new images/persons were added to the database)\n5 - activate/deactivate sensor message gateway\n6 - get detections\nq - Quit\n\n";
00385                 key = getch();
00386                 if (key == '1')
00387                         addData(add_data_client, capture_image_client, finish_recording_client);//train(trainContinuousClient, trainCaptureSampleClient);
00388                 else if (key == '2')
00389                         updateData(update_data_client);//recognize(recognizeClient);
00390                 else if (key == '3')
00391                         deleteData(delete_data_client);//train_continuous(trainContinuousClient, trainCaptureSampleClient);
00392                 else if (key == '4')
00393                         loadRecognitionModel(load_model_client);//show(showClient, 0);
00394                 else if (key == '5')
00395                         activateSensorMessageGateway(sensor_message_gateway_open_client, sensor_message_gateway_close_client);//show(showClient, 1);
00396                 else if (key == '6')
00397                         getDetections(get_detections_client);
00398         } while (key != 'q');
00399 
00400         return 0;
00401 }
00402 


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Fri Aug 28 2015 10:24:13