Skip to content
Snippets Groups Projects
SimpleMover.java 7.48 KiB
package mv3302;

import java.awt.geom.Point2D;
import static mv3302.SimplestMover.NaP;
import simkit.Schedule;
import simkit.SimEntityBase;

import simkit.smd.Mover;

/**
 * A simple implementation of the DES "Mover" concept.
 *
 * @author ahbuss
 */
public class SimpleMover extends SimEntityBase implements Mover {

    /**
     * Start here
     */
    private Point2D initialLocation;

    /**
     * All movement will be at this speed
     */
    private double maxSpeed;

    /**
     * Current velocity vector
     */
    protected Point2D velocity;

    /**
     * Location where SimpleMover last stopped
     */
    protected Point2D lastStopLocation;

    /**
     * Current destination
     */
    protected Point2D destination;

    /**
     * simTime when move starts (or when it stops)
     */
    protected double startMoveTime;

    /**
     * Instantiate Point2D states by cloning NaP
     */
    public SimpleMover() {
        lastStopLocation = (Point2D) NaP.clone();
        velocity = (Point2D) NaP.clone();
        destination = (Point2D) NaP.clone();
    }

    /**
     * Instantiate with the given parameters
     *
     * @param initialLocation Given initial location
     * @param maxSpeed Given maxSpeed
     */
    public SimpleMover(Point2D initialLocation, double maxSpeed) {
        this();
        setInitialLocation(initialLocation);
        setMaxSpeed(maxSpeed);
    }

    /**
     * set destination location to NaP<br>
     * set lastStopLocation to initialLocation<br>
     * set velocity to (0.0, 0.0)<br>
     * set startMoveTime to 0.0
     *
     */
    @Override
    public void reset() {
        super.reset();
        destination = (Point2D) NaP.clone();
        lastStopLocation = getInitialLocation();
        velocity.setLocation(0.0, 0.0);
        startMoveTime = 0.0;
    }

    /**
     * Nothing scheduled - waiting to hear MoveTo event
     */
    public void doRun() {
        firePropertyChange("startMoveTime", getStartMoveTime());
        firePropertyChange("lastStopLocation", getLastStopLocation());
        firePropertyChange("velocity", getVelocity());
        firePropertyChange("destination", getDestination());
    }

    /**
     * To be "heard" from a mover manager.<br>
     * set destination to the given argument<br>
     * schedule StartMove if non-zero travel distance
     *
     * @param destination Given new destination
     */
    public void doMoveTo(Point2D destination) {
        Point2D oldDestination = getDestination();
        this.destination = destination;
        firePropertyChange("destination", oldDestination, getDestination());

        if (lastStopLocation.distance(destination) > 0.0) {
            waitDelay("StartMove", 0.0, this);
        }
    }

    /**
     * set velocity per the new destination and maxSpeed<br>
     * set startMoveTime to current simTime<br>
     * schedule EndMove with delay of travel time
     *
     * @param mover Should be "this" Mover
     */
    @Override
    public void doStartMove(Mover mover) {
        Point2D oldVelocity = getVelocity();
        velocity = new Point2D.Double(
                destination.getX() - lastStopLocation.getX(),
                destination.getY() - lastStopLocation.getY()
        );

        double distance = lastStopLocation.distance(destination);

        velocity.setLocation(velocity.getX() * maxSpeed / distance,
                velocity.getY() * maxSpeed / distance);
        firePropertyChange("velocity", oldVelocity, getVelocity());

        double oldStartMoveTime = getStartMoveTime();
        startMoveTime = Schedule.getSimTime();
        firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());

        double travelTime = distance / maxSpeed;
        waitDelay("EndMove", travelTime, mover);
    }

    /**
     * Set lastStopLocation coordinates to destination<br>
     * set velocity to (0.0, 0.0)<br>
     * set destination of NaP
     *
     * @param mover Should be "this" Mover
     */
    public void doEndMove(Mover mover) {
        Point2D oldLastStopLocation = getLastStopLocation();
        lastStopLocation.setLocation(destination);
        firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());

        Point2D oldVelocity = getVelocity();
        velocity.setLocation(0.0, 0.0);
        firePropertyChange("velocity", oldVelocity, getVelocity());

        Point2D oldDestination = getDestination();
        destination.setLocation(NaP);
        firePropertyChange("destination", oldDestination, getDestination());
    }

    /**
     * Scheduled when Mover "stops" for a period of time.<br>
     * Set lastStopLocation to currentLocation<br>
     * setVelocity to (0.0, 0.0)
     *
     * @param mover Should be "this" Mover
     */
    @Override
    public void doStop(Mover mover) {
        Point2D oldLastStopLocation = getLastStopLocation();
        lastStopLocation.setLocation(getCurrentLocation());
        firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());

        Point2D oldVelocity = getVelocity();
        velocity.setLocation(0.0, 0.0);
        firePropertyChange("velocity", oldVelocity, getVelocity());

    }

    /**
     * to be "heard" from Mover Manager when stopping<br>
     * Schedule Stop
     */
    public void doOrderStop() {
        waitDelay("Stop", 0.0, this);
    }

    /**
     * "Implicit" state - determined using the linear equation of motion.
     *
     * @return The current location of this Mover
     */
    @Override
    public Point2D getCurrentLocation() {
        Point2D currentLocation = (Point2D) NaP.clone();
        double elapsedTime = Schedule.getSimTime() - getStartMoveTime();
        currentLocation.setLocation(lastStopLocation.getX() + elapsedTime * velocity.getX(),
                lastStopLocation.getY() + elapsedTime * velocity.getY());
        return currentLocation;

    }

    /**
     *
     * @return the maxSpeed
     */
    @Override
    public double getMaxSpeed() {
        return this.maxSpeed;
    }

    /**
     *
     * @return copy of velocity
     */
    @Override
    public Point2D getVelocity() {
        return (Point2D) velocity.clone();
    }

    /**
     * @return copy of the initialLocation
     */
    public Point2D getInitialLocation() {
        return (Point2D) initialLocation;
    }

    /**
     * @param initialLocation the initialLocation to set
     */
    public void setInitialLocation(Point2D initialLocation) {
        this.initialLocation = (Point2D) initialLocation.clone();
    }

    /**
     * @param maxSpeed the maxSpeed to set
     * @throws IllegalArgumentException if maxSpeed &lt; 0.0
     */
    public void setMaxSpeed(double maxSpeed) {
        if (maxSpeed < 0.0) {
            throw new IllegalArgumentException("maxSpeed must be 0.0: " + maxSpeed);
        }
        this.maxSpeed = maxSpeed;
    }

    /**
     * @return copy of the lastStopLocation
     */
    public Point2D getLastStopLocation() {
        return (Point2D) lastStopLocation;
    }

    /**
     * @return copy of the destination
     */
    public Point2D getDestination() {
        return (Point2D) destination.clone();
    }

    /**
     * @return the startMoveTime
     */
    public double getStartMoveTime() {
        return startMoveTime;
    }

    /**
     * 
     * @return Name currentLocation velocity
     */
    @Override
    public String toString() {
        return String.format("%s %s %s", getName(), getCurrentLocation(), getVelocity());
    }

    /**
     * 
     * @return super toString()
     */
    public String paramString() {
        return super.toString();
    }

}