Ground Control is the program which allows you to control the Maslow CNC machine.
======================
Ground Control is the program which allows you to control the Maslow CNC machine.
From within Ground Control, you can move the machine to where you want to begin a cut, calibrate the machine, open and run a g-code file, or monitor the progress of an ongoing cut.
At present, the UI looks like this:
Ground Control is written in Python. It was chosen because it has good cross platform support and is relatively simple to work with.
Two of the goals of Ground Control are:
- It runs on as many platforms as possible.
- It is as easy as possible for members of the community to contribute to making the program better.
- Installation
- Documentation
- Development Setup
- Support
- How To Contribute
- Program Data Flow
- Beginner's Tips
For Windows and OS X binaries, see the releases page.
For help installing binaries, see the installation guides.
Ground control documentation is available on the project wiki.
For help in using Ground Control, see the users guide.
Ground Control is built using the 2.7.x version of the Python language. 2.7 was chosen instead of 3.x because the support for compiling binaries for the 3.x version is not good enough yet.
Maslow uses the Kivy framework for the UI and the pyserial module for USB communication.
You might also consider taking a look at Virtual Environments to save you from python version headaches later on. This is not a prerequisite for installation on any platform.
To setup your computer to run Ground Control from the source code, first download and install Python version 2.7.x.
Once you have installed Python 2.7.x, open the command prompt and type
python --version
You should then see something similar to this:
Python 2.7.11
If python does not open, it is most likely an issue with the PATH
environment variable.
For more information about configuring the PATH
in Windows, see superuser: How to add python to the windows path.
Next, you need to install Kivy and Pyserial. Fortunately, python comes with a built in package manager, pip
which will install both of them for you.
To install pyserial, type:
python -m pip install pyserial
Installing Kivy is a little more complicated. First, check to make sure your version of pip
is up to date by running:
python -m pip install --upgrade pip wheel setuptools
then install dependencies:
python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew
and finally install Kivy:
python -m pip install kivy
To install Python on OS X, first install Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
then install Python:
brew install python
Install required dependencies:
pip install -r requirements_osx.txt
Python is bundled with all major linux distributions. You can confirm the version of python you have installed with:
python --version
See documentation for your linux distro on how to install Python 2.7.x if it is not installed.
Once Python 2.7.x is installed, install required dependencies:
pip install -r requirements_linux.txt
Ground Control can be run from the command line. From within the project folder, run the following:
python main.py
If you have any questions or issues with this process please get in touch through the Maslow forums.
If you had any issues which you were able to resolve, please consider raising a Pull Request on this README.md
file with corrections or additions. For more information, see How To Contribute below.
Maslow is an open source project, get involved!
If you find a bug in the software, report it on the issues page.
If you have an idea for a new feature, let us know in the Maslow forums.
If you want to get involved, say hi in the Maslow forums.
If you've already jumped in and started making the software better, feel free to submit a pull request! You can learn more about how to do that here Github Help: Creating a pull request
Kivy uses groundcontrol.kv as a description language for most of the widgets in GroundControl; some tips:
-
Class References:
root.X
refers to things inside the class. You can add your own variables, but they don't get initialized in time to be used (so root.data doesn't work) but you can useapp.X
to refer to things in the app namespace, soapp.data
will always work. BUT you must define the variable inDataStructures/data.py
; things put in the data dict at runtime will not work. -
Formatting: You can include format strings and logic in the .kv file; eg
text: "{Z: %.2f}"%app.data.zPos
will automatically expand/update whenapp.data.zPos
changes. But, if it's a text input field, you need to hook the field to an event -- changing the text in the box will not updateapp.data.zPos
. -
Referring to UI bits in code: If you want to refer to a widget in the code, you need to give it an id, and you need to put a
id:id
statement after the widget definition starts Otherwise, you won't be able to access it in the code. If you put anid:id
statement in place but you don't declare a widget with that id, it will crash when you bring up the widget. -
Attributes: Most attributes (eg.
text_size
,multiline
,disabled
, etc) are not inheritable (you can't set the attribute in the "GridLayout" portion); they have to be decorated on each control. -
Layouts: GridLayout's et al don't support "span" to span columns or rows. If you want to do that kind of thing, redo the grid to the large size and put sub-GridLayouts in the cells. Try to make the cells the same size so they line up nicely. The Layouts will not actually work unless you have
rows
&columns
attributes in them. The log file will complain about this, so watch for it. You can auto-size-to-the-minimum sometimes withsize_hint_x: None
. But if you give it a 2 (ie,size_hint_x: 2
for 2%), it always works kinda (it always works but may not do what you expected). -
Coordinate Systems: Kivy defines things as origin is bottom-left, an increasing Y is up, increasing X is right. Please use
self.origin
in the code -- if you draw something, 0,0 is the bottom-left of the application, not the bottom-left of your widget. -
Events: Always bind to the
on_touch_up
event. If you bind to theon_touch_down
instead, you get a behavior that looks like a click-through:- You catch the
on_touch_down
, and pop-up a menu with a button on it. - The mouse is still down... so it will select a file (if file_dialog), or if the next dialog catches the
on_touch_up
event, it will fire as soon as the click is released
- You catch the
- If an object begins with a capital letter, it is a global object (eg,
CanvasSize=4
). Don't doCamelCase
; docamelCase
instead. - If you want to persist values across functions, they need to be in the object-space (
self.x
) or in the global-space (CanvasSize
), or in App-space (app.data.X
orself.data.X
after init) If you use a variable without theself.
, it will work but it won't be persisted, so it can be annoying to figure out what (didn't) happened. - If you want to call another function in your class, preface it with
self.
(eg,self.recomputethis()
-- and the self arg gets passed in automagically) - Always remember to call the super if you're implementing
__init__
- Remember - your dialog/widget/etc can go away without calling the callback function - the user just clicks back to the main window. Don't count on the callback to save state. Don't use the callback to put the machine in a known state (because it may not get executed).
- Dialogs don't get to close themselves; when your
self.done
is executed, call your callback function, and your parent can get data out of your dialog and is responsible for closing you. But see rule #5. - Remember - Python is case-sensitive... and filename/directory/case sensitive as well.
- Much mumbo-jumbo about how to save data in the .ini file
- Some mumbo-jumbo about how to use the logger
- If you need to send a command to Maslow, use the
self.data.gcode_queue.put('GCode-Here')
- Mumbo-jumbo about how to get data back from Maslow
- On the g-code canvas, 0,0 is the center, and bottom-left is -X,-Y (y axis is reversed compared to old computer code, but "usual" in math terms).
- json does not know about tuples. It will make the variables a list and if your functions can't handle that, you need to convert them.
- frontPage - is the root host for all widgets.
- screenControls - has all the buttons on the main screen (both the top bar and the right side)