diff --git a/test/planning_utils.py b/test/planning_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..f09d096a4c9666e02baa2b689aa48ab060e88005
--- /dev/null
+++ b/test/planning_utils.py
@@ -0,0 +1,67 @@
+import gcode2contour as gc
+import numpy as np
+from gcode2contour import Position 
+
+
+class Action:
+    """
+    An action can be a job, or moving between jobs.
+
+    It has a start location, an end location, a time to execute
+        and when relevant, the associated job
+    """
+
+    def __init__(self, start_loc, end_loc, t, job=None):
+        self.start_location = start_loc
+        self.end_location = end_loc
+        self.time = t
+        self.job = job
+
+    def travel_to(self, other_job):
+        """
+        Calculate distance to another job
+        End position of this job to the start position of the other job
+        """
+        return abs(self.end_location - other_job.start_location)
+
+    def travel_from(self, other_job):
+        """
+        Calculate distance to another job
+        Start position of this job to the end position of the other job
+        """
+        return abs(self.start_location - other_job.end_location)
+
+
+def contours2Actions(contours):
+    """
+    Convert a list of contours into a list of actions
+    """
+
+    actions = []
+    for c in contours:
+        actions.append(Action(c.pos[0], c.pos[-1], c.time[-1], c))
+
+    return actions
+
+
+class Plan:
+    """
+    stores the plan of the whole system so far
+    """
+
+    def __init__(self, robot_list):
+        """
+        initiate at unplanned state
+        """
+
+        self.robots = robot_list
+        self.actions = {k:[] for k in robot_list}
+        self.time = {k:0 for k in robot_list}
+
+    def __getitem__(self, robot):
+        return (self.actions[robot], self.times[robot])
+
+    def append(self, action, robot):
+        self.actions[robot].append(action)
+        self.time[robot] += action.time
+
diff --git a/test/scheduler.py b/test/scheduler.py
index 244d4fd36358826e6763edb8ca52754818bfb162..18b4201adff2e554e6938b83edf24b7992280ba9 100644
--- a/test/scheduler.py
+++ b/test/scheduler.py
@@ -1,5 +1,6 @@
 from DecMCTS import Tree
 import numpy.random as rand
+from planning_utils import *
 
 # Creat a bunch of jobs
 # Each job has a time to do (in seconds?)
@@ -9,24 +10,34 @@ n_jobs = 20
 job_time_min = 0
 job_time_max = 10
 vel = 0.1
+
 rand.seed(1)
-job_locs = [(x,y) for x,y in zip(rand.rand(n_jobs), rand.rand(n_jobs))]
+job_locs  = [Position(x,y,0)
+             for x,y in zip(rand.rand(n_jobs), rand.rand(n_jobs))]
 job_times = [job_time_min+(job_time_max-job_time_min)*t
              for t in rand.rand(n_jobs)]
-def dist(p1,p2):
-    return ((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)**0.5
-travel_time = {(j1,j2):dist(job_locs[j1], job_locs[j2])/vel 
+
+# This is the todo list for the decmcts scheduler
+# - for now not considering dependencies
+actions = [Action(job_locs[i], job_locs[i], job_times[i], job=i)
+           for i in range(n_jobs)]
+
+# Premptively calculate distance pairs
+travel_time = {(j1,j2):actions[j1].travel_to(actions[j2])/vel
                for j1 in range(n_jobs)
-               for j2 in range(n_jobs)}
+               for j2 in range(n_jobs)
+               if j1!=j2}
 # Data needed for any calculations
 data = {
-    "job_locs": job_locs,
-    "job_times": job_times
+    "actions": actions
     "tt": travel_time
 }
 
-# State For a particular robot
 class State:
+    """
+    Stores the state of one robot for MCTS
+    """
+
     def __init__(self, start_pos):
         self.jobs = []
         self.time_so_far = 0
@@ -40,21 +51,22 @@ class State:
         self.time_wasted += data["tt"][self.jobs[-1], self.jobs[-2]]
         self.current_pos = job_locs[new_job]
 
-
 def state_storer(data, parent_state, action):
     if parent_state == None:
         return State((0,0)) # This state is also used Null action when calculating local reward
-    state = deepcopy(parent_state)
+    state = deepcopy(parent_state) # NOTE THIS WILL NEED TO CHANGE WITH CONTOURS
     state.append(action)
     return state
 
 # All actions not done by the current robot are considered available
 # actions of other robots are not considered
 def avail_actions(data, states, robot_id):
+    # NOTE THIS WILL NEED TO CHANGE WITH DEPENDENCY GRAPH
     return [j for j in list(range(n_jobs)) if j not in states[robot_id].jobs]
 
 # reward is inversely proportional to total time taken
 def reward(dat, states):
+    # TODO WILL NEED TO DO GREEDY ROLLOUT TO CALC REWARD
     time_wasted = [states[robot].time_wasted for robot in states]
     return 1/sum(each_robot_sum)