Git Product home page Git Product logo

papalotis / ft-fsd-path-planning Goto Github PK

View Code? Open in Web Editor NEW
52.0 2.0 19.0 7.01 MB

Formula Student Driverless Path Planning Algorithm. Colorblind centerline calculation algorithm developed by FaSTTUBe. It introduces a novel approach that uses neither Delaunay Triangulation nor RRT.

License: MIT License

Python 75.61% Jupyter Notebook 24.39%
algorithm driverless path-planning formula-student numba numpy python scipy formula-student-driverless robotics autonomous-driving

ft-fsd-path-planning's Introduction

ft-fsd-path-planning

FaSTTUBe Formula Student Driverless Path Planning Algorithm

With color information Without color information
Autocross FSG 2019
An animation demoing the path planning algorithm An animation demoing the path planning algorithm without color
Skidpad
An animation demoing the path planning algorithm An animation demoing the path planning algorithm without color

Updates

December 2023, July 2024 (v0.4)

(v0.4.3)

  • Added Acceleartion relocalization and stable acceleration path calculation.
  • Added caching mechanism for the sorrting step (about 20% performance improvement). The caching step slightly changes the logic of the algorithm and has not been thoroughly tested. By default, the caching is disabled. To enable it, set the experimental_performance_improvements parameter of the PathPlanner class to True.

(v0.4.1)

Added a property to the PathPlanner class that gives information about the relocalization process. The property is called relocalization_info and is a dataclass called RelocalizationInformation. It contains the following fields:

  • translation - A 2d array with the translation of the relocalization
  • rotation - A float with the rotation of the relocalization

If the relocalization process has not been run, or is not relevant (currently only Skidpad has relocalization), the property will return None.

The internal Skidpad frame has its origin at the center of the Skidpad, with the x-axis pointing towards the exit of the Skidpad and the y-axis pointing to the left-hand loop.

(v0.4.0)

Further improvements were added in December 2023. The main focus was to make the Skidpad mission more robust. The algorithm now uses a different approach for the Skidpad mission, which is much simpler and does not rely on the color of the cones at all.

The logic that runs during the Skidpad mission is stateful, so if you want to use it, you will have to review the usage of the relevant classes including PathPlanner. More specifically, while in the past one could create a new instance of the PathPlanner class, for each computation, with minimal performance penalties, now this will cause the Skidpad path calculation to fail. It is recommended to create a new instance of the PathPlanner class when the vehicle enters AS-READY state and the SLAM pose has stabilized.

This version also adds scikit-learn as a dependency, which is used for the Skidpad mission. You may use the summer-23 tag if you want to use the version of the algorithm that does not require scikit-learn and does not have the Skidpad improvements.

March 2023 (v0.3)

In March 2023, a further development of this algorithm was published. The new version has two main improvements:

  • The algorithm can now work without color. It can use cones for which the color is known and cones for which the color is unknown at the same time.
  • Performance improvements. The algorithm is faster, with the main focus of improvement being the cone sorting step.

Introduction

This repository contains the path planning algorithm developed by FaSTTUBe for the 2021/22 and 2022/23 Formula Student seasons.

You can find an interactive demo of the algorithm here.

The intention of this repository is to provide teams entering the driverless category with a path planning algorithm, so that they can get up and running as fast as possible. Teams are encouraged to use this repository as a basis and adapt it to their own pipeline, as well as make changes that will improve the algorithm's performance. If your team decides to use this repository, feel free to inform us. We would be happy to hear about your experience.

The algorithm differs from other common path planning approaches in that it can very robustly handle one side of the track not being visible, for example the inside of a corner. This is a common problem in the driverless category, especially for teams with less sophisticated detection pipelines.

Parts that are specific to the FaSTTUBe pipeline have been removed. The algorithm is now a standalone library that can be used in any pipeline. It is a Python package that can be installed using pip.

The algorithm requires the following inputs:

  • The car's current position and orientation in the slam map
  • The position of the (optionally colored) cones in the slam map

