Project: engagement_recognition License: BSD Dependencies:
Used by:
None |
engagement_recognition/src/recognition/actors/actor.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 "actor.h" 00036 00037 // Include ROS and the objects file 00038 #include <ros/ros.h> 00039 #include "../objects/engagement_objects.h" 00040 #include "../lib/engagement_params.h" 00041 00042 Actor::~Actor() 00043 { 00044 // Delete the statistics 00045 delete this->statistics_; 00046 00047 // Delete this actor's handler 00048 if (this->handler_) 00049 delete this->handler_; 00050 00051 // Delete all the semaphores 00052 delete this->semaphore_; 00053 } 00054 00055 Actor::Actor() 00056 { 00057 // Create the prefix for the logger 00058 std::string prefix = std::string(EngagementParams::getRecogTag()) + 00059 std::string(EngagementParams::getActorTag(engagement::ACTOR_TYPE)); 00060 00061 // Create the logger for the actor off of the RNode logger 00062 this->setLogger(prefix); 00063 00064 this->createSemaphores(); 00065 00066 this->id_ = std::string(""); 00067 this->engaged_ = false; 00068 this->facial_gaze_ = false; // true; 00069 this->speaking_ = false; 00070 this->looking_ = std::vector<std::string>(); 00071 this->pointing_ = std::vector<std::string>(); 00072 this->handler_ = NULL; 00073 00074 // Set up the timeline 00075 this->statistics_ = new Timeline(); 00076 } 00077 00078 Actor::Actor(std::string id) 00079 { 00080 // Create the prefix for the logger 00081 std::string prefix = std::string(EngagementParams::getRecogTag()) + 00082 std::string(EngagementParams::getActorTag(id)); 00083 00084 // Create the logger for the actor off of the RNode logger 00085 this->setLogger(prefix); 00086 00087 this->createSemaphores(); 00088 00089 this->id_ = std::string(id); 00090 this->engaged_ = false; 00091 this->facial_gaze_ = false; // true; 00092 this->speaking_ = false; 00093 this->looking_ = std::vector<std::string>(); 00094 this->pointing_ = std::vector<std::string>(); 00095 this->handler_ = NULL; 00096 00097 // Set up the timeline 00098 this->statistics_ = new Timeline(); 00099 } 00100 00101 void Actor::createSemaphores() 00102 { 00103 this->semaphore_ = new Semaphore(1); 00104 } 00105 00106 00107 void Actor::updateDirGazeRecognizers(std::vector<std::string> objects) 00108 { 00109 // Traverse all the objects, and update the handler with each 00110 // of the objects 00111 for (unsigned c = 0; c < objects.size(); c++) 00112 this->handler_->updateDirectedGazeRecognizer(objects.at(c)); 00113 } 00114 00115 void Actor::received(std::string topic, ros::Message *message) 00116 { 00117 this->handler_->received(topic, message); 00118 } 00119 00120 ServiceResponse Actor::dirGazeService(ros::Message *message, 00121 std::vector<std::string> objects) 00122 { 00123 return this->handler_->dirGazeService(message, objects); 00124 } 00125 00126 ServiceResponse Actor::mfGazeService(ros::Message *message) 00127 { 00128 return this->handler_->mfGazeService(message); 00129 } 00130 00131 APServiceResponse Actor::adjPairService(ros::Message *message) 00132 { 00133 return this->handler_->adjPairService(message); 00134 } 00135 00136 void Actor::setHandler(Handler *handler) 00137 { 00138 // Free the current copy before changing it 00139 if (this->handler_) 00140 delete this->handler_; 00141 00142 // Use the new handler 00143 this->handler_ = handler; 00144 } 00145 00146 Handler *Actor::getHandler() 00147 { 00148 return this->handler_; 00149 } 00150 00151 void Actor::setEngaged(bool engaged) 00152 { 00153 this->semaphore_->wait(); 00154 this->engaged_ = engaged; 00155 this->semaphore_->post(); 00156 } 00157 00158 bool Actor::getEngaged() 00159 { 00160 this->semaphore_->wait(); 00161 bool temp = this->engaged_; 00162 this->semaphore_->post(); 00163 00164 return temp; 00165 } 00166 00167 std::string Actor::getID() 00168 { 00169 // Return the Actor's id 00170 return this->id_; 00171 } 00172 00173 bool Actor::isFacialGaze() 00174 { 00175 this->semaphore_->wait(); 00176 bool temp = this->facial_gaze_; 00177 this->semaphore_->post(); 00178 00179 // Return if the actor is making facial gaze 00180 return temp; 00181 } 00182 00183 bool Actor::isSpeaking() 00184 { 00185 this->semaphore_->wait(); 00186 bool temp = this->speaking_; 00187 this->semaphore_->post(); 00188 00189 // Return if the actor is making facial gaze 00190 return temp; 00191 } 00192 00193 bool Actor::isLooking(std::vector<std::string> objects) 00194 { 00195 this->semaphore_->wait(); 00196 std::vector<std::string> temp = this->looking_; 00197 this->semaphore_->post(); 00198 00199 // Return if the set of objects are identical 00200 return objects::same(temp, objects); 00201 } 00202 00203 bool Actor::isPointing(std::vector<std::string> objects) 00204 { 00205 this->semaphore_->wait(); 00206 std::vector<std::string> temp = this->pointing_; 00207 this->semaphore_->post(); 00208 00209 // return if the set of objects are identical 00210 return objects::same(temp, objects); 00211 } 00212 00213 std::vector<std::string> Actor::getLooking() 00214 { 00215 this->semaphore_->wait(); 00216 std::vector<std::string> temp = this->looking_; 00217 this->semaphore_->post(); 00218 00219 // Return the vector of objects being looked at 00220 return temp; 00221 } 00222 00223 std::vector<std::string> Actor::getPointing() 00224 { 00225 this->semaphore_->wait(); 00226 std::vector<std::string> temp = this->pointing_; 00227 this->semaphore_->post(); 00228 00229 // Return the vector of object being pointed at 00230 return temp; 00231 } 00232 00233 bool Actor::setFacialGaze(bool start) 00234 { 00235 this->semaphore_->wait(); 00236 bool temp = this->facial_gaze_; 00237 this->semaphore_->post(); 00238 00239 // Make sure the facial gaze is not currently in the same state 00240 if (temp != start) 00241 { 00242 // Update the Actor's facial gaze flag 00243 this->semaphore_->wait(); 00244 this->facial_gaze_ = start; 00245 this->semaphore_->post(); 00246 00247 this->debug(9, "Updated actor [%s]'s facial gaze [%s].", 00248 this->id_.c_str(), (start ? "true" : "false")); 00249 00250 return true; 00251 } 00252 00253 this->warn("Actor [%s]'s already in [%s] facial gaze state.", 00254 this->id_.c_str(), 00255 (this->facial_gaze_ ? "true" : "false")); 00256 00257 return false; 00258 } 00259 00260 bool Actor::setSpeaking(bool start) 00261 { 00262 this->semaphore_->wait(); 00263 bool temp = this->speaking_; 00264 this->semaphore_->post(); 00265 00266 // Make sure the speaking is not trying to move to the same state 00267 // if speaking cannot start, if not speaking cannot end 00268 if (temp != start) 00269 { 00270 // Update the Actor's speaking flag 00271 this->semaphore_->wait(); 00272 this->speaking_ = start; 00273 this->semaphore_->post(); 00274 00275 this->debug(9, "Updated actor [%s]'s speaking.", 00276 this->id_.c_str()); 00277 00278 return true; 00279 } 00280 00281 this->warn("Actor [%s]'s already in [%s] speaking state.", 00282 this->id_.c_str(), (start ? "start" : "stop")); 00283 00284 return false; 00285 } 00286 00287 bool Actor::setLooking(std::vector<std::string> objects, bool start) 00288 { 00289 // Determine if looking is starting or ending 00290 if (start) 00291 { 00292 this->semaphore_->wait(); 00293 std::vector<std::string> temp = this->looking_; 00294 this->semaphore_->post(); 00295 00296 // We're adding the objects, so ensure that they do 00297 // not already exist (intersection should be the null set) 00298 if (!objects::intersect(temp, objects)) 00299 { 00300 // The objects do not exist yet, add them 00301 // Loop through the new objects vector 00302 for (unsigned i = 0; i < objects.size(); i++) 00303 { 00304 // Push the new object onto the back of the vector 00305 temp.push_back(objects.at(i)); 00306 00307 this->debug(9, "Actor [%s] looking at '%s'", this->id_.c_str(), 00308 objects.at(i).c_str()); 00309 } 00310 00311 this->semaphore_->wait(); 00312 this->looking_ = temp; 00313 this->semaphore_->post(); 00314 00315 return true; 00316 } 00317 } 00318 else 00319 { 00320 this->semaphore_->wait(); 00321 std::vector<std::string> temp = this->looking_; 00322 this->semaphore_->post(); 00323 00324 // We're removing the objects, so ensure that they exist (contains is true) 00325 if (objects::contains(temp, objects)) 00326 { 00327 // Remove the objects from the looking vector 00328 // Loop through the objects vector 00329 for (unsigned i = 0; i < objects.size(); i++) 00330 { 00331 // Loop through the looking vector 00332 for (unsigned j = 0; j < temp.size(); j++) 00333 { 00334 // Compare the two objects 00335 if (objects.at(i) == temp.at(j)) 00336 { 00337 // Remove the object from the first vector 00338 temp.erase(temp.begin() + j); 00339 00340 this->debug(9, "Actor [%s] stopped looking at '%s'.", this->id_.c_str(), 00341 objects.at(i).c_str()); 00342 break; 00343 } 00344 } 00345 } 00346 00347 this->semaphore_->wait(); 00348 this->looking_ = temp; 00349 this->semaphore_->post(); 00350 00351 return true; 00352 } 00353 } 00354 00355 this->warn("Actor [%s] %s looking at these objects.", 00356 this->id_.c_str(), 00357 (start ? "is already" : "is already not")); 00358 00359 return false; 00360 } 00361 00362 bool Actor::setPointing(std::vector<std::string> objects, bool start) 00363 { 00364 // Determine if pointing is starting or ending 00365 if (start) 00366 { 00367 this->semaphore_->wait(); 00368 std::vector<std::string> temp = this->pointing_; 00369 this->semaphore_->post(); 00370 00371 // We're adding the objects, so ensure that they do 00372 // not already exist (intersection should be the null set) 00373 if (!objects::intersect(temp, objects)) 00374 { 00375 // The objects do not exist yet, add them 00376 // Loop through the new objects vector 00377 for (unsigned i = 0; i < objects.size(); i++) 00378 { 00379 // Push the new object onto the back of the vector 00380 temp.push_back(objects.at(i)); 00381 00382 this->debug(9, "Actor [%s] pointing at '%s'", this->id_.c_str(), 00383 objects.at(i).c_str()); 00384 } 00385 00386 this->semaphore_->wait(); 00387 this->pointing_ = temp; 00388 this->semaphore_->post(); 00389 00390 return true; 00391 } 00392 } 00393 else 00394 { 00395 this->semaphore_->wait(); 00396 std::vector<std::string> temp = this->pointing_; 00397 this->semaphore_->post(); 00398 00399 // We're removing the objects, so ensure that they exist (contains is true) 00400 if (objects::contains(temp, objects)) 00401 { 00402 // Remove the objects from the pointing vector 00403 // Loop through the objects vector 00404 for (unsigned i = 0; i < objects.size(); i++) 00405 { 00406 // Loop through the pointing vector 00407 for (unsigned j = 0; j < temp.size(); j++) 00408 { 00409 // Compare the two objects 00410 if (objects.at(i) == temp.at(j)) 00411 { 00412 // Remove the object from the first vector 00413 temp.erase(temp.begin() + j); 00414 00415 this->debug(9, "Actor [%s] stopped pointing at '%s'.", 00416 this->id_.c_str(), objects.at(i).c_str()); 00417 break; 00418 } 00419 } 00420 } 00421 00422 this->semaphore_->wait(); 00423 this->pointing_ = temp; 00424 this->semaphore_->post(); 00425 00426 return true; 00427 } 00428 } 00429 00430 this->warn("Actor [%s] %s pointing at these objects.", 00431 this->id_.c_str(), 00432 (start ? "is already" : "is already not")); 00433 00434 return false; 00435 } 00436 00437 void Actor::addEvent(std::string type, bool success, unsigned long start, 00438 unsigned long delay, unsigned long duration, 00439 std::string data) 00440 { 00441 // Add the event to the statistics 00442 this->statistics_->addEvent(type, success, start, delay, duration, data); 00443 } 00444 00445 std::vector<unsigned long> Actor::getStatistics() 00446 { 00447 this->semaphore_->wait(); 00448 00449 // Grab the overall mean and max TBCE 00450 unsigned long mean_tbce = this->statistics_->getMeanTBCE(); 00451 unsigned long max_tbce = this->statistics_->getMaxTBCE(); 00452 00453 // Grab the recent mean and max TBCE 00454 unsigned long recent_mean_tbce = this->statistics_->getRecentMeanTBCE(); 00455 unsigned long recent_max_tbce = this->statistics_->getRecentMaxTBCE(); 00456 00457 // Grab the overall mean and max delay 00458 unsigned long mean_delay = this->statistics_->getMeanDelay(); 00459 unsigned long max_delay = this->statistics_->getMaxDelay(); 00460 00461 // Grab the overall mean and max duration 00462 unsigned long mean_duration = this->statistics_->getMeanDuration(); 00463 unsigned long max_duration = this->statistics_->getMaxDuration(); 00464 00465 // Grab the recent mean and max delay 00466 unsigned long recent_mean_delay = this->statistics_->getRecentMeanDelay(); 00467 unsigned long recent_max_delay = this->statistics_->getRecentMaxDelay(); 00468 00469 // Grab the overall and recent event failure rate 00470 unsigned long failure_rate = this->statistics_->getFailureRate(); 00471 unsigned long recent_failure_rate = this->statistics_->getRecentFailureRate(); 00472 00473 // Grab the recent mean and max duration 00474 unsigned long recent_mean_duration = this->statistics_->getRecentMeanDuration(); 00475 unsigned long recent_max_duration = this->statistics_->getRecentMaxDuration(); 00476 00477 this->semaphore_->post(); 00478 00479 // Store the statistics into a vector 00480 std::vector<unsigned long> stats; 00481 stats.push_back(mean_tbce); 00482 stats.push_back(max_tbce); 00483 stats.push_back(mean_delay); 00484 stats.push_back(max_delay); 00485 stats.push_back(mean_duration); 00486 stats.push_back(max_duration); 00487 stats.push_back(failure_rate); 00488 stats.push_back(recent_mean_tbce); 00489 stats.push_back(recent_max_tbce); 00490 stats.push_back(recent_mean_delay); 00491 stats.push_back(recent_max_delay); 00492 stats.push_back(recent_mean_duration); 00493 stats.push_back(recent_max_duration); 00494 stats.push_back(recent_failure_rate); 00495 00496 // Return the vector of statistics 00497 return stats; 00498 } |