BDG

General approach

The Board Description Generator (BDG) is a tool which allows to generate description files for boards. For doing so, a picture of the board is needed which will serve as reference image for the BSP.

The picture should meet the following criteria: well lightning conditions, at least hd resolution, board is fully visible and not too small. Generally, the window is resizable and the content will be scaled accordingly. The radius of the LEDs will be adjusted as well.

Note

Although resizing the windows is possible, the actual image will be saved in the original resolution.

Place board corner points

With the BDG such an image can be loaded and edited. The BDG ca be operated in two modes ‘Place corner point’ or ‘Place LED’. In ‘Place corner point’ mode, corner points can be placed. These corner points are intended to mark the corners of the board in the picture. The region marked will be visible in red.

../_images/example_corner_points.png

An example where a picture of a raspberry pi is loaded and the corners points have been placed.

The selected area will be used by the BSP to perform a feature detection, so the resolution should be around full hd for better results in the detection.

Additionally, the board id has to be set. The id will be used to publish the changes via Mqtt.

Place LEDs

In the second mode markers for the LEDs can be placed. For each placed LED there is an entry for the unique name or function and checkboxes for the possible colors on the right hand side of the window. The index of the LED is displayed in the list and on the lower left corner of each LED as well. By using the mousewheel the radius of the circles can be adjusted.

The BSP will use these regions to detect the status of the LED.

Warning

The names of the LEDs should be unique because they are used to publish the changes in the mqtt.

Key support

Control + Z / Control + Y: Undo/Redo placement of a corner or LED.

Arrow Keys: Move the last selected circle a pixel in the direction

Mouse Wheel: Increase/Decrease size of a LED

In addition it is possible to resize the window but this will not affect the final coordinates of the corners/leds.

Classes of the BDG

The BDG is implemented with the Model View Controller (MVC) pattern in mind to allow easy maintenance. View is responsible for the UI and displays the data which is saved in the coordinator. The coordinator module has classes which allow to register for events (image change or point change). Thus there is no dependency of the view in the coordinator. Finally, the model provides the Board object which is used in the BSP as well.

This class diagram states the components and their relations.

Following the classes and their members:

Board

The data object which contains the specifications of the board to detect.

class BDG.model.board_model.Board(name='', author='', img_path='', corners=None, led_objects=None, image=None)

Dataclass for Board Specifications

add_led(led: BDG.model.board_model.Led, relative_vector=False)

Adds an led object and calculates the relative vector if the given vector is from (0,0)

Parameters
  • led – Is an LED object

  • relative_vector – (bool, optional): True if the vector is from the upper left corner of the BOARD, False if the vector is from the upper left corner of the IMAGE. Defaults to False.

get_relative_vector(vector: numpy.array)

helper class for calculating relative vector

Parameters

vector – np.array

Returns

vector

set_board_corners(points: List)

Creates corner points and sorted them against clockwise direction

Parameters

points – (np.array): is an array of points which are a convex polygon

set_image(image)

Sets pil image

Parameters

image – (Image): is an PIL image or a str

CreationState

class BDG.model.CreationState.CreationState(value)

The current placement mode. If it is BOARD, an anchor point is placed on left mouse click, if it is LED a LED is placed.

EventHandler

Contains two lists in the on_update dictionary which represent some sort of publish/subscribe. The ‘on_update_point’ and the ‘on_update_image’ lists contain methods which will be called when the image or the points were updated by user input.

Consequently, the view does only subscribe via writing methods in the lists and updates the UI then when the methods are being called.

In addition, the EventHandler contains the current Board reference and this reference should only be accessed by this EventHandler.

class BDG.coordinator.event_handler.EventHandler

Contains the other event handler and methods to signal an update of the image or the points.

update(channel='')

Calls all function which are in the list indicated by ‘channel’ :param channel: The channel to update. Either ‘on_update_point’ or ‘on_update_image’. If nothing, all channels will be updates

update_board(board: BDG.model.board_model.Board)

Updates the board object in the handler and calls all update methods. :param board: The new board which will be set in self

update_image()