The algorithm outputs:

  • Samples of a parameterized b-spline with the x,y and curvature of the samples

The algorithm is completely stateless. Every time it is called no previous results are used. The only aspect that can be used again is the path that was previously generated. It is only used if the path calculation has failed.

The parts of the pipeline are also available as individual classes, so if you only want to use parts of it you can do so.

The codebase is written entirely in Python and makes heavy use of NumPy, SciPy, and Numba.

The algorithm has demonstrated its success as part of the FaSTTUBe pipeline, contributing to a 2nd place finish in Trackdrive at FS Czech 2023.

Installation

The package can be installed using pip:

pip install "fsd-path-planning[demo] @ git+https://[email protected]/papalotis/ft-fsd-path-planning.git"

This will also install the dependencies needed to run the demo (cli, matplotlib, streamlit, etc.). If you don't want to install the demo dependencies, you can install the package without the demo extra:

pip install "fsd-path-planning @ git+https://[email protected]/papalotis/ft-fsd-path-planning.git"

You can also clone the repository and install the package locally:

git clone https://github.com/papalotis/ft-fsd-path-planning.git
cd ft-fsd-path-planning
pip install -e .[demo]

You can again skip the [demo] extra if you don't want to install the demo dependencies.

Performance

The algorithm (with default parameters) is fast enough to run in real-time on a Jetson Xavier AGX 16GB on MAXN power mode. On that platform, the algorithm takes on average around 10ms from start to finish. You can run the demo to get an idea of the performance on your hardware.

Note that the first time that you run the algorithm, it will take around 30-60 seconds to compile all the Numba functions. Run the demo a second time to get a real indicator on performance.

Run the following command to run the demo on your machine:

python -m fsd_path_planning.demo

Basic usage

from fsd_path_planning import PathPlanner, MissionTypes, ConeTypes

path_planner = PathPlanner(MissionTypes.trackdrive)
# you have to load/get the data, this is just an example
global_cones, car_position, car_direction = load_data() 
# global_cones is a sequence that contains 5 numpy arrays with shape (N, 2),
# where N is the number of cones of that type

# ConeTypes is an enum that contains the following values:
# ConeTypes.UNKNOWN which maps to index 0
# ConeTypes.RIGHT/ConeTypes.YELLOW which maps to index 1
# ConeTypes.LEFT/ConeTypes.BLUE which maps to index 2
# ConeTypes.START_FINISH_AREA/ConeTypes.ORANGE_SMALL which maps to index 3
# ConeTypes.START_FINISH_LINE/ConeTypes.ORANGE_BIG which maps to index 4

# car_position is a 2D numpy array with shape (2,)
# car_direction is a 2D numpy array with shape (2,) representing the car's direction vector
# car_direction can also be a float representing the car's direction in radians

path = path_planner.calculate_path_in_global_frame(global_cones, car_position, car_direction)

# path is a Mx4 numpy array, where M is the number of points in the path
# the columns represent the spline parameter (distance along path), x, y and path curvature

Take a look at this notebook for a more detailed example: simple_application.ipynb

There is no resetting functionality in the classes. If you want to reset the path planner, you can simply create a new instance of the class. It is recommended to create a new instance of the relevant classes when the vehicle enters AS-READY state.

Previous versions

Alternate versions of the algorithm are available as git tags:

  • color-dependent - The algorithm needs color information to work. This version was used in the 2021/22 season.
  • summer-23 - The algorithm can work without color information. This version was used in the 2022/23 season.

ft-fsd-path-planning's People

Contributors

papalotis avatar rohrschacht avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ft-fsd-path-planning's Issues

IndexError in sorting

IndexError in sorting stage

