Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Important information for anyone interested in hacking on or contributing to any of the OpenPnP modules.
Before starting to develop for OpenPnP you should review the [User Manual](User Manual) to become familiar with the interface and major components of the system.
OpenPnP uses a Fork and Pull style of development. If you would like to submit changes you should fork the project, make your changes and submit a pull request. More information about that process is available at https://help.github.com/articles/using-pull-requests. There is also also specific tutorial made for OpenPnP at https://github.com/openpnp/openpnp/wiki/Your-First-Pull-Request.
Licensing and Copyright
OpenPnP uses different licenses for different components. Before submitting changes, please review the license for that module by looking at the LICENSE file in the root directory of the module and decide if it is acceptable to you. Changes under a different license will not be accepted for merge into the repository.
Contributors submitting large pieces of functionality, i.e. whole source files, whole part designs, major rewrites, etc. may assign their own copyright to the submission as long as you are willing to license it under the existing license for that module.
All pull requests will be reviewed by the maintainers and will either be merged or comments will be provided as to why it's not being merged. You can submit new changes to the pull request as needed if the review uncovers issues.
Try to send as little as possible in a given pull request. A single small feature, a single bug fix, etc. The smaller a pull request is the easier it is to integrate into the project and the less likely it is to contain a looked over problem. If you are changing base classes expect significant discussion as to why the change is needed.
Your commits should be generally useful, not specifically useful to just your machine or your setup. If the code cannot be shown to be useful to other people, it probably doesn't belong in the main OpenPnP codebase. That's what's private forks are for. In addition, take consideration of the fact that the code will be used in many different configurations. Avoid quick hacks.
Please try to adhere to the existing code style as much as possible. Understand that your code is likely to be reformatted to fit the project standard if it doesn't follow it.
OpenPnP closely follows the Google Java Style. While there may be existing code in OpenPnP that does not follow the style exactly, any new code must follow the style.
There is an Eclipse formatter definition here. You can import this into Eclipse and use it to format your code to be sure it's following the standard.
Two things in particular are extremely important:
Code that does not follow these two guidelines (at least) will not be accepted.
Describe Your Work
In the pull request comments, explain what the change does. If it is new functionality, explain why it's useful and how it is to be used. If you are fixing an issue, reference the issue number.
Automated Testing (Required)
OpenPnP contains a JUnit based test suite that must pass before anything new can be merged. You can run it with
mvn test or from your favorite IDE. You should also try to include new tests for your code if possible.
Manual Testing (Strongly Recommended)
In addition to the automated tests, it's a good idea to run a manual test using OpenPnP's base configuration. To do this:
- Delete your configuration directory or start OpenPnP with
-DoverrideUserConfig=trueon the command line. This will reset your configuration to the same configuration that OpenPnP ships with.
- Start OpenPnP and load the pnp-test.job.xml from the samples directory.
- Run the job. You should see the camera image move and the machine should simulate picking and placing the entire job.
- Verify that the job runs and completes without errors. Watch the camera view and see if anything strange is happening.
JDK or JRE 8+
OpenPnP is written in Java and requires Java 8 to run (Java 9+ support is still in development). If you want to do development on OpenPnP or recompile it, you should install the JDK. If you just want to run it you can install the smaller JRE.
You can download the latest revision of the JDK or JRE at:
OpenCV is now included with OpenPnP, so an additional installation is not required. Binaries are included for Windows (x86/x64), Mac (Universal) and Linux (x86/x64).
OpenPnP uses Maven for dependencies and building. You can get it at http://maven.apache.org/download.cgi#. See http://maven.apache.org/install.html for additional information on installing it. Once installed, make sure
you can run
mvn --version from your command line with no errors.
If you are using an IDE with Maven included you don't need to install the command line version.
To build the entire package so that it can be run from the command line or distributed,
run the command
mvn package. Once this is complete you can use the
openpnp.bat scripts to start the program.
You can import the
openpnp folder into Eclipse as a Maven project.
For additional help with Eclipse see:
IntelliJ IDEA v12+
Simply import the
openpnp folder as a Maven project.
OpenPnP is written in Java using Swing and WindowBuilder. Dependency and build management are performed using Maven. The majority of the code has been written using the Eclipse IDE but the system uses no Eclipse specific components and any IDE can be used.
Bindings and property change listeners are used extensively wherever possible. Bindings are provided by JBindings with some custom helper code that is part of OpenPnP.
OpenPnP is made up of 5 core components: Configuration, Service Provider Interface, Model, User Interface and Reference Implementation.
Configuration of OpenPnP is managed with the Configuration class. The Configuration class is used to query and store to two configuration stores.
The primary one is a set of XML configuration files stored under the user's home directory in a subdirectory called
.openpnp. These XML files are read and written using the Simple XML framework and are generally pretty transparent to developers. Reviewing the sample configuration files that come with OpenPnP is a good place to start when thinking about adding functionality.
The second configuration store is the user specific Java preferences data store. This is used to store user preferences for the application itself such as window size, units preference, locations of split windows, etc.
The Configuration class is a singleton accessed with Configuration.get() throughout the system. It has a listener system that can be used to be notified of configuration state changes.
In the various machine Java files, you will notice that parameters tagged with
@Element will correspond to an attribute or element in the machine.xml file. The names of these attributes and elements will vary slightly between the XML and the code. For example, the source code might be:
private double feedRateMmPerMinute;
whereas the XML would be:
<driver class="org.openpnp.machine.reference.driver.TinygDriver" port-name="COM5" baud="115200" feed-rate-mm-per-minute="3000.0"/>
Basically, in Java, property names are in lower camel case by convention ( http://c2.com/cgi/wiki?LowerCamelCase ) and the XML serializer just splits the words on capital letters and adds a hyphen. So, feed-rate-mm-per-minute becomes feedRateMmPerMinute.
Service Provider Interface
The Service Provider Interface (SPI) is a set of Java interfaces that specify OpenPnP's interface to the real world. Examples of things in the SPI are things like Machine definitions, Camera drivers, Vision Providers, Nozzles, Actuators, etc.
In general, unless you are adding a new type of hardware to OpenPnP you don't need to implement the SPI but in developing features for OpenPnP you will be interacting deeply with objects that themselves implement the SPI.
The Reference Implementation, discussed later, is the core implementation of the OpenPnP SPI.
Like most MVC based systems, The Model makes up the domain for data storage in OpenPnP.
The model includes all of the classes that users use to store their data such as Jobs, Boards, Parts, Packages, etc. but the SPI also provides models for storing configuration information.
The root of the model in OpenPnP is the Configuration object and it is responsible for creating all of the rest of the models in the application.
The user interface is the heart of OpenPnP. It starts with
MainFrame in the gui package and branches out from there.
The user interface is primarily a single window application with 3 main content areas. These are Machine Controls, Cameras, and Jobs and Configuration.
It should be noted that the user interface is in transition. I am not very happy with the currently model driven user interface and will be working to make it more of a workflow based interface in the future. For the time being, most of the things you see in the user interface map very closely to one of the model classes.
The reference implementation is the default implementation of the SPI. It has two main purposes. The most important one is to be the implementation that runs the actual OpenPnP machine and the second is to serve as an example for people wanting to write their own custom implementations.
Whenever possible, the reference implementation is written to be compatible with a wide class of machines and hardware.
The core of the reference implementation is the ReferenceMachine class. Serialization of this class and all it's children becomes the
machine.xml configuration file. If you want to add hardware to the system you will want to become intimately familiar with this class and the classes it references.
Vision tasks in OpenPnP are specified by the VisionProvider SPI class. This area is still in it's infancy and suggestions on it's architecture are welcome.
Currently, the concept is that VisionProviders provide data about images they receive from a camera. A VisionProvider has a reference to a Camera and can use it to capture images as needed. When other parts of the system have a need for a vision task, they query the involved Camera for it's VisionProvider and then ask the VisionProvider to provide vision services.
The VisionProvider interface specifies a few methods that are used by existing vision systems to get data but these are fairly rigidly defined and change may be needed to make this system more generic.
For the time being, if you are adding vision capabilities to OpenPnP you will need to add methods to the VisionProvider SPI and then implement those methods in the reference classes.
The concept of a "wizard" is used quite often in OpenPnP. A wizard in OpenPnP is a simple interface that provides a JPanel for display to the user and allows a class to communicate back to a caller. Wizards are typically used for providing user interfaces to configuration tasks and many SPI and Model classes will implement WizardConfigurable, showing that they are able to provide a wizard to be configured.
The Wizard and WizardConfigurable interfaces are provided so that SPI providers can supply user interface without having to modify the core OpenPnP system.
The Job Processor is the part of OpenPnP that actually does all the work of picking and placing. When the user starts a Job, the Job Processor takes over and controls the machine until the job is complete.
Job Processor is a bit of a black box from a programming point of view. To learn more about how it works it's best to examine the source code.
How can I manage multiple configurations?
-DconfigDir on the command line you can override the default configuration directory for OpenPnP. Example:
I manage a number of configurations by creating various Run Configurations in Eclipse. I have one for my primary machine, one for my secondary machine, one for the default directory (no command line parameters) and one that wipes the configuration for the default directory. I use this when I want to reset OpenPnP to it's factory state.
How can I reset my configuration to the default?
-DoverrideUserConfig=true on the command line to overwrite your configuration with the defaults. If paired with
-DconfigDir you can choose which configuration to overwrite.