示例#1
0
def calc_fonts():
    """
    Iterate through all the Latin "1 & 5" fonts, and use ANSI escape sequences to see how many rows/columns
    the EV3 LCD console can accommodate for each font
    """
    console = Console()

    files = [
        f for f in listdir("/usr/share/consolefonts/")
        if f.startswith("Lat15") and f.endswith(".psf.gz")
    ]
    files.sort()
    for font in files:
        console.set_font(font, True)

        # position cursor at 50, 50, and ask the console to report its actual cursor position
        console.text_at("\x1b[6n", 50, 50, False)
        console.text_at(font, 1, 1, False, True)
        console.clear_to_eol()

        # now, read the console response of the actual cursor position, in the form of esc[rr;ccR
        # requires pressing the center button on the EV3 for each read
        dims = ''
        while True:
            ch = stdin.read(1)
            if ch == '\x1b' or ch == '[' or ch == '\r' or ch == '\n':
                continue
            if ch == 'R':
                break
            dims += str(ch)
        (rows, cols) = dims.split(";")
        print("({}, {}, \"{}\"),".format(rows, cols, font), file=stderr)
        sleep(.5)
示例#2
0
 def write_to_console(self, msg:str, column:int, row:int, reset_console=True, inverse=False, alignment='L', font_size='M'):
     """Write msg to console at column, and row
     reset_console clears console first
     inverse reverses out text
     alignment: 'L', 'C', or 'R'
     font_size: 'S', 'M', 'L'
     Small: 8 rows, 22 columns
     Medium: 6 rows, 17 columns
     Large: 4 rows, 12 columns
     """
     console = Console()
     if font_size == 'S':
         console.set_font('Lat15-TerminusBoldVGA16.psf.gz', True)
     elif font_size == 'M':
         console.set_font('Lat15-Terminus20x10.psf.gz', True)
     else:
         console.set_font('Lat15-Terminus32x16.psf.gz', True)
     console.text_at(msg, column, row, reset_console=reset_console, inverse=inverse, alignment=alignment)
示例#3
0
def show_fonts():
    """
    Iterate over the known Latin "1 & 5" fonts and display each on the EV3 LCD console.
    Note: `Terminus` fonts are "thinner"; `TerminusBold` and `VGA` offer more contrast on the LCD console
    and are thus more readable; the `TomThumb` font is waaaaay too small to read!
    """
    # Create a list of tuples with calulated rows, columns, font filename
    fonts = [
        (4, 11, "Lat15-Terminus32x16.psf.gz"),
        (4, 11, "Lat15-TerminusBold32x16.psf.gz"),
        (4, 11, "Lat15-VGA28x16.psf.gz"), (4, 11, "Lat15-VGA32x16.psf.gz"),
        (4, 12, "Lat15-Terminus28x14.psf.gz"),
        (4, 12, "Lat15-TerminusBold28x14.psf.gz"),
        (5, 14, "Lat15-Terminus24x12.psf.gz"),
        (5, 14, "Lat15-TerminusBold24x12.psf.gz"),
        (5, 16, "Lat15-Terminus22x11.psf.gz"),
        (5, 16, "Lat15-TerminusBold22x11.psf.gz"),
        (6, 17, "Lat15-Terminus20x10.psf.gz"),
        (6, 17, "Lat15-TerminusBold20x10.psf.gz"),
        (7, 22, "Lat15-Fixed18.psf.gz"), (8, 22, "Lat15-Fixed15.psf.gz"),
        (8, 22, "Lat15-Fixed16.psf.gz"), (8, 22, "Lat15-Terminus16.psf.gz"),
        (8, 22, "Lat15-TerminusBold16.psf.gz"),
        (8, 22, "Lat15-TerminusBoldVGA16.psf.gz"),
        (8, 22, "Lat15-VGA16.psf.gz"), (9, 22, "Lat15-Fixed13.psf.gz"),
        (9, 22, "Lat15-Fixed14.psf.gz"), (9, 22, "Lat15-Terminus14.psf.gz"),
        (9, 22, "Lat15-TerminusBold14.psf.gz"),
        (9, 22, "Lat15-TerminusBoldVGA14.psf.gz"),
        (9, 22, "Lat15-VGA14.psf.gz"), (10, 29, "Lat15-Terminus12x6.psf.gz"),
        (16, 22, "Lat15-VGA8.psf.gz"), (21, 44, "Lat15-TomThumb4x6.psf.gz")
    ]

    # Paint the screen full of numbers that represent the column number, reversing the even rows
    console = Console()
    for rows, cols, font in fonts:
        print(rows, cols, font, file=stderr)
        console.set_font(font, True)
        for row in range(1, rows + 1):
            for col in range(1, cols + 1):
                console.text_at("{}".format(col % 10), col, row, False,
                                (row % 2 == 0))
        console.text_at(font.split(".")[0], 1, 1, False, True)
        console.clear_to_eol()
        sleep(.5)
