Пример #1
0
 def update_allocation_metrics(self, allocation_time):
     allocation_info = self.auctioneer.winning_bid.get_allocation_info()
     task = Task.get_task(allocation_info.new_task.task_id)
     self.performance_tracker.update_allocation_metrics(task, allocation_time)
     if allocation_info.next_task:
         task = Task.get_task(allocation_info.next_task.task_id)
         self.performance_tracker.update_allocation_metrics(task, only_constraints=True)
Пример #2
0
 def get_next_task(self, task):
     task_last_node = self.stn.get_task_node_ids(task.task_id)[-1]
     if self.stn.has_node(task_last_node + 1):
         next_task_id = self.stn.nodes[task_last_node + 1]['data'].task_id
         try:
             next_task = Task.get_task(next_task_id)
         except DoesNotExist:
             self.logger.warning("Task %s is not in db", next_task_id)
             next_task = Task.create_new(task_id=next_task_id)
         return next_task
Пример #3
0
    def check_termination_test(self):
        unallocated_tasks = Task.get_tasks_by_status(
            TaskStatusConst.UNALLOCATED)
        allocated_tasks = Task.get_tasks_by_status(TaskStatusConst.ALLOCATED)
        preempted_tasks = Task.get_tasks_by_status(TaskStatusConst.PREEMPTED)
        planned_tasks = Task.get_tasks_by_status(TaskStatusConst.PLANNED)
        dispatched_tasks = Task.get_tasks_by_status(TaskStatusConst.DISPATCHED)
        ongoing_tasks = Task.get_tasks_by_status(TaskStatusConst.ONGOING)

        with switch_collection(TaskStatus, TaskStatus.Meta.archive_collection):
            completed_tasks = Task.get_tasks_by_status(
                TaskStatusConst.COMPLETED)
            canceled_tasks = Task.get_tasks_by_status(TaskStatusConst.CANCELED)
            aborted_tasks = Task.get_tasks_by_status(TaskStatusConst.ABORTED)

        self.logger.info("Unallocated: %s", len(unallocated_tasks))
        self.logger.info("Allocated: %s", len(allocated_tasks))
        self.logger.info("Planned: %s ", len(planned_tasks))
        self.logger.info("Dispatched: %s", len(dispatched_tasks))
        self.logger.info("Ongoing: %s", len(ongoing_tasks))
        self.logger.info("Completed: %s ", len(completed_tasks))
        self.logger.info("Preempted: %s ", len(preempted_tasks))
        self.logger.info("Canceled: %s", len(canceled_tasks))
        self.logger.info("Aborted: %s", len(aborted_tasks))

        tasks = completed_tasks + preempted_tasks

        if len(tasks) == len(self.tasks):
            self.logger.info("Terminating test")
            self.logger.info("Allocations: %s", self.allocations)
            self.terminated = True
Пример #4
0
    def task_status_cb(self, msg):
        payload = msg['payload']
        timestamp = TimeStamp.from_str(
            msg["header"]["timestamp"]).to_datetime()
        task_status = TaskStatus.from_payload(payload)

        if self.robot_id == task_status.robot_id:

            task = Task.get_task(task_status.task_id)
            self.logger.debug("Received task status %s for task %s",
                              task_status.task_status, task.task_id)

            self.logger.debug("Sending task status %s for task %s",
                              task_status.task_status, task.task_id)
            self.api.publish(msg, groups=["TASK-ALLOCATION"])

            if task_status.task_status == TaskStatusConst.ONGOING:
                self.update_timetable(task, task_status.task_progress,
                                      timestamp)

            elif task_status.task_status == TaskStatusConst.COMPLETED:
                self.logger.debug("Completing execution of task %s",
                                  task.task_id)
                self.task = None

            task.update_status(task_status.task_status)
Пример #5
0
 def get_earliest_task(self):
     task_id = self.stn.get_earliest_task_id()
     if task_id:
         try:
             task = Task.get_task(task_id)
             return task
         except DoesNotExist:
             self.logger.warning("Task %s is not in db or its first node is not the start node", task_id)
Пример #6
0
 def get_r_time_previous_task(self,
                              insertion_point,
                              node_type,
                              earliest=True):
     task_id = self.stn.get_task_id(insertion_point - 1)
     previous_task = Task.get_task(task_id)
     return self.dispatchable_graph.get_time(previous_task.task_id,
                                             node_type, earliest)
