Class FollowerExecutor

java.lang.Object
me.wobblyyyy.pathfinder.thread.FollowerExecutor

public class FollowerExecutor
extends java.lang.Object
Execute a given follower among several different threads.

In order to compensate for the computationally-expensive nature of complex pathfinding and trajectory generation, important following code is offloaded to a secondary thread. This ensures that the main thread stays freed enough to allow a user to still have control over the program.

As with any threaded things, however, they suck to conceptualize. The aim of this class is to make it easier to follow along with how the pathfinder actually generates and follows paths and trajectories.

Since:
0.1.0
Author:
Colin Robertson
  • Field Summary

    Fields
    Modifier and Type Field Description
    private me.wobblyyyy.edt.StaticArray<java.lang.Runnable> actions
    Actions to execute.
    private Drive drive
    The robot's drivetrain.
    private java.lang.Runnable executor
    Execution thread.
    private java.util.ArrayList<Follower> followers
    The currently-executed followers.
    private me.wobblyyyy.edt.DynamicArray<Follower> hasCalculated
    A list of all of the followers that have run their calculation method already.
    private boolean shouldRun
    Should the thread continue its execution.
  • Constructor Summary

    Constructors
    Constructor Description
    FollowerExecutor​(Drive drive)
    Create a new follower executor and initialize the executor thread.
  • Method Summary

    Modifier and Type Method Description
    void addActions()
    Thread-safe method to generate actions.
    void clear()
    Clear all of the followers and runnables, essentially resetting the FollowerExecutor instance.
    void clearActions()
    Thread-safe method to clear all of the actions.
    void close()
    Stop this FollowerExecutor's execution, or at least attempt to do so.
    me.wobblyyyy.edt.StaticArray<java.lang.Runnable> generateRunnables()
    Generate a list of Runnable elements to be executed by the execution thread.
    me.wobblyyyy.edt.StaticArray<java.lang.Runnable> getActions()
    Thread-safe way to get all of the actions.
    boolean isEmpty()
    Check whether or not both of the follower array lists are empty, indicating that there's nothing for the pathfinder to do.
    void lock()
    Lock the current thread until the pathfinder has finished its execution.
    private java.lang.Runnable moveUp​(Follower f)
    Generate a Runnable that can be executed to progress past the current follower and onto the next one.
    void queueFollower​(Follower f)
    Queue a single follower element.
    void queueFollowers​(me.wobblyyyy.edt.DynamicArray<Follower> followers)
    Queue a collection of follower elements.
    void start()
    Start the follower executor's thread.
    void stop()
    Stop the follower executor's thread.
    void tick()
    Run the follower executor once.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • executor

      private final java.lang.Runnable executor
      Execution thread.
    • followers

      private final java.util.ArrayList<Follower> followers
      The currently-executed followers.
    • hasCalculated

      private final me.wobblyyyy.edt.DynamicArray<Follower> hasCalculated
      A list of all of the followers that have run their calculation method already.

      Depending on for how long the pathfinder is run for, this array list may eventually overflow. In order to compensate for this potential overflow, we should add some code that clears this list at some point.

    • actions

      private me.wobblyyyy.edt.StaticArray<java.lang.Runnable> actions
      Actions to execute. MUST BE THREAD SAFE!

      Modification should only be handled through synchronized methods to ensure no bad stuff happens.

    • shouldRun

      private boolean shouldRun
      Should the thread continue its execution.
    • drive

      private final Drive drive
      The robot's drivetrain.

      This is used for enabling and disabling user control when the pathfinder is enabled or disabled.

  • Constructor Details

    • FollowerExecutor

      public FollowerExecutor​(Drive drive)
      Create a new follower executor and initialize the executor thread.

      PLEASE NOTE: Nothing's going to happen after you construct a new instance of this executor. The thread must be enabled with the start method prior to having any function. To disable the thread, you can run the stop method.

      At this point, the thread hasn't been started yet. If you're interfacing directly with this class rather than using a pathfinder manager instance as a proxy, you'll need to remember to start the threads before trying to follow paths.

      Parameters:
      drive - the robot's drivetrain.
  • Method Details

    • start

      public void start()
      Start the follower executor's thread.

      Threads should not be started after they're already running.

    • tick

      public void tick()
      Run the follower executor once.
    • stop

      public void stop()
      Stop the follower executor's thread.

      Thread.stop() has been a deprecated method for a while - is there an effective alternative we can use?

      THIS DOES NOT ACTUALLY STOP THE THREAD! Rather, it updates the flag indicating whether or not the follower should be run as intended.

    • getActions

      public me.wobblyyyy.edt.StaticArray<java.lang.Runnable> getActions()
      Thread-safe way to get all of the actions.
      Returns:
      actions to be executed.
    • addActions

      public void addActions()
      Thread-safe method to generate actions.
    • clearActions

      public void clearActions()
      Thread-safe method to clear all of the actions.
    • clear

      public void clear()
      Clear all of the followers and runnables, essentially resetting the FollowerExecutor instance.
    • generateRunnables

      public me.wobblyyyy.edt.StaticArray<java.lang.Runnable> generateRunnables()
      Generate a list of Runnable elements to be executed by the execution thread.

      If a follower has not finished its execution yet, we disable user control for the robot's drivetrain as a precautionary measure. If the follower HAS finished its execution, we can then enable user control once again.

      Returns:
      to-be-executed Runnable elements.
    • moveUp

      private java.lang.Runnable moveUp​(Follower f)
      Generate a Runnable that can be executed to progress past the current follower and onto the next one.
      Parameters:
      f - the current follower.
      Returns:
      a Runnable to move upwards in the execution order.
    • queueFollower

      public void queueFollower​(Follower f)
      Queue a single follower element.

      Queuing followers isn't a complicated process. Note, however, that if the thread that executes the followers IS NOT active, nothing will actually happen to the followers.

      After a follower has been queued, it won't take effect immediately. After the current bank of followers has been exhausted, it'll move on to newly-queued followers, such as the follower that you may have just provided. How cool!

      Parameters:
      f - the follower to queue.
    • queueFollowers

      public void queueFollowers​(me.wobblyyyy.edt.DynamicArray<Follower> followers)
      Queue a collection of follower elements.

      Queuing followers isn't a complicated process. Note, however, that if the thread that executes the followers IS NOT active, nothing will actually happen to the followers.

      After a follower has been queued, it won't take effect immediately. After the current bank of followers has been exhausted, it'll move on to newly-queued followers, such as the follower that you may have just provided. How cool!

      Parameters:
      followers - the follower elements to queue.
    • isEmpty

      public boolean isEmpty()
      Check whether or not both of the follower array lists are empty, indicating that there's nothing for the pathfinder to do.
      Returns:
      whether or not the pathfinder is idle.
    • lock

      public void lock()
      Lock the current thread until the pathfinder has finished its execution.

      Unfortunately, we can't use a Thread.join() like method because of the way Pathfinder handles multithreading, especially path following. This should be (roughly) the same.

      As a locking operation, the calling thread will not be able to progress until the execution of this thread has finished. If you'd like to queue another follower while the system is active, you can do so. Yay!

    • close

      public void close()
      Stop this FollowerExecutor's execution, or at least attempt to do so. This method won't actually stop the execution of the thread - rather, it'll signal the thread's execution to come to a stop.
      See Also:
      stop()