def show_fonts():
    """
    Iterate through all the Latin "1 & 5" fonts, and see how many rows/columns
    the EV3 LCD console can accommodate for each font.
    Note: ``Terminus`` fonts are "thinner"; ``TerminusBold`` and ``VGA`` offer more contrast on the LCD console
    and are thus more readable; the ``TomThumb`` font is waaaaay too small to read!
    """
    console = Console()
    files = [
        f for f in listdir("/usr/share/consolefonts/")
        if f.startswith("Lat15") and f.endswith(".psf.gz")
    ]
    files.sort()
    fonts = []
    for font in files:
        console.set_font(font, True)
        console.text_at(font, 1, 1, False, True)
        console.clear_to_eol()
        console.text_at("{}, {}".format(console.columns, console.rows),
                        column=2,
                        row=4,
                        reset_console=False,
                        inverse=False)
        print("{}, {}, \"{}\"".format(console.columns, console.rows, font),
              file=stderr)
        fonts.append((console.columns, console.rows, font))

    fonts.sort(key=lambda f: (f[0], f[1], f[2]))

    # Paint the screen full of numbers that represent the column number, reversing the even rows
    for cols, rows, font in fonts:
        print(cols, rows, font, file=stderr)
        console.set_font(font, True)
        for row in range(1, rows + 1):
            for col in range(1, cols + 1):
                console.text_at("{}".format(col % 10), col, row, False,
                                (row % 2 == 0))
        console.text_at(font.split(".")[0], 1, 1, False, True)
        console.clear_to_eol()
示例#5
0
def menu(choices, before_run_function=None, after_run_function=None):
    """
    Console Menu that accepts choices and corresponding functions to call.
    The user must press the same button twice: once to see their choice highlited,
    a second time to confirm and run the function. The EV3 LEDs show each state change:
    Green = Ready for button, Amber = Ready for second button, Red = Running
    Parameters:
    - `choices` a dictionary of tuples "button-name": ("mission-name", function-to-call)
        Example:
            choices = {
                # "button-name": ("mission-name", function-to-call)
                # or "button-name": ("mission-name", lambda: call(x, y, z))
                "enter": ("CAL", lambda: auto_calibrate(robot, 1.0)),
                "up": ("MI2", fmission2),
                "right": ("MI3", fmission3),
                "down": ("MI4", fmission4),
                "left": ("MI5", fmission5)
            }
        where fmission2, fmission3 are functions;
        note don't call them with parentheses, unless preceded by lambda: to defer the call
    - `before_run_function` when not None, call this function before each mission run, passed with mission-name
    - `after_run_function` when not None, call this function after each mission run, passed with mission-name
    """

    console = Console()
    leds = Leds()
    button = Button()

    leds.all_off()
    leds.set_color("LEFT", "GREEN")
    leds.set_color("RIGHT", "GREEN")
    menu_positions = get_positions(console)

    last = None  # the last choice--initialize to None

    while True:
        # display the menu of choices, but show the last choice in inverse
        console.reset_console()
        for btn, (name, _) in choices.items():
            align, col, row = menu_positions[btn]
            console.text_at(name, col, row, inverse=(btn == last), alignment=align)

        pressed = wait_for_button_press(button)

        # get the choice for the button pressed
        if pressed in choices:
            if last == pressed:   # was same button pressed?
                console.reset_console()
                leds.set_color("LEFT", "RED")
                leds.set_color("RIGHT", "RED")

                # call the user's subroutine to run the mission, but catch any errors
                try:
                    name, mission_function = choices[pressed]
                    if before_run_function is not None:
                        before_run_function(name)
                    mission_function()
                except Exception as ex:
                    print("**** Exception when running")
                    print(ex)
                finally:
                    if after_run_function is not None:
                        after_run_function(name)
                    last = None
                    leds.set_color("LEFT", "GREEN")
                    leds.set_color("RIGHT", "GREEN")
            else:   # different button pressed
                last = pressed
                leds.set_color("LEFT", "AMBER")
                leds.set_color("RIGHT", "AMBER")