Пример #7
0
 def previous_task_is_frozen(self, insertion_point):
     task_id = self.stn.get_task_id(insertion_point - 1)
     previous_task = Task.get_task(task_id)
     if previous_task.status.status in [
             TaskStatusConst.DISPATCHED, TaskStatusConst.ONGOING
     ]:
         return True
     return False
Пример #8
0
 def to_attrs(cls, dict_repr):
     attrs = super().to_attrs(dict_repr)
     tasks = list()
     for task_id, task_dict in attrs.get("tasks").items():
         tasks.append(
             Task.from_payload(task_dict,
                               constraints=TaskConstraints,
                               request=TransportationRequest))
     attrs.update(tasks=tasks)
     return attrs
Пример #9
0
 def get_tasks_status(robot_id):
     tasks_status = collections.OrderedDict()
     with switch_collection(Task, Task.Meta.archive_collection):
         tasks = Task.get_tasks_by_robot(robot_id)
     with switch_collection(TaskStatus, TaskStatus.Meta.archive_collection):
         for task in tasks:
             task_status = TaskStatus.objects.get({"_id": task.task_id})
             if task_status.status == TaskStatusConst.COMPLETED:
                 tasks_status[task.task_id] = task_status
     return tasks_status
Пример #10
0
    def receive_msg_cb(self, msg_content):
        msg = self.convert_zyre_msg_to_dict(msg_content)
        if msg is None:
            return
        msg_type = msg['header']['type']
        payload = msg['payload']

        if msg_type == 'TASK':
            task = Task.from_payload(payload)
            if self.robot_id in task.assigned_robots:
                self.logger.debug("Received task %s", task.task_id)
                self.task = task
Пример #11
0
    def start_test_cb(self, msg):
        self.simulator_interface.stop()
        initial_time = msg["payload"]["initial_time"]
        self.logger.info("Start test at %s", initial_time)

        tasks = Task.get_tasks_by_status(TaskStatusConst.UNALLOCATED)
        for robot_id in self.auctioneer.robot_ids:
            RobotPerformance.create_new(robot_id=robot_id)
        for task in tasks:
            self.add_task_plan(task)
            TaskPerformance.create_new(task_id=task.task_id)

        self.simulator_interface.start(initial_time)

        self.auctioneer.allocate(tasks)
Пример #12
0
    def task_status_cb(self, msg):
        payload = msg['payload']
        timestamp = TimeStamp.from_str(
            msg["header"]["timestamp"]).to_datetime()
        task_status = TaskStatus.from_payload(payload)

        if self.robot_id == task_status.robot_id:
            task = Task.get_task(task_status.task_id)
            self.logger.debug("Received task status %s for task %s",
                              task_status.task_status, task.task_id)

            if task_status.task_status == TaskStatusConst.ONGOING:
                self._update_timetable(task, task_status.task_progress,
                                       timestamp)
                task.update_status(task_status.task_status)
Пример #13
0
    def merge_temporal_graph(previous_graph, new_graph):
        tasks = list()
        new_task_ids = new_graph.get_tasks()

        scheduled_tasks = [
            task.task_id
            for task in Task.get_tasks_by_status(TaskStatusConst.SCHEDULED)
            if task
        ]
        ongoing_tasks = [
            task.task_id
            for task in Task.get_tasks_by_status(TaskStatusConst.ONGOING)
            if task
        ]

        for i, task_id in enumerate(new_task_ids):
            if task_id in scheduled_tasks or task_id in ongoing_tasks:
                # Keep current version of task
                tasks.append(previous_graph.get_task_graph(task_id))
            else:
                # Use new version of task
                tasks.append(new_graph.get_task_graph(task_id))

        # Get type of previous graph
        merged_graph = previous_graph.__class__()

        for task_graph in tasks:
            merged_graph.add_nodes_from(task_graph.nodes(data=True))
            merged_graph.add_edges_from(task_graph.edges(data=True))

        for i in merged_graph.nodes():
            if i != 0 and merged_graph.has_node(
                    i + 1) and not merged_graph.has_edge(i, i + 1):
                merged_graph.add_constraint(i, i + 1)

        return merged_graph
