예제 #1
0
    def from_dict(request_dict):

        id = request_dict.get('id', generate_uuid())
        request = TaskRequest(id=id)

        request.load_type = request_dict["loadType"]
        request.load_id = request_dict["loadId"]
        request.user_id = request_dict["userId"]
        request.earliest_pickup_time = TimeStamp.from_str(
            request_dict["earliestPickupTime"])
        request.latest_pickup_time = TimeStamp.from_str(
            request_dict["latestPickupTime"])

        pickup_area_dict = request_dict.get('pickup_pose', None)
        if pickup_area_dict:
            request.pickup_pose = Area.from_dict(pickup_area_dict)
        else:  # when the provided dict is from json schema
            request.pickup_pose = Area()
            request.pickup_pose.name = request_dict.get("pickupLocation", '')
            request.pickup_pose.floor_number = request_dict.get(
                "pickupLocationLevel", 0)

        delivery_area_dict = request_dict.get('delivery_pose', None)
        if delivery_area_dict:
            request.delivery_pose = Area.from_dict(delivery_area_dict)
        else:  # when the provided dict is from json schema
            request.delivery_pose = Area()
            request.delivery_pose.name = request_dict.get(
                "deliveryLocation", '')
            request.delivery_pose.floor_number = request_dict.get(
                "deliveryLocationLevel", 0)

        request.priority = request_dict["priority"]

        return request
예제 #2
0
    def check_msg_retries(self, message, zyre_msg_type, **kwargs):
        msg_type = message['header']['type']
        if msg_type not in self.message_types:
            return
        msg_id = message['header']['msgId']
        queued_msg = self.unacknowledged_msgs.get(msg_id, None)
        if queued_msg:
            retry = queued_msg.get('retry_number', 0)
            self.unacknowledged_msgs[msg_id]['retry_number'] = retry + 1
            self.unacknowledged_msgs[msg_id][
                'last_retry'] = self.unacknowledged_msgs[msg_id]['next_retry']

        else:
            self.unacknowledged_msgs[msg_id] = dict()
            self.unacknowledged_msgs[msg_id]['retry_number'] = 0
            current_ts = ts.get_time_stamp()
            self.unacknowledged_msgs[msg_id]['first_attempt'] = current_ts
            self.unacknowledged_msgs[msg_id]['last_retry'] = current_ts
            self.unacknowledged_msgs[msg_id]['zyre_msg_type'] = zyre_msg_type
            if 'receiverIds' in message['header'].keys():
                self.unacknowledged_msgs[msg_id]['receiverIds'] = message[
                    'header']['receiverIds']
            else:
                self.unacknowledged_msgs[msg_id]['receiverIds'] = list()
            self.unacknowledged_msgs[msg_id]['msg_args'] = dict()
            self.unacknowledged_msgs[msg_id]['msg_args']['msg'] = message
            self.unacknowledged_msgs[msg_id]['msg_args'].update(kwargs)
            deadline = timedelta(seconds=5**5)
            self.unacknowledged_msgs[msg_id]['reply_by'] = ts.get_time_stamp(
                deadline)

        # TODO This needs to be probably adapted by message type
        next_attempt = timedelta(seconds=5)
        self.unacknowledged_msgs[msg_id]['next_retry'] = ts.get_time_stamp(
            next_attempt)
예제 #3
0
 def init_ztp(self):
     midnight = self.get_current_time().replace(hour=0,
                                                minute=0,
                                                second=0,
                                                microsecond=0)
     ztp = TimeStamp()
     ztp.timestamp = midnight
     return ztp
예제 #4
0
    def is_executable(self):
        current_time = TimeStamp()
        start_time = TimeStamp.from_datetime(self.start_time)

        if start_time < current_time:
            return True
        else:
            return False
예제 #5
0
def reference_to_current_time(earliest_time, latest_time):
    delta = timedelta(minutes=earliest_time)
    r_earliest_time = TimeStamp(delta).to_str()

    delta = timedelta(minutes=latest_time)
    r_latest_time = TimeStamp(delta).to_str()

    return r_earliest_time, r_latest_time
예제 #6
0
def to_timestamp(ztp, r_time):
    """ Returns a timestamp ztp(TimeStamp) + relative time(float) in seconds
    """
    if r_time == float('inf'):
        time_ = TimeStamp()
        time_.timestamp = datetime.max
    else:
        time_ = ztp + timedelta(seconds=r_time)
    return time_