示例#6
0
    def display_menu(self, start_page=0, before_run_function=None, after_run_function=None, skip_to_next_page=True):
        """
        Console Menu that accepts choices and corresponding functions to call.
        The user must press the same button twice: once to see their choice highlited,
        a second time to confirm and run the function. The EV3 LEDs show each state change:
        Green = Ready for button, Amber = Ready for second button, Red = Running
        Parameters:
        - `choices` a dictionary of tuples "button-name": ("function-name", function-to-call)
        NOTE: Don't call functions with parentheses, unless preceded by lambda: to defer the call
        - `before_run_function` when not None, call this function before each function run, passed with function-name
        - `after_run_function` when not None, call this function after each function run, passed with function-name
        """

        self.current_page = start_page

        console = Console()
        leds = Leds()
        button = Button()

        leds.all_off()
        leds.set_color("LEFT", "GREEN")
        leds.set_color("RIGHT", "GREEN")
        menu_positions = self.get_menu_positions(console)

        last = None  # the last choice--initialize to None

        self.menu_tone()
        self.debug("Starting Menu")
        while True:
            # display the menu of choices, but show the last choice in inverse
            console.reset_console()
            self.debug("Reset the display screen")
            console.set_font('Lat15-TerminusBold24x12.psf.gz', True)
            
            # store the currently selected menu page
            menu_page = self.menu_pages[self.current_page]
            # store the currently selected menu items
            menu_options_on_page = menu_page.items() 
            
            for btn, (name, _) in menu_options_on_page:
                align, col, row = menu_positions[btn]
                console.text_at(name, col, row, inverse=(btn == last), alignment=align)
            self.debug("Waiting for button press...")
            pressed = self.wait_for_button_press(button)
            self.debug("Registered button press: {}".format(pressed))
            
            # get the choice for the button pressed
            if pressed in menu_page:
                if last == pressed:   # was same button pressed?
                    console.reset_console()
                    leds.set_color("LEFT", "RED")
                    leds.set_color("RIGHT", "RED")

                    # call the user's subroutine to run the function, but catch any errors
                    try:
                        name, run_function = menu_page[pressed]
                        if before_run_function is not None:
                            self.debug('Running before function')
                            before_run_function(name)
                        self.press_tone()
                        type_of_run_function = type(run_function)
                        self.debug("Type of run_function: {}".format(type_of_run_function))

                        if isinstance(run_function, str):
                            self.debug("Running {}".format(run_function))
                            if run_function == 'next':
                                self.debug("About to call next")
                                self.next()
                            elif run_function =='back':
                                self.debug("About to call back")
                                self.back()
                        elif callable(run_function):
                            run_function()
                    except Exception as e:
                        print("**** Exception when running")
                        raise(e)
                    finally:
                        if after_run_function is not None:
                            after_run_function(name)
                        last = None
                        leds.set_color("LEFT", "GREEN")
                        leds.set_color("RIGHT", "GREEN")
                else:   # different button pressed
                    last = pressed
                    leds.set_color("LEFT", "AMBER")
                    leds.set_color("RIGHT", "AMBER")
