ptolemy.domains.wireless.lib
Class Triangulator

java.lang.Object
  extended by ptolemy.kernel.util.NamedObj
      extended by ptolemy.kernel.InstantiableNamedObj
          extended by ptolemy.kernel.Entity
              extended by ptolemy.kernel.ComponentEntity
                  extended by ptolemy.actor.AtomicActor
                      extended by ptolemy.actor.TypedAtomicActor
                          extended by ptolemy.domains.wireless.lib.Triangulator
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable, Actor, Executable, FiringsRecordable, Initializable, TypedActor, Changeable, Debuggable, DebugListener, Derivable, Instantiable, ModelErrorHandler, MoMLExportable, Moveable, Nameable

public class Triangulator
extends TypedAtomicActor

Given inputs that represent the location of a sensor and the time at which those sensors detect an event, this actor outputs the location of the source of the event. It uses the specified signalPropagationSpeed and triangulates.

The input is a record with two fields named "location" and "time". The location field is an array of doubles, and the time is a double. In the current implementation, the actor assumes a two-dimensional space, so the location field is assumed to be an array with two doubles, which represent the horizontal (east-west) and vertical (north-south) location of the sensor. The time field is assumed to be a double representing the time at which the event was detected by the sensor.

The triangulation algorithm requires three distinct sensor inputs for the same event in order to be able to calculate the location of the origin of the event. Suppose that the event occurred at time t and location x. Suppose that three sensors at locations y1, y2, and y3 have each detected events at times t1, t2, and t3, respectively. Then this actor looks for a solution for x and t in the following equations: distance(x, y1)/v = t1 - t,
distance(x, y2)/v = t2 - t,
distance(x, y3)/v = t3 - t,
where v is the value of propagationSpeed. If such a solution is found, then the output x is produced.

Since three distinct observations are required, this actor will produce no output until it has received three distinct observations. The observations are distinct if the sensor locations are distinct. If the three observations yield no solution, then this actor will produce no output. However, it is possible for the three observations to come from distinct events, in which case the output may be erroneous. To guard against this, this actor provides a timeWindow parameter. The times of the three observations must be within the value of timeWindow, or no output will be produced. The output is an array of doubles, which in this implementation represent the X and Y locations of the event.

Since:
Ptolemy II 4.0
Version:
$Id: Triangulator.java 57046 2010-01-27 23:35:53Z cxh $
Author:
Xiaojun Liu, Edward A. Lee
See Also:
Serialized Form
Accepted Rating:
Red (ptolemy)
Proposed Rating:
Yellow (eal)

Nested Class Summary
 
Nested classes/interfaces inherited from class ptolemy.kernel.Entity
Entity.ContainedObjectsIterator
 
Field Summary
private static double _EPSILON
           
private  double[] _locationsX
           
private  double[] _locationsY
           
private  double[] _times
           
 TypedIOPort input
          The input port for an event detection, which is a record containing the location of a sensor that has detected the event and the time at which the sensor detected the event.
 TypedIOPort output
          The output producing the calculated event location.
 Parameter signalPropagationSpeed
          Speed of propagation of the signal to be used for triangulation.
 Parameter timeWindow
          Time window within which observations are assumed to come from the same sound event.
 
Fields inherited from class ptolemy.actor.AtomicActor
_actorFiringListeners, _initializables, _notifyingActorFiring, _stopRequested
 
Fields inherited from class ptolemy.kernel.util.NamedObj
_changeListeners, _changeLock, _changeRequests, _debugging, _debugListeners, _elementName, _isPersistent, _verbose, _workspace, ATTRIBUTES, CLASSNAME, COMPLETE, CONTENTS, DEEP, FULLNAME, LINKS
 
Fields inherited from interface ptolemy.actor.Executable
COMPLETED, NOT_READY, STOP_ITERATING
 
Constructor Summary
Triangulator(CompositeEntity container, java.lang.String name)
          Construct an actor with the given container and name.
 
Method Summary
private  double _checkResult(double[] result, double x1, double y1, double t1, double x2, double y2, double t2, double x3, double y3, double t3, double v)
          Check whether the calculated location and time of a sound event is consistent with the observations.
private static double _distance(double x1, double y1, double x2, double y2)
          Return the Cartesian distance between (x1, y1) and (x2, y2).
private  double[] _locate(double x1, double y1, double t1, double x2, double y2, double t2, double x3, double y3, double t3, double v)
          Calculate the location and time of a sound event from the given observations of the event.
 java.lang.Object clone(Workspace workspace)
          Clone this actor into the specified workspace.
 void fire()
          Read all available input tokens and attempt to use them to triangulate the signal source.
 void initialize()
          Override the base class to initialize the signal count.
 
