Project: engagement_generation License: BSD Dependencies:
Used by:
None |
engagement_generation/src/edu/wpi/hri/gen/comm/GazeKnowledge.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.Subscriber; 00043 import ros.pkg.engagement_msgs.msg.ActorID; 00044 import ros.pkg.bml_msgs.msg.Entity; 00045 import ros.pkg.bml_msgs.msg.Flag; 00046 import ros.pkg.engagement_msgs.msg.Performance; 00047 import edu.wpi.hri.bml.XMLInterface; 00048 import edu.wpi.hri.bml.behavior.GazeBehavior; 00049 import edu.wpi.hri.gen.ebml.EBMLList; 00050 import edu.wpi.hri.log.Logger; 00051 import edu.wpi.hri.log.Logger.Colors; 00052 import edu.wpi.hri.log.Logger.LoggerLevel; 00053 00065 public class GazeKnowledge extends GazeListener implements 00066 ros.Subscriber.Callback<Performance> { 00067 00068 private final Subscriber<Flag> gazeLockSub; 00069 private final Subscriber<Performance> lookSub; 00070 private final Publisher<Entity> triedPub; 00071 00072 private final Logger logger; 00073 private String target; 00074 private boolean locked; 00075 private final List<GazeListener> listeners; 00076 private GazeListener bottomListener; 00077 private final XMLInterface xml; 00078 private final BMLRealizer realizer; 00079 00095 public GazeKnowledge(NodeHandle handle, Logger logger, XMLInterface xml, 00096 BMLRealizer realizer) throws RosException { 00097 super(null); 00098 this.logger = logger.sub(Colors.GAZE_KNOWLEDGE, "GAZE"); 00099 this.target = "DOWN_FRONT"; 00100 this.locked = false; 00101 this.listeners = new ArrayList<GazeListener>(); 00102 this.xml = xml; 00103 this.realizer = realizer; 00104 00105 this.gazeLockSub = handle.subscribe("generation/lock_gaze", new Flag(), 00106 new LockListener(), 100); 00107 this.lookSub = handle.subscribe("performing/look", new Performance(), 00108 this, 100); 00109 this.triedPub = handle.advertise("generation/tried_gaze", new Entity(), 00110 100); 00111 00112 this.logger.debug(LoggerLevel.INIT, "setup ..."); 00113 } 00114 00118 public void shutdown() { 00119 this.gazeLockSub.shutdown(); 00120 this.lookSub.shutdown(); 00121 this.triedPub.shutdown(); 00122 } 00123 00129 public String getTarget() { 00130 return target; 00131 } 00132 00136 public boolean isLocked() { 00137 return locked; 00138 } 00139 00147 public void setBottomListener(GazeListener gl) { 00148 this.bottomListener = gl; 00149 } 00150 00158 public synchronized void addListener(GazeListener gl) { 00159 this.listeners.add(gl); 00160 } 00161 00170 @Override 00171 public boolean trySetGaze(String target) { 00172 if (!this.locked) { 00173 if (this.bottomListener != null 00174 && (target == null || target.isEmpty())) 00175 return bottomListener.trySetGaze(null); 00176 00177 this.logger.debug(LoggerLevel.IO, "Setting gaze to " + target); 00178 EBMLList list = new EBMLList(logger, xml, "set-gaze-bml"); 00179 list.getGazes().add( 00180 new GazeBehavior(logger, "set-gaze", target, true)); 00181 this.target = target; 00182 return (this.realizer.sendBML(list).success == Flag.SUCCESS); 00183 } else { 00184 this.logger.debug(LoggerLevel.IO, "Publishing locked gaze: " 00185 + target); 00186 // send a message saying we need to look at something we didn't 00187 Entity ent = new Entity(); 00188 ent.id = target; 00189 ent.type = Entity.UNKNOWN; 00190 triedPub.publish(ent); 00191 return false; 00192 } 00193 } 00194 00206 @Override 00207 public synchronized void gazeChanged(String target, boolean face, 00208 boolean lock) { 00209 logger.debug(LoggerLevel.ALL, "Informing Listeners of [" + target + "]"); 00210 for (GazeListener gl : this.listeners) 00211 gl.gazeChanged(target, face, lock); 00212 } 00213 00214 @Override 00215 public void call(Performance perf) { 00216 // if the robot is beginning to look at something, store it and inform 00217 // the rest of generation 00218 if ((perf.actor.id.equals(ActorID.ROBOT)) 00219 && (perf.begin.value == Flag.BEGIN)) { 00220 if (perf.objects.size() > 0) { 00221 String newTarget = perf.objects.get(0).id; 00222 00223 // ensure that we don't already know that we are looking at this 00224 // object 00225 if (this.target == null || !this.target.equals(newTarget)) { 00226 logger.debug(LoggerLevel.ALWAYS, "Robot began looking at " 00227 + newTarget); 00228 boolean face = perf.objects.get(0).type == Entity.FACE; 00229 00230 this.target = newTarget; 00231 this.gazeChanged(this.target, face, this.locked); 00232 } 00233 } 00234 } 00235 } 00236 00237 private class LockListener implements Subscriber.Callback<Flag> { 00238 @Override 00239 public void call(Flag flag) { 00240 locked = (flag.value == Flag.TRUE); 00241 } 00242 } 00243 } |