示例#7
0
class Robot:
    def __init__(self):
        self.sound = Sound()
        self.direction_motor = MediumMotor(OUTPUT_D)
        self.swing_motorL = LargeMotor(OUTPUT_A)
        self.swing_motorC = LargeMotor(OUTPUT_B)
        self.swing_motorR = LargeMotor(OUTPUT_C)
        self.swing_motors = [
            self.swing_motorL, self.swing_motorC, self.swing_motorR
        ]
        self.touch_sensor = TouchSensor(INPUT_1)
        self.console = Console(DEFAULT_FONT)
        self.buttons = Button()
        self.beeps_enabled = True

    def beep(self, frequency=700, wait_for_comeplete=False):
        if not self.beeps_enabled:
            return
        play_type = Sound.PLAY_WAIT_FOR_COMPLETE if wait_for_comeplete else Sound.PLAY_NO_WAIT_FOR_COMPLETE
        self.sound.beep("-f %i" % frequency, play_type=play_type)

    def calibrate_dir(self):
        ''' Calibrate direction motor '''
        # Run motor with 25% power, and wait until it stops running
        self.direction_motor.on(SpeedPercent(-10), block=False)
        # while (not self.direction_motor.STATE_OVERLOADED):
        #     print(self.direction_motor.duty_cycle)
        self.direction_motor.wait_until(self.direction_motor.STATE_OVERLOADED)

        self.direction_motor.stop_action = Motor.STOP_ACTION_COAST
        self.direction_motor.stop()

        time.sleep(.5)

        # Reset to straight
        # self.direction_motor.on_for_seconds(SpeedPercent(10), .835, brake=True, block=True)
        self.direction_motor.on_for_degrees(SpeedPercent(10),
                                            127,
                                            brake=True,
                                            block=True)
        self.direction_motor.reset()

        print("Motor reset, position: " + str(self.direction_motor.position))

        time.sleep(.5)

    def calibrate_swing(self):
        for m in self.swing_motors:
            m.stop_action = m.STOP_ACTION_HOLD
            m.on(SpeedPercent(6))

        self.swing_motorC.wait_until(self.swing_motorC.STATE_OVERLOADED, 2000)

        for m in self.swing_motors:
            m.stop_action = m.STOP_ACTION_HOLD
            m.on_for_degrees(SpeedPercent(5), -15, brake=True, block=False)

        self.swing_motorC.wait_while('running')

        for m in self.swing_motors:
            m.reset()
            m.stop_action = m.STOP_ACTION_HOLD
            m.stop()

        print("Ready Angle: %i" % self.swing_motorC.position)

    def ready_swing(self, angle: int):
        right_angle = -(angle / 3)
        # adjust motors to target angle
        for m in self.swing_motors:
            m.stop_action = Motor.STOP_ACTION_HOLD
            m.on_for_degrees(SpeedPercent(2),
                             right_angle,
                             brake=True,
                             block=False)

        self.swing_motorC.wait_while('running')

        for m in self.swing_motors:
            m.stop_action = Motor.STOP_ACTION_HOLD
            m.stop()

        print("Swing Angle: %i" % self.swing_motorC.position)

    def set_direction(self, direction):
        print("Setting direction to: " + str(direction))
        #direction = self.__aim_correction(direction)
        self.direction_motor.on_for_degrees(SpeedPercent(10),
                                            round(direction * 3))
        print("Direction set to: " + str(self.direction_motor.position))

#
#    def __aim_correction(self, direction):
#        x = direction
#        y = -0.00000000429085685725*x**6 + 0.00000004144345630728*x**5 + 0.00001219331494759860*x**4 + 0.00020702946527870400*x**3 + 0.00716486965517779000*x**2 + 1.29675836037884000000*x + 0.27064829453014400000
#
#        return y

    def shoot(self, power):

        print("SHOOT, power: %i" % power)

        for m in self.swing_motors:
            m.duty_cycle_sp = -power

        for m in self.swing_motors:
            m.run_direct()

        time.sleep(.5)

        self.swing_motorC.wait_until_not_moving()

        for m in self.swing_motors:
            m.reset()

    def wait_for_button(self):
        self.touch_sensor.wait_for_bump()

    def __set_display(self, str):
        self.console.set_font(font=LARGER_FONT, reset_console=True)
        self.console.text_at(str, column=1, row=1, reset_console=True)

    def wait_for_power_select(self, power=0, angle=0, steps=1):
        self.__set_display("Pow: %i\nAngle: %i" % (power, angle))

        def left():
            power -= steps
            if power < 0:
                power = 0
            self.__set_display("Pow: %i\nAngle: %i" % (power, angle))
            self.buttons.wait_for_released(buttons=['left'], timeout_ms=150)

        def right():
            power += steps
            if power > 100:
                power = 100
            self.__set_display("Pow: %i\nAngle: %i" % (power, angle))
            self.buttons.wait_for_released(buttons=['right'], timeout_ms=150)

        def up():
            angle += steps
            if angle > 110:
                angle = 110
            self.__set_display("Pow: %i\nAngle: %i" % (power, angle))
            self.buttons.wait_for_released(buttons=['up'], timeout_ms=150)

        def down():
            angle -= steps
            if angle < 0:
                angle = 0
            self.__set_display("Pow: %i\nAngle: %i" % (power, angle))
            self.buttons.wait_for_released(buttons=['down'], timeout_ms=150)

        while not self.touch_sensor.is_pressed:
            if self.buttons.left:
                left()
            elif self.buttons.right:
                right()
            elif self.buttons.up:
                up()
            elif self.buttons.down:
                down()

        self.console.set_font(font=DEFAULT_FONT, reset_console=True)
        return (power, angle)

    def select_connection_mode(self):
        self.__set_display("Enable Connection\nLeft: True - Right: False")

        enabled = True

        while not self.touch_sensor.is_pressed:
            if self.buttons.left:
                enabled = True
                self.buttons.wait_for_released(buttons=['left'])
                break
            elif self.buttons.right:
                enabled = False
                self.buttons.wait_for_released(buttons=['right'])
                break

        self.console.set_font(font=DEFAULT_FONT, reset_console=True)
        return enabled

    def print(self, string):
        print(string)