Methods inherited from class ptolemy.actor.TypedAtomicActor
_addPort, _fireAt, _fireAt, attributeTypeChanged, clone, newPort, typeConstraintList, typeConstraints
 
Methods inherited from class ptolemy.actor.AtomicActor
_actorFiring, _actorFiring, addActorFiringListener, addInitializable, connectionsChanged, createReceivers, declareDelayDependency, getCausalityInterface, getDirector, getExecutiveDirector, getManager, inputPortList, isFireFunctional, isStrict, iterate, newReceiver, outputPortList, postfire, prefire, preinitialize, pruneDependencies, recordFiring, removeActorFiringListener, removeDependency, removeInitializable, setContainer, stop, stopFire, terminate, wrapup
 
Methods inherited from class ptolemy.kernel.ComponentEntity
_adjustDeferrals, _checkContainer, _getContainedObject, _propagateExistence, getContainer, instantiate, isAtomic, isOpaque, moveDown, moveToFirst, moveToIndex, moveToLast, moveUp, propagateExistence, setName
 
Methods inherited from class ptolemy.kernel.Entity
_description, _exportMoMLContents, _removePort, _validateSettables, connectedPortList, connectedPorts, containedObjectsIterator, getAttribute, getPort, getPorts, linkedRelationList, linkedRelations, portList, removeAllPorts, setClassDefinition, uniqueName
 
Methods inherited from class ptolemy.kernel.InstantiableNamedObj
_setParent, exportMoML, getChildren, getElementName, getParent, getPrototypeList, isClassDefinition, isWithinClassDefinition
 
Methods inherited from class ptolemy.kernel.util.NamedObj
_addAttribute, _adjustOverride, _attachText, _cloneFixAttributeFields, _debug, _debug, _debug, _debug, _debug, _getIndentPrefix, _isMoMLSuppressed, _markContentsDerived, _propagateValue, _recordDecoratedAttributes, _removeAttribute, _splitName, _stripNumericSuffix, addChangeListener, addDebugListener, attributeChanged, attributeList, attributeList, deepContains, depthInHierarchy, description, description, event, executeChangeRequests, exportMoML, exportMoML, exportMoML, exportMoML, exportMoMLPlain, getAttribute, getAttributes, getChangeListeners, getClassName, getDecoratorAttribute, getDecoratorAttributes, getDerivedLevel, getDerivedList, getDisplayName, getFullName, getModelErrorHandler, getName, getName, getSource, handleModelError, isDeferringChangeRequests, isOverridden, isPersistent, lazyContainedObjectsIterator, message, propagateValue, propagateValues, removeChangeListener, removeDebugListener, requestChange, setClassName, setDeferringChangeRequests, setDerivedLevel, setDisplayName, setModelErrorHandler, setPersistent, setSource, sortContainedObjects, toplevel, toString, validateSettables, workspace
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface ptolemy.actor.Actor
createReceivers, getCausalityInterface, getDirector, getExecutiveDirector, getManager, inputPortList, newReceiver, outputPortList
 
Methods inherited from interface ptolemy.actor.Executable
isFireFunctional, isStrict, iterate, postfire, prefire, stop, stopFire, terminate
 
Methods inherited from interface ptolemy.actor.Initializable
addInitializable, preinitialize, removeInitializable, wrapup
 
Methods inherited from interface ptolemy.kernel.util.Nameable
description, getContainer, getDisplayName, getFullName, getName, getName, setName
 
Methods inherited from interface ptolemy.kernel.util.Derivable
getDerivedLevel, getDerivedList, propagateValue
 

Field Detail

input

public TypedIOPort input
The input port for an event detection, which is a record containing the location of a sensor that has detected the event and the time at which the sensor detected the event. This has type {location = {double}, time = double} The location is assumed to have two entries.


output

public TypedIOPort output
The output producing the calculated event location. This has type {double}, a double array with two entries.


signalPropagationSpeed

public Parameter signalPropagationSpeed
Speed of propagation of the signal to be used for triangulation. This is a double that defaults to 344.0 (the speed of sound in air at room temperature, in meters per second).


timeWindow

public Parameter timeWindow
Time window within which observations are assumed to come from the same sound event. This is a double that defaults to 0.5 (in seconds).


_locationsX

private double[] _locationsX

_locationsY

private double[] _locationsY

_times

private double[] _times

_EPSILON

private static final double _EPSILON
Constructor Detail

