diff --git a/MV3302ClassCode/src/mv3302/SimpleMover.java b/MV3302ClassCode/src/mv3302/SimpleMover.java new file mode 100644 index 0000000000000000000000000000000000000000..9cc726cae00b8c55ad7315902804e70eb8beae68 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/SimpleMover.java @@ -0,0 +1,204 @@ +/* + * 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 simkit.Schedule; +import simkit.SimEntityBase; +import simkit.smd.Mover; + +/** + * + * @author ahbuss + */ +public class SimpleMover extends SimEntityBase { + + public static Point2D NaP = new Point2D.Double(NaN, NaN); + + public Point2D initialLocation; + + public double maxSpeed; + + public Point2D lastStopLocation; + + public Point2D velocity; + + public Point2D destination; + + public double startMoveTime; + + public SimpleMover() { + lastStopLocation = (Point2D) NaP.clone(); + velocity = (Point2D) NaP.clone(); + destination = (Point2D) NaP.clone(); + } + + public SimpleMover(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, this); + } + } + + public void doStartMove(Mover mover) { + 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, mover); + } + + public void doEndMove(Mover mover) { + 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()); + } + + 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); + } + + /** + * @return the NaP + */ + public static Point2D getNaP() { + return NaP; + } + + /** + * @param aNaP the NaP to set + */ + public static void setNaP(Point2D aNaP) { + NaP = aNaP; + } + + /** + * @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; + } + + /** + * @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; + } + + /** + * @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; + } + + 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()); + } + + public String paramString() { + return super.toString(); + } +} diff --git a/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java new file mode 100644 index 0000000000000000000000000000000000000000..9090d7665e79486709c93a3d9907785f6ec65705 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java @@ -0,0 +1,128 @@ +/* + * 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 simkit.SimEntityBase; +import simkit.smd.Mover; + +/** + * + * @author dansl + */ +public class SimplePathMoverManager extends SimEntityBase { + + private boolean startOnRun; + + protected Point2D[] path; + + protected int nextIndex; + + protected Point2D nextWaypoint; + + public SimplePathMoverManager() { + } + + public SimplePathMoverManager(Point2D[] path, boolean startOnRun) { + setPath(path); + setStartOnRun(startOnRun); + } + + @Override + public void reset() { + super.reset(); + nextIndex = 0; + + } + + public void doRun() { + int oldNextIndex = getNextIndex(); + nextIndex -= 1; + firePropertyChange("nextIndex", getNextIndex()); + nextWaypoint = new Point2D.Double(NaN, NaN); + if (isStartOnRun()) { + waitDelay("NextWP", 0.0); + } + } + + public void doNextWP(){ + int oldNextIndex = getNextIndex(); + nextIndex += 1; + firePropertyChange("nextIndex", getNextIndex()); + Point2D oldNextWaypoint = getNextWaypoint(); + nextWaypoint = path[nextIndex]; + firePropertyChange("nextWaypoint", getNextWaypoint()); + waitDelay("MoveTo", 0.0, nextWaypoint); + } + + public void doEndMove(Mover mover){ + if (nextIndex < path.length -1){ + waitDelay("NextWP", 0.0); + } + if (nextIndex == path.length -1){ + waitDelay("Stop", 0.0); + } + } + + public void doStop(){ + } + + public void doOrderStop(){ + } + + public void doMoveTo(Point2D nextWaypoint){ + } + + /** + * @return the startOnRun + */ + public boolean isStartOnRun() { + return startOnRun; + } + + /** + * @param startOnRun the startOnRun to set + */ + public void setStartOnRun(boolean startOnRun) { + this.startOnRun = startOnRun; + } + + /** + * @return the path + */ + public Point2D[] getPath() { + return path; + } + + public Point2D getPath(int index) { + return path[index]; + } + + /** + * @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); + } + } + + /** + * @return the nextIndex + */ + public int getNextIndex() { + return nextIndex; + } + + /** + * @return the nextWaypoint + */ + public Point2D getNextWaypoint() { + return (Point2D) nextWaypoint; + } +} diff --git a/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java new file mode 100644 index 0000000000000000000000000000000000000000..ed4c0fc37bb76c6d3189bccf778cfd0a744a1949 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java @@ -0,0 +1,56 @@ +/* + * 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; + +/** + * + * @author dansl + */ +public class SimplePatrolMoverManager extends SimplePathMoverManager{ + + /** + * Zero-argument constructor + */ + public SimplePatrolMoverManager() { + } + + /** + * Instantiate with given given parameters + * + * @param path Given waypoints + * @param startOnRun true if start immediately + */ + 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) + */ + @Override + public void doEndMove(Mover mover) { + waitDelay("NextWP", 0.0, getPath(nextIndex)); + } + + @Override + public void doNextWP(){ + int oldNextIndex = getNextIndex(); + nextIndex = (nextIndex+1)%path.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){ + } + +} diff --git a/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java new file mode 100644 index 0000000000000000000000000000000000000000..ec2ab863feb7e67ed60774c15522d7b716cfbd82 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java @@ -0,0 +1,123 @@ +/* + * 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 simkit.random.RandomVariate; +import simkit.smd.Mover; + +/** + * + * @author dansl + */ +public class SimpleRandomMoverManager extends SimplePathMoverManager { + + /** + * Array to generate coordinates randomly + */ + public RandomVariate[] coordinateGenerator; + + /** + * If true start immediately + */ + public boolean startOnRun; + + public SimpleRandomMoverManager() { + } + + /** + * Instantiate with the given parameters + * + * @param coordinateGenerator Given random coordinate generator + * @param startOnRun true if starting immediately + */ + public SimpleRandomMoverManager(RandomVariate[] coordinateGenerator, + boolean startOnRun) { + this.setCoordinateGenerator(coordinateGenerator); + this.setStartOnRun(startOnRun); + } + + /** + * If startOnRun is true, generate random coordinates and schedule MoveTo + * with that destination + */ + @Override + public void doRun() { + Point2D oldNextWaypoint = getNextWaypoint(); + nextWaypoint = new Point2D.Double(NaN, NaN); + firePropertyChange("nextWaypoint", oldNextWaypoint, nextWaypoint); + if (isStartOnRun()) { + waitDelay("NextWP", 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); + } + + @Override + public void doMoveTo(Point2D nextWayPoint) { + } + + @Override + public void doEndMove(Mover mover) { + waitDelay("NextWP", 0.0); + } + + @Override + public void doStop(){ + waitDelay("OrderStop", 0.0); + } + + @Override + public void doOrderStop(){ + } + + /** + * @return the coordinateGenerator + */ + public RandomVariate[] getCoordinateGenerator() { + return coordinateGenerator.clone(); + } + + public RandomVariate getCoordinateGenerator(int index) { + return coordinateGenerator[index]; + } + + /** + * @param coordinateGenerator the coordinateGenerator to set + */ + 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; + } + + /** + * @param startOnRun the startOnRun to set + */ + @Override + public void setStartOnRun(boolean startOnRun) { + this.startOnRun = startOnRun; + } + +} diff --git a/MV3302ClassCode/src/mv3302/run/Assignment6.java b/MV3302ClassCode/src/mv3302/run/Assignment6.java new file mode 100644 index 0000000000000000000000000000000000000000..ae309cd1551e57abbddc1739810133731074df03 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/run/Assignment6.java @@ -0,0 +1,94 @@ +/* + * 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.SimplePatrolMoverManager; +import mv3302.SimpleRandomMoverManager; +import simkit.Schedule; +import simkit.random.RandomVariate; +import simkit.random.RandomVariateFactory; +import simkit.util.SimplePropertyDumper; + +/** + * + * @author dansl + */ +public class Assignment6 { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Point2D initialLocation = new Point2D.Double(0.0, 250.0); + double maxSpeed = 30.0; + + SimpleMover simpleMover = new SimpleMover(initialLocation, maxSpeed); + System.out.println(simpleMover); + + Point2D[] path = new Point2D[]{ + new Point2D.Double(-200.0, 0.0), + new Point2D.Double(-200.0, 250.0), + new Point2D.Double(200.0, 250.0), + new Point2D.Double(0.0, 250.0)}; + + SimplePathMoverManager simplePathMoverManager = new SimplePathMoverManager(path, true); + System.out.println(simplePathMoverManager); + + Point2D initialLocation2 = new Point2D.Double(0.0, 150.0); + double maxSpeed2 = 40.0; + SimpleMover simpleMover2 = new SimpleMover(initialLocation2, maxSpeed2); + System.out.println(simpleMover2); + + Point2D[] path2 = new Point2D[]{ + new Point2D.Double(0.0, 300.0), + new Point2D.Double(0.0, -100.0)}; + + SimplePatrolMoverManager simplePatrolMoverManager = new SimplePatrolMoverManager(path2, true); + System.out.println(simplePatrolMoverManager); + + // The coordinate generators + RandomVariate[] coordinateGenerator = new RandomVariate[]{ + RandomVariateFactory.getInstance("Uniform", -250.0, 250.0), + RandomVariateFactory.getInstance("Uniform", -100, 300.0) + }; +// Note startOnRun is now true + SimpleRandomMoverManager simpleRandomMoverManager = new SimpleRandomMoverManager(coordinateGenerator, + true); + System.out.println(simpleRandomMoverManager); + + Point2D initialLocation3 = new Point2D.Double(0.0, 0.0); + double maxSpeed3 = 50.0; + SimpleMover simpleMover3 = new SimpleMover(initialLocation3, maxSpeed3); + System.out.println(simpleMover3); + + simpleMover.addSimEventListener(simplePathMoverManager); + simplePathMoverManager.addSimEventListener(simpleMover); + +// simpleMover.addSimEventListener(simplePatrolMoverManager); +// simplePatrolMoverManager.addSimEventListener(simpleMover); +// +// simpleMover.addSimEventListener(simpleRandomMoverManager); +// simpleRandomMoverManager.addSimEventListener(simpleMover); + + SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(); + simpleMover.addPropertyChangeListener(simplePropertyDumper); + simplePathMoverManager.addPropertyChangeListener(simplePropertyDumper); + + Schedule.setVerbose(true); + +// Schedule.stopAtTime(10.5); + Schedule.reset(); + simpleMover.waitDelay("MoveTo", 0.0); + simpleMover.waitDelay("OrderStop", 0.1); + simpleMover.waitDelay("Stop", 0.2); + simplePatrolMoverManager.waitDelay("Stop", 10.0); + simpleRandomMoverManager.waitDelay("Stop", 20.0); + Schedule.startSimulation(); + } + +}