Пример #14
0
    def get_task(self, position):
        """ Returns the task in the given position

        :param position: (int) position in the STN
        :return: (Task) task
        """
        task_id = self.stn.get_task_id(position)
        if task_id:
            try:
                return Task.get_task(task_id)
            except DoesNotExist:
                self.logger.warning("Task %s is not in db", task_id)
                raise DoesNotExist
        else:
            raise TaskNotFound(position)
Пример #15
0
    def announce_tasks(self):
        tasks = list(self.tasks_to_allocate.values())
        earliest_task = Task.get_earliest_task(tasks)
        closure_time = earliest_task.pickup_constraint.earliest_time - self.closure_window

        if not self.is_valid_time(closure_time) and self.alternative_timeslots:
            # Closure window should be long enough to allow robots to bid (tune if necessary)
            closure_time = self.get_current_time() + self.closure_window

        elif not self.is_valid_time(
                closure_time) and not self.alternative_timeslots:
            self.logger.warning(
                "Task %s cannot not be allocated at its given temporal constraints",
                earliest_task.task_id)
            earliest_task.update_status(TaskStatusConst.PREEMPTED)
            self.tasks_to_allocate.pop(earliest_task.task_id)
            return

        self.changed_timetable.clear()
        for task in tasks:
            if not task.hard_constraints:
                self.update_soft_constraints(task)

        self.round = Round(self.robot_ids,
                           self.tasks_to_allocate,
                           n_tasks=len(tasks),
                           closure_time=closure_time,
                           alternative_timeslots=self.alternative_timeslots,
                           simulator=self.simulator)

        earliest_admissible_time = TimeStamp()
        earliest_admissible_time.timestamp = self.get_current_time(
        ) + timedelta(minutes=1)
        task_announcement = TaskAnnouncement(tasks, self.round.id,
                                             self.timetable_manager.ztp,
                                             earliest_admissible_time)

        self.logger.debug("Starting round: %s", self.round.id)
        self.logger.debug("Number of tasks to allocate: %s", len(tasks))

        msg = self.api.create_message(task_announcement)

        self.logger.debug("Auctioneer announces tasks %s",
                          [task.task_id for task in tasks])

        self.round.start()
        self.api.publish(msg, groups=['TASK-ALLOCATION'])
Пример #16
0
 def run(self):
     try:
         self.api.start()
         while True:
             try:
                 tasks = Task.get_tasks_by_robot(self.robot_id)
                 if self.schedule_execution_monitor.task is None:
                     self.schedule_execution_monitor.process_tasks(tasks)
                 self.executor.run()
             except DoesNotExist:
                 pass
             self.api.run()
     except (KeyboardInterrupt, SystemExit):
         self.logger.info("Terminating %s robot ...", self.robot_id)
         self.api.shutdown()
         self.executor.shutdown()
         self.logger.info("Exiting...")
Пример #17
0
    def task_status_cb(self, msg):
        while self.deleting_task:
            time.sleep(0.1)

        self.processing_task = True

        payload = msg['payload']
        timestamp = TimeStamp.from_str(
            msg["header"]["timestamp"]).to_datetime()
        task_status = TaskStatus.from_payload(payload)
        task_progress = task_status.task_progress
        task = Task.get_task(task_status.task_id)
        self.logger.debug("Received task status %s for task %s by %s",
                          task_status.task_status, task_status.task_id,
                          task_status.robot_id)

        if task_status.task_status == TaskStatusConst.ONGOING:
            self._update_progress(task, task_progress, timestamp)
            self.update_timetable(task, task_status.robot_id, task_progress,
                                  timestamp)
            self._update_task_schedule(task, task_progress, timestamp)
            task.update_status(task_status.task_status)

        elif task_status.task_status == TaskStatusConst.COMPLETED:
            self.logger.debug("Adding task %s to tasks to remove",
                              task.task_id)
            self.tasks_to_remove.append((task, task_status.task_status))

        elif task_status.task_status == TaskStatusConst.UNALLOCATED:
            self.re_allocate(task)

        elif task_status.task_status == TaskStatusConst.PREEMPTED:
            if task.status.status == TaskStatusConst.PREEMPTED:
                self.logger.warning("Task %s is already preempted",
                                    task_status.task_id)
                return
            try:
                self._remove_task(task, task_status.task_status)
            except TaskNotFound:
                return

        self.processing_task = False
