Project: engagement_recognition License: BSD Dependencies:
Used by:
None |
engagement_recognition/src/recognition/handlers/engagement_handler.cppGo to the documentation of this file.00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2010, Worcester Polytechnic Institute 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Worcester Polytechnic Institute. nor the names 00018 * of its contributors may be used to endorse or promote products 00019 * derived from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 // @author Brett Ponsler (bponsler (at) wpi (dot) edu) 00035 #include "engagement_handler.h" 00036 00037 // Include the boost thread library 00038 #include <boost/thread.hpp> 00039 00040 // Include the recognizer factory 00041 #include "../recognizers/recognizer_factory.h" 00042 00043 EngagementHandler::EngagementHandler() : 00044 Handler() 00045 { 00046 // Cast ourselves into an EventSink 00047 EventSink *sink = (EventSink*)this; 00048 00049 Recognizer *mfg = 00050 RecognizerFactory::createMutualFacialGazeRecognizer(NULL, sink); 00051 Recognizer *ap = 00052 RecognizerFactory::createAdjacencyPairRecognizer(NULL, sink); 00053 Recognizer *bc = 00054 RecognizerFactory::createBackchannelRecognizer(NULL, sink); 00055 00056 // Add the three concrete recognizers to the vector 00057 this->setMutualFacialGazeRecognizer(mfg); 00058 this->setAdjacencyPairRecognizer(ap); 00059 this->setBackchannelRecognizer(bc); 00060 } 00061 00062 EngagementHandler::EngagementHandler(std::string actor, EventSink *parent) : 00063 Handler(actor, parent) 00064 { 00065 // Cast ourselves into an EventSink 00066 EventSink *sink = (EventSink*)this; 00067 00068 // Create the three concrete recognizers 00069 // Use the given actor for each of the Recognizers 00070 Recognizer *mfg = 00071 RecognizerFactory::createMutualFacialGazeRecognizer(actor, sink); 00072 Recognizer *ap = 00073 RecognizerFactory::createAdjacencyPairRecognizer(actor, sink); 00074 Recognizer *bc = 00075 RecognizerFactory::createBackchannelRecognizer(actor, sink); 00076 00077 // Add the three concrete recognizers to the vector 00078 this->setMutualFacialGazeRecognizer(mfg); 00079 this->setAdjacencyPairRecognizer(ap); 00080 this->setBackchannelRecognizer(bc); 00081 } 00082 00083 void EngagementHandler::castEvent(Event event) 00084 { 00085 // Add the event to the actor's timeline, before casting it up 00086 this->addEvent(event); 00087 00088 // Cast the event up the parent chain 00089 if (this->parent_ != NULL) 00090 this->parent_->castEvent(event); 00091 } 00092 00093 bool EngagementHandler::compareAdditional(std::vector<std::string> additional, 00094 std::string compare) 00095 { 00096 // There is no need to compare additional information for this handler 00097 return false; 00098 } 00099 00100 void EngagementHandler::updateDirectedGazeRecognizer(std::string object) 00101 { 00102 // Try to find the directed gaze recognizer associated with this object 00103 Recognizer *dg = this->getDirectedGazeRecognizer(object); 00104 00105 // If no recognizer exists, we need to create one 00106 if (dg == NULL) 00107 { 00108 // Create the new recognizer 00109 Recognizer *dg = 00110 RecognizerFactory::createDirectedGazeRecognizer(this->getActor(), 00111 object, 00112 (EventSink*)this); 00113 00114 // Add a new recognizer for this object 00115 this->addDirectedGazeRecognizer(dg); 00116 } 00117 } 00118 00119 ServiceResponse EngagementHandler::dirGazeService(ros::Message *message, 00120 std::vector<std::string> objects) 00121 { 00122 // Create a new boost barrier (add one to include the current thread) 00123 boost::barrier barrier(objects.size() + 1); 00124 std::vector<Recognizer*> recognizers = std::vector<Recognizer*>(); 00125 00126 // Traverse the number of objects given 00127 for (unsigned d = 0; d < objects.size(); d++) 00128 { 00129 // First update the recognizers to make sure we have one for this object 00130 this->updateDirectedGazeRecognizer(objects.at(d)); 00131 00132 // Grab the current directed gaze recognizer 00133 Recognizer *dg = this->getDirectedGazeRecognizer(objects.at(d)); 00134 00135 // If the objects are the same, then call the directed gaze service for 00136 // this recognizer 00137 if (dg != NULL) 00138 { 00139 // Add the recognizer to the vector of used recognizers 00140 recognizers.push_back(dg); 00141 00142 dg->debug(15, "Calling service on new thread."); 00143 00144 // Create the new thread to call the service 00145 boost::thread thread(boost::bind(&Recognizer::callService, dg, 00146 &barrier)); 00147 } 00148 00149 // Send the message to all the recognizers 00150 this->received(engagement::RECOGNITION_NAMESPACE + "/" + 00151 engagement::ROBOT_NAMESPACE + "/" + 00152 engagement::RECOG_DIRECTED_GAZE_TOPIC, message); 00153 } 00154 00155 // The barrier will wait until ALL the threads are finished 00156 barrier.wait(); 00157 00158 // Now that all the threads have completed, determine if any 00159 // of the events succeeded 00160 bool successful = false; 00161 00162 // Traverse the number of objects given, so long as we're not successful 00163 for (unsigned d = 0; !successful && d < recognizers.size(); d++) 00164 { 00165 // Grab the current recognizer 00166 Recognizer *dg = recognizers.at(d); 00167 00168 // Make sure the recognizer exists, and grab its status 00169 if (dg != NULL) 00170 { 00171 // Grab the status for this recognizer 00172 ServiceResponse response = dg->getStatus(); 00173 00174 dg->debug(15, "Passed the service barrier [%s]", 00175 (response.isSucceeded() ? "SUCCEEDED" : "FAILED")); 00176 00177 // If any single recognizer completes we want to complete 00178 successful = successful || (response.isSucceeded()); 00179 } 00180 } 00181 00182 // Return the status depending on if any of the calls succeeded 00183 return (successful ? ServiceResponse::succeeded() 00184 : ServiceResponse::failed()); 00185 } 00186 00187 ServiceResponse EngagementHandler::mfGazeService(ros::Message *message) 00188 { 00189 // Create a barrier (2 due to this thread, and the one we create) 00190 boost::barrier barrier(2); 00191 00192 // Grab our mutual facial gaze recognizer 00193 Recognizer *rec = this->getMutualFacialGazeRecognizer(); 00194 00195 // Make sure that we have a recognizer 00196 if (rec == NULL) 00197 { 00198 // Create a new mutual facial gaze recognizer 00199 rec = 00200 RecognizerFactory::createMutualFacialGazeRecognizer(this->getActor(), 00201 this->parent_); 00202 00203 // Set our mutual facial gaze recognizer to this recognizer 00204 this->setMutualFacialGazeRecognizer(rec); 00205 } 00206 00207 rec->debug(15, "Calling service on new thread."); 00208 00209 // Now call the specific mutual facial gaze recognizer to block 00210 boost::thread thread(boost::bind(&Recognizer::callService, rec, 00211 &barrier)); 00212 00213 // Send this message through to all the recognizers 00214 this->received(engagement::RECOGNITION_NAMESPACE + "/" + 00215 engagement::ROBOT_NAMESPACE + "/" + 00216 engagement::RECOG_MUTUAL_FACIAL_GAZE_TOPIC, message); 00217 00218 // Wait for the recognizer to complete before continuing 00219 barrier.wait(); 00220 00221 // Grab the status of the recognizer 00222 ServiceResponse response = rec->getStatus(); 00223 00224 rec->debug(15, "Passed service barrier [%s]", 00225 (response.isSucceeded() ? "SUCCEEDED" : "FAILED")); 00226 00227 return response; 00228 } 00229 00230 APServiceResponse EngagementHandler::adjPairService(ros::Message *message) 00231 { 00232 // Create a barrier (2 due to this thread, and the one we create) 00233 boost::barrier barrier(2); 00234 00235 // Get the adjacency pair recognizer 00236 Recognizer *rec = this->getAdjacencyPairRecognizer(); 00237 00238 // Make sure we have an adjacency pair recognizers 00239 if (rec == NULL) 00240 { 00241 // Create a new adjacency pair recognizer 00242 rec = 00243 RecognizerFactory::createAdjacencyPairRecognizer(this->getActor(), 00244 this->parent_); 00245 00246 // Set our mutual facial gaze recognizer to this recognizer 00247 this->setAdjacencyPairRecognizer(rec); 00248 } 00249 00250 rec->debug(15, "Calling service on new thread."); 00251 00252 // Now call the specific adjacency pair recognizer to block 00253 boost::thread thread(boost::bind(&Recognizer::callService, rec, 00254 &barrier)); 00255 00256 // Send this message through to all the recognizers 00257 this->received(engagement::RECOGNITION_NAMESPACE + "/" + 00258 engagement::ROBOT_NAMESPACE + "/" + 00259 engagement::RECOG_ADJACENCY_PAIR_TOPIC, message); 00260 00261 // Wait for the recognizer to complete before continuing 00262 barrier.wait(); 00263 00264 // Grab the status of the recognizer 00265 APServiceResponse response = APServiceResponse::cycle(); 00266 00267 // Grab the action from the recognizer 00268 Action act = rec->getAction(); 00269 00270 // Select the appropriate action 00271 if (act.isNod()) 00272 response.setNod(); 00273 else if (act.isShake()) 00274 response.setShake(); 00275 else if (act.isSpeech()) 00276 response.setSpeech(); 00277 else if (act.isPoint()) 00278 response.setPoint(); 00279 else if (act.isLook()) 00280 response.setLook(); 00281 else if (act.isExtendedAction()) 00282 response.setExtendedAction(); 00283 else 00284 response.setNoAction(); 00285 00286 // Set the status from the recognizer 00287 response.set(rec->getStatus()); 00288 response.setData(act.getData()); 00289 00290 rec->debug(15, "Passed service barrier [%s] [%s]", 00291 (response.isSucceeded() ? "SUCCEEDED" : "FAILED"), 00292 act.toString()); 00293 00294 return response; 00295 } |