Getting Started
Installation
To install TaskGraphs.jl, start up Julia and type the following code-snipped into the REPL.
julia> ] # enter package mode by typing "]"
(@v1.4) pkg> add https://github.com/kylejbrown17/TaskGraphs.jl.git
Example
To construct and solve a predefined precedence-constrained multi agent task assignment and pathfinding (PC-TAPF) problem.
julia> using TaskGraphs
julia> solver = NBSSolver() # initialize a solver
NBSSolver{TaskGraphsMILPSolver{SparseAdjacencyMILP, Int64}, CBSSolver{ISPS{DefaultAStarSC, NTuple{5, Float64}}, NTuple{5, Float64}}, Float64} assignment_model: TaskGraphsMILPSolver{SparseAdjacencyMILP, Int64} path_planner: CBSSolver{ISPS{DefaultAStarSC, NTuple{5, Float64}}, NTuple{5, Float64}} logger: SolverLogger{Float64} return_first_feasible: Bool false
julia> prob = pctapf_problem_1(solver) # initialize the problem
PC_TAPF{SearchEnv{CompositeCostModel{Tuple{SumOfMakeSpans, FullCostModel{typeof(sum), Float64, ConflictCostModel{HardConflictTable{SparseArrays.SparseVector{Int64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}}}}, FullCostModel{typeof(sum), Float64, TravelDistance}, FullCostModel{typeof(sum), Float64, NullCost}, FullCostModel{typeof(sum), Float64, TransformCostModel{Float64, TravelTime}}}, NTuple{5, Float64}}, CompositeHeuristic{Tuple{EnvDistanceHeuristic, NullHeuristic, EnvDistanceHeuristic, EnvDistanceHeuristic, NullHeuristic}, NTuple{5, Float64}}, LowLevelSolution{TaskGraphs.State, GraphAction, NTuple{5, Float64}, CompositeCostModel{Tuple{SumOfMakeSpans, FullCostModel{typeof(sum), Float64, ConflictCostModel{HardConflictTable{SparseArrays.SparseVector{Int64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}}}}, FullCostModel{typeof(sum), Float64, TravelDistance}, FullCostModel{typeof(sum), Float64, NullCost}, FullCostModel{typeof(sum), Float64, TransformCostModel{Float64, TravelTime}}}, NTuple{5, Float64}}}}}(SearchEnv: cache: PlanningCache: closed_set: Set{Int64}() active_set: Set([4, 6, 8, 3]) node_queue: DataStructures.PriorityQueue(3 => (0, 0.0), 4 => (0, 1.0), 8 => (1, Inf), 6 => (1, Inf)) active task nodes: v = 4 => O(2,[8]) v = 6 => R(1,1) v = 8 => R(2,4) v = 3 => O(1,[5]) route_plan: LowLevelSolution: T: 0 1: [1 ] 2: [4 ] )
julia> solution, cost = solve!(solver,prob) # solve it
(SearchEnv: cache: PlanningCache: closed_set: Set([5, 16, 20, 12, 8, 17, 1, 19, 6, 11, 9, 14, 3, 7, 4, 13, 15, 2, 10, 18, 21]) active_set: Set{Int64}() node_queue: DataStructures.PriorityQueue{Int64, Tuple{Int64, Float64}, Base.Order.ForwardOrdering}() active task nodes: route_plan: LowLevelSolution: T: 0 1 2 3 4 5 1: [1 5 9 13 14 15 ] 2: [4 8 12 12 12 12 ] , 5.0)
julia> optimal_status(solver) # check the solution status
true
If you want to build your own PC_TAPF problem from scratch:
# copied from TaskGraphs/scripts/pctapf_demo.jl
using TaskGraphs
## set up the environment
vtx_grid = initialize_dense_vtx_grid(4,4) # 4 x 4 grid world
# 1 2 3 4
# 5 6 7 8
# 9 10 11 12
# 13 14 15 16
env = construct_factory_env_from_vtx_grid(vtx_grid)
## Define the initial conditions of the robots
robot_ics = [
ROBOT_AT(1,2), # robot 1 starts at vertex 2
ROBOT_AT(2,9), # robot 2 starts at vertex 9
]
## Define the manufacturing project
spec = ProjectSpec()
# set initial conditions of "raw materials"
set_initial_condition!(spec,OBJECT_AT(1,4)) # object 1 starts at vertex 4
set_initial_condition!(spec,OBJECT_AT(2,16)) # object 2 starts at vertex 16
# define the operations that need to take place
op1 = Operation(Δt=2) # operation 1 has a duration of 2 time steps
# inputs
set_precondition!(op1,OBJECT_AT(1,8)) # object 1 must be at vertex 8 before op1 can begin
set_precondition!(op1,OBJECT_AT(2,12)) # object 2 must be at vertex 12 before op1 can begin
# outputs
set_postcondition!(op1,OBJECT_AT(3,7)) # object 3 appears at vertex 7 when op1 is completed
add_operation!(spec,op1)
# add a terminal operation with no outputs
op2 = Operation(Δt=0)
set_precondition!(op2,OBJECT_AT(3,13))
add_operation!(spec,op2)
## define solver
solver = NBSSolver()
# finalize problem construction (the solver is passed as an argument here
# because it determines what cost model is used for the problem)
prob = pctapf_problem(solver,spec,env,robot_ics)
# solve the problem
solution, cost = solve!(solver,prob)
# check if the problem was solved to optimality
@show feasible_status(solver)
@show optimal_status(solver)