[global_planner-4]     all_end_configurations, history = find_all_end_configurations(
[global_planner-4]   File "/usr/local/lib/python3.10/dist-packages/fsd_path_planning/sorting_cones/trace_sorter/end_configurations.py", line 512, in find_all_end_configurations
[global_planner-4]     ) = _impl_find_all_end_configurations(
[global_planner-4]   File "/usr/local/lib/python3.10/dist-packages/fsd_path_planning/sorting_cones/trace_sorter/end_configurations.py", line 397, in _impl_find_all_end_configurations
[global_planner-4]     current_attempt[position_in_stack] = next_idx
[global_planner-4] IndexError: index 1 is out of bounds for axis 0 with size 1

Run pipeline up to raw path only when needed

Currently every step of the pipeline runs for every function call. However when no new cones have been added to the map and the picked started cones are the same as in the last calculation we can use the results from the previous calculation and only compute the fine path that starts from the car. This will potentially improve performance especially when the car moves slowly and the pose doesn't change often.

Thorough documentation

This will be the last year this repo will be intensely maintained by me. In order to make sure that the algorithm can be used in the future a thorough documentation of every aspect of the pipeline needs to be created. This needs to happen until the end of September which is the time after which I no longer plan to be involved in FS anymore.

Make relocalization information available through public API

Currently Skidpad relocalization process is obfuscated. However it is important for many Pipelines to have information about the relocalization. The PathPlanner public API needs to be updated so that the information is made available.

The information that need to be made publicly available are:

  • Has the relocalization succeeded?
  • What is the transform from the global to the internal skidpad frame?

To encode the relocalization information a dataclass will be created that will contain that info.

The PathPlanner class will get a new method (probably property) that will return an instance of the new dataclass.

The issue will be updated if any amendments are needed.

Pin numba to <0.60

Latest numba version seems to not be compatible/have a bug. Using numba <0.60 seems to work.

Automatic parameter estimation

Create a system that given a set of tracks, applies an automated parameter estimation algorithm that finds parameters that maximizes the number of track configurations for which the algorithm works correctly. This way the correct parameters can be found for the track configuration one cares for.

Make all algorithm parameters available to be adjustable through public API

Currently many parameters of the algorithm are either hardcoded or only adjustable in deep parts of the codebase. All parameters that can meaningfully affect either the algorithm's output or performance need to be made available in the public API. Furthermore, two parameter presets need to be made available, one for when the algorithm runs in colorless mode and one when colors are always available and are guaranteed to be mostly correct.

Add relocalization for remaining missions

Currently only the Skidpad mission has relocalization abilities. We want to extend this to Acceleration and AutoX/Trackdrive.

For Acceleration we want to estimate the track width and the angle of the car relative to the Acceleration track direction.

For AX/TD we want to be given cone observation from a previous run and align it with the cones seen in this run.

Skidpad mission ZeroDivisionError

I am using the fsd_path_planning package for a Skidpad mission and encountering a ZeroDivisionError during path calculation. Additionally, the path planner seems to ignore orange cones.

When executing the path planning for a Skidpad mission, a ZeroDivisionError occurs in the connect_path_to_car method. The error trace is as follows:

Traceback (most recent call last):
  ...
  File "[...]/lib/python3.10/site-packages/fsd_path_planning/calculate_path/core_calculate_path.py", line 451, in connect_path_to_car
    angle_to_first_point = vec_angle_between(...)
ZeroDivisionError: division by zero

I also noticed that the path planner does not consider the orange cones in its calculations. I am not sure if this is an intended behavior or a limitation in the current Skidpad implementation.

Python Version: 3.10
fsd_path_planning version: 0.3.2

I am attaching the relevant code snippet for reference. Any insights or fixes for this issue would be greatly appreciated.

import numpy as np
from fsd_path_planning import PathPlanner, MissionTypes, ConeTypes
import matplotlib.pyplot as plt

# Skidpad track
cones_blue = np.array(
    [[0.0, 15.0], [-0.5804185646014384, 17.91796117178381], [-2.233310793452575, 20.391689206547426],
     [-4.70703882821619, 22.044581435398563], [-7.624999999999999, 22.625], [-10.542961171783809, 22.044581435398563],
     [-13.016689206547424, 20.391689206547426], [-14.669581435398563, 17.91796117178381], [-15.25, 15.000000000000002],
     [-14.669581435398563, 12.082038828216191], [-13.016689206547426, 9.608310793452576],
     [-10.542961171783814, 7.95541856460144], [-7.625000000000002, 7.375], [-4.707038828216189, 7.955418564601439],
     [-2.233310793452577, 9.608310793452574], [-0.5804185646014401, 12.082038828216186],
     [6.5589885311209155, 5.183779967067581], [10.624999999999998, 4.375], [14.691011468879081, 5.183779967067579],
     [18.138009550107064, 7.4869904498929305], [20.44122003293242, 10.933988531120914], [21.25, 15.0],
     [20.44122003293242, 19.06601146887908], [18.138009550107068, 22.513009550107068],
     [14.69101146887908, 24.81622003293242], [10.625, 25.625], [6.558988531120922, 24.81622003293242],
     [4.722066274166729, 23.834364630714546], [4.7220662741667265, 6.165635369285457]])

cones_yellow = np.array(
    [[18.25, 15.0], [17.669581435398563, 17.91796117178381], [16.016689206547426, 20.391689206547426],
     [13.54296117178381, 22.044581435398563], [10.625, 22.625], [7.7070388282161915, 22.044581435398563],
     [5.233310793452576, 20.391689206547426], [3.5804185646014384, 17.91796117178381], [3.0, 15.000000000000002],
     [3.5804185646014375, 12.082038828216191], [5.233310793452574, 9.608310793452576],
     [7.707038828216186, 7.95541856460144], [10.624999999999998, 7.375], [13.542961171783812, 7.955418564601439],
     [16.016689206547422, 9.608310793452574], [17.66958143539856, 12.082038828216186],
     [-3.558988531120921, 24.81622003293242], [-7.624999999999999, 25.625], [-11.69101146887908, 24.81622003293242],
     [-15.138009550107068, 22.513009550107068], [-17.44122003293242, 19.06601146887908], [-18.25, 15.000000000000002],
     [-17.44122003293242, 10.933988531120923], [-15.13800955010707, 7.486990449892933],
     [-11.691011468879084, 5.183779967067581], [-7.625000000000002, 4.375], [-3.558988531120919, 5.183779967067579],
     [-1.7220662741667256, 23.834364630714543], [-1.72206627416673, 6.165635369285454]])

cones_orange_big = np.array([[0.0, 14.5], [0.0, 15.5], [3.0, 14.5], [3.0, 15.5]])

cones_orange_small = np.array(
    [[0.0, 0.0], [3.0, 0.0], [0.0, 5.0], [3.0, 5.0], [0.0, 40.0], [1.0, 40.0], [2.0, 40.0], [3.0, 40.0], [0.0, 37.0],
     [0.0, 34.0], [0.0, 31.0], [0.0, 28.0], [0.0, 25.0], [3.0, 37.0], [3.0, 34.0], [3.0, 31.0], [3.0, 28.0],
     [3.0, 25.0]])

#create empty array for unknown cones
cones_unknown_raw = np.empty((0, 2), float)

def load_data():
    global_cones = [cones_unknown_raw, cones_yellow, cones_blue, cones_orange_small, cones_orange_big]
    car_position = np.array([1.5, 2])
    car_direction = np.array([0, 1.0])
    return global_cones, car_position, car_direction

# Load data and create path planner
global_cones, car_position, car_direction = load_data()
path_planner = PathPlanner(MissionTypes.skidpad)

#  Calculate path
out = path_planner.calculate_path_in_global_frame(global_cones, car_position, car_direction, return_intermediate_results = True)

(
    path,
    sorted_left,
    sorted_right,
    left_cones_with_virtual,
    right_cones_with_virtual,
    left_to_right_match,
    right_to_left_match,
) = out

# Plot results
plt.plot(*left_cones_with_virtual.T, "o-", c="b")
plt.plot(*right_cones_with_virtual.T, "o-", c="r")
plt.plot(*sorted_left.T, "o-", c="b")
plt.plot(*sorted_right.T, "o-", c="r")
plt.plot(*path[:, 1:3].T)
plt.axis("equal")
plt.show()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.