Calls all functions which are in the list ‘on_update_image’.

update_points()

Calls all functions which are in the list ‘on_update_point’.

EditHandler

Contains the board corners, the placed LEDs, the scaling, deleted corners or LEDs and the current placement state. Every change of the the corners or LEDs is processed here. The view takes the data from this class as well.

class BDG.coordinator.edit_handler.EditHandler(parent: EventHandler)

Responsible for edit event of the UI such as creating, deleting, undoing, redoing. The methods which alter the LEDs or corners always call the update points method. Consequently the UI just has to subscribe to the events and update the content accordingly. Realises the Model View Controller pattern.

add_corner(event)

Adds a corner at the coordinates of the click event

Parameters

event – The click event with the x and y coordinate

Returns

None

add_led(event)

Adds a LED on the coordinates in the click event.

Parameters

event – The click event with x and y coordinates

Returns

None

board() BDG.model.board_model.Board

Returns the current board object

Returns

Board

check_hovered(cx, cy)

Helper function for checking the currently hovered anchor point or LED.

Parameters
  • cx – The x coordinate to check

  • cy – The y coordinate to check

Returns

an np array

delete_point(event)

Removes the currently hovered point or LED

Parameters

event – is a Mouse event

Returns

is_state(state)

Checks if the CreationState is currently in ‘state’

Parameters

state – The state to check

Returns

True, if the CreationState is the passed state

move_current_led_one_pixel_horizontally(amount: int)

Moves the active led horizontally by the amount

Parameters

amount – The amount negative means left, positive right

Returns

move_current_led_one_pixel_vertically(amount: int)

Moves the active led vertically by the amount

Parameters

amount – The amount to move, negative means up, positive down

Returns

moving_point(event)

Moves the currently selected anchor point or LED

Parameters

event

on_mousewheel(event)

Processes a mousewheel event. Optimised for Windows and Unix events. Does increase/decrease the radius of the active led.

Parameters

event – The mousewheel event

redo()

Redoes the last deleted, undone point or LED

undo()

Undoes the last LED or Point

FileHandler

class BDG.coordinator.file_handler.FileHandler(parent)

Responsible for saving and loading the svg, json or image file.

load()

loads either a predifined json file as board or inits a new board with a selected image

Args:

file_path (str): [description]

save()

saves the current board either as svg or json

Args:

file_name (str, optional): [description]. Defaults to “”.

ControlPane

class BDG.view.ControlPane.ControlPane(container)

ImagePane

class BDG.view.ImagePane.ImagePane(master, container, handler: BDG.coordinator.edit_handler.EditHandler)

This class contains the drawing functionalities

Parameters
  • self.img_path – is a relative path to the image which is loaded

  • self.master – is the master frame in which this frame is inserted

  • self.polygon – is a reference for the current polygon

  • self.polygon_images – is a dict holding the drawn polygons. IMPORTANT: PLEASE DON’T DELETE THIS; OTHERWISE THE IMAGE IS OPTIMISED OUT

  • self.canvas – is a tkinter canvas object

  • self.points – are the currently displayed circles

  • self.active_circle – is a reference as Integer to the currently selected circle

  • self.anchor_points – are the anchor points for the polygon

activate_board_state()

Change all bindings to board state settings

Returns

void

activate_led_state()

Change all bindings to LED state settings

Returns

void

create_circle(position, r)

Helper function for creating circle

Parameters
  • position – The coordinates of the circle

  • r – is the radius

Returns

a canvas object ref represented as Integer

create_polygon(*args, **kwargs)

Creates an polygon using either PIL or tk.Canvas-

Because tk.Canvas doesn’t support RGBA, the PIL lib is used to create an tkImage, which is added to the canvas

Parameters
  • args – is an even array of coordinates such as [x0, y0, x1, y1, … , xn, yn]

  • kwargs – are some named arguments which can be read in the ImageDraw Documentation. The fill keyword is required!

Returns

an canvas element

delete_circles()

Deletes the corner points bounding circles in the canvas. Used when the CreationState is switched to LED as the circles are then not visible anymore

draw_corner(point)

