Package: cbs-mapf
Multi-Agent Path FindingAnonymous Multi-Agent Path Finding (MAPF) with Conflict-Based Search (CBS) and Space-Time A* (STA*). I strongly recommend you to also check out mySpace-Time A*repository for a complete picture of how this package works.VisualizationInstallationUsageTheoretical BackgroundContributingLicenseVisualization4 agents at the 4 corners of the map trying to align themselves in the middle:16 agents in a circlular layout trying to form a grid layout:The above visualizations are generated usingvisualizer.pyand scenario yaml files in thevisualization folder. Once the package (and otherrequirements) is installed, you can generate them like so:python3visualizer.pyscenario1.yaml
python3visualizer.pyscenario2.yamlInstallationThe package is namedcbs-mapfand listed onPyPI. You can use the pip to install:pip3installcbs-mapfThis will also install its sister packagespace-time-astar, also onGitHubandPyPI.UsageImport Plannerfromcbs_mapf.plannerimportPlannerConstructor ParametersPlanner(grid_size:int,robot_radius:int,static_obstacles:List[Tuple[int,int]])grid_size: int - each grid will be square with side lengthgrid_size.robot_radius: int - agents are assumed to be circles with radius beingrobot_radius.static_obstacles: List[Tuple[int, int]] - A list of coordinates specifying the static obstacles in the map.It is important thatgrid_sizeis not too small andstatic_obstaclesdoes not contain too many coordinates, otherwise the performance will severely deteriorate. What is 'too many' you might ask? It depends on your requirements.Find PathUsePlanner'splan()method:plan(starts: List[Tuple[int, int]],
     goals: List[Tuple[int, int]],
     assign:Callable = greedy_assign,
     max_iter:int = 200,
     low_level_max_iter:int = 100,
     max_process:int = 10,
     debug:bool = False) -> np.ndarrayParameters:starts: List[Tuple[int, int]] - A list of start coordinates.goals: List[Tuple[int, int]] - A list of goal coordinates.assign: Callable,optional- A function that assign each start coordinate to a goal coordinate. The default assignment yields a minimum cost with repesct to straight line euclidean distances, seeHungarian Algorithm.max_iter: int,optional- Max iterations of the high-level CBS algorithm. Default to200.low_level_max_iter: int,optional- Max iterations of the low-level STA* algorithm. Default to100.max_process: int,optional- Maximum number of processes to spawn. Default to10.debug: bool,optional- Prints some debug message. Default toFalse.The size ofstartsandgoalsmust be equal.Theassignfunction returns a list ofAgent, seeagent.pyfor more details.Return:Anumpy.ndaarraywith shape(N, L, 2)withNbeing the number of agents (i.e. # of start coordinates) andLbeing the length of the path.To get the path of the first agent (i.e. the agent with the first start coordinates instarts), simply take the 0th-indexed element.The individual path for each agent is padded to the same lengthL.Theoretical BackgroundThe high-level conflict-based search (CBS) is based on the paper[Sharon et al. 2012]. The low-level space-time A* (STA*) is like normal A* with an additional time dimension, see theGitHub pagefor more information.Constraint TreeThe core of the algorithm is the maintenance of a constraint tree (a binary min-heap in my implementation). The nodes in the constraint tree have 3 component:constraints - detailing what each agent should avoid in space-timesolution - path for each agentcost - the sum of the cost of individual pathsThe low-level STA* planner can take the constraints for an agent and calculate a collison-free path for that agent.PseudocodeTaken from[Sharon et al. 2012]with minor modification.node = Find paths for individual agents with no constraints.
Add node to the constraint tree.

while constraint tree is not empty:
  best = node with the lowest cost in the constraint tree

  Validate the solution in best until a conflict occurs.
  if there is no conflict:
    return best

  conflict = Find the first 2 agents with conflicting paths.

  new_node1 = node where the 1st agent avoid the 2nd agent
  Add new_node1 to the constraint tree.

  new_node2 = node where the 2nd agent avoid the 1st agent
  Add new_node2 to the constraint tree.ContributingSuggestions and pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.LicenseMIT