Package net.javlov.world

Source Code of net.javlov.world.CompositeSensor

/*
* Javlov - a Java toolkit for reinforcement learning with multi-agent support.
*
* Copyright (c) 2009 Matthijs Snel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package net.javlov.world;

import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;

import net.javlov.VectorState;

/**
* Sensor that manages a group of child sensors. The child sensors need to implement the
* GroupedSensor interface in order to be able to produce a reading from a list of predefined
* objects. The group of objects that the children read from is prefiltered from the world by the
* CompositeSensor. In addition the sensor only modifies the position and rotation of its children
* when necessary, i.e. when there are objects in range and the children need to produce a reading.
*
* NOTE: this class doesn't produce a reading if there are less than 2 bodies within range; this
* is because DistanceSensors always detect the agent's own body. And this class has only been tested
* with DistanceSensors.
*
* @author Matthijs Snel
*
*/
public class CompositeSensor implements PhysicalSensor {

  private int numChildren;
  protected List<GroupedSensor> children;
  protected World world;
  protected Path2D.Double rangeArea;
 
  private double totaldx, totaldy, totalRot, lastCentreX, lastCentreY;
 
  public CompositeSensor() {
    children = new ArrayList<GroupedSensor>();
    rangeArea = new Path2D.Double();
  }
 
  public CompositeSensor(World world) {
    this();
    setWorld(world);
  }
 
  public void add(GroupedSensor s) {
    children.add(s);
    rangeArea.append(s.getRangeArea(), false);
  }

  public void setWorld(World w) {
    world = w;
  }
 
  @Override
  public void rotate(double angle) {
    for ( GroupedSensor s : children )
      s.rotate(angle);
    reCalcRangeArea();
  }

  @Override
  public void rotate(double angle, double x, double y) {
    totalRot += angle;
    lastCentreX = x;
    lastCentreY = y;
    rangeArea.transform(AffineTransform.getRotateInstance(angle, x, y))
  }

  @Override
  public void setBody(Body b) {
    //not needed
  }
 
  @Override
  public void translate(double dx, double dy) {
    totaldx += dx;
    totaldy += dy;
    rangeArea.transform(AffineTransform.getTranslateInstance(dx, dy))
  }

  @Override
  public double[] getReading() {
    List<Body> objectsInRange = world.getIntersectingObjects(rangeArea.getBounds2D());
    //TODO dangerous assumption: own body is always in range for distance sensors,
    //but might not be for other sensors
    if ( objectsInRange.size() < 2 )
      return new double[numChildren];

    VectorState st = new VectorState();
    for ( GroupedSensor gs : children ) {
      gs.translate(totaldx, totaldy);
      gs.rotate(totalRot, lastCentreX, lastCentreY);
      st.append(gs.getReadingFromObjects(objectsInRange));
    }
    totalRot = totaldx = totaldy = 0;
    return st.getData();
  }

  @Override
  public void init() {
    for ( GroupedSensor s : children )
      s.init();
    //assume no more sensors added
    numChildren = children.size();
   
  }

  @Override
  public void reset() {
    for ( GroupedSensor s : children )
      s.reset();
    numChildren = children.size();
  }
 
  private void reCalcRangeArea() {
    rangeArea.reset();
    for ( GroupedSensor s : children )
      rangeArea.append(s.getRangeArea(), false);
  }

  @Override
  public Shape getRangeArea() {
    return rangeArea;
  }

  @Override
  public int getReadingDim() {
    int dim = 0;
    for ( GroupedSensor gs : children )
      dim += gs.getReadingDim();
    return dim;
  }
}
TOP

Related Classes of net.javlov.world.CompositeSensor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.