Draws a corner at the given coordinates

Parameters

point – The coordinates to draw

draw_led(position, radius)

Draws a LED at the given coordinates

Parameters
  • position – The coordinates of the new LED

  • radius – The radius of the new LED

on_resize(event)

Resizes the image in the canvas to fit the canvas while still having the same proportions.

Parameters

event

update_board()

Sets the board object in self to the board object of the handler.

update_image()

Reloads the image of the current board object in the canvas. Automatically fits the image to the windows size by invoking a resize event.

update_led_indices()

Redraws the indices of the LEDs anew.

update_points()

Removes and creates again all corner points and LEDs

update_polygon()

Reads the current anchor_points and updates shape of polygon

Returns

void

Scrollable

class BDG.view.Scrollable.ScrollbarFrame(parent, edit_handler: BDG.coordinator.edit_handler.EditHandler, **kwargs)

Extends class tk.Frame to support a scrollable Frame This class is independent from the widgets to be scrolled and can be used to replace a standard tk.Frame

on_configure(event)

Set the scroll region to encompass the scrolled frame

Toolbar

class BDG.view.Toolbar.Toolbar(master, image_pane: BDG.view.ImagePane.ImagePane, handler: BDG.coordinator.edit_handler.EditHandler)

Responsible for the Radiobuttons which allow to switch between the CreationStates. The Radiobuttons update the tk.IntVar in the EditHandler.

LedDisplay

class BDG.view.LedDisplay.LedDisplay(parent, index, led: BDG.model.board_model.Led, **kwargs)

A class which contains the widgets to enter the necessary meta information about LEDs. Will be grided into a Scrollable

update_number(new_number)

Updates the displayed number :param new_number: The new number to display :return:

JsonUtil

Provides functions for encoding and decoding board description models from or to json

BDG.utils.json_util.to_json(board_dict: dict) str

Converts a Board Model to a json string

Args:

board (Board): is a valid Board instance

Returns:

str: is a json representation

UtilFunctions

Utility functions for creating Board Description Model such as Sorting Points

BDG.utils.util_functions.angle_between(v1, v2)

Returns the angle in radians between vectors ‘v1’ and ‘v2’:

>>> angle_between((1, 0, 0), (0, 1, 0))

1.5707963267948966 >>> angle_between((1, 0, 0), (1, 0, 0)) 0.0 >>> angle_between((1, 0, 0), (-1, 0, 0)) 3.141592653589793

BDG.utils.util_functions.convert_image_to_data_uri(path: str) str

Reads an image from path and converts it to a data uri scheme as string

Parameters

path – is a path to an image

Returns

a binary image as datauri

BDG.utils.util_functions.decode_img_data(img_attr: str) numpy.array

Decodes the embedded image string.

Args:

img_attr (str): is the href data

BDG.utils.util_functions.find_index_closest_point(arr, point)

Returns closest point using the cartesian product

BDG.utils.util_functions.is_equal(a: numpy.ndarray, b: numpy.ndarray)

Compares two numpy arrays and returns true if the values are equal. this helper function was to avoid Value errors

Parameters
  • a – a numpy array

  • b – a numpy array

Returns

True -> the arrays are equal, False -> the arrays are differnt

BDG.utils.util_functions.led_id_generator(name_prefix='led-', suffix=0)

Generator function for creating led ids such as led-1

Parameters
  • name_prefix

  • suffix

Returns

BDG.utils.util_functions.sort_points(points: numpy.array)

Sorts a given array of vectors clockwise. It is assumed that the spanned polygon is convex

Parameters

points – is a numpy array of shape n,2 with array[n] = [x_n, y_n].

Returns

the clockwise sorted array

BDG.utils.util_functions.split_to_list(array)

converts a 2d numpy array into a python list, where every item is an numpy array Example: input: np.array([[1,1],[2,2]]) output: [np.array([1,1]),np.array([2,2])

Parameters

np_array – is an 2d numpy array or a 2d list

Returns

a list containing numpy arrays

BDG.utils.util_functions.unit_vector(vector)

Returns the unit vector of the vector.