Triangulator

public Triangulator(CompositeEntity container,
                    java.lang.String name)
             throws NameDuplicationException,
                    IllegalActionException
Construct an actor with the given container and name.

Parameters:
container - The container.
name - The name of this actor.
Throws:
IllegalActionException - If the actor cannot be contained by the proposed container.
NameDuplicationException - If the container already has an actor with this name.
Method Detail

clone

public java.lang.Object clone(Workspace workspace)
                       throws java.lang.CloneNotSupportedException
Clone this actor into the specified workspace. This overrides the base class to handle private variables.

Overrides:
clone in class AtomicActor
Parameters:
workspace - The workspace for the cloned object.
Returns:
A new ComponentEntity.
Throws:
java.lang.CloneNotSupportedException - If cloned ports cannot have as their container the cloned entity (this should not occur), or if one of the attributes cannot be cloned.
See Also:
NamedObj.exportMoML(Writer, int, String), NamedObj.setDeferringChangeRequests(boolean)

fire

public void fire()
          throws IllegalActionException
Read all available input tokens and attempt to use them to triangulate the signal source. If the attempt is successful, then output the location of the signal source. Otherwise, output nothing. This method keeps a buffer of the three most recently seen inputs from distinct sensors (as determined by their locations). If a new input token has a location field that matches a location already in the buffer, then the new input simply replaces that previous observation. Otherwise, it replaces the oldest observation in the buffer. If there are three observations in the buffer with time stamps within the timeWindow parameter value, then triangulation is performed, and if the the three observations are consistent, then an output is produced.

Specified by:
fire in interface Executable
Overrides:
fire in class AtomicActor
Throws:
IllegalActionException - If there is no director, or if the parameters cannot be evaluated.

initialize

public void initialize()
                throws IllegalActionException
Override the base class to initialize the signal count.

Specified by:
initialize in interface Initializable
Overrides:
initialize in class AtomicActor
Throws:
IllegalActionException - If the base class throws it.

_checkResult

private double _checkResult(double[] result,
                            double x1,
                            double y1,
                            double t1,
                            double x2,
                            double y2,
                            double t2,
                            double x3,
                            double y3,
                            double t3,
                            double v)
Check whether the calculated location and time of a sound event is consistent with the observations.

Parameters:
result - The calculated location and time of a sound event.
x1 - The x-coordinate of the first observation.
y1 - The y-coordinate of the first observation.
t1 - The time of the first observation.
x2 - The x-coordinate of the second observation.
y2 - The y-coordinate of the second observation.
t2 - The time of the second observation.
x3 - The x-coordinate of the third observation.
y3 - The y-coordinate of the third observation.
t3 - The time of the third observation.
v - The speed of sound propagation.
Returns:
The sum of the differences between the calculated distances and the result argument. Double.POSITIVE_INFINITY is returned if any one of the times (t1, t2, t3) is greater than result[2].

_distance

private static double _distance(double x1,
                                double y1,
                                double x2,
                                double y2)
Return the Cartesian distance between (x1, y1) and (x2, y2).

Parameters:
x1 - The first x coordinate.
y1 - The first y coordinate.
x2 - The second x coordinate.
y2 - The second y coordinate.
Returns:
The distance.

_locate

private double[] _locate(double x1,
                         double y1,
                         double t1,
                         double x2,
                         double y2,
                         double t2,
                         double x3,
                         double y3,
                         double t3,
                         double v)
Calculate the location and time of a sound event from the given observations of the event. In the returned array, the first element is the x-coordinate of the event, the second is the y-coordinate, and the third is the time of the event. These are obtained by solving the following equations for x, y, and t:
  distance(x, y, x1, y1)/v = t1 - t
  distance(x, y, x2, y2)/v = t2 - t
  distance(x, y, x3, y3)/v = t3 - t
  
If there is no valid solution to these equations, possible when the observations are of different sound events, the returned values are all negative infinity (Double.NEGATIVE_INFINITY). It is also possible that a valid solution to the equations exists even though the observations are of different sound events. This algorithm does not rule out such false positives.

Parameters:
x1 - The x-coordinate of the first observation.
y1 - The y-coordinate of the first observation.
t1 - The time of the first observation.
x2 - The x-coordinate of the second observation.
y2 - The y-coordinate of the second observation.
t2 - The time of the second observation.
x3 - The x-coordinate of the third observation.
y3 - The y-coordinate of the third observation.
t3 - The time of the third observation.
v - The speed of sound propagation.
Returns:
The location and time of the sound event consistent with the observations.