Class Pathfinder

java.lang.Object
me.wobblyyyy.pathfinder.api.Pathfinder

public class Pathfinder
extends java.lang.Object
The highest-level Pathfinder available.

As an abstraction, this class provides everything you'd possibly need to get started with finding paths and conquering noobs. Operation is fairly simple - if you're not following a tutorial on what's going on right now, you might want to go check one out.

Documentation is always available online - check out Pathfinder's GitHub repository if you're confused about where to find it. From there, you can learn about all kinds of very wonderful and very cool topics.

Although this class is designed to be as incredibly simple as possible, there's a ton of customizable features behind Pathfinder. In order to customize these features, and, actually, in order to instantiate a new Pathfinder, you'll need to read up on all of the different options available in the PathfinderConfig class.

This class, as a result of its high level of abstraction, is little more than a wrapper class with more user-friendly documentation. Anything that you'd like to accomplish but can't with this class can likely be accomplished by using the PathfinderManager class, which contains many more methods and bits of functionality that you can make use of.

Since:
0.1.0
Author:
Colin Robertson
See Also:
PathfinderManager
  • Field Summary

    Fields
    Modifier and Type Field Description
    private PathfinderConfig config
    The pathfinder's configuration.
    private PathfinderManager pathfinderManager
    The code that interfaces with the pathfinding math.
  • Constructor Summary

    Constructors
    Constructor Description
    Pathfinder​(PathfinderConfig config)
    Create a new Pathfinder instance.
  • Method Summary

    Modifier and Type Method Description
    void close()
    Finish this instance of the PathfinderManager's execution.
    PromisedFinder followPath​(me.wobblyyyy.edt.DynamicArray<HeadingPoint> points)
    Follow a given path.
    PromisedFinder followTrajectory​(Trajectory trajectory)
    Follow an inputted trajectory.
    PathfinderManager getManager()
    Get the PathfinderManager that Pathfinder uses.
    HeadingPoint getPosition()
    Get the position, including heading, of the robot.
    PromisedFinder goToPosition​(HeadingPoint target)
    Find a path to a position and go to it!
    void lock()
    Lock the current thread and prevent it from progressing until the pathfinder's execution thread is idle.
    void open()
    Open the PathfinderManager's threads and make it start doing its thing.
    void stopRobot()
    Stop the robot's drivetrain from moving.
    void tick()
    "Tick" the Pathfinder once.
    void tickUntil()
    Tick the pathfinder repeatedly until the pathfinder's execution has finished.
    void waitFor​(PromisedFinder path)
    Wait for a path to finish being followed before continuing.
    void waitForAndStop​(PromisedFinder path)
    Wait for a path's completion, stop the robot, and then continue.

    Methods inherited from class java.lang.Object

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

    • config

      private final PathfinderConfig config
      The pathfinder's configuration.
    • pathfinderManager

      private final PathfinderManager pathfinderManager
      The code that interfaces with the pathfinding math.
  • Constructor Details

    • Pathfinder

      public Pathfinder​(PathfinderConfig config)
      Create a new Pathfinder instance.

      Although you CAN have multiple pathfinders running at the same time, I don't think you'd really want to - a single pathfinder should do the trick for you.

      Once a Pathfinder instance is created, the thread manager will begin running its thread. Although technically a busy-wait, onSpinLoop() should help to reduce any performance overhead caused by running a thread in the background. If you'd like to manually control the thread and thread manager, you can access the threadManager and run the stop or start methods.

      Parameters:
      config - the pathfinder's configuration. You should go check out the field descriptions for the PathfinderConfig class if you're at all confused about what each of these configuration options do.
  • Method Details

    • getPosition

      public HeadingPoint getPosition()
      Get the position, including heading, of the robot.

      This position is based exclusively on the provided odometry system's reported position - if this isn't accurate, its very likely an issue you're having with your odometry system.

      Returns:
      the robot's position.
    • goToPosition

      public PromisedFinder goToPosition​(HeadingPoint target)
      Find a path to a position and go to it!

      Generating a path, especially on a larger field, is rather expensive. Unless you need to, you should try to avoid generating paths. The larger your field is, and the higher your specificity value is, the more expensive a pathfinding operation is.

      If the pathfinder fails to find/generate a path, nothing will happen. No path will be followed. The robot won't move. The robot won't do anything at all, actually. So if you're wondering why a path isn't generating, well... now you know.

      Post-2.0, a huge optimization area would be converting off of a grid based pathfinder and onto a node based one. Node pathfinders don't require as large of a memory commitment from the host.

      As Pathfinder is still a developing library (and I'm still a developing developer) (and I'm really awful at math), this might not always be entirely the most efficient way possible. Optimizations will certainly be needed.

      If your motors have the ability to enable and disable user control, which they should if they're implementing the Motor interface, and automatic thread-based updating is enabled, this method will handle absolutely everything for you.

      After a path is found, the robot will attempt to navigate along the path to the target position. If no path is found, nothing will happen. If a path is found and execution begins, only for an issue to take place, such as an odometry failure, a motor failure, or pathfinding timeout, the pathfinder will stop and this method will finish. This method is non-blocking, meaning you can execute other code after calling this.

      Parameters:
      target - the robot's target position and orientation.
      Returns:
      a chainable PromisedFinder object.
      See Also:
      PathfinderManager.goToPosition(HeadingPoint)
    • followPath

      public PromisedFinder followPath​(me.wobblyyyy.edt.DynamicArray<HeadingPoint> points)
      Follow a given path.

      Unlike the goToPosition(HeadingPoint) method, this does not attempt to optimize a path to as few targets as possible. Rather, this method generates paths to each of the waypoints and merges them all together - thus ensuring that these waypoints are still reached and not entirely ignored.

      If the pathfinder fails to find/generate a path, nothing will happen. No path will be followed. The robot won't move. The robot won't do anything at all, actually. So if you're wondering why a path isn't generating, well... now you know.

      Path and trajectory generations can be very expensive. The longer the path you'd like to follow, the more paths, and thus the more trajectories, that need to be generated.

      This method is used most effectively in conjunction with any type of trajectory-based follower, such as the SwerveFollower. Although it does work with any other type of follower, you don't get any of the benefits of waypoint-based path generation by using a simpler follower type, such as the PIDFollower.

      Parameters:
      points - the points to be used as waypoints in path generation.
      Returns:
      a chainable PromisedFinder object.
      See Also:
      PathfinderManager.followPath(HeadingPoint...)
    • followTrajectory

      public PromisedFinder followTrajectory​(Trajectory trajectory)
      Follow an inputted trajectory.
      Parameters:
      trajectory - the trajectory that should be followed.
      Returns:
      a PromisedFinder for the trajectory. Please note that this instance of promised finder doesn't contain any useful information. Additionally, it's always assumed that the finder has passed, even if it hasn't actually passed.
    • waitFor

      public void waitFor​(PromisedFinder path)
      Wait for a path to finish being followed before continuing. In addition to waiting for the path's completion, this method will halt the robot's drivetrain after the path has been completed.
      Parameters:
      path - the path that will be waited for. If there was an issue with generating the path itself, this method will do nothing, and, instead of waiting, will immediately return.
    • waitForAndStop

      public void waitForAndStop​(PromisedFinder path)
      Wait for a path's completion, stop the robot, and then continue. This method can best be described as a fusion of these two methods: lock() and stopRobot(). The robot's drivetrain will be stopped after the path has finished execution or after the path's generation fails.
      Parameters:
      path - the path that should be waited for. That didn't really make sense, but yeah - the promised result of a path that should be waited for.
    • lock

      public void lock()
      Lock the current thread and prevent it from progressing until the pathfinder's execution thread is idle.

      This is used in situations such as an autonomous program where you don't know how long the execution of a path will take. You can tell the pathfinder to follow a path or go to a point, then call this method, which will prevent the method from progressing until the pathfinder indicates that it has finished moving.

      This can also be used during tele-operated parts of matches - say you'd like to drive the robot to a certain point using the most mathematically optimized route. You can tell the pathfinder to go to your target point and then lock the tele-operated thread until the pathfinder has reached its destination.

      This type of code is known as blocking code, meaning that nothing on the current thread can happen until a certain thing has happened.

      See Also:
      PathfinderManager.lock(), tickUntil()
    • stopRobot

      public void stopRobot()
      Stop the robot's drivetrain from moving. This doesn't stop anything other than the robot's drivetrain - Pathfinder's threads will still be just as active as ever.
    • open

      public void open()
      Open the PathfinderManager's threads and make it start doing its thing. The PathfinderManager or Pathfinder MUST be opened before it can be used - not opening the PathfinderManager will result in NullPointerExceptions being thrown. And we all know those aren't very fun.
    • close

      public void close()
      Finish this instance of the PathfinderManager's execution. This will stop any of the threads that are still active, or at least try to do so. Threads spawned by followers can't be managed through here, but follower execution and general execution/odometry updating can be.

      This method will close both the execution and general pathfinder threads. Before finishing using a pathfinder, remember to call the close methods. Otherwise, you might have dangling threads that can eat up a lot of CPU.

    • tick

      public void tick()
      "Tick" the Pathfinder once. A tick is an update of both the follower queue and the odometry systems. This method is an alternative to the multithreading Pathfinder can also use. If you'd prefer to have all of our pathfinding related adventures operated in a sync fashion, this method right here is your guy.
      See Also:
      tickUntil()
    • tickUntil

      public void tickUntil()
      Tick the pathfinder repeatedly until the pathfinder's execution has finished. This method is different than the lock() method in that this doesn't utilize more than a single thread - all of the important execution stuff happens in the calling thread. This is mostly useful in situations where creating more than a single thread can be rather challenging - I'm looking at you, FRC and FTC... - but can be used just about anywhere.

      The end effect of this method is exactly the same as that of the lock() method, it's just the way it works internally is a bit different.

      See Also:
      lock()
    • getManager

      public PathfinderManager getManager()
      Get the PathfinderManager that Pathfinder uses.

      Unless you want to do some really advanced and cool stuff with the pathfinder, you don't need to get the manager to do anything.

      Returns:
      this instance of Pathfinder's manager class.