Project: engagement_generation License: BSD Dependencies:
Used by:
None |
engagement_generation/src/edu/wpi/hri/gen/comm/SituationKnowledge.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.Hashtable; 00037 import java.util.Set; 00038 00039 import ros.NodeHandle; 00040 import ros.RosException; 00041 import ros.Subscriber; 00042 import ros.pkg.bml_msgs.msg.Entity; 00043 import ros.pkg.bml_msgs.msg.EntityPosition; 00044 import edu.wpi.hri.gen.GenerationParams; 00045 import edu.wpi.hri.gen.policy.ref.Point; 00046 import edu.wpi.hri.log.Logger; 00047 import edu.wpi.hri.log.Logger.Colors; 00048 import edu.wpi.hri.log.Logger.LoggerLevel; 00049 00058 public class SituationKnowledge implements Subscriber.Callback<EntityPosition> { 00059 00060 private final Logger logger; 00061 private final Hashtable<String, Point> locations; 00062 private final Subscriber<EntityPosition> posSub; 00063 private final Hashtable<String, Point> objects; 00064 00075 public SituationKnowledge(Logger logger, NodeHandle handle) 00076 throws RosException { 00077 this.logger = logger.sub(Colors.SITUATION_KNOWLEDGE, "WORLD"); 00078 this.locations = new Hashtable<String, Point>(); 00079 this.objects = new Hashtable<String, Point>(); 00080 this.posSub = handle.subscribe("vision/entity_position", 00081 new EntityPosition(), this, 100); 00082 this.logger.debug(LoggerLevel.INIT, "setup ..."); 00083 } 00084 00088 public synchronized void shutdown() { 00089 this.posSub.shutdown(); 00090 } 00091 00092 @Override 00093 public synchronized void call(EntityPosition pos) { 00094 logger.debug(LoggerLevel.IO, "Received new [" + pos.entity.id 00095 + "] location (" + pos.x + ", " + pos.y + ", " + pos.z 00096 + ") at rotation (" + pos.rotation + ")"); 00097 00098 Point loc = new Point(pos.x, pos.y, pos.z, pos.rotation); 00099 this.locations.put(pos.entity.id, loc); 00100 00101 //TODO: possibly remove the OBJECT check after moving coordinate transforms 00102 if (pos.entity.type == Entity.OBJECT) { 00103 this.objects.put(pos.entity.id, loc); 00104 } 00105 } 00106 00112 public synchronized Set<String> getAllObjects() { 00113 return this.objects.keySet(); 00114 } 00115 00123 public synchronized Point get(String id) { 00124 if (id == null) 00125 throw new InvalidIDException("ID can not be null"); 00126 else { 00127 Point val = this.locations.get(id); 00128 if (val == null) 00129 throw new InvalidIDException("ID could not be found: " + id); 00130 return val; 00131 } 00132 } 00133 00139 public synchronized Point getRobot() { 00140 logger.debug(LoggerLevel.ALL, "retrieving robot position"); 00141 return this.get("ROBOT"); 00142 } 00143 00150 public synchronized Point getRobotHead() { 00151 Point robot = getRobot(); 00152 logger.debug(LoggerLevel.ALL, "retrieving robot head position"); 00153 return new Point(robot.getX(), robot.getY(), 00154 GenerationParams.ROBOT_HEAD_HEIGHT.getDouble(), robot.getzRot()); 00155 } 00156 00162 public synchronized Point getRobotLeftHand() { 00163 return this.get("ROBOT_LEFT_HAND"); 00164 } 00165 00171 public Point getRobotRightHand() { 00172 return this.get("ROBOT_RIGHT_HAND"); 00173 } 00174 00180 public synchronized Point getRobotLeftShoulder() { 00181 Point robot = this.getRobot(); 00182 double shoulderLength = GenerationParams.ROBOT_SHOULDER_LENGTH 00183 .getDouble(); 00184 double x = robot.getX() 00185 - (Math.cos(Math.PI * robot.getzRot() / 180.0) * shoulderLength); 00186 double y = robot.getY() 00187 - (Math.sin(Math.PI * robot.getzRot() / 180.0) * shoulderLength); 00188 double z = GenerationParams.ROBOT_SHOULDER_HEIGHT.getDouble(); 00189 return new Point(x, y, z); 00190 } 00191 00197 public synchronized Point getRobotRightShoulder() { 00198 Point robot = this.getRobot(); 00199 double shoulderLength = GenerationParams.ROBOT_SHOULDER_LENGTH 00200 .getDouble(); 00201 double x = robot.getX() 00202 + (Math.cos(Math.PI * robot.getzRot() / 180.0) * shoulderLength); 00203 double y = robot.getY() 00204 + (Math.sin(Math.PI * robot.getzRot() / 180.0) * shoulderLength); 00205 double z = GenerationParams.ROBOT_SHOULDER_HEIGHT.getDouble(); 00206 return new Point(x, y, z); 00207 } 00208 00216 public synchronized Point convertToRobotSpace(Point from) { 00217 Point robot = this.getRobot(); 00218 logger.debug(LoggerLevel.MATH, 00219 "CONVERTING $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "); 00220 logger.debug(LoggerLevel.MATH, "\tRobot position: " + robot.toString()); 00221 logger.debug(LoggerLevel.MATH, "\tfrom position: " + from.toString()); 00222 00223 double fromDist = from.xyDistance(robot); 00224 00225 logger.debug(LoggerLevel.MATH, "\tdistance: " + fromDist); 00226 00227 double angle = Math.atan2(from.getY() - robot.getY(), from.getX() 00228 - robot.getX()); 00229 00230 logger.debug(LoggerLevel.MATH, "\tangle: " + angle); 00231 logger.debug(LoggerLevel.MATH, "\trobot rotation: " + robot.getzRot()); 00232 00233 angle = ((Math.PI / 2) - angle) + (robot.getzRot() * Math.PI / 180.0); 00234 00235 logger.debug(LoggerLevel.MATH, "\tOffset angle: " + angle); 00236 00237 double x = Math.sin(angle) * fromDist; 00238 double y = Math.cos(angle) * fromDist; 00239 double z = from.getZ(); 00240 logger.debug(LoggerLevel.MATH, 00241 "DONE $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "); 00242 00243 return new Point(x, y, z); 00244 } 00245 00254 public synchronized boolean isObjectOnRight(String object) { 00255 // grab the useful information 00256 Point robot = getRobot(); 00257 Point loc = get(object); 00258 double theta = robot.getzRot() * Math.PI / 180.0; 00259 00260 double x = ((loc.getX() - robot.getX()) * Math.cos(theta)) 00261 + (loc.getY() * Math.sin(theta)); 00262 00263 // then finally check if the loc is to the right of the robot 00264 return x > 0; 00265 } 00266 00267 @SuppressWarnings("serial") 00268 public static class InvalidIDException extends RuntimeException { 00269 public InvalidIDException(String str) { 00270 super(str); 00271 } 00272 } 00273 } |