Commit e5aae54c by Jayant Khatkar

### moved scheduler files to different repo

parent 2afd8445
 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
 from DecMCTS import Tree from copy import copy, deepcopy import numpy as np import numpy.random as rand from planning_utils import * import matplotlib.pyplot as plt # Creat a bunch of jobs # Each job has a time to do (in seconds?) # Each job has an x-y location (0-1 m) # Each job pair has a time to travel between them (fixed velocity m/s) n_jobs = 20 job_time_min = 0 job_time_max = 10 vel = 0.1 rand.seed(1) 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)] # 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):j1.travel_to(j2)/vel for j1 in actions for j2 in actions if j1 is not j2} # Data needed for any calculations data = { "actions": set(actions), "tt": travel_time, "mean_tt": sum(travel_time.values())/len(travel_time) } class State: """ Stores the state of one robot for MCTS """ def __init__(self, start_pos): self.actions = [] self.time_so_far = 0 self.time_wasted = 0 self.current_pos = start_pos def append(self, new_job): self.actions.append(new_job) if len(self.actions)>1: self.time_so_far += data["tt"][self.actions[-1], self.actions[-2]] \ + new_job.time self.time_wasted += data["tt"][self.actions[-1], self.actions[-2]] else: self.time_wasted = \ Action(Position(0,0,0),Position(0,0,0),0).travel_to(new_job)/vel self.time_so_far = new_job.time + self.time_wasted self.current_pos = new_job.end_location def state_storer(data, parent_state, action): if parent_state == None: return State(Position(0,0,0)) # This state is also used Null action when calculating local reward state = State(action.start_location) state.actions = copy(parent_state.actions) state.time_so_far = parent_state.time_so_far state.time_wasted = parent_state.time_wasted 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, state, robot_id): # NOTE THIS WILL NEED TO CHANGE WITH DEPENDENCY GRAPH return [j for j in data["actions"] if j not in state.actions] # reward is inversely proportional to total time taken def reward(dat, states): # TODO DO GREEDY ROLLOUT TO CALC REWARD ?? # Reward is 1/(estimation of total time wasted) # the estimation is a sum of: # 1- time wasted so far in the plan # 2- estimated time wasted in doing the remaining jobs # This is the number of remaining jobs * mean travel time # 3- time diff between each robot and the robot with longest plan # 4- Duplicate executions of jobs done_jobs = sum([states[robot].actions for robot in states], []) time_wasted_1 = sum([states[robot].time_wasted for robot in states]) time_wasted_2 = len(data["actions"] - set(done_jobs))*data["mean_tt"] t_so_far= [states[robot].time_so_far for robot in states] time_wasted_3 = sum(max(t_so_far) - np.array(t_so_far)) time_wasted_4 = sum([a.time for a in done_jobs if done_jobs.count(a)>1])/2 return -(time_wasted_1 + time_wasted_2 + time_wasted_3 + time_wasted_4) # Communicate top n nodes of the MCTS tree comm_n = 5 n_robots = 2 def trees2Plan(trees): """ extract the best action sequence from each tree and convert it into a Plan object """ plan = Plan(list(range(len(trees)))) for i in range(len(trees)): plan.actions[i] = trees[i].my_act_dist.best_action().actions plan.time[i] = trees[i].my_act_dist.best_action().time_so_far return plan # Plot function def plot_actions(actions, plan = None): """ Plot actions - actions - list of actions """ xs = [p.start_location[0] for p in actions] ys = [p.start_location[1] for p in actions] max_size = 50 min_size = 10 ss = [p.time for p in actions] ss = [(p-min(ss))*(max_size-min_size)+min_size for p in ss] plt.scatter(xs, ys, s = ss) if plan is not None: for r in plan.robots: xs = [0]+[p.start_location[0] for p in plan.actions[r]] ys = [0]+[p.start_location[1] for p in plan.actions[r]] plt.plot(xs,ys) plt.show() if __name__=="__main__": trees = [None]*n_robots for i in range(n_robots): trees[i] = Tree(data, reward, avail_actions, state_storer, comm_n, i) for i in range(200): trees[0].grow() trees[1].grow() trees[0].receive_comms(trees[1].send_comms(), 1) trees[1].receive_comms(trees[0].send_comms(), 0)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment