From a4c7d19c3980a1d84ac99314ecb1708f9639fb44 Mon Sep 17 00:00:00 2001 From: dansl <dansl@LAPTOP-SIKRVJU7.ern.nps.edu> Date: Wed, 24 May 2023 10:43:12 -0700 Subject: [PATCH] Commit initial Simple Mover corrections --- MV3302ClassCode/src/mv3302/SimpleMover.java | 234 ++++++++++++------ .../src/mv3302/SimplePathMoverManager.java | 134 ++++++---- .../src/mv3302/SimplePatrolMoverManager.java | 59 ++--- .../src/mv3302/SimpleRandomMoverManager.java | 123 ++++----- MV3302ClassCode/src/mv3302/SimplestMover.java | 170 +++++++++++++ .../src/mv3302/run/Assignment7.java | 73 ++++++ .../mv3302/sensor/AbstractSimpleSensor.java | 109 ++++++++ MV3302ClassCode/src/mv3302/sensor/Sensor.java | 22 ++ .../sensor/SimpleConstantRateSensor.java | 36 +++ .../sensor/SimpleConstantTimeSensor.java | 36 +++ .../sensor/SimpleCookieCutterSensor.java | 23 ++ 11 files changed, 812 insertions(+), 207 deletions(-) create mode 100644 MV3302ClassCode/src/mv3302/SimplestMover.java create mode 100644 MV3302ClassCode/src/mv3302/run/Assignment7.java create mode 100644 MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java create mode 100644 MV3302ClassCode/src/mv3302/sensor/Sensor.java create mode 100644 MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java create mode 100644 MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java create mode 100644 MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java diff --git a/MV3302ClassCode/src/mv3302/SimpleMover.java b/MV3302ClassCode/src/mv3302/SimpleMover.java index b631b6cc55..a28e919049 100644 --- a/MV3302ClassCode/src/mv3302/SimpleMover.java +++ b/MV3302ClassCode/src/mv3302/SimpleMover.java @@ -1,66 +1,106 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package mv3302; import java.awt.geom.Point2D; -import static java.lang.Double.NaN; +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 { - public static Point2D NaP = new Point2D.Double(NaN, NaN); - - public Point2D initialLocation; + /** + * Start here + */ + private Point2D initialLocation; - public double maxSpeed; + /** + * All movement will be at this speed + */ + private double maxSpeed; - public Point2D lastStopLocation; + /** + * Current velocity vector + */ + protected Point2D velocity; - public Point2D velocity; + /** + * Location where SimpleMover last stopped + */ + protected Point2D lastStopLocation; - public Point2D destination; + /** + * Current destination + */ + protected Point2D destination; - public double startMoveTime; + /** + * 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(); - lastStopLocation.setLocation(initialLocation); + destination = (Point2D) NaP.clone(); + lastStopLocation = getInitialLocation(); velocity.setLocation(0.0, 0.0); - destination.setLocation(NaP); 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()); - firePropertyChange("startMoveTime", getStartMoveTime()); } - public void doMoveTo(Point2D newDestination) { + /** + * 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.setLocation(newDestination); + this.destination = destination; firePropertyChange("destination", oldDestination, getDestination()); if (lastStopLocation.distance(destination) > 0.0) { @@ -68,26 +108,43 @@ public class SimpleMover extends SimEntityBase implements Mover { } } + /** + * 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) { - double oldStartMoveTime = getStartMoveTime(); - startMoveTime = Schedule.getSimTime(); - firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime()); + Point2D oldVelocity = getVelocity(); + velocity = new Point2D.Double( + destination.getX() - lastStopLocation.getX(), + destination.getY() - lastStopLocation.getY() + ); + double distance = lastStopLocation.distance(destination); - double a = getMaxSpeed() / distance; - Point2D oldVelocity = getVelocity(); - velocity.setLocation(destination.getX() - lastStopLocation.getX(), destination.getY() - lastStopLocation.getY()); - velocity.setLocation(a * velocity.getX(), a * velocity.getY()); + velocity.setLocation(velocity.getX() * maxSpeed / distance, + velocity.getY() * maxSpeed / distance); firePropertyChange("velocity", oldVelocity, getVelocity()); - waitDelay("EndMove", 1.0/a, mover); - } - - public void doEndMove(Mover mover) { 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()); @@ -95,36 +152,74 @@ public class SimpleMover extends SimEntityBase implements Mover { 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()); + } - - public void doOrderStop(){ + + /** + * to be "heard" from Mover Manager when stopping<br> + * Schedule Stop + */ + public void doOrderStop() { waitDelay("Stop", 0.0, this); } - - public void doStop(Mover mover){ - Point2D oldLastStopLocation = lastStopLocation; - lastStopLocation = getCurrentLocation(); - firePropertyChange("lastStopLocation", oldLastStopLocation, lastStopLocation); - velocity.setLocation(0.0, 0.0); - interrupt("EndMove", mover); + + /** + * "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 NaP + * + * @return the maxSpeed */ - public static Point2D getNaP() { - return NaP; + @Override + public double getMaxSpeed() { + return this.maxSpeed; } /** - * @param aNaP the NaP to set + * + * @return copy of velocity */ - public static void setNaP(Point2D aNaP) { - NaP = aNaP; + @Override + public Point2D getVelocity() { + return (Point2D) velocity.clone(); } /** - * @return the initialLocation + * @return copy of the initialLocation */ public Point2D getInitialLocation() { return (Point2D) initialLocation.clone(); @@ -138,28 +233,25 @@ public class SimpleMover extends SimEntityBase implements Mover { } /** - * @return the maxSpeed + * @param maxSpeed the maxSpeed to set + * @throws IllegalArgumentException if maxSpeed < 0.0 */ - public double getMaxSpeed() { - return maxSpeed; + public void setMaxSpeed(double maxSpeed) { + if (maxSpeed < 0.0) { + throw new IllegalArgumentException("maxSpeed must be 0.0: " + maxSpeed); + } + this.maxSpeed = maxSpeed; } /** - * @return the lastStopLocation + * @return copy of the lastStopLocation */ public Point2D getLastStopLocation() { return (Point2D) lastStopLocation.clone(); } /** - * @return the velocity - */ - public Point2D getVelocity() { - return (Point2D) velocity.clone(); - } - - /** - * @return the destination + * @return copy of the destination */ public Point2D getDestination() { return (Point2D) destination.clone(); @@ -173,32 +265,20 @@ public class SimpleMover extends SimEntityBase implements Mover { } /** - * @param maxSpeed the maxSpeed to set + * + * @return Name currentLocation velocity */ - public void setMaxSpeed(double maxSpeed) { - if (maxSpeed < 0.0) { - throw new IllegalArgumentException("maxSpeed must be >= 0.0: " + maxSpeed); - } - this.maxSpeed = maxSpeed; - } - - public Point2D getCurrentLocation() { - double updateTime = Schedule.getSimTime() - getStartMoveTime(); - return new Point2D.Double(lastStopLocation.getX() + updateTime * velocity.getX(), - lastStopLocation.getY() + updateTime * velocity.getY()); -// Point2D currentLocation = getVelocity(); -// currentLocation.setLocation(currentLocation.getX() * updateTime, currentLocation.getY() * updateTime); -// currentLocation.setLocation(lastStopLocation.getX() + currentLocation.getX(), lastStopLocation.getY() + currentLocation.getY()); -// return currentLocation; - - } - @Override public String toString() { return String.format("%s %s %s", getName(), getCurrentLocation(), getVelocity()); } + /** + * + * @return super toString() + */ public String paramString() { return super.toString(); } + } diff --git a/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java index 9090d7665e..d971360051 100644 --- a/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java +++ b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java @@ -1,81 +1,112 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package mv3302; import java.awt.geom.Point2D; -import static java.lang.Double.NaN; +import static mv3302.SimplestMover.NaP; import simkit.SimEntityBase; import simkit.smd.Mover; /** + * Simple Path Mover Manager. Directs a listening Mover to each wayPoint in + * order until the last, when it "stops" * - * @author dansl + * @author ahbuss */ public class SimplePathMoverManager extends SimEntityBase { + /** + * If true, start immediately + */ private boolean startOnRun; - protected Point2D[] path; + /** + * Given list of wayPoints + */ + private Point2D[] path; + /** + * index of next wayPoint + */ protected int nextIndex; - protected Point2D nextWaypoint; + /** + * next destination + */ + protected Point2D nextDestination; + /** + * Instantiate nextDestination as copy of NaP + */ public SimplePathMoverManager() { + nextDestination = (Point2D) NaP.clone(); } + /** + * Instantiate with the given parameters + * + * @param path Given path + * @param startOnRun if true, start on Run event + */ public SimplePathMoverManager(Point2D[] path, boolean startOnRun) { + this(); setPath(path); setStartOnRun(startOnRun); } + /** + * Set nextIndex to -1<br> + * set nextDestination to NaP coordinates + */ @Override public void reset() { super.reset(); - nextIndex = 0; - + nextIndex = -1; + nextDestination.setLocation(NaP); } + /** + * If startOnRun is true, schedule NextWayPoint + */ public void doRun() { - int oldNextIndex = getNextIndex(); - nextIndex -= 1; firePropertyChange("nextIndex", getNextIndex()); - nextWaypoint = new Point2D.Double(NaN, NaN); + if (isStartOnRun()) { - waitDelay("NextWP", 0.0); + waitDelay("NextWayPoint", 0.0); } } - - public void doNextWP(){ + + /** + * Increment nextIndex<br> + * set nextDestination to path[nextIndex]<br> + * schedule MoveTo with nextDestination + */ + public void doNextWayPoint() { int oldNextIndex = getNextIndex(); nextIndex += 1; - firePropertyChange("nextIndex", getNextIndex()); - Point2D oldNextWaypoint = getNextWaypoint(); - nextWaypoint = path[nextIndex]; - firePropertyChange("nextWaypoint", getNextWaypoint()); - waitDelay("MoveTo", 0.0, nextWaypoint); + firePropertyChange("nextIndex", oldNextIndex, getNextIndex()); + + Point2D oldDestination = getNextDestination(); + nextDestination.setLocation(path[nextIndex]); + firePropertyChange("nextDestination", oldDestination, getNextDestination()); + + waitDelay("MoveTo", 0.0, getNextDestination()); } - - public void doEndMove(Mover mover){ - if (nextIndex < path.length -1){ - waitDelay("NextWP", 0.0); + + /** + * If more way points on path, schedule NextWayPoint<br> + * Else schedule OrderStop + * + * @param mover Given Mover (should be the one this is listening to) + */ + public void doEndMove(Mover mover) { + if (nextIndex < path.length - 1) { + waitDelay("NextWayPoint", 0.0); } - if (nextIndex == path.length -1){ - waitDelay("Stop", 0.0); + + if (nextIndex == path.length - 1) { + waitDelay("OrderStop", 0.0); } } - - public void doStop(){ - } - public void doOrderStop(){ - } - - public void doMoveTo(Point2D nextWaypoint){ - } - /** * @return the startOnRun */ @@ -91,12 +122,17 @@ public class SimplePathMoverManager extends SimEntityBase { } /** - * @return the path + * @return topy of he path */ public Point2D[] getPath() { - return path; + return path.clone(); } + /** + * + * @param index Given index + * @return path[index] + */ public Point2D getPath(int index) { return path[index]; } @@ -105,11 +141,16 @@ public class SimplePathMoverManager extends SimEntityBase { * @param path the path to set */ public void setPath(Point2D[] path) { - if (path.length > 0) { - this.path = path.clone(); - } else { - throw new IllegalArgumentException("path must be at least lengt 1: " + path.length); - } + this.path = path.clone(); + } + + /** + * + * @param index Given index + * @param path Given waypoint + */ + public void setPath(int index, Point2D path) { + this.path[index] = path; } /** @@ -120,9 +161,10 @@ public class SimplePathMoverManager extends SimEntityBase { } /** - * @return the nextWaypoint + * @return copy of the nextDestination */ - public Point2D getNextWaypoint() { - return (Point2D) nextWaypoint; + public Point2D getNextDestination() { + return (Point2D) nextDestination.clone(); } + } diff --git a/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java index ed4c0fc37b..0773257d7b 100644 --- a/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java +++ b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java @@ -1,56 +1,59 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package mv3302; import java.awt.geom.Point2D; import simkit.smd.Mover; /** + * Similar to PathMoverManager; directs a Mover to a sequence of way points. + * Instead of stopping at the end, return to the first and cycle through again + * until stopped by an external component. * - * @author dansl + * @author ahbuss */ -public class SimplePatrolMoverManager extends SimplePathMoverManager{ +public class SimplePatrolMoverManager extends SimplePathMoverManager { /** - * Zero-argument constructor + * Zero argument constructor */ public SimplePatrolMoverManager() { } /** - * Instantiate with given given parameters + * Instantiate with the given parameters * - * @param path Given waypoints - * @param startOnRun true if start immediately + * @param path Given path + * @param startOnRun if true, start on Run event */ public SimplePatrolMoverManager(Point2D[] path, boolean startOnRun) { super(path, startOnRun); } - /** - * Increment nextIndex; if it is beyond the last index, modulo back to - * 0.<br> - * Schedule MoveTo with path[nextIndex] (using getter, since path is - * private) + + /** + * Always schedule NextWayPoint + * + * @param mover Given Mover */ @Override public void doEndMove(Mover mover) { - waitDelay("NextWP", 0.0, getPath(nextIndex)); + waitDelay("NextWaypoint", 0.0); + } - - @Override - public void doNextWP(){ + + /** + * Increment nextIndext and set modulo the length of the path<br> + * setNextDestination<br> + * Schedule MoveTo + */ + public void doNextWaypoint() { int oldNextIndex = getNextIndex(); - nextIndex = (nextIndex+1)%path.length; + nextIndex = (nextIndex + 1) % getPath().length; firePropertyChange("nextIndex", oldNextIndex, getNextIndex()); - Point2D oldNextWaypoint = getNextWaypoint(); - nextWaypoint = path[nextIndex]; - firePropertyChange("nextWaypoint", oldNextWaypoint, getNextWaypoint()); - waitDelay("MoveTo", 0.0, nextWaypoint); - } - - public void doMoveTo(Mover mover){ + + Point2D oldDestination = getNextDestination(); + nextDestination.setLocation(getPath(nextIndex)); + firePropertyChange("nextDestination", oldDestination, getNextDestination()); + + waitDelay("MoveTo", 0.0, getNextDestination()); } - + } diff --git a/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java index ec2ab863fe..b703beb2e3 100644 --- a/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java +++ b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java @@ -1,113 +1,118 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package mv3302; import java.awt.geom.Point2D; -import static java.lang.Double.NaN; +import static mv3302.SimplestMover.NaP; +import simkit.SimEntity; +import simkit.SimEntityBase; import simkit.random.RandomVariate; -import simkit.smd.Mover; /** + * A MoverManager that generates a random destination and directs a Mover there. + * When the Mover reaches that destination, generate the next, etc. * - * @author dansl + * @author ahbuss */ -public class SimpleRandomMoverManager extends SimplePathMoverManager { +public class SimpleRandomMoverManager extends SimEntityBase { /** - * Array to generate coordinates randomly + * Generates the coordinates */ - public RandomVariate[] coordinateGenerator; + private RandomVariate[] coordinateGenerator; /** - * If true start immediately + * If true, start on the Run event */ - public boolean startOnRun; + private boolean startOnRun; + /** + * Next destination + */ + protected Point2D nextWayPoint; + + /** + * set nextWayPoint to clone of NaP + */ public SimpleRandomMoverManager() { + this.nextWayPoint = (Point2D) NaP.clone(); } /** - * Instantiate with the given parameters * - * @param coordinateGenerator Given random coordinate generator - * @param startOnRun true if starting immediately + * @param coordinateGenerator Given coordinate generators + * @param startOnRun if true, start in Run event */ - public SimpleRandomMoverManager(RandomVariate[] coordinateGenerator, - boolean startOnRun) { + public SimpleRandomMoverManager(RandomVariate[] coordinateGenerator, boolean startOnRun) { + this(); this.setCoordinateGenerator(coordinateGenerator); this.setStartOnRun(startOnRun); } /** - * If startOnRun is true, generate random coordinates and schedule MoveTo - * with that destination + * set nextWayPoint to NaP coordinates */ @Override + public void reset() { + super.reset(); + nextWayPoint.setLocation(NaP); + } + + /** + * If startOnRun, schedule Start event + */ public void doRun() { - Point2D oldNextWaypoint = getNextWaypoint(); - nextWaypoint = new Point2D.Double(NaN, NaN); - firePropertyChange("nextWaypoint", oldNextWaypoint, nextWaypoint); + firePropertyChange("nextWayPoint", getNextWayPoint()); if (isStartOnRun()) { - waitDelay("NextWP", 0.0); + waitDelay("Start", 0.0); } } - @Override - public void doNextWP() { - Point2D oldNextWaypoint = getNextWaypoint(); - nextWaypoint = new Point2D.Double( - coordinateGenerator[0].generate(), - coordinateGenerator[1].generate()); - firePropertyChange("nextWaypoint", oldNextWaypoint, nextWaypoint); - waitDelay("MoveTo", 0.0, nextWaypoint); - } + /** + * Generate nextWaypoint<br> + * schedule MoveTo + */ + public void doStart() { + nextWayPoint = new Point2D.Double(coordinateGenerator[0].generate(), coordinateGenerator[1].generate()); + firePropertyChange("nextWaypoint", getNextWayPoint()); - @Override - public void doMoveTo(Point2D nextWayPoint) { + waitDelay("MoveTo", 0.0, nextWayPoint); } - @Override - public void doEndMove(Mover mover) { - waitDelay("NextWP", 0.0); + /** + * To be "heard" from Mover. generate nextWayPoint and schedule MoveTo + * + * @param mover Given Mover + */ + public void doEndMove(SimEntity mover) { + nextWayPoint = new Point2D.Double(coordinateGenerator[0].generate(), coordinateGenerator[1].generate()); + firePropertyChange("nextWaypoint", getNextWayPoint()); + + waitDelay("MoveTo", 0.0, nextWayPoint); } - - @Override - public void doStop(){ + + /** + * Schedule OrderStop (which should "Stop" the Mover listening) + */ + public void doStop() { waitDelay("OrderStop", 0.0); } - - @Override - public void doOrderStop(){ - } /** - * @return the coordinateGenerator + * @return copy of the coordinateGenerator */ public RandomVariate[] getCoordinateGenerator() { return coordinateGenerator.clone(); } - public RandomVariate getCoordinateGenerator(int index) { - return coordinateGenerator[index]; - } - /** - * @param coordinateGenerator the coordinateGenerator to set + * @param coordinateGenerator the coordinateGenerator to set (copy of) */ public void setCoordinateGenerator(RandomVariate[] coordinateGenerator) { this.coordinateGenerator = coordinateGenerator.clone(); } - public void setCoordinateGenerator(int index, RandomVariate coordinateGenerator) { - this.coordinateGenerator[index] = coordinateGenerator; - } - /** * @return the startOnRun */ - @Override public boolean isStartOnRun() { return startOnRun; } @@ -115,9 +120,15 @@ public class SimpleRandomMoverManager extends SimplePathMoverManager { /** * @param startOnRun the startOnRun to set */ - @Override public void setStartOnRun(boolean startOnRun) { this.startOnRun = startOnRun; } + /** + * @return the nextWayPoint + */ + public Point2D getNextWayPoint() { + return nextWayPoint; + } + } diff --git a/MV3302ClassCode/src/mv3302/SimplestMover.java b/MV3302ClassCode/src/mv3302/SimplestMover.java new file mode 100644 index 0000000000..f24607b670 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/SimplestMover.java @@ -0,0 +1,170 @@ +package mv3302; + +import java.awt.geom.Point2D; +import static java.lang.Double.NaN; +import simkit.Schedule; +import simkit.SimEntityBase; + +/** + * + * @author ahbuss + */ +public class SimplestMover extends SimEntityBase { + + public static final Point2D NaP = new Point2D.Double(NaN, NaN); + + private Point2D initialLocation; + + private double maxSpeed; + + protected Point2D lastStopLocation; + + protected Point2D velocity; + + protected Point2D destination; + + protected double startMoveTime; + + public SimplestMover() { + lastStopLocation = (Point2D) NaP.clone(); + velocity = (Point2D) NaP.clone(); + destination = (Point2D) NaP.clone(); + } + + public SimplestMover(Point2D initialLocation, double maxSpeed) { + this(); + setInitialLocation(initialLocation); + setMaxSpeed(maxSpeed); + } + + @Override + public void reset() { + super.reset(); + lastStopLocation.setLocation(initialLocation); + velocity.setLocation(0.0, 0.0); + destination.setLocation(NaP); + startMoveTime = 0.0; + } + + public void doRun() { + firePropertyChange("lastStopLocation", getLastStopLocation()); + firePropertyChange("velocity", getVelocity()); + firePropertyChange("destination", getDestination()); + firePropertyChange("startMoveTime", getStartMoveTime()); + } + + public void doMoveTo(Point2D newDestination) { + Point2D oldDestination = getDestination(); + this.destination.setLocation(newDestination); + firePropertyChange("destination", oldDestination, getDestination()); + + if (lastStopLocation.distance(destination) > 0.0) { + waitDelay("StartMove", 0.0); + } + } + + public void doStartMove() { + double oldStartMoveTime = getStartMoveTime(); + startMoveTime = Schedule.getSimTime(); + firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime()); + + double distance = lastStopLocation.distance(destination); + double a = getMaxSpeed() / distance; + + Point2D oldVelocity = getVelocity(); + velocity.setLocation(destination.getX() - lastStopLocation.getX(), destination.getY() - lastStopLocation.getY()); + velocity.setLocation(a * velocity.getX(), a * velocity.getY()); + firePropertyChange("velocity", oldVelocity, getVelocity()); + + waitDelay("EndMove", 1.0 / a); + } + + public void doEndMove() { + double oldStartMoveTime = getStartMoveTime(); + startMoveTime = Schedule.getSimTime(); + firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime()); + + Point2D oldLastStopLocation = getLastStopLocation(); + lastStopLocation.setLocation(destination); + firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation()); + + Point2D oldVelocity = getVelocity(); + velocity.setLocation(0.0, 0.0); + firePropertyChange("velocity", oldVelocity, getVelocity()); + + } + + /** + * @return the initialLocation + */ + public Point2D getInitialLocation() { + return (Point2D) initialLocation.clone(); + } + + /** + * @param initialLocation the initialLocation to set + */ + public void setInitialLocation(Point2D initialLocation) { + this.initialLocation = (Point2D) initialLocation.clone(); + } + + /** + * @return the maxSpeed + */ + public double getMaxSpeed() { + return maxSpeed; + } + + /** + * @param maxSpeed the maxSpeed to set + */ + public void setMaxSpeed(double maxSpeed) { + if (maxSpeed < 0.0) { + throw new IllegalArgumentException("maxSpeed must be >= 0.0: " + maxSpeed); + } + this.maxSpeed = maxSpeed; + } + + /** + * @return the lastStopLocation + */ + public Point2D getLastStopLocation() { + return (Point2D) lastStopLocation.clone(); + } + + /** + * @return the velocity + */ + public Point2D getVelocity() { + return (Point2D) velocity.clone(); + } + + /** + * @return the destination + */ + public Point2D getDestination() { + return (Point2D) destination.clone(); + } + + /** + * @return the startMoveTime + */ + public double getStartMoveTime() { + return startMoveTime; + } + + public Point2D getCurrentLocation() { + double elapsedTime = Schedule.getSimTime() - getStartMoveTime(); + return new Point2D.Double(lastStopLocation.getX() + elapsedTime * velocity.getX() , + lastStopLocation.getY() + elapsedTime * velocity.getY()); + } + + @Override + public String toString() { + return String.format("%s %s", getName(), getCurrentLocation()); + } + + public String paramString() { + return super.toString(); + } +} diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7.java b/MV3302ClassCode/src/mv3302/run/Assignment7.java new file mode 100644 index 0000000000..241d6c5094 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/run/Assignment7.java @@ -0,0 +1,73 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template + */ +package mv3302.run; + +import java.awt.geom.Point2D; +import mv3302.SimpleMover; +import mv3302.SimplePathMoverManager; +import mv3302.sensor.SimpleConstantRateSensor; +import mv3302.sensor.SimpleConstantTimeSensor; +import mv3302.sensor.SimpleCookieCutterSensor; +import simkit.Schedule; +import simkit.util.SimplePropertyDumper; + +/** + * + * @author dansl + */ +public class Assignment7 { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + SimpleCookieCutterSensor cookieCutterSensor = new SimpleCookieCutterSensor(); + cookieCutterSensor.setSimpleMover(new SimpleMover()); + cookieCutterSensor.setMaxRange(10.0); + System.out.println(cookieCutterSensor); + + SimpleConstantTimeSensor constantTimeSensor = new SimpleConstantTimeSensor(); + constantTimeSensor.setSimpleMover(new SimpleMover()); + constantTimeSensor.setMaxRange(10); + constantTimeSensor.setTimeToDetect(5.0); + System.out.println(constantTimeSensor); + + SimpleConstantRateSensor constantRateSensor = new SimpleConstantRateSensor(); + constantRateSensor.setSimpleMover(new SimpleMover()); + constantRateSensor.setMaxRange(10.0); + constantRateSensor.setMeanTimeToDetect(3.0); + System.out.println(constantRateSensor); + + Point2D sensorLocation = new Point2D.Double(0.0, 0.0); + SimpleMover simpleSensorMover = new SimpleMover(); + double maxRange = 20.0; + double timeToDetect = 5.0; + SimpleConstantTimeSensor simpleConstantTimeSensor = new SimpleConstantTimeSensor(simpleSensorMover, maxRange, timeToDetect); + System.out.println(simpleSensorMover.paramString()); + + Point2D targetLocation = new Point2D.Double(0.0, 10.0); + double targetMaxSpeed = 40; + SimpleMover simpleMover = new SimpleMover(targetLocation, targetMaxSpeed); + System.out.println(simpleMover.paramString()); + + Point2D[] path = new Point2D[]{new Point2D.Double(50.0, -20.0)}; + SimplePathMoverManager simplePathMoverManager = new SimplePathMoverManager(path, true); + System.out.println(simplePathMoverManager); + + simplePathMoverManager.addSimEventListener(simpleMover); + simpleMover.addSimEventListener(simplePathMoverManager); + + SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true); + simpleConstantTimeSensor.addPropertyChangeListener(simplePropertyDumper); + simpleMover.addPropertyChangeListener(simplePropertyDumper); + simplePathMoverManager.addPropertyChangeListener(simplePropertyDumper); + + Schedule.setVerbose(true); + + Schedule.reset(); + Schedule.startSimulation(); + } + +} diff --git a/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java b/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java new file mode 100644 index 0000000000..09568c82eb --- /dev/null +++ b/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java @@ -0,0 +1,109 @@ + +package mv3302.sensor; + +import java.awt.geom.Point2D; +import java.util.HashSet; +import java.util.Set; +import mv3302.SimpleMover; +import simkit.SimEntityBase; + +/** + * + * @author dansl + */ +public abstract class AbstractSimpleSensor extends SimEntityBase implements Sensor { + + public double maxRange; + public SimpleMover simpleMover; + public Set<SimpleMover> contacts; + + public AbstractSimpleSensor() { + contacts = new HashSet<>(); + } + + public AbstractSimpleSensor(SimpleMover simpleMover, double maxRange) { + this(); + setSimpleMover(simpleMover); + setMaxRange(maxRange); + } + + public void doRun() { + contacts.clear(); + } + + public void doDetection(SimpleMover simpleMover) { + Set<SimpleMover> oldContacts = getContacts(); + contacts.add(simpleMover); + firePropertyChange("contacts", oldContacts, getContacts()); + + firePropertyChange("detection", simpleMover); + } + + public void doUndetection(SimpleMover simpleMover) { + Set<SimpleMover> oldContacts = getContacts(); + contacts.remove(simpleMover); + firePropertyChange("contacts", oldContacts, getContacts()); + + firePropertyChange("undetection", simpleMover); + } + + public void doStartMove(SimpleMover simpleMover) { + waitDelay("StartMove", 0.0, this); + } + + public void doStartMove(Sensor sensor) { + } + + public void doStop(SimpleMover simpleMover) { + waitDelay("Stop", 0.0, this); + } + + public void doStop(Sensor sensor) { + + } + + @Override + public Point2D getCurrentLocation() { + return simpleMover.getCurrentLocation(); + } + + public Point2D getVelocity() { + return simpleMover.getVelocity(); + } + + public void setSimpleMover(SimpleMover simpleMover) { + this.simpleMover = simpleMover; + } + + public void setMaxRange(double maxRange) { + if (maxRange <= 0.0) { + throw new IllegalArgumentException("maxRange must be > 0.0: " + maxRange); + } + this.maxRange = maxRange; + } + + public Set<SimpleMover> getContacts() { + return new HashSet<>(contacts); + } + + @Override + public String toString() { + return String.format("%s %s", getSimpleMover(), getMaxRange()); + } + + /** + * @return the maxRange + */ + @Override + public double getMaxRange() { + return maxRange; + } + + /** + * @return the simpleMover + */ + @Override + public SimpleMover getSimpleMover() { + return simpleMover; + } +} diff --git a/MV3302ClassCode/src/mv3302/sensor/Sensor.java b/MV3302ClassCode/src/mv3302/sensor/Sensor.java new file mode 100644 index 0000000000..7c2c05bd81 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/sensor/Sensor.java @@ -0,0 +1,22 @@ +package mv3302.sensor; + +import java.awt.geom.Point2D; +import java.util.Set; +import mv3302.SimpleMover; +import simkit.SimEntity; + +/** + * + * @author dansl + */ +interface Sensor extends SimEntity { + + public Point2D getCurrentLocation(); + public Point2D getVelocity(); + public double getMaxRange(); + public void doStartMove(SimpleMover simpleMover); + public void doStop(SimpleMover simpleMover); + public SimpleMover getSimpleMover(); + public Set<SimpleMover> getContacts(); + +} diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java new file mode 100644 index 0000000000..ba79c9b488 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java @@ -0,0 +1,36 @@ + +package mv3302.sensor; + +import java.util.HashSet; +import mv3302.SimpleMover; + +/** + * + * @author dansl + */ +public class SimpleConstantRateSensor extends AbstractSimpleSensor { + + private double meanTimeToDetect; + + public SimpleConstantRateSensor() { + contacts = new HashSet<>(); + } + + public SimpleConstantRateSensor(SimpleMover simpleMover, double maxRange, double meanTimeToDetect) { + this(); + setSimpleMover(simpleMover); + setMaxRange(maxRange); + setMeanTimeToDetect(meanTimeToDetect); + } + + public double getMeanTimeToDetect() { + return meanTimeToDetect; + } + + public void setMeanTimeToDetect(double meanTimeToDetect) { + if (meanTimeToDetect < 0.0) { + throw new IllegalArgumentException("meanTimeToDetect must be >= 0.0: " + meanTimeToDetect); + } + this.meanTimeToDetect = meanTimeToDetect; + } +} diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java new file mode 100644 index 0000000000..da862ca784 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java @@ -0,0 +1,36 @@ + +package mv3302.sensor; + +import java.util.HashSet; +import mv3302.SimpleMover; + +/** + * + * @author dansl + */ +public class SimpleConstantTimeSensor extends AbstractSimpleSensor { + + private double timeToDetect; + + public SimpleConstantTimeSensor() { + contacts = new HashSet<>(); + } + + public SimpleConstantTimeSensor(SimpleMover simpleMover, double maxRange, double timeToDetect) { + this(); + setSimpleMover(simpleMover); + setMaxRange(maxRange); + setTimeToDetect(timeToDetect); + } + + double getTimeToDetect() { + return timeToDetect; + } + + public void setTimeToDetect(double timeToDetect) { + if (timeToDetect < 0.0) { + throw new IllegalArgumentException("timeToDetect must be >= 0.0: " + timeToDetect); + } + this.timeToDetect = timeToDetect; + } +} diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java new file mode 100644 index 0000000000..b1d3fdc10f --- /dev/null +++ b/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java @@ -0,0 +1,23 @@ + +package mv3302.sensor; + +import java.util.HashSet; +import mv3302.SimpleMover; + +/** + * + * @author dansl + */ +public class SimpleCookieCutterSensor extends AbstractSimpleSensor { + + public SimpleCookieCutterSensor() { + contacts = new HashSet<>(); + } + + public SimpleCookieCutterSensor(SimpleMover simpleMover, double maxRange) { + this(); + setSimpleMover(simpleMover); + setMaxRange(maxRange); + } + +} -- GitLab