Пример #18
0
def load_tasks_to_db(dataset_module, dataset_name, **kwargs):
    dataset_dict = load_yaml_file_from_module(dataset_module,
                                              dataset_name + '.yaml')
    initial_time = kwargs.get('initial_time', datetime.now())

    tasks_dict = dataset_dict.get('tasks')
    ordered_tasks = collections.OrderedDict(sorted(tasks_dict.items()))
    tasks = list()

    for task_id, task_info in ordered_tasks.items():
        earliest_pickup_time, latest_pickup_time = reference_to_initial_time(
            task_info.get("earliest_pickup_time"),
            task_info.get("latest_pickup_time"), initial_time)
        request = TransportationRequest(
            request_id=generate_uuid(),
            pickup_location=task_info.get('pickup_location'),
            delivery_location=task_info.get('delivery_location'),
            earliest_pickup_time=earliest_pickup_time,
            latest_pickup_time=latest_pickup_time,
            hard_constraints=task_info.get('hard_constraints'))
        request.save()

        duration = InterTimepointConstraint()

        pickup = TimepointConstraint(
            earliest_time=request.earliest_pickup_time,
            latest_time=request.latest_pickup_time)

        temporal = TransportationTemporalConstraints(pickup=pickup,
                                                     duration=duration)

        constraints = TransportationTaskConstraints(
            hard=request.hard_constraints, temporal=temporal)

        task = TransportationTask.create_new(task_id=task_id,
                                             request=request.request_id,
                                             constraints=constraints)

        tasks.append(task)

    return tasks
Пример #19
0
    def allocate_to_robot(self, task_id):
        allocation_info = self.bid_placed.get_allocation_info()
        self.timetable.add_stn_task(allocation_info.new_task)
        if allocation_info.next_task:
            self.timetable.add_stn_task(allocation_info.next_task)

        self.timetable.stn = allocation_info.stn
        self.timetable.dispatchable_graph = allocation_info.dispatchable_graph
        self.timetable.store()

        self.logger.debug("Robot %s allocated task %s", self.robot_id, task_id)
        self.logger.debug("STN: \n %s", self.timetable.stn)
        self.logger.debug("Dispatchable graph: \n %s",
                          self.timetable.dispatchable_graph)

        tasks = [task for task in self.timetable.get_tasks()]

        self.logger.debug("Tasks allocated to robot %s:%s", self.robot_id,
                          tasks)
        task = Task.get_task(task_id)
        task.update_status(TaskStatusConst.ALLOCATED)
        task.assign_robots([self.robot_id])
Пример #20
0
    def get_smallest_bid(bids):
        """ Get the bid with the smallest cost among all bids.

        :param bids: list of bids
        :return: the bid with the smallest cost
        """
        smallest_bid = None

        for bid in bids:
            # Do not consider bids for tasks that were dispatched after the bid computation
            task = Task.get_task(bid.task_id)
            if task.status.status in [
                    TaskStatusConst.DISPATCHED, TaskStatusConst.ONGOING
            ]:
                continue

            if smallest_bid is None or\
                    bid < smallest_bid or\
                    (bid == smallest_bid and bid.task_id < smallest_bid.task_id):

                smallest_bid = copy.deepcopy(bid)

        return smallest_bid
Пример #21
0
 def get_previous_task(self, task):
     task_first_node = self.stn.get_task_node_ids(task.task_id)[0]
     if task_first_node > 1 and self.stn.has_node(task_first_node - 1):
         prev_task_id = self.stn.nodes[task_first_node - 1]['data'].task_id
         prev_task = Task.get_task(prev_task_id)
         return prev_task
Пример #22
0
 def remove_task_cb(self, msg):
     payload = msg['payload']
     remove_task = RemoveTaskFromSchedule.from_payload(payload)
     task = Task.get_task(remove_task.task_id)
     self._remove_task(task, remove_task.status)
Пример #23
0
 def task_cb(self, msg):
     payload = msg['payload']
     task = Task.from_payload(payload)
     if self.robot_id in task.assigned_robots:
         self.logger.debug("Received task %s", task.task_id)
         task.update_status(TaskStatusConst.DISPATCHED)