예제 #7
0
 def __init__(self, id=''):
     if not id:
         self.id = generate_uuid()
     else:
         self.id = id
     self.pickup_pose = Area()
     self.delivery_pose = Area()
     self.earliest_pickup_time = TimeStamp()
     self.latest_pickup_time = TimeStamp()
     self.user_id = ''
     self.load_type = ''
     self.load_id = ''
     self.priority = -1
예제 #8
0
 def from_dict(sub_area_reservation_dict):
     sub_area_reservation = SubAreaReservation()
     sub_area_reservation.sub_area_id = sub_area_reservation_dict[
         'subAreaId']
     sub_area_reservation.task_id = sub_area_reservation_dict['taskId']
     sub_area_reservation.robot_id = sub_area_reservation_dict['robotId']
     sub_area_reservation.start_time = TimeStamp.from_str(
         sub_area_reservation_dict['startTime'])
     sub_area_reservation.end_time = TimeStamp.from_str(
         sub_area_reservation_dict['endTime'])
     sub_area_reservation.status = sub_area_reservation_dict['status']
     sub_area_reservation.required_capacity = sub_area_reservation_dict[
         'requiredCapacity']
     return sub_area_reservation
예제 #9
0
 def update_timestamp(message):
     header = message.get('header')
     if header:
         header.update(timeStamp=TimeStamp().to_str())
     else:
         header = MessageFactoryBase.get_header(None)
         message.update(header)
예제 #10
0
    def __init__(self,
                 ccu_store,
                 api,
                 stp_solver,
                 allocation_method,
                 round_time=5,
                 **kwargs):

        self.logger = logging.getLogger("mrs.auctioneer")

        self.robot_ids = list()
        self.timetables = dict()

        self.api = api
        self.stp = STP(stp_solver)

        self.allocation_method = allocation_method
        self.round_time = timedelta(seconds=round_time)
        self.alternative_timeslots = kwargs.get('alternative_timeslots', False)

        self.logger.debug("Auctioneer started")

        self.tasks_to_allocate = dict()
        self.allocations = list()
        self.waiting_for_user_confirmation = list()
        self.round = Round()

        # TODO: Update zero_timepoint
        today_midnight = datetime.today().replace(hour=0,
                                                  minute=0,
                                                  second=0,
                                                  microsecond=0)
        self.zero_timepoint = TimeStamp()
        self.zero_timepoint.timestamp = today_midnight
예제 #11
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)
예제 #12
0
def relative_to_ztp(ztp, time_, resolution="seconds"):
    """Returns the relative time between the given time_ (datetime) and the ztp (TimeStamp)"""
    if time_.isoformat().startswith("9999-12-31T"):
        r_time = float('inf')
    else:
        r_time = TimeStamp.from_datetime(time_).get_difference(ztp, resolution)
    return r_time
예제 #13
0
파일: timetable.py 프로젝트: mas-group/mrta
    def from_dict(timetable_dict, stp):
        robot_id = timetable_dict['robot_id']
        timetable = Timetable(robot_id, stp)
        stn_cls = timetable.initialize_stn()

        zero_timepoint = timetable_dict.get('zero_timepoint')
        if zero_timepoint:
            timetable.zero_timepoint = TimeStamp.from_str(zero_timepoint)
        else:
            timetable.zero_timepoint = zero_timepoint

        timetable.risk_metric = timetable_dict['risk_metric']
        timetable.temporal_metric = timetable_dict['temporal_metric']

        stn = timetable_dict.get('stn')
        if stn:
            timetable.stn = stn_cls.from_dict(stn)
        else:
            timetable.stn = stn

        dispatchable_graph = timetable_dict.get('dispatchable_graph')
        if dispatchable_graph:
            timetable.dispatchable_graph = stn_cls.from_dict(dispatchable_graph)
        else:
            timetable.dispatchable_graph = dispatchable_graph

        schedule = timetable_dict.get('schedule')
        if schedule:
            timetable.schedule = stn_cls.from_dict(schedule)
        else:
            timetable.schedule = schedule

        return timetable
