Skip to content

Commit

Permalink
Merge pull request #24 from ropod-project/develop
Browse files Browse the repository at this point in the history
New release version 0.2.0
  • Loading branch information
argenos authored Sep 26, 2019
2 parents 035a38f + 469caa0 commit 1f2a998
Show file tree
Hide file tree
Showing 42 changed files with 1,059 additions and 2,411 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ before_install:

script:
- docker-compose up -d robot
- docker-compose up -d task_allocator
- docker-compose up -d ccu
- docker-compose up --exit-code-from task_allocation_test
after_script:
- docker stop $(docker ps -aq)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ python3 robot.py ropod_001
Run in another terminal

```
python3 task_allocator.py
python3 ccu.py
```

Go to `/tests` and run test in another terminal
Expand Down
69 changes: 22 additions & 47 deletions config/config.yaml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
version: 2
ccu_store:
db_name: ropod_ccu_store
db_name: ccu_store
port: 27017
robot_store:
db_name: ropod_store
db_name: robot_store
port: 27017
resources:
fleet:
- ropod_001
- ropod_002
- ropod_003
resource_manager:
resources:
fleet:
- ropod_001
- ropod_002
- ropod_003
plugins:
- auctioneer

plugins:
task_allocation:
# Assuming we can have different types of tasks,
# specify from where to import the Task and TaskStatus classes
task_type:
class: 'mrs.structs.task'
allocation_method: tessi
robot_proxies: true
mrta:
allocation_method: mrta-srea
stp_solver: srea
auctioneer:
round_time: 15 # seconds
alternative_timeslots: True
dispatcher:
freeze_window: 300 # seconds
robot_proxies: true
freeze_window: 3 # minutes
auctioneer:
round_time: 15 # seconds
alternative_timeslots: True
dispatcher:
re-allocate: True

robot_proxy:
bidder:
Expand All @@ -48,8 +48,6 @@ robot_proxy:
message_types: # Types of messages the node will listen to. Messages not listed will be ignored
- TASK-ANNOUNCEMENT
- ALLOCATION
- TIMETABLE
- DELETE-TASK
debug_msgs: false
acknowledge: false
publish:
Expand All @@ -70,10 +68,6 @@ robot_proxy:
component: 'bidder.task_announcement_cb'
- msg_type: 'ALLOCATION'
component: 'bidder.allocation_cb'
- msg_type: 'TIMETABLE'
component: '.timetable_cb'
- msg_type: 'DELETE-TASK'
component: '.delete_task_cb'

api:
version: 0.1.0
Expand All @@ -92,7 +86,7 @@ api:
- TASK-PROGRESS
- BID
- FINISH-ROUND
- ALLOCATE-TASK
- START-TEST
acknowledge: false
debug_messages:
- 'TASK-REQUEST'
Expand All @@ -106,31 +100,12 @@ api:
groups: ['TASK-ALLOCATION']
method: shout
callbacks:
- msg_type: 'ALLOCATE-TASK'
component: 'auctioneer.allocate_task_cb'
- msg_type: 'START-TEST'
component: '.start_test_cb'
- msg_type: 'BID'
component: 'auctioneer.bid_cb'
- msg_type: 'FINISH-ROUND'
component: 'auctioneer.finish_round_cb'
rest:
server:
ip: 127.0.0.1
port: 8081
routes:
- path: '/number'
resource:
module: 'fleet_management.api.rest.resources'
class: 'RandomGenerator'
ros:
publishers:
- topic: '/fms/task'
msg_type: Task
msg_module: ropod_ros_msgs.msg
subscribers:
- topic: '/fms/task_request'
msg_type: TaskRequest
msg_module: ropod_ros_msgs.msg
callback: task_cb

logger:
version: 1
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ services:
tty: true
stdin_open: true

task_allocator:
container_name: task-allocator
ccu:
container_name: ccu
image: ropod-mrs
working_dir: /mrta/mrs/
command: ["python3", "task_allocator.py"]
command: ["python3", "ccu.py"]
network_mode: "host"
tty: true
stdin_open: true
Expand All @@ -30,6 +30,6 @@ services:
stdin_open: true
depends_on:
- robot
- task_allocator
- ccu


68 changes: 68 additions & 0 deletions mrs/ccu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import logging
import time

from fmlib.api import API
from fleet_management.config.config import FMSBuilder
from fmlib.db.mongo import Store
from fmlib.db.queries import get_tasks_by_status
from ropod.structs.task import TaskStatus as TaskStatusConst

from mrs.config.builder import MRTABuilder
from mrs.utils.datasets import load_yaml

_component_modules = {'api': API,
'ccu_store': Store,
}

_config_order = ['api', 'ccu_store']


class MRS(object):
def __init__(self, config_file=None):

self.logger = logging.getLogger('mrs')
config_params = load_yaml(config_file)

logger_config = config_params.get('logger')
logging.config.dictConfig(logger_config)

fms_builder = FMSBuilder(component_modules=_component_modules,
config_order=_config_order)
fms_builder.configure(config_params)

self.api = fms_builder.get_component('api')
self.ccu_store = fms_builder.get_component('ccu_store')

mrta_builder = MRTABuilder.configure(self.api, self.ccu_store, config_params)
self.auctioneer = mrta_builder.get_component('auctioneer')
self.dispatcher = mrta_builder.get_component('dispatcher')

self.api.register_callbacks(self)
self.logger.info("Initialized MRS")

def start_test_cb(self, msg):
self.logger.debug("Start test msg received")
tasks = get_tasks_by_status(TaskStatusConst.UNALLOCATED)
self.auctioneer.allocate(tasks)

def run(self):
try:
self.api.start()

while True:
self.auctioneer.run()
self.api.run()
time.sleep(0.5)
except (KeyboardInterrupt, SystemExit):
self.api.shutdown()
self.logger.info('FMS is shutting down')

def shutdown(self):
self.api.shutdown()


if __name__ == '__main__':
config_file_path = '../config/config.yaml'
fms = MRS(config_file_path)

fms.run()
56 changes: 56 additions & 0 deletions mrs/config/builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from fleet_management.exceptions.config import InvalidConfig
from mrs.task_allocation import auctioneer
from mrs.task_execution import dispatcher
import logging


class MRTABuilder:
def __init__(self):
self._auctioneer = None
self._dispatcher = None

def __call__(self, **kwargs):
plugins = dict()
for plugin, config in kwargs.items():
if plugin == 'auctioneer':
self.auctioneer(**kwargs)
plugins.update(auctioneer=self._auctioneer)
if plugin == 'dispatcher':
self.dispatcher(**kwargs)
plugins.update(dispatcher=self._dispatcher)

return plugins

def auctioneer(self, **kwargs):
if not self._auctioneer:
try:
self._auctioneer = auctioneer.configure(**kwargs)
except InvalidConfig:
raise InvalidConfig('MRTA plugin requires an auctioneer configuration')
return self._auctioneer

def dispatcher(self, **kwargs):
if not self._dispatcher:
try:
self._dispatcher = dispatcher.configure(**kwargs)
except InvalidConfig:
raise InvalidConfig('MRTA plugin requires a dispatcher configuration')
return self._dispatcher

def get_component(self, name):
if name == 'auctioneer':
return self._auctioneer
elif name == 'dispatcher':
return self.dispatcher

@classmethod
def configure(cls, api, ccu_store, config_params):
mrta_builder = cls()
logging.info("Configuring MRTA...")
mrta_config = config_params.get('plugins').get('mrta')
if mrta_config is None:
logging.debug("Found no mrta in the configuration file.")
return None

mrta_builder(api=api, ccu_store=ccu_store, **mrta_config)
return mrta_builder
27 changes: 0 additions & 27 deletions mrs/config/task_factory.py

This file was deleted.

Empty file added mrs/db/__init__.py
Empty file.
Empty file added mrs/db/models/__init__.py
Empty file.
Empty file.
60 changes: 60 additions & 0 deletions mrs/db/models/performance/dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import logging

from mrs.db.models.performance.task import TaskPerformance
from pymodm import fields, MongoModel
from pymodm.context_managers import switch_collection
from pymongo.errors import ServerSelectionTimeoutError
from ropod.utils.uuid import generate_uuid


class DatasetPerformance(MongoModel):
""" Stores dataset performance information:
dataset_id (UUID): uniquely identifies the dataset
completion_time (float): Difference between the start navigation of the
first task and the finish time of the last allocated
task
makespan (float): Finish time of the last allocated task
fleet_work_time (float): % of time taken to perform all allocated tasks.
fleet_travel_time (float): % of time taken to travel to task locations
fleet_idle_time (float): % of time robots are idle (waiting) to start their next allocated task
robot_usage (float): % of robots used out of all the available robots
usage_most_loaded_robot (float): % of tasks allocated to the robot with most allocations
"""
dataset_id = fields.UUIDField(primary_key=True, default=generate_uuid())
completion_time = fields.FloatField()
makespan = fields.FloatField()
fleet_work_time = fields.FloatField()
fleet_travel_time = fields.FloatField()
fleet_idle_time = fields.FloatField()
robot_usage = fields.FloatField()
usage_most_loaded_robot = fields.FloatField()
tasks = fields.ListField(fields.ReferenceField(TaskPerformance))

class Meta:
archive_collection = 'dataset_performance_archive'
ignore_unknown_fields = True

def save(self):
try:
super().save(cascade=True)
except ServerSelectionTimeoutError:
logging.warning('Could not save models to MongoDB')

def archive(self):
with switch_collection(DatasetPerformance, DatasetPerformance.Meta.archive_collection):
super().save()
self.delete()

@classmethod
def create(cls, dataset_id, task_ids):
performance = cls(dataset_id=dataset_id, tasks=task_ids)
performance.save()
return performance
Loading

0 comments on commit 1f2a998

Please sign in to comment.