class Popup(): "a popup" def __init__(self, brick, title, contentType): self.brick = brick self.title = title self.titleFont = Font(family='arial', size=15, bold=True) self.normalFont = Font(family='arial', size=13) self.contentType = contentType def open(self, position=[]): self.draw(position=position) def close(self, position): position.insert(0, -1) def draw(self): self.brick.screen.draw_image(9, 11, 'assets/graphics/misc/popup.png', transparent=Color.RED) self.brick.screen.set_font(self.titleFont) self.brick.screen.draw_text( self.brick.screen.width / 2 - self.titleFont.text_width(self.title) / 2, 15, self.title) self.brick.screen.draw_line( self.brick.screen.width / 2 - self.titleFont.text_width(self.title) / 2 - 1, 31, self.brick.screen.width / 2 + self.titleFont.text_width(self.title) / 2 + 1, 31, width=2)
def __init__(self, type, brick=None): self.brick = brick self.type = type self.objects, self.llist = [], [] self.maxX = 0 self.maxY = 0 self.font = Font(family='arial', size=13) self.raster = self.rasterize()
def drawInfoBox(self): self.brick.screen.draw_box(self.bounds.width + self.padding[0] + 3, 0, self.brick.screen.width - 1, self.brick.screen.height - 1, r=5, fill=False, color=Color.BLACK) self.brick.screen.set_font(Font(size=14)) self.brick.screen.draw_text(self.bounds.width + 5, 0, self.name, text_color=Color.BLACK, background_color=None)
def drawSettings(self, pos, settings, selected): ''' Function to draw the settings-menu Args: pos (int): The position in the settings menu settings (int): The settings dict to get names and values from selected (bool): Wether or not the current option is selected ''' def drawOptions(value, *args): '''Subfunction that draws the 5 currenty visible options on the screen''' for i in range(5): if value + i == pos: if selected: self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=True, color=Color.BLACK) self.brick.screen.draw_text(29, 30 + i * 20, '%s: %s' % (keys[value + i], settings['options'][keys[value + i]]), text_color=Color.WHITE, background_color=None) if settings['types'][keys[value + i]] == 'int' else self.brick.screen.draw_text( 29, 30 + i * 20, '%s: %s' % (keys[value + i], bool(settings['options'][keys[value + i]])), text_color=Color.WHITE, background_color=None) else: self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=True, color=Color.WHITE) self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=False, color=Color.BLACK) self.brick.screen.draw_text(29, 30 + i * 20, '%s: %s' % (keys[value + i], settings['options'][keys[value + i]]), text_color=Color.BLACK, background_color=None) if settings['types'][keys[value + i]] == 'int' else self.brick.screen.draw_text( 29, 30 + i * 20, '%s: %s' % (keys[value + i], bool(settings['options'][keys[value + i]])), text_color=Color.BLACK, background_color=None) else: self.brick.screen.draw_box( 26, 29 + i * 20, 170, 46 + i * 20, fill=True, color=Color.WHITE) self.brick.screen.draw_text(29, 30 + i * 20, '%s: %s' % (keys[value + i], settings['options'][keys[value + i]]), text_color=Color.BLACK, background_color=Color.WHITE) if settings['types'][keys[value + i] ] == 'int' else self.brick.screen.draw_text(29, 30 + i * 20, '%s: %s' % (keys[value + i], bool(settings['options'][keys[value + i]])), text_color=Color.BLACK, background_color=Color.WHITE) keys = list(settings['options'].keys()) self.brick.screen.set_font(Font(family='arial', size=13)) self.drawScrollBar(len(settings['options']), pos) if pos > 1 and pos < (len(settings['options']) - 2): drawOptions(pos - 2) elif pos == 0: drawOptions(pos) elif pos == 1: drawOptions(pos - 1) elif pos == len(settings['options']) - 2: drawOptions(pos - 3) elif pos == len(settings['options']) - 1: drawOptions(pos - 4)
def drawDictlist(self, pos, dictlist, selected): ''' Draws a dictionary on the screen with formatting "Key: Value" Args: pos (int): the current position in the dictionary dictlist (bool): the dict to draw selected (bool): wether or not the current element is selected ''' def drawOptions(value, *args): '''Subfunction that draws the 5 current options on the screen''' for i in range(5): if value + i == pos: if selected: self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=True, color=Color.BLACK) self.brick.screen.draw_text(29, 30 + i * 20, '%s: %s' % ( keys[value + i], dictlist[keys[value + i]]), text_color=Color.WHITE, background_color=None) else: self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=True, color=Color.WHITE) self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=False, color=Color.BLACK) self.brick.screen.draw_text(29, 30 + i * 20, '%s: %s' % ( keys[value + i], dictlist[keys[value + i]]), text_color=Color.BLACK, background_color=None) else: self.brick.screen.draw_box( 26, 29 + i * 20, 170, 46 + i * 20, fill=True, color=Color.WHITE) self.brick.screen.draw_text(29, 30 + i * 20, '%s: %s' % ( keys[value + i], dictlist[keys[value + i]]), text_color=Color.BLACK, background_color=Color.WHITE) keys = list(dictlist.keys()) self.brick.screen.set_font(Font(family='arial', size=13)) self.drawScrollBar(len(dictlist), pos) if pos > 1 and pos < (len(dictlist) - 2): drawOptions(pos - 2) elif pos == 0: drawOptions(pos) elif pos == 1: drawOptions(pos - 1) elif pos == len(dictlist) - 2: drawOptions(pos - 3) elif pos == len(dictlist) - 1: drawOptions(pos - 4)
def display_sensor_values(self): """Displays sensor values """ gyro_value = "Gyro : {}".format(self.gyro.angle()) left_color_value = "Left Color : {}".format( self.left_color.reflection()) right_color_value = "Right Color : {}".format( self.right_color.reflection()) center_color_value = "Center Color : {}".format( self.center_color.reflection()) big_font = Font(size=18) brick.screen.set_font(big_font) brick.screen.clear() brick.screen.draw_text(0, 20, gyro_value) brick.screen.draw_text(0, 40, left_color_value) brick.screen.draw_text(0, 60, right_color_value) brick.screen.draw_text(0, 80, center_color_value)
def drift_check(self): brick.speaker.beep(1200, 500) wait(100) brick.speaker.beep(1200, 500) drift = False start_gyro = self.gyro.angle() brick.screen.clear() big_font = Font(size=18) brick.screen.set_font(big_font) brick.screen.draw_text(0, 20, "Checking Gyro drift...") wait(2000) if start_gyro != self.gyro.angle(): brick.screen.draw_text(0, 60, "Error!") brick.screen.draw_text(0, 80, "Gyro drift") drift = True return drift
def __init__(self): """Class that represents the robot """ try: self.state = "Port 1: Right Color" self.right_color = ColorSensor(Port.S1) self.state = "Port 2: Center Color" self.center_color = ColorSensor(Port.S2) self.state = "Port 3: Left Color" self.left_color = ColorSensor(Port.S3) self.state = "Port 4: Gyro" self.gyro = GyroSensor(Port.S4, Direction.COUNTERCLOCKWISE) self.state = "Port A: Left Motor" self.left_motor = Motor(Port.A) self.state = "Port B: Right Motor" self.right_motor = Motor(Port.B) self.state = "Port C: Linear Gear" self.linear_attachment_motor = Motor(Port.C) self.state = "Port D: Block Dropper" self.dropper_attachment_motor = Motor(Port.D) self.wheel_diameter = 55 self.axle_track = 123 self.drive_base = DriveBase(self.left_motor, self.right_motor, self.wheel_diameter, self.axle_track) self.state = "OK" self.clock = StopWatch() self.dance_clock = 0 self.sign = 1 except: brick.screen.clear() big_font = Font(size=18) brick.screen.set_font(big_font) brick.screen.draw_text(0, 20, "Error!") brick.screen.draw_text(0, 40, self.state)
def drawExtendableList(self, pos, llist): ''' Draws a list on the screen. At the end of the list, ther will be a + symbol placed that is used for making the list 'extendable' Args: pos (int): the current position in the list llist (bool): the list to draw ''' def drawOptions(value, *args): '''Subfunction that draws the 5 current options on the screen''' self.brick.screen.draw_box( 26, 29, 168, 46 + 5 * 20, fill=True, color=Color.WHITE) for i in range(5): if value + i > len(llist): pass elif value + i == pos: self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=False, color=Color.BLACK) self.brick.screen.draw_text(29, 30 + i * 20, llist[value + i], text_color=Color.BLACK, background_color=None) if (value + i != len( llist)) else self.brick.screen.draw_image(90, 30 + i * 20, 'assets/graphics/misc/plus-button_selected.png', transparent=Color.RED) else: self.brick.screen.draw_text( 29, 30 + i * 20, llist[value + i], text_color=Color.BLACK, background_color=Color.WHITE) if (value + i != len(llist)) else self.brick.screen.draw_image( 80, 30 + (i - 1) * 20, 'assets/graphics/misc/plus-button.png', transparent=Color.RED) llist.append('') self.brick.screen.set_font(Font(family='arial', size=12)) self.drawScrollBar(len(llist), pos) if pos > 1 and pos < (len(llist) - 2): drawOptions(pos - 2) elif pos == 0: drawOptions(pos) elif pos == 1: drawOptions(pos - 1) elif pos == len(llist) - 2: drawOptions(pos - 3) elif pos == len(llist) - 1: drawOptions(pos - 4) llist.pop()
def __init__(self, name: str, brick: EV3Brick, bounds: Box, contentType, content, padding=(0, 0, False), font=Font(family='arial', size=11), visible=True): # self.logger = logger self.name = name self.brick = brick self.bounds = bounds self.padding = padding self.contentType = contentType self.content = content self.font = font self.visibility = visible self.radius = 0 self.selected = False
def drawList(self, pos, llist): ''' Draws a list on the screen Args: pos (int): the current position in the list llist (bool): the list to draw ''' def drawOptions(value): '''Subfunction that draws the 5 current options on the screen''' for i in range(5): if value + i == pos: self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=True, color=Color.WHITE) self.brick.screen.draw_box( 26, 29 + i * 20, 168, 46 + i * 20, r=3, fill=False, color=Color.BLACK) self.brick.screen.draw_text( 29, 30 + i * 20, llist[value + i], text_color=Color.BLACK, background_color=None) else: self.brick.screen.draw_box( 26, 29 + i * 20, 170, 46 + i * 20, fill=True, color=Color.WHITE) self.brick.screen.draw_text( 29, 30 + i * 20, llist[value + i], text_color=Color.BLACK, background_color=Color.WHITE) self.brick.screen.set_font(Font(family='arial', size=13)) self.drawScrollBar(len(llist), pos) if pos > 1 and pos < (len(llist) - 2): drawOptions(pos - 2) elif pos == 0: drawOptions(pos) elif pos == 1: drawOptions(pos - 1) elif pos == len(llist) - 2: drawOptions(pos - 3) elif pos == len(llist) - 1: drawOptions(pos - 4)
def __init__(self, brick, title, contentType): self.brick = brick self.title = title self.titleFont = Font(family='arial', size=15, bold=True) self.normalFont = Font(family='arial', size=13) self.contentType = contentType
# global variables (the robot is restarted everyday so a simple array is enough) color_scanned_today = [] server = BluetoothMailboxServer() mbox = TextMailbox('greeting', server) server.wait_for_connection() # set up the ev3 ev3 = EV3Brick() # set up the speaker ev3.speaker.set_speech_options('fr', 'm1', 150, 35) ev3.speaker.set_volume(100, which='_all_') ev3.speaker.beep() big_font = Font(size=16) ev3.screen.set_font(big_font) # set up the sensors doorbell_sensor = TouchSensor(Port.S1) color_sensor = ColorSensor(Port.S2) music_sensor = TouchSensor(Port.S4) time_sensor = TouchSensor(Port.S3) # set up the motors back_motor = Motor(Port.C, Direction.COUNTERCLOCKWISE) front_motor = Motor(Port.D) # check time if top of the clock (say time and run motors if needed)
#!/usr/bin/env pybricks-micropython from pybricks.hubs import EV3Brick from pybricks.parameters import Button from pybricks.tools import wait from pybricks.media.ev3dev import Font # Load Font big_font = Font(size=24, bold=True) # Initialize the EV3 ev3 = EV3Brick() # Print Battery parameters ev3.screen.set_font(big_font) ev3.screen.print('Voltage: \n', ev3.battery.voltage(), ' mV') ev3.screen.print('Current: \n', ev3.battery.current(), ' mA') while True: buttons = ev3.buttons.pressed() wait(150) if Button.UP in buttons: break
InfraredSensor, UltrasonicSensor, GyroSensor) from pybricks.parameters import Port, Stop, Direction, Button, Color from pybricks.tools import wait, StopWatch, DataLog from pybricks.robotics import DriveBase from pybricks.media.ev3dev import SoundFile, ImageFile, Font import config import grogu from time import sleep import new_trip1 import new_trip2 import new_trip3 import new_trip4 font = Font(size=13) trip_font = Font(size=15, bold=True) xaxis = 25 yaxis = 40 while True: grogu.ev3.screen.clear() grogu.ev3.screen.set_font(font) # Display the instructions to run the different trips. grogu.ev3.screen.draw_text(xaxis, yaxis, "Up Button") grogu.ev3.screen.draw_text(xaxis + 90, yaxis, "- Trip 1") grogu.ev3.screen.draw_text(xaxis, yaxis + 20, "Right Button") grogu.ev3.screen.draw_text(xaxis + 90, yaxis + 20, "- Trip 2") grogu.ev3.screen.draw_text(xaxis, yaxis + 40, "Down Button") grogu.ev3.screen.draw_text(xaxis + 90, yaxis + 40, "- Trip 3")
# 8-tooth, a 24-tooth, and a 40-tooth gear connected to it. Set the # motor direction to counterclockwise, so that positive speed values # make the rear structure move upward. lift_motor = Motor(Port.D, Direction.COUNTERCLOCKWISE, [8, 24, 40]) # Set up the Gyro Sensor. It is used to measure the angle of the robot. # Keep the Gyro Sensor and EV3 steady when connecting the cable and # during start-up of the EV3. gyro_sensor = GyroSensor(Port.S2) # Set up the Touch Sensor. It is used to detect when the rear # structure has moved to its maximum position. touch_sensor = TouchSensor(Port.S3) # Using a very large font big_font = Font(size=24) ev3.screen.set_font(big_font) # Initialize the rear structure. In order to move the structure both # the rear motor and lift motor must run in sync. First, the rear # motor moves the robot backward while the lift motor moves the rear # structure up until the Touch Sensor is pressed. Second, the rear # motor moves the robot forward while the lift motor moves the rear # structure down for a set amount of degrees to move to its starting # position. Finally, the lift motor resets the angle to "0." This # means that when it moves to "0" later on, it returns to this starting # position. rear_motor.dc(-20) lift_motor.dc(100) while not touch_sensor.pressed(): wait(10)
from robot import Pid, Robot, LineEdge, LineSensor from pybricks.hubs import EV3Brick from pybricks.ev3devices import (Motor, ColorSensor, GyroSensor) from pybricks.parameters import (Port, Stop, Direction, Color, SoundFile, Button) from pybricks.tools import wait, StopWatch from pybricks.robotics import DriveBase from pybricks.media.ev3dev import Font font = Font(size=14) small_font = Font(size=8) brick = EV3Brick() def run(robot: Robot): robot.reset_sensors() brick.screen.clear() running = True speeds = [50, 100, 200, 400, 800] linear_counter = -1 dropper_counter = -1 display_menu() while running: brick.screen.set_font(font) if Button.RIGHT in brick.buttons.pressed(): while len(brick.buttons.pressed()) != 0: pass brick.screen.clear() attachment_motor_name = "block dropper" attachment_motor = robot.dropper_attachment_motor dropper_counter += 1 linear_counter = -1
# Click "Open user guide" on the EV3 extension tab for more information. # Create your objects here. ev3 = EV3Brick() # Write your program here. ev3.speaker.beep() ev3.screen.print('World') #World 화면에 출력 wait(1000) ev3.screen.clear() #화면 지우기 ev3.screen.draw_text(60, 50, 'Hello') # x=60, y=50 Hello 출력 wait(1000) ev3.screen.load_image(ImageFile.LEFT) #EV3 내장된 이미지를 표시 wait(1000) #글자 크기 변경 #글자 크기 정의 font = Font(size=100) #폰트 설정 ev3.screen.set_font(font) #화면 지우기 ev3.screen.clear() #글자 크기 확인 ev3.screen.print('Big Font') wait(5000)
parser.add_argument('--touch', help='the EV3 port attached to the touch sensor', type=Port, default=Port.S1) parser.add_argument('--label', help='the target value of the feature data', default='') parser.add_argument('--filename', help='the log filename', default='log') parser.add_argument('--predict', help='the predicted character') args = parser.parse_args() # Initialize the EV3 Brick. ev3 = EV3Brick() # Display font, style and size big = Font(family='Helvetica', size=24, bold=True) ev3.screen.set_font(big) if args.predict is None: # Initialize motors platform_motor = Motor(args.motor) # Initialise sensors platform_color_sensor = ColorSensor(args.color) trigger_button = TouchSensor(args.touch) # Initialise DataLog - append target label to filename if supplied filename = args.filename + args.label data = DataLog('angle', 'reflectivity', name=filename)
def __init__(self, config, settings, brick, logger, settingsPath, charlieOSX): # general variable setup logger.info(self, 'Starting UI initialisation') self.__config = config self.__settings = settings self.__click = 'assets/media/click.wav' self.__confirm = 'assets/media/confirm.wav' self.__settingsPath = settingsPath self.brick = brick self.logger = logger self.os = charlieOSX self.profileHelper = ProfileHelper(self.logger, self.__config) self.__sound_lock = _thread.allocate_lock() self.__almostBigFont = Font(family='Arial', size=12, bold=False) self.__bigFont = Font(family='Arial', size=15, bold=True) self.position = [0, 0, False] # Main Menu self.mainMenu = Menu('sidebar') mainPages = [ "assets/graphics/menus/programming.png", "assets/graphics/menus/testing.png", "assets/graphics/menus/remote.png", "assets/graphics/menus/competition.png", "assets/graphics/menus/settings.png", ] for i in range(len(mainPages)): name = mainPages[i].split('/')[3].split('.')[0] self.mainMenu.addObject( UIObject(name, self.brick, Box(0, i, 30, 25), 'img', mainPages[i], padding=(0, 0, True))) # Programming Menu self.programming = Menu('list', self.brick) self.programming.setList(self.__config['profileNames']) self.programming.setClickAction(self.runProgramming) # Testing Menu self.testing = Menu('list', self.brick) self.testing.setList(self.__config['profileNames']) self.testing.setClickAction(self.runTesting) # Remote-Control Menu self.remote = Menu('canvas') self.remote.addObject( UIObject('startButton', self.brick, Box(58, 80, 82, 14), 'textBox', 'Start Webremote', padding=(-1, -1, False))) self.remote.addObject( UIObject('endButton', self.brick, Box(59, 80, 81, 14), 'textBox', 'Stop Webremote', padding=(-1, -1, False), visible=False)) self.remote.getObjectByName('startButton').setClickAction( self.runWebremote) # Competition-Mode Menu self.competition = Menu('canvas') self.competition.addObject( UIObject('startButton', self.brick, Box(55, 80, 88, 14), 'textBox', 'Start Competition', padding=(-1, -1, False))) self.competition.addObject( UIObject('runButton', self.brick, Box(74, 90, 48, 14), 'textBox', 'Start Run', padding=(-1, -1, False), visible=False)) self.competition.addObject( UIObject('nextButton', self.brick, Box(72, 90, 53, 14), 'textBox', 'Start Next', padding=(-1, -1, False), visible=False)) self.competition.getObjectByName('startButton').setClickAction( self.runCompetition) # Settings Menu self.settingsMenu = Menu('dict', self.brick) self.settingsMenu.setDict(self.__settings) # menu Variables self.loop = True self.currentMenu = self.mainMenu self.subMenus = [ self.programming, self.testing, self.remote, self.competition, self.settingsMenu ] self.types = { 4: 'Turn', 5: 'Action' if not self.__config['useGearing'] else 'Gearing', 7: 'Straight', 9: 'Intervall', 11: 'Curve', 12: 'to Color', 15: 'to Wall' } self.secondParam = { 4: 'Angle', 5: 'Revs', 7: 'Distance', 9: 'Distance', 11: 'Distance', 12: 'Color', 15: 'none', 'units': { 4: '°', 5: 'Revs', 7: 'cm', 9: 'cm', 11: 'cm', 12: '', 15: '' } } self.thirdParam = { 4: 'Port', 5: 'Port', 7: 'none' if self.__config['robotType'] != 'MECANUM' else 'Angle', 9: 'Amount', 11: 'Angle', 12: 'Side', 15: 'none', 'units': { 4: '', 5: '', 7: '°', 9: '', 11: '°', 12: '', 15: '' } } self.valueTypes = { 1: { 4: 'percentage', 5: 'percentage', 7: 'percentage', 9: 'percentage', 11: 'percentage', 12: 'percentage', 15: 'percentage' }, 2: { 4: 'largeInt', 5: 'largeInt', 7: 'largeInt', 9: 'largeInt', 11: 'largeInt', 12: 'bool', 15: 'none' }, 3: { 4: 'side', 5: 'port', 7: 'none', 9: 'largeInt', 11: 'largeInt', 12: 'side', 15: 'none' } } self.valueRanges = { 'percentage': range(0, 101), 'type': [7, 4, 5, 11, 9, 12, 15], 'largeInt': range(0, 10000), 'side': [2, 3, 23], 'bool': [0, 1], 'port': range(0, 4), 'none': [0] }
def __init__(self): self._ev3 = EV3Brick() self._ev3.screen.set_font(Font(size=12)) self.last_log = "" self.log_files = [] self.log_files_names = []
from pybricks.ev3devices import (ColorSensor, GyroSensor, InfraredSensor, Motor, TouchSensor, UltrasonicSensor) from pybricks.parameters import (Align, Button, Color, Direction, ImageFile, Port, SoundFile, Stop) from pybricks.robotics import DriveBase from pybricks.tools import StopWatch, print, wait from pybricks.hubs import EV3Brick from pybricks.media.ev3dev import Font import random import time big_font = Font(size=20, bold=True, monospace=True) ev3 = EV3Brick() ev3.screen.set_font(big_font) def reset(motor: Motor): motor.run_until_stalled(100, Stop.BRAKE, 50) def scan(motor: Motor): global scan_done global scan_started scan_started = True motor.run_until_stalled(-50, Stop.BRAKE, 25) scan_done = True
#!/usr/bin/env pybricks-micropython from pybricks.hubs import EV3Brick from pybricks.parameters import Button, Color from pybricks.tools import wait from pybricks.media.ev3dev import Font from pybricks.media.ev3dev import Image, ImageFile # It takes some time for fonts to load from file, so it is best to only # load them once at the beginning of the program like this: tiny_font = Font(size=6) big_font = Font(size=24, bold=True) chinese_font = Font(size=24, lang='zh-cn') ukrainian_font = Font(size=20, lang='uk') # Initialize the EV3 ev3 = EV3Brick() # Say hello ev3.screen.print('Hello!') # Say tiny hello ev3.screen.set_font(tiny_font) ev3.screen.print('hello') # Say big hello ev3.screen.set_font(big_font) ev3.screen.print('HELLO') # Say Chinese hello ev3.screen.set_font(chinese_font) ev3.screen.print('你好') # Say Ukrainian hello ev3.screen.set_font(ukrainian_font) ev3.screen.print('Привіт')
from pybricks.media.ev3dev import Font print(Font.DEFAULT.family) print(Font.DEFAULT.style) print(Font.DEFAULT.width) print(Font.DEFAULT.height) print(Font.DEFAULT.text_width("test")) print(Font.DEFAULT.text_height("test")) # all args are optional Font() # 1st arg can be None or str Font("sans-serif") Font(None) Font(family="sans-serif") Font(family=None) # 2nd arg is int Font(None, 12) Font(size=12) # 3rd arg is bool Font(None, 12, False) Font(bold=False) # 4th arg is bool Font(None, 12, False, False) Font(monospace=False) # 5th arg is None or str
def error(self, method, msg, exception): ''' This method formats the given inputs as <[time] [MethodName] [Wrror] msg>. The output of this fuction can be disabled by setting the "Logging-Level" in the settings to 4 or higher. Also dependent on wether or not "Show Errors" is disabled or not in the settings, this function will create a 'popup' on-screen with the given warn-message. Args: method (obj): A passthrough of the object calling this fuction msg (str): The error message exception (exception / str): string or exception of the error that occured ''' if self.__settings['options']['Logging-level'] <= 3: print( self.getFormattedTime(), '[%s] [Error] %s: %s: %s' % (str(method), msg, type(exception).__name__, str(exception))) self.__logFile.write('%s [%s] [Error] %s: %s: %s\n' % (self.getFormattedTime(), str(method), msg, type(exception).__name__, str(exception))) if self.__settings['options']['Show Errors']: exception = str(exception) self.__sound(SoundFile.GENERAL_ALERT) self.__brick.screen.draw_image( 26, 24, 'assets/graphics/notifications/error.png', transparent=Color.RED) self.__brick.screen.set_font(Font(family='arial', size=7)) if Font.text_width(Font(family='arial', size=7), exception) <= 90: self.__brick.screen.draw_text(32, 47, exception, text_color=Color.BLACK) elif len(exception) <= 30 * 2: exception1, exception2 = exception[:27], exception[27:] self.__brick.screen.draw_text(32, 47, exception1, text_color=Color.BLACK) self.__brick.screen.draw_text(32, 57, exception2, text_color=Color.BLACK) else: exception1, exception2, exception3 = exception[:27], exception[ 27:53], exception[53:] self.__brick.screen.draw_text(32, 47, exception1, text_color=Color.BLACK) self.__brick.screen.draw_text(32, 57, exception2, text_color=Color.BLACK) self.__brick.screen.draw_text(32, 67, exception3, text_color=Color.BLACK) #wait for user to press middle button while not Button.CENTER in self.__brick.buttons.pressed(): pass self.__brick.screen.draw_image( 26, 24, 'assets/graphics/notifications/errorSel.png', transparent=Color.RED) #wait for user letting button go while Button.CENTER in self.__brick.buttons.pressed(): pass self.__refreshScreenNeeded = 1
def warn(self, method, msg): ''' This method formats the given inputs as <[time] [MethodName] [Warn] msg>. The output of this fuction can be disabled by setting the "Logging-Level" in the settings to 3 or higher. Also dependent on wether or not "Show Warnings" is disabled or not in the settings, this function will create a 'popup' on-screen with the given warn-message. Args: method (obj): A passthrough of the object calling this fuction msg (str): The warn message ''' if self.__settings['options']['Logging-level'] <= 2: print(self.getFormattedTime(), '[%s] [Warning]' % str(method), msg) self.__logFile.write('%s [%s] [Warning] %s\n' % (self.getFormattedTime(), str(method), msg)) if self.__settings['options']['Show Warnings']: self.__sound(SoundFile.GENERAL_ALERT) self.__brick.screen.draw_image( 26, 24, 'assets/graphics/notifications/warn.png', transparent=Color.RED) self.__brick.screen.draw_text(31, 34, msg, text_color=Color.BLACK) if Font.text_width(Font(family='arial', size=7), exception) <= 90: self.__brick.screen.draw_text(32, 47, msg, text_color=Color.BLACK) elif len(exception) <= 30 * 2: msg1, msg2 = msg[:27], msg[27:] self.__brick.screen.draw_text(32, 47, msg1, text_color=Color.BLACK) self.__brick.screen.draw_text(32, 57, msg2, text_color=Color.BLACK) else: msg1, msg2, msg3 = exception[:27], exception[27:53], exception[ 53:] self.__brick.screen.draw_text(32, 47, msg1, text_color=Color.BLACK) self.__brick.screen.draw_text(32, 57, msg2, text_color=Color.BLACK) self.__brick.screen.draw_text(32, 67, msg3, text_color=Color.BLACK) #wait for user to press middle button while not Button.CENTER in self.__brick.buttons.pressed(): pass self.__brick.screen.draw_image( 26, 24, 'assets/graphics/notifications/warnSel.png', transparent=Color.RED) #wait for user letting button go while Button.CENTER in self.__brick.buttons.pressed(): pass self.__refreshScreenNeeded = 1
def printMotor(motor, screen): screen.print('speed: ', motor.speed(), 'deg/s') screen.print('angle: ', motor.angle(), 'deg') return def waiter(ir_sensor): while True: btn = ir_sensor.buttons(1) wait(150) if Button.LEFT_UP in btn: return big_font = Font(size=16, bold=True) ev3 = EV3Brick() ev3.screen.set_font(big_font) # Initialize IR sensor ir = InfraredSensor(Port.S4) # Initialize motors motorB = Motor(port=Port.B, positive_direction=Direction.CLOCKWISE, gears=None) motorC = Motor(port=Port.C, positive_direction=Direction.COUNTERCLOCKWISE, gears=[36, 12]) ev3.screen.print('=Motor C=') printMotor(motorC, ev3.screen) waiter(ir)
class UIManager: """ Basicly a Menu """ def __init__(self, config, settings, brick, logger, settingsPath, charlieOSX): # general variable setup logger.info(self, 'Starting UI initialisation') self.__config = config self.__settings = settings self.__click = 'assets/media/click.wav' self.__confirm = 'assets/media/confirm.wav' self.__settingsPath = settingsPath self.brick = brick self.logger = logger self.os = charlieOSX self.profileHelper = ProfileHelper(self.logger, self.__config) self.__sound_lock = _thread.allocate_lock() self.__almostBigFont = Font(family='Arial', size=12, bold=False) self.__bigFont = Font(family='Arial', size=15, bold=True) self.position = [0, 0, False] # Main Menu self.mainMenu = Menu('sidebar') mainPages = [ "assets/graphics/menus/programming.png", "assets/graphics/menus/testing.png", "assets/graphics/menus/remote.png", "assets/graphics/menus/competition.png", "assets/graphics/menus/settings.png", ] for i in range(len(mainPages)): name = mainPages[i].split('/')[3].split('.')[0] self.mainMenu.addObject( UIObject(name, self.brick, Box(0, i, 30, 25), 'img', mainPages[i], padding=(0, 0, True))) # Programming Menu self.programming = Menu('list', self.brick) self.programming.setList(self.__config['profileNames']) self.programming.setClickAction(self.runProgramming) # Testing Menu self.testing = Menu('list', self.brick) self.testing.setList(self.__config['profileNames']) self.testing.setClickAction(self.runTesting) # Remote-Control Menu self.remote = Menu('canvas') self.remote.addObject( UIObject('startButton', self.brick, Box(58, 80, 82, 14), 'textBox', 'Start Webremote', padding=(-1, -1, False))) self.remote.addObject( UIObject('endButton', self.brick, Box(59, 80, 81, 14), 'textBox', 'Stop Webremote', padding=(-1, -1, False), visible=False)) self.remote.getObjectByName('startButton').setClickAction( self.runWebremote) # Competition-Mode Menu self.competition = Menu('canvas') self.competition.addObject( UIObject('startButton', self.brick, Box(55, 80, 88, 14), 'textBox', 'Start Competition', padding=(-1, -1, False))) self.competition.addObject( UIObject('runButton', self.brick, Box(74, 90, 48, 14), 'textBox', 'Start Run', padding=(-1, -1, False), visible=False)) self.competition.addObject( UIObject('nextButton', self.brick, Box(72, 90, 53, 14), 'textBox', 'Start Next', padding=(-1, -1, False), visible=False)) self.competition.getObjectByName('startButton').setClickAction( self.runCompetition) # Settings Menu self.settingsMenu = Menu('dict', self.brick) self.settingsMenu.setDict(self.__settings) # menu Variables self.loop = True self.currentMenu = self.mainMenu self.subMenus = [ self.programming, self.testing, self.remote, self.competition, self.settingsMenu ] self.types = { 4: 'Turn', 5: 'Action' if not self.__config['useGearing'] else 'Gearing', 7: 'Straight', 9: 'Intervall', 11: 'Curve', 12: 'to Color', 15: 'to Wall' } self.secondParam = { 4: 'Angle', 5: 'Revs', 7: 'Distance', 9: 'Distance', 11: 'Distance', 12: 'Color', 15: 'none', 'units': { 4: '°', 5: 'Revs', 7: 'cm', 9: 'cm', 11: 'cm', 12: '', 15: '' } } self.thirdParam = { 4: 'Port', 5: 'Port', 7: 'none' if self.__config['robotType'] != 'MECANUM' else 'Angle', 9: 'Amount', 11: 'Angle', 12: 'Side', 15: 'none', 'units': { 4: '', 5: '', 7: '°', 9: '', 11: '°', 12: '', 15: '' } } self.valueTypes = { 1: { 4: 'percentage', 5: 'percentage', 7: 'percentage', 9: 'percentage', 11: 'percentage', 12: 'percentage', 15: 'percentage' }, 2: { 4: 'largeInt', 5: 'largeInt', 7: 'largeInt', 9: 'largeInt', 11: 'largeInt', 12: 'bool', 15: 'none' }, 3: { 4: 'side', 5: 'port', 7: 'none', 9: 'largeInt', 11: 'largeInt', 12: 'side', 15: 'none' } } self.valueRanges = { 'percentage': range(0, 101), 'type': [7, 4, 5, 11, 9, 12, 15], 'largeInt': range(0, 10000), 'side': [2, 3, 23], 'bool': [0, 1], 'port': range(0, 4), 'none': [0] } #self.logger.info(self, 'UI initialized') def __str__(self): return "UIManager" def __sound(self, file): ''' This private method is used for playing a sound in a separate thread so that other code can be executed simultaneously. Args: file (str / SoundFile): The path to the soundfile to play ''' def __playSoundFile(soundFile): with self.__sound_lock: self.brick.speaker.play_file(soundFile) _thread.start_new_thread(__playSoundFile, (file, )) def mainLoop(self): # Welcome screen self.brick.screen.draw_image(0, 0, 'assets/graphics/menus/mainMenu.png', transparent=Color.RED) while not any(self.brick.buttons.pressed()): pass if Button.UP in self.brick.buttons.pressed(): self.position[1] = self.currentMenu.maxY elif Button.DOWN in self.brick.buttons.pressed(): self.position[1] = 0 self.currentMenu.draw(self.position) print(self.position) time.sleep(0.3) self.menuLocations = [ "assets/graphics/animations/mainProgram/10.png", "assets/graphics/animations/mainTest/10.png", "assets/graphics/animations/mainRemote/10.png", "assets/graphics/animations/mainCompetition/10.png", "assets/graphics/animations/mainSettings/10.png", ] while self.loop: if any(self.brick.buttons.pressed()): if Button.UP in self.brick.buttons.pressed( ) and not self.position[2]: self.position[1] = self.position[1] - 1 if self.position[ 1] > 0 else self.currentMenu.maxY elif Button.DOWN in self.brick.buttons.pressed( ) and not self.position[2]: self.position[1] = self.position[1] + 1 if self.position[ 1] < self.currentMenu.maxY else 0 elif Button.LEFT in self.brick.buttons.pressed() and len( self.position) > 3 and not self.position[2]: if self.currentMenu.getType( ) == 'canvas' and self.position[0] > 0: self.position[ 0] = self.position[0] - 1 if self.position[ 0] > 0 else self.currentMenu.maxX else: self.position.pop(0) self.position.pop(0) self.position.pop(0) if len(self.position) == 3: self.animate(self.position[1], False) self.currentMenu = self.mainMenu elif Button.RIGHT in self.brick.buttons.pressed( ) and not self.position[2]: # self.position[0] = self.position[0] + 1 if self.position[0] < self.currentMenu.maxX else 0 if self.currentMenu.getType() == 'canvas': self.position[ 0] = self.position[0] + 1 if self.position[ 0] < self.currentMenu.maxX else 0 else: if len(self.position) == 3: self.animate(self.position[1], True) self.currentMenu = self.subMenus[self.position[1]] self.position.insert(0, False) self.position.insert(0, 0) self.position.insert(0, 0) elif Button.RIGHT in self.brick.buttons.pressed( ) and self.position[2]: self.position[0] = self.position[0] + 1 if self.position[ 0] < self.currentMenu.maxX else 0 self.__settings['options'][list( self.__settings['options'].keys())[ self.position[1]]] = self.position[0] elif Button.LEFT in self.brick.buttons.pressed( ) and self.position[2]: self.position[0] = self.position[0] - 1 if self.position[ 0] > 0 else self.currentMenu.maxX self.__settings['options'][list( self.__settings['options'].keys())[ self.position[1]]] = self.position[0] elif Button.CENTER in self.brick.buttons.pressed(): if self.currentMenu.getType() == 'list': self.currentMenu.click(self.position) elif self.currentMenu.getType() == 'dict': if self.position[2]: self.position.pop(0) self.position.pop(0) self.position.pop(0) self.position[2] = not self.position[2] self.os.storeSettings(self.__settings, 'default') self.os.applySettings(self.__settings) else: self.position[2] = not self.position[2] self.position.insert(0, True) self.position.insert(0, self.position[2]) self.position.insert( 0, self.__settings['options'][list( self.__settings['options'].keys())[ self.position[0]]]) elif len(self.position) != 3: self.position[2] = not self.position[2] self.currentMenu.getObjectByPostion( self.position).click() if self.currentMenu.getType() not in ['canvas']: self.position.insert(0, False) self.position.insert(0, 0) self.position.insert(0, 0) if self.position[0] == -1: self.position.pop(0) self.brick.screen.draw_image( 0, 0, self.menuLocations[self.position[len(self.position) - 4]], transparent=Color.RED) self.currentMenu.draw(self.position) print(self.position) time.sleep(0.3) def animate(self, state, direction): ''' Animates the transition between the main-menu-pages and the submenu-pages Args: state (int): The menu-transition to animate direction (bool): wether it should play the animation forwards or backwards ''' menus = [ 'mainProgram', 'mainTest', 'mainRemote', 'mainCompetition', 'mainSettings' ] if direction: try: for i in range(1, 11): self.brick.screen.draw_image( 0, 0, 'assets/graphics/animations/%s/%s.png' % (menus[state], i), transparent=Color.RED) time.sleep(0.05) except Exception as exception: self.logger.error(self, "Could not animate menu: ", str(exception)) else: try: for i in reversed(range(1, 11)): self.brick.screen.draw_image( 0, 0, 'assets/graphics/animations/%s/%s.png' % (menus[state], i), transparent=Color.RED) time.sleep(0.05) except Exception as exception: self.logger.error(self, "Could not animate menu: ", str(exception)) def runProgramming(self, position): index = position[1] content = self.profileHelper.getProfileData( self.__config['profileNames'][index]) self.runList = Menu('progList', self.brick) self.runList.setList(content) self.runList.setClickAction(self.runEditing) self.runList.draw(self.position) # sideloop for interactive sub submenu while not Button.LEFT in self.brick.buttons.pressed(): if any(self.brick.buttons.pressed()): if Button.UP in self.brick.buttons.pressed( ) and not self.position[2]: self.position[1] = self.position[1] - 1 if self.position[ 1] > 0 else self.runList.maxY elif Button.DOWN in self.brick.buttons.pressed( ) and not self.position[2]: self.position[1] = self.position[1] + 1 if self.position[ 1] < self.runList.maxY else 0 elif Button.CENTER in self.brick.buttons.pressed(): startTime = time.time() deleted = False while Button.CENTER in self.brick.buttons.pressed(): if time.time() - startTime > 2 and not deleted: deleted = True content.pop() content.pop(self.position[1]) self.runList.setList(content) self.runList.draw(self.position) self.brick.speaker.beep() buttonTime = time.time() - startTime if buttonTime < 2: # edit step if self.position[1] != len(content) - 1: self.runList.click(self.position) else: content.pop() content.append([7, 100, 10, 0]) self.runList.setList(content) self.profileHelper.setProfileData( self.__config['profileNames'][index], content) if self.position[0] == -1: self.position.pop(0) self.brick.screen.draw_image( 0, 0, self.menuLocations[self.position[len(self.position) - 4]], transparent=Color.RED) print(self.position, content) self.runList.draw(self.position) time.sleep(0.3) def runEditing(self, position): def formatScreenContent(thirdType): screenContent[0] = 'Type: %s' % self.types[content[index][0]] screenContent[1] = 'Speed: %s%%' % content[index][1] screenContent[2] = '%s: %s%s' % ( self.secondParam[content[index][0]], content[index][2], self.secondParam['units'][content[index][0]] ) if self.secondParam[content[index][0]] != 'none' else '' value = str(content[index][3]).replace('23', 'Left/Right').replace( '2', 'Left').replace( '3', 'Right') if thirdType == 'side' else content[index][3] screenContent[3] = '%s: %s%s' % ( self.thirdParam[content[index][0]], value, self.thirdParam['units'][content[index][0]] ) if self.thirdParam[content[index][0]] != 'none' else '' smallStep = 1 bigStep = 5 index = position[1] screenContent = ['', '', '', ''] content = self.profileHelper.getProfileData( self.__config['profileNames'][position[4]]) formatScreenContent(self.valueTypes[3][content[index][0]]) menu = ProgrammingWindow(self.brick, 'Edit Step', 'list', screenContent) self.position.insert(0, False) self.position.insert(0, 0) self.position.insert(0, 0) mmax = 3 menu.open(position) while not (Button.LEFT in self.brick.buttons.pressed() and not position[2]): if any(self.brick.buttons.pressed()): valueType = self.valueTypes[position[1]][ content[index][0]] if position[1] != 0 else 'type' valueRange = self.valueRanges[valueType] if Button.UP in self.brick.buttons.pressed(): if self.position[2]: if valueType not in ['type', 'side']: content[index][position[1]] = content[index][position[ 1]] + smallStep if content[index][position[ 1]] + smallStep in valueRange else valueRange[ 0] else: try: content[index][position[1]] = valueRange[ valueRange. index(content[index][position[1]]) - 1 if valueRange. index(content[index][position[1]]) - 1 >= 0 else len(valueRange) - 1] except ValueError: content[index][position[1]] = valueRange[0] else: self.position[1] = self.position[ 1] - 1 if self.position[1] > 0 else mmax elif Button.DOWN in self.brick.buttons.pressed(): if self.position[2]: if valueType not in ['type', 'side']: content[index][position[1]] = content[index][position[ 1]] - smallStep if content[index][position[ 1]] - smallStep in valueRange else valueRange[ len(valueRange) - 1] else: try: content[index][position[1]] = valueRange[ valueRange. index(content[index][position[1]]) + 1 if valueRange. index(content[index][position[1]]) + 1 < len(valueRange) else 0] except ValueError: content[index][position[1]] = valueRange[0] else: self.position[1] = self.position[ 1] + 1 if self.position[1] < mmax else 0 elif Button.RIGHT in self.brick.buttons.pressed(): if self.position[2]: if valueType not in ['type', 'side']: content[index][position[1]] = content[index][ position[1]] + bigStep if content[index][position[ 1]] + bigStep in valueRange else valueRange[ 0] elif Button.LEFT in self.brick.buttons.pressed(): if self.position[2]: if valueType not in ['type', 'side']: content[index][position[1]] = content[index][ position[1]] - bigStep if content[index][position[ 1]] - bigStep in valueRange else valueRange[ len(valueRange) - 1] elif Button.CENTER in self.brick.buttons.pressed(): position[2] = not position[2] formatScreenContent(self.valueTypes[3][content[index][0]]) menu.updateContent(screenContent) menu.draw(position=position) if not (Button.LEFT in self.brick.buttons.pressed() and not position[2]): time.sleep(0.3) self.position.pop(0) self.position.pop(0) self.position.pop(0) self.profileHelper.setProfileData( self.__config['profileNames'][position[4]], content) menu.close(position) time.sleep(0.3) def runTesting(self, position): index = position[1] profileData = self.profileHelper.getProfileData( self.__config['profileNames'][index]) time.sleep(0.3) self.os.robot.execute(profileData) def runWebremote(self): self.currentMenu.getObjectByName('startButton').setVisibility(False) self.currentMenu.getObjectByName('endButton').setVisibility(True) self.position[1] += 1 self.currentMenu.draw(self.position) time.sleep(0.3) self.os.webremote.run() self.currentMenu.getObjectByName('startButton').setVisibility(True) self.currentMenu.getObjectByName('endButton').setVisibility(False) self.position[2] = False self.position[1] -= 1 self.currentMenu.draw(self.position) time.sleep(0.3) def runCompetition(self): dataArray = [] self.wireless( False ) # uncomment to not loose connectivity for console-logging and effective development through wifi self.currentMenu.getObjectByName('startButton').setVisibility(False) self.currentMenu.getObjectByName('runButton').setVisibility(True) self.position[0], self.position[1] = 1, 1 self.currentMenu.draw(self.position) for i in self.__config['profileNames']: dataArray.append(self.profileHelper.getProfileData(i)) self.currentMenu.getObjectByName('runButton').setVisibility(False) self.currentMenu.getObjectByName('nextButton').setVisibility(True) time.sleep(0.3) for index in range(0, len(dataArray)): self.brick.screen.draw_box(30, 30, 200, 80, fill=True, color=Color.WHITE) self.brick.screen.set_font(self.__almostBigFont) self.brick.screen.draw_text(74, 36, "Run %s/%s:" % (index, len(dataArray) - 1), background_color=Color.WHITE) self.brick.screen.set_font(self.__bigFont) self.brick.screen.draw_text(98 - self.__bigFont.text_width( self.__config['profileNames'][index]) / 2, 60, self.__config['profileNames'][index], background_color=Color.WHITE) while Button.CENTER not in self.brick.buttons.pressed(): pass self.position[0], self.position[1] = 1, 1 self.currentMenu.draw(self.position) time.sleep(0.3) self.os.robot.execute(dataArray[index]) time.sleep(0.3) self.position[0], self.position[1] = 1, 0 self.currentMenu.draw(self.position) self.wireless(True) self.brick.screen.draw_box(30, 30, 200, 80, fill=True, color=Color.WHITE) self.position[0], self.position[1], self.position[2] = 0, 0, False self.currentMenu.getObjectByName('startButton').setVisibility(True) self.currentMenu.getObjectByName('runButton').setVisibility(False) self.currentMenu.getObjectByName('nextButton').setVisibility(False) self.currentMenu.draw(self.position) def wireless(self, enable): cmd = 'enable' if not enable else 'disable' os.system('connmanctl {} offline'.format(cmd))
# log_2020_02_13_10_07_44_431260.csv # * You can optionally specify the titles of your data columns. For example, # if you want to record the motor angles at a given time, you could do: data = DataLog('time', 'sensor_value', name='log', timestamp=False, extension='csv', append=False) colorValues = DataLog('color', 'value', name='color', timestamp=False, extension='csv', append=False) message = Font() # Start a stopwatch to measure elapsed time watch = StopWatch() # Create your objects here. ev3 = EV3Brick() # Initialize the color sensor. left_sensor = ColorSensor(Port.S1) # Place on black. ev3.speaker.say("Place on black") # Write the value of the left color sensor to the screen. while True:
# Initialize the EV3 ev3 = EV3Brick() # SPLIT SCREEN ################################################################ # Make a sub-image for the left half of the screen left = Image(ev3.screen, sub=True, x1=0, y1=0, x2=ev3.screen.width // 2 - 1, y2=ev3.screen.height - 1) # Make a sub-image for the right half of the screen right = Image(ev3.screen, sub=True, x1=ev3.screen.width // 2, y1=0, x2=ev3.screen.width - 1, y2=ev3.screen.height - 1) # Use a monospaced font so that text is vertically aligned when we print right.set_font(Font(size=8, monospace=True)) # Graphing y = sin(x) def f(x): return math.sin(x) for t in range(200): # Graph on left side # Scale t to x-axis and compute y values x0 = (t - 1) * 2 * math.pi / left.width y0 = f(x0) x1 = t * 2 * math.pi / left.width y1 = f(x1)