예제 #14
0
 def _get_value(cls, key, value):
     if key in ['task_id', 'round_id', 'action_id']:
         return from_str(value)
     elif key in ['ztp', 'earliest_admissible_time', 'earliest_start_time']:
         return TimeStamp.from_str(value)
     else:
         return value
예제 #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
파일: round.py 프로젝트: mas-group/mrta
    def time_to_close(self):
        current_time = TimeStamp()

        if current_time < self.closure_time:
            return False

        self.logger.debug("Closing round at %s", current_time)
        self.opened = False
        return True
예제 #17
0
    def get_header(message_type, meta_model='msg', recipients=[]):
        if recipients is not None and not isinstance(recipients, list):
            raise Exception("Recipients must be a list of strings")

        return {"header": {'type': message_type,
                           'metamodel': 'ropod-%s-schema.json' % meta_model,
                           'msgId': generate_uuid(),
                           'timestamp': TimeStamp().to_str(),
                           'receiverIds': recipients}}
예제 #18
0
 def is_executable(self):
     """Returns True if the given task needs to be dispatched based on
      the task schedule; returns False otherwise
     """
     current_time = TimeStamp()
     if self.start_time < current_time:
         return True
     else:
         return False
예제 #19
0
 def add_next_retry(self, msg_id):
     retry = self.unacknowledged_msgs[msg_id]['retry_number']
     timeout = 5**retry
     next_attempt = timedelta(seconds=timeout)
     self.unacknowledged_msgs[msg_id][
         'last_retry'] = self.unacknowledged_msgs[msg_id]['next_retry']
     self.unacknowledged_msgs[msg_id]['next_retry'] = ts.get_time_stamp(
         next_attempt)
     self.unacknowledged_msgs[msg_id]['retry_number'] = retry + 1
예제 #20
0
    def __init__(self, robot_id, api, robot_store, stp_solver, task_type):

        self.id = robot_id
        self.api = api
        self.stp = STP(stp_solver)

        self.timetable = Timetable(robot_id, self.stp)

        today_midnight = datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
        self.timetable.zero_timepoint = TimeStamp()
        self.timetable.zero_timepoint.timestamp = today_midnight
예제 #21
0
    def trigger(self):
        print("Test triggered")
        test_msg = dict()
        test_msg['header'] = dict()
        test_msg['payload'] = dict()
        test_msg['header']['type'] = 'START-TEST'
        test_msg['header']['metamodel'] = 'ropod-msg-schema.json'
        test_msg['header']['msgId'] = generate_uuid()
        test_msg['header']['timestamp'] = TimeStamp().to_str()

        test_msg['payload']['metamodel'] = 'ropod-bid_round-schema.json'

        self.shout(test_msg)
예제 #22
0
    def __new__(cls, message_type, meta_model=None, **kwargs):

        recipients = kwargs.get('recipients', list())
        if recipients is not None and not isinstance(recipients, list):
            raise Exception("Recipients must be a list of strings")

        return {
            'type': message_type,
            'metamodel': meta_model,
            'msgId': str(generate_uuid()),
            'timestamp': TimeStamp().to_str(),
            'receiverIds': recipients
        }
예제 #23
0
    def from_dict(timetable_dict):
        robot_id = timetable_dict['robot_id']
        stp_solver = STP(timetable_dict['solver_name'])
        timetable = Timetable(robot_id, stp_solver)
        stn_cls = timetable.stp_solver.get_stn()

        ztp = timetable_dict.get('ztp')
        timetable.ztp = TimeStamp.from_str(ztp)
        timetable.stn = stn_cls.from_dict(timetable_dict['stn'])
        timetable.dispatchable_graph = stn_cls.from_dict(timetable_dict['dispatchable_graph'])
        timetable.stn_tasks = timetable_dict['stn_tasks']

        return timetable
예제 #24
0
파일: round.py 프로젝트: mas-group/mrta
    def start(self):
        """ Starts and auction round:
        - opens the round
        - marks the round as not finished

        opened: The auctioneer processes bid msgs
        closed: The auctioneer no longer processes incoming bid msgs, i.e.,
                bid msgs received after the round has closed are not
                considered in the election process

        After the round closes, the election process takes place

        finished: The election process is over, i.e., an mrs has been made
                    (or an exception has been raised)

        """
        open_time = TimeStamp()
        self.closure_time = TimeStamp(delta=self.round_time)
        self.logger.debug("Round opened at %s and will close at %s", open_time,
                          self.closure_time)

        self.finished = False
        self.opened = True