示例#8
0
#!/usr/bin/env micropython
from ev3dev2.console import Console
from time import sleep

# create a Console instance, which uses the default font
console = Console()

# reset the console to clear it, home the cursor at 1,1, and then turn off the cursor
console.reset_console()

# display 'Hello World!' at row 5, column 1 in inverse, but reset the EV3 LCD console first
console.text_at('Hello World!',
                column=1,
                row=5,
                reset_console=True,
                inverse=True)
sleep(10)
示例#9
0
文件: fllman.py 项目: KePeterZ/fllman
                program -= 1
        elif type(plus) == type(True):
            run = currentProgram
        currentProgram = (program % len(programs)) + 1


button.on_right = lambda x: c(1)
button.on_left = lambda x: c(-1)
button.on_enter = lambda x: c(True)

# Program running handling
currentProgram = 1
pastProgram = currentProgram

console.reset_console()
console.text_at("Selected: " + str(currentProgram))

while True:
    button.process()
    if currentProgram != pastProgram:
        clearColumn(1)
        console.text_at("Selected: " + str(currentProgram))
    if run:
        clearColumn(1)
        console.text_at("Running: " + str(currentProgram), 1, 1)
        console.text_at("            ", 1, 2)
        console.text_at("", 1, 2)
        # Running file here
        reimportModulesAndRun("run%i" % currentProgram)
        run = False
        # Running file ending here
示例#10
0
def menu(choices, before_run_function=None, after_run_function=None, skip_to_next_page=True):
    """
    Console Menu that accepts choices and corresponding functions to call.
    The user must press the same button twice: once to see their choice highlited,
    a second time to confirm and run the function. The EV3 LEDs show each state change:
    Green = Ready for button, Amber = Ready for second button, Red = Running
    Parameters:
    - `choices` a dictionary of tuples "button-name": ("mission-name", function-to-call)
    NOTE: Don't call functions with parentheses, unless preceded by lambda: to defer the call
    - `before_run_function` when not None, call this function before each mission run, passed with mission-name
    - `after_run_function` when not None, call this function after each mission run, passed with mission-name
    """

    global proc
    console = Console()
    leds = Leds()
    button = Button()

    leds.all_off()
    leds.set_color("LEFT", "GREEN")
    leds.set_color("RIGHT", "GREEN")
    menu_positions = get_positions(console)

    last = None  # the last choice--initialize to None

    while True:
        # display the menu of choices, but show the last choice in inverse
        console.reset_console()
        for btn, (name, _) in choices.items():
            align, col, row = menu_positions[btn]
            console.text_at(name, col, row, inverse=(btn == last), alignment=align)

        pressed = wait_for_button_press(button)

        # get the choice for the button pressed
        if pressed in choices:
            if last == pressed:   # was same button pressed?
                console.reset_console()
                leds.set_color("LEFT", "RED")
                leds.set_color("RIGHT", "RED")

                # call the user's subroutine to run the mission, but catch any errors
                try:
                    name, mission_function = choices[pressed]
                    if before_run_function is not None:
                        before_run_function(name)
                    if name in ('NEXT', 'BACK', 'OFF'):
                        mission_function()
                    else:
                        # launch a sub process so it could be canceled with the enter button
                        # store the subprocess in self to reference in the stop function
                        proc = Process(target=mission_function)
                        debug('Starting {}'.format(name))
                        proc.start()
                        debug('Just started {} in proc {}'.format(name, proc.pid))
                        sleep(1)
                        proc.terminate()
                        # TODO: Need to figure out when to call self.proc.join
                except Exception as e:
                    print("**** Exception when running")
                    debug('Exception when running {}'.format(e))
                finally:
                    if after_run_function is not None:
                        after_run_function(name)
                    last = None
                    leds.set_color("LEFT", "GREEN")
                    leds.set_color("RIGHT", "GREEN")
            else:   # different button pressed
                last = pressed
                leds.set_color("LEFT", "AMBER")
                leds.set_color("RIGHT", "AMBER")