Project: engagement_generation License: BSD Dependencies:
Used by:
None |
engagement_generation/src/edu/wpi/hri/gen/comm/BMLEmitListener.javaGo 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 package edu.wpi.hri.gen.comm; 00035 00036 import java.util.ArrayList; 00037 import java.util.List; 00038 00039 import ros.NodeHandle; 00040 import ros.Publisher; 00041 import ros.RosException; 00042 import ros.ServiceClient; 00043 import ros.Subscriber; 00044 import ros.Subscriber.Callback; 00045 import ros.pkg.bml_msgs.msg.BMLEmit; 00046 import ros.pkg.bml_msgs.msg.Entity; 00047 import ros.pkg.bml_msgs.msg.Flag; 00048 import ros.pkg.engagement_srvs.srv.RobotDirectedGaze; 00049 import ros.pkg.engagement_srvs.srv.RobotMutualFacialGaze; 00050 import edu.wpi.hri.bml.behavior.Behavior; 00051 import edu.wpi.hri.bml.behavior.EmitBehavior; 00052 import edu.wpi.hri.bml.behavior.EmitBehavior.EventBehavior; 00053 import edu.wpi.hri.bml.behavior.SyncRef; 00054 import edu.wpi.hri.bml.behavior.SyncRef.SyncPoint; 00055 import edu.wpi.hri.gen.GenerationParams; 00056 import edu.wpi.hri.log.Logger; 00057 import edu.wpi.hri.log.Logger.Colors; 00058 import edu.wpi.hri.log.Logger.LoggerLevel; 00059 00070 public class BMLEmitListener implements Callback<BMLEmit> { 00071 00072 private final Logger logger; 00073 private int emitCounter; 00074 private final List<Thread> threads; 00075 private final ServiceClient<RobotDirectedGaze.Request, RobotDirectedGaze.Response, RobotDirectedGaze> dgsrv; 00076 private final ServiceClient<RobotMutualFacialGaze.Request, RobotMutualFacialGaze.Response, RobotMutualFacialGaze> mfgsrv; 00077 private final Subscriber<BMLEmit> emitSub; 00078 private final Publisher<ros.pkg.bml_msgs.msg.Behavior> endEmit; 00079 00095 public BMLEmitListener(NodeHandle handle, Logger logger) 00096 throws RosException { 00097 this.logger = logger.sub(Colors.BML, "EMIT"); 00098 this.threads = new ArrayList<Thread>(); 00099 00100 this.dgsrv = handle.serviceClient( 00101 GenerationParams.ROBOT_DG_PATH.getString(), 00102 new RobotDirectedGaze()); 00103 this.mfgsrv = handle.serviceClient( 00104 GenerationParams.ROBOT_MFG_PATH.getString(), 00105 new RobotMutualFacialGaze()); 00106 this.emitSub = handle.subscribe( 00107 GenerationParams.BML_EMIT_PATH.getString(), new BMLEmit(), 00108 this, 100); 00109 this.endEmit = handle.advertise("bml/end_emit", 00110 new ros.pkg.bml_msgs.msg.Behavior(), 100); 00111 this.logger.debug(LoggerLevel.INIT, "Created ..."); 00112 } 00113 00117 public void shutdown() { 00118 this.emitSub.shutdown(); 00119 waitForEnd(); 00120 this.dgsrv.shutdown(); 00121 this.mfgsrv.shutdown(); 00122 } 00123 00127 public void waitForEnd() { 00128 while (threads.size() > 0) { 00129 try { 00130 threads.get(0).join(); 00131 threads.remove(0); 00132 } catch (InterruptedException e) { 00133 logger.debug(LoggerLevel.ALL, 00134 "Failed to wait for end of connection event"); 00135 } 00136 } 00137 } 00138 00154 private void robotDG(final ros.pkg.bml_msgs.msg.Behavior behav, 00155 final String actor, final String[] objects) { 00156 logger.debug(LoggerLevel.POLICY_EXECUTION, "Starting Directed Gaze: " 00157 + behav.id); 00158 Thread t = new Thread() { 00159 public void run() { 00160 // create the request 00161 RobotDirectedGaze.Request req = new RobotDirectedGaze.Request(); 00162 req.actor.id = actor; 00163 req.done.value = Flag.NOT_DONE; 00164 req.objects = new ArrayList<Entity>(); 00165 for (String obj : objects) { 00166 Entity ent = new Entity(); 00167 ent.id = obj; 00168 ent.type = Entity.UNKNOWN; 00169 req.objects.add(ent); 00170 } 00171 00172 try { 00173 dgsrv.call(req); 00174 logger.debug(LoggerLevel.IO, "finished DG: " + behav.id); 00175 endEmit.publish(behav); 00176 } catch (RosException e) { 00177 logger.printThrowable(LoggerLevel.IO, e); 00178 } 00179 } 00180 }; 00181 t.start(); 00182 this.threads.add(t); 00183 } 00184 00197 private void robotMFG(final ros.pkg.bml_msgs.msg.Behavior behav, 00198 final String actor) { 00199 logger.debug(LoggerLevel.POLICY_EXECUTION, 00200 "Starting Mutual Facial Gaze: " + behav.id); 00201 Thread t = new Thread() { 00202 public void run() { 00203 // create the request 00204 RobotMutualFacialGaze.Request req = new RobotMutualFacialGaze.Request(); 00205 req.actor.id = actor; 00206 try { 00207 mfgsrv.call(req); 00208 logger.debug(LoggerLevel.IO, "finished MFG: " + behav.id); 00209 endEmit.publish(behav); 00210 } catch (RosException e) { 00211 logger.printThrowable(LoggerLevel.IO, e); 00212 } 00213 } 00214 }; 00215 t.start(); 00216 this.threads.add(t); 00217 } 00218 00219 @Override 00220 public void call(BMLEmit emit) { 00221 String[] tokens = emit.body.split(","); 00222 if (tokens[0].trim().equalsIgnoreCase("DG")) { 00223 String[] objects = new String[tokens.length - 2]; 00224 for (int c = 2; c < tokens.length; c++) 00225 objects[c - 2] = tokens[c]; 00226 00227 this.robotDG(emit.behavior, tokens[1].trim(), objects); 00228 } else if (tokens[0].trim().equalsIgnoreCase("MFG")) { 00229 this.robotMFG(emit.behavior, tokens[1].trim()); 00230 } 00231 } 00232 00246 public EmitBehavior createMFGEmit(String actor, Behavior source) { 00247 String emitID = "mfg-emit-" + this.emitCounter; 00248 EmitBehavior emit = new EmitBehavior(logger, emitID, new SyncRef( 00249 source, SyncPoint.START, 0.0), new EventBehavior(logger, 00250 "mfg-event-" + this.emitCounter, "MFG," + actor), false); 00251 this.emitCounter++; 00252 return emit; 00253 } 00254 00273 public EmitBehavior createDGEmit(String actor, String[] targets, 00274 Behavior source, boolean required) { 00275 String emitID = "dg-emit-" + this.emitCounter; 00276 String tars = ""; 00277 00278 for (int c = 0; c < targets.length - 1; c++) 00279 tars += targets[c] + ","; 00280 tars += targets[targets.length - 1]; 00281 00282 EmitBehavior emit = new EmitBehavior(logger, emitID, new SyncRef( 00283 source, SyncPoint.START, 0.0), new EventBehavior(logger, 00284 "dg-event-" + this.emitCounter, "DG," + actor + "," + tars), 00285 required); 00286 this.emitCounter++; 00287 return emit; 00288 } 00289 } |