예제 #25
0
파일: timetable.py 프로젝트: mas-group/mrta
    def to_stn_task(self, task_lot):
        """ Converts a task to an stn task

        Args:
            task_lot (obj): task_lot object to be converted
            zero_timepoint (TimeStamp): Zero Time Point. Origin time to which task temporal information is referenced to
        """
        start_timepoint_constraints = task_lot.constraints.timepoint_constraints[0]

        r_earliest_start_time, r_latest_start_time = TimepointConstraints.relative_to_ztp(start_timepoint_constraints,
                                                                                          self.zero_timepoint)
        delta = timedelta(minutes=1)
        earliest_navigation_start = TimeStamp(delta)
        r_earliest_navigation_start = earliest_navigation_start.get_difference(self.zero_timepoint, "minutes")

        stn_task = STNTask(task_lot.task.task_id,
                           r_earliest_navigation_start,
                           r_earliest_start_time,
                           r_latest_start_time,
                           task_lot.start_location,
                           task_lot.finish_location)

        return stn_task
예제 #26
0
    def fetch(self):
        try:
            self.logger.debug("Fetching timetable of robot %s", self.robot_id)
            timetable_mongo = TimetableMongo.objects.get_timetable(self.robot_id)
            self.stn = self.stn.from_dict(timetable_mongo.stn)
            self.dispatchable_graph = self.stn.from_dict(timetable_mongo.dispatchable_graph)
            self.ztp = TimeStamp.from_datetime(timetable_mongo.ztp)
            self.stn_tasks = {task_id: STNTask.from_dict(task) for (task_id, task) in timetable_mongo.stn_tasks.items()}

        except DoesNotExist:
            self.logger.debug("The timetable of robot %s is empty", self.robot_id)
            # Resetting values
            self.stn = self.stp_solver.get_stn()
            self.dispatchable_graph = self.stp_solver.get_stn()
예제 #27
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)
예제 #28
0
    def from_payload(payload):
        round_id = from_str(payload['roundId'])
        zero_timepoint = TimeStamp.from_str(payload['zeroTimepoint'])

        tasks_dict = payload['tasksLots']
        tasks_lots = list()

        for task_id, task_dict in tasks_dict.items():
            Task.create_new(task_id=task_id)
            tasks_lots.append(TaskLot.from_payload(task_dict))

        task_announcement = TaskAnnouncement(tasks_lots, round_id,
                                             zero_timepoint)

        return task_announcement
예제 #29
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
예제 #30
0
    def get_task_schedule(self, task_id, robot_id):
        # For now, returning the start navigation time from the dispatchable graph
        task_schedule = dict()

        timetable = self.timetables.get(robot_id)

        relative_start_navigation_time = timetable.dispatchable_graph.get_time(
            task_id, "navigation")
        relative_start_time = timetable.dispatchable_graph.get_time(
            task_id, "start")
        relative_latest_finish_time = timetable.dispatchable_graph.get_time(
            task_id, "finish", False)

        self.logger.debug("Current time %s: ", TimeStamp())
        self.logger.debug("zero_timepoint %s: ", self.zero_timepoint)
        self.logger.debug("Relative start navigation time: %s",
                          relative_start_navigation_time)
        self.logger.debug("Relative start time: %s", relative_start_time)
        self.logger.debug("Relative latest finish time: %s",
                          relative_latest_finish_time)

        start_navigation_time = self.zero_timepoint + timedelta(
            minutes=relative_start_navigation_time)
        start_time = self.zero_timepoint + timedelta(
            minutes=relative_start_time)
        finish_time = self.zero_timepoint + timedelta(
            minutes=relative_latest_finish_time)

        self.logger.debug("Start navigation of task %s: %s", task_id,
                          start_navigation_time)
        self.logger.debug("Start of task %s: %s", task_id, start_time)
        self.logger.debug("Latest finish of task %s: %s", task_id, finish_time)

        task_schedule['start_time'] = start_navigation_time.to_datetime()
        task_schedule['finish_time'] = finish_time.to_datetime()

        return task_schedule