updated template for 2nd round of RoboLab Spring 2018

This commit is contained in:
7HAL32 2017-03-05 23:03:21 +01:00 committed by Lutz Thies
commit e6b628f41a
11 changed files with 629 additions and 0 deletions

29
src/communication.py Normal file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env python3
# Suggestion: Do not import the ev3dev.ev3 module in this file
class Communication:
"""
Class to hold the MQTT client
Feel free to add functions, change the constructor and the example send_message() to satisfy your requirements and thereby solve the task according to the specifications
"""
def __init__(self, mqtt_client):
""" Initializes communication module, connect to server, subscribe, etc. """
# THESE TWO VARIABLES MUST NOT BE CHANGED
self.client = mqtt_client
self.client.on_message = self.on_message
# ADD YOUR VARIABLES HERE
# THIS FUNCTIONS SIGNATURE MUST NOT BE CHANGED
def on_message(self, client, data, message):
""" Handles the callback if any message arrived """
pass
# Example
def send_message(self, topic, message):
""" Sends given message to specified channel """
pass

26
src/main.py Normal file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env python3
import ev3dev.ev3 as ev3
import uuid
import paho.mqtt.client as mqtt
from planet import Direction, Planet
from communication import Communication
client = None # DO NOT EDIT
def run():
# DO NOT EDIT
global client
client = mqtt.Client(client_id=str(uuid.uuid4()), # client_id has to be unique among ALL users
clean_session=False,
protocol=mqtt.MQTTv31)
# the execution of all code shall be started from within this function
# ADD YOUR OWN IMPLEMENTATION HEREAFTER
print("Hello World!")
# DO NOT EDIT
if __name__ == '__main__':
run()

2
src/odometry.py Normal file
View file

@ -0,0 +1,2 @@
# Suggestion: implement odometry as class that is not using the ev3dev.ev3 package
# establish value exchange with main driving class via getters and setters

72
src/planet.py Normal file
View file

@ -0,0 +1,72 @@
#!/usr/bin/env python3
from enum import IntEnum, unique
from typing import List, Optional, Tuple, Dict
# IMPORTANT NOTE: DO NOT IMPORT THE ev3dev.ev3 MODULE IN THIS FILE
@unique
class Direction(IntEnum):
""" Directions in degrees """
NORTH = 0
EAST = 90
SOUTH = 180
WEST = 270
# simple alias, no magic here
Weight = int
"""
Weight of a given path (received from the server)
value: -1 if broken path
>0 for all other paths
never 0
"""
class Planet:
"""
Contains the representation of the map and provides certain functions to manipulate it according to the specifications
"""
def __init__(self):
""" Initializes the data structure """
self.target = None
def add_path(self, start: Tuple[Tuple[int, int], Direction], target: Tuple[Tuple[int, int], Direction], weight: int):
"""
Adds a bidirectional path defined between the start and end coordinates to the map and assigns the weight to it
example:
add_path(((0, 3), Direction.NORTH), ((0, 3), Direction.WEST), 1)
"""
pass
def get_paths(self) -> Dict[Tuple[int, int], Dict[Direction, Tuple[Tuple[int, int], Direction, Weight]]]:
"""
Returns all paths
example:
get_paths() returns: {
(0, 3): {
Direction.NORTH: ((0, 3), Direction.WEST, 1),
Direction.EAST: ((1, 3), Direction.WEST, 2)
},
(1, 3): {
Direction.WEST: ((0, 3), Direction.EAST, 2),
...
},
...
}
"""
pass
def shortest_path(self, start: Tuple[int, int], target: Tuple[int, int]) -> Optional[List[Tuple[Tuple[int, int], Direction]]]:
"""
Returns a shortest path between two nodes
examples:
shortest_path((0,0), (2,2)) returns: [((0, 0), Direction.EAST), ((1, 0), Direction.NORTH)]
shortest_path((0,0), (1,2)) returns: None
"""
pass

85
src/planettest.py Executable file
View file

@ -0,0 +1,85 @@
#!/usr/bin/env python3
import unittest
from planet import Direction, Planet
class ExampleTestPlanet(unittest.TestCase):
def setUp(self):
"""
Instantiates the planet data structure and fills it with paths
example planet:
+--+
| |
+-0,3------+
| |
0,2-----2,2 (target)
| /
+-0,1 /
| | /
+-0,0-1,0
|
(start)
"""
# set your data structure
self.planet = Planet()
# add the paths
self.planet.add_path(((0, 0), Direction.NORTH), ((0, 1), Direction.SOUTH), 1)
self.planet.add_path(((0, 1), Direction.WEST), ((0, 0), Direction.WEST), 1)
def test_target_not_reachable_with_loop(self):
# does the shortest path algorithm loop infinitely?
# there is no shortest path
self.assertIsNone(self.planet.shortest_path((0, 0), (1, 2)))
class YourFirstTestPlanet(unittest.TestCase):
def setUp(self):
"""
Instantiates the planet data structure and fills it with paths
MODEL YOUR TEST PLANET HERE (if you'd like):
"""
# set your data structure
self.planet = Planet()
# ADD YOUR PATHS HERE:
# self.planet.add_path(...)
def test_integrity(self):
# were all paths added correctly to the planet
# check if add_path() works by using get_paths()
self.fail('implement me!')
def test_empty_planet(self):
self.fail('implement me!')
def test_target_not_reachable(self):
self.fail('implement me!')
def test_shortest_path(self):
# at least 2 possible paths
self.fail('implement me!')
def test_same_length(self):
# at least 2 possible paths with the same weight
self.fail('implement me!')
def test_shortest_path_with_loop(self):
# does the shortest path algorithm loop infinitely?
# there is a shortest path
self.fail('implement me!')
def test_target_not_reachable_with_loop(self):
# there is no shortest path
self.fail('implement me!')
if __name__ == "__main__":
unittest.main()