EMC Software

Introduction

As part of our collaboration with the OMAC User's Group, we have written software which implements real-time control of equipment such as machine tools, robots, and coordinate measuring machines. The goal of this software development is twofold: first, to provide complete software implementations of all OMAC modules for the purpose of validating application programming interfaces; and second, to provide a vehicle for the transfer of control technology to small- and medium-sized manufacturers via the NIST Manufacturing Extension Partnership.

The EMC software is based on the NIST Real-time Control System (RCS) Methodology, and is programmed using the NIST RCS Library. The RCS Library eases the porting of controller code to a variety of Unix and Microsoft platforms, providing a neutral application programming interface (API) to operating system resources such as shared memory, semaphores, and timers. The RCS Library also implements a communication model, the Neutral Manufacturing Language, which allows control processes to read and write C++ data structures throughout a single homogeneous environment or a heterogeneous networked environment.

The EMC software is written in C and C++, and has been ported to the PC Linux, Windows NT, and Sun Solaris operating systems. When running actual equipment, a real-time version of Linux is used to achieve the deterministic computation rates required (200 microseconds is typical). The software can also be run entirely in simulation, down to simulations of the machine motors. This enables entire factories of EMC machines to be set up and run in a computer integrated manufacturing environment. A Windows NT simulation self-installing archive runs the controller on simulated DC motors, with a Java GUI.

The EMC software is available free of charge on our FTP site. Please read the README file before getting or installing the software.

This software was prepared by United States Government employees as part of their official duties and is, therefore, a work of the U.S. Government and not subject to copyright.

The EMC at Work

EMCs have been installed on many machines, both with servo motors and stepper motors. Here is a sampling:

3-axis Bridgeport knee mill at Shaver Engineering. The machine uses DC brush servo motors and encoders for motion control, and OPTO-22 compatible I/O interfaced to the PC parallel port for digital I/O to the spindle, coolant, lube, and estop systems.
3-axis desktop milling machine used for prototype development. The machine uses DC brush servo motors and encoders. Spindle control is accomplished using the 4th motion control axis. The machine cuts wax parts.
4-axis Kearney & Trecker horizontal machining center at General Motors Powertrain in Pontiac, MI. This machine ran a precursor to the full-software EMC which used a hardware motion control board.

EMC Components

There are four components to the EMC software: a motion controller (EMCMOT), a discrete I/O controller (EMCIO), a task executor which coordinates them (EMCTASK), and a collection of text-based or graphical user interfaces.

Graphical User Interfaces

The EMC comes with several types of user interfaces: an interactive command-line program emcpanel, a character-based screen graphics program keystick, an X Windows program xemc, a Java-based GUI emcgui, and a Tcl/Tk-based GUI TkEmc.

TkEmc is most well-supported, and runs on Linux and Microsoft Windows. The Windows version can connect to a real-time EMC running on a Linux machine via a network connection, allowing the monitoring of the machine from a remote location. TkEmc comes with the Linux distribution of the EMC. Instructions for installing and configuring the Windows version can be found in wintkemc.html.

Motion Controller EMCMOT

The motion controller (Figure 1) is written in C for maximum portability to real-time operating systems. Motion control includes sampling the position of the axes to be controlled, computing the next point on the trajectory, interpolating between these trajectory points, and computing an output to the motors. For servo systems, the output is based on a PID compensation algorithm. For stepper systems, the calculations run open-loop, and pulses are sent to the steppers based on whether their accumulated position is more than a pulse away from where their commanded position should be. The motion controller includes programmable software limits, interfaces to hardware limit and home switches, PID servo compensation with zero, first, and second order feedforward, maximum following error, selectable velocity and acceleration values, individual axis jogging (continuous, incremental, absolute), queued blended moves for linear and generalized circular motion, and programmable forward and inverse kinematics.

The motion controller is written to be fairly generic. Initialization files (with the same syntax as Microsoft Windows INI files) are used to configure parameters such as number and type of axes (e.g., linear or rotary), scale factors between feedback devices (e.g., encoder counts) and axis units (e.g., millimeters), servo gains, servo and trajectory planning cycle times, and other system parameters. Complex kinematics for robots can be coded in C according to a prescribed function interface and linked in to replace the default 3-axis Cartesian machine kinematics routines. A C language application programming interface (API) between the motion controller and the external world is provided so that specific hardware can be integrated into the EMC without modifying any of the core control code. Programmers must implement these API functions for each board.

Figure 1. Motion controller software architecture. This figure shows two axes of control, with axis 1 using a servo motor and axis 2 using a stepper motor. For steppers, the commanded position is feed back directly as the motor position, so the system operates open-loop. A second task compares the output position with the accumulated pulse count, and generates a pulse if the difference is greater than half the pulse distance. The motion controller is a single C program, executing cyclically. When controlling actual machines, the motion controller requires a real-time operating system. In our installations, we have used RT-Linux. This gives real-time deterministic cycle times down to about 100 microseconds. The motion controller uses either shared memory or RT-Linux FIFOs to receive commands or send status, error, or logging information. NML is not used directly by the motion controller since NML requires C++ and the coding was limited to C to maximize portability to other real-time operating systems.

Setting up Stepper Motors

Currently the EMC supports stepper motors with a 2-bit step-and-direction interface, with bits mapped to the parallel port. Each parallel port has 12 bits of output and 5 bits of input. The outputs are used to drive the step and direction of each motor. 12 bits of output mean that up to 6 stepper motors can be controlled. The inputs can be used to detect limit or home switch trips. 5 bits of input mean that only one axes can get full positive, negative, and home switch inputs. The EMC mapping compromises for 3 axes of stepper motor control, with all positive limit switches being mapped to one input, all negative limit switches being mapped to another input, and all home switches being mapped to a third input. Other permutations are possible, of course, and can be changed in the software. You could also add 2 additional parallel ports (LPT2, LPT3), and get 36 bits of output and 15 bits of input. Some parallel ports also let you take 4 outputs and use them as inputs, for 8 outputs and 9 inputs for each parallel port. This would let you get 3 axes of control and full switch input per parallel port. See Using the PC parallel port for digital I/O for more information on the parallel port.

The pinout for the EMC stepper motor interface is as follows:

Output        Parallel Port
------        -------------
X direction   D0, pin 2
X clock       D1, pin 3
Y direction   D2, pin 4
Y clock       D3, pin 5
Z direction   D4, pin 6
Z clock       D5, pin 7

Input         Parallel Port
-----         -------------
X/Y/Z lim +   S3, pin 15
X/Y/Z lim -   S4, pin 13
X/Y/Z home    S5, pin 12
Stepper motor control is implemented using a second real-time task that runs at 100 microseconds. This task writes the parallel port output with bits set or cleared based on whether the a pulse should be raised or lowered. This gives an effective period of 200 microseconds for a full up-and-down pulse, or a 5 kilohertz frequency.

Discrete I/O Controller EMCIO

The discrete I/O controller (bottom right in Figure 2) is written in C++, using the NIST RCS Library. It is based on a hierarchy of C++ controller classes derived from the NML_MODULE base class, each communicating using NML. Discrete I/O controllers are highly machine-specific, and are not customizable in general using the INI file technique used to configure the more generic motion controller.

A C language application programming interface (API) between the discrete I/O controller and the external world is provided so that specific hardware can be integrated into the EMC without modifying any of the core control code. Programmers must implement these API functions for each board.

Task Executor EMCTASK

The Task Executor (at the top in Figure 2) is coded similarly to the discrete I/O controller, using the NML_MODULE base class and the RCS Library. It is less machine specific than the discrete I/O controller, as it is responsible for interpreting G and M code programs whose behavior does not vary appreciably between machines.

External Programs

Indicated at the very top in Figure 2 is the fourth component of the EMC software, the external programs such as the graphical user interface (GUI) or flexible manufacturing system (FMS) which are used to run the EMC. These communicate using NML, sending messages such as power on, enter automatic mode, run a program, or power down. GUIs may send manual commands initiated by the operator, for example jogging machine axes in manual mode, or homing each axis.

Figure 2. EMC controller software architecture. At the coarsest level, the EMC is a hierarchy of three controllers: the task level command handler and program interpreter, the motion controller, and the discrete I/O controller. The motion controller is detailed in Figure 1. The discrete I/O controller is implemented as a hierarchy of controllers, in this case for spindle, coolant, and auxiliary (e.g., estop, lube) subsystems. The task controller coordinates the actions of the motion and discrete I/O controllers. Their actions are programmed in conventional numerical control "G and M code" programs, which are interpreted by the task controller into NML messages and sent to either the motion or discrete I/O controllers at the appropriate times.

Configuring the EMC

The EMC is configured with files that are read at startup and used to override the compiled defaults. No real controller will likely use the compiled defaults, so you will certainly need to edit at least some of these files to reflect the specifics of your machine.

There are four files: emc.ini, emc.nml, tool.tbl, and rs274ngc.var. The first, emc.ini, contains all the machine parameters such as servo gains, scale factors, cycle times, units, etc. and will certainly need to be edited. emc.nml contains communication settings for shared memory and network ports you may need to override on your system, although it is likely that you can leave these settings alone. tool.tbl contains the tool information such as which pocket contains which tool, and the length and diameter for each tool. rs274ngc.var contains variables specific to the RS-274-NGC dialect of NC code, notably for setting the persistent numeric variables for the nine work coordinate systems. The specific formats of each of these files is detailed in the following sections.

Machine Configuration file emc.ini

The machine configuration file emc.ini follows the Microsoft INI file format, in which values are associated with keywords on single lines, perhaps in sections denoted with square brackets, e.g.,
[SECTION]

; COMMENT
SYMBOL = VALUE
Everything from the first non-whitespace character after the = up to the end of the line is passed as the value, so you can embed spaces in string symbols if you want to.

You can edit the values for each keyword in any text editor. The changes won't take effect until the next time the controller is run. The file should be called emc.ini, but the name can be overriden using a command line argument to the controllers. See the section "Starting Up" for information on how to do this. The following sections detail each section of the configuration file, using sample values for the configuration lines.

[EMC] Section

The [EMC] section contains general parameters for the whole controller. These are:

[TASK] Section

The [TASK] section contains general parameters for EMCTASK, which includes primarily the NC language interpreter and the sequencing logic for sending commands to EMCMOT and EMCIO.

[TRAJ] Section

The [TRAJ] section contains general parameters for the trajectory planning module in EMCMOT.

[AXIS_#] Sections

The [AXIS_0], [AXIS_1], etc. sections contains general parameters for the individual axis control modules in EMCMOT. The axis section names begin numbering at 0, and run through the number of axes specified in the [TRAJ] AXES entry minus 1. The following parameters P, I, D, FF0, FF1, FF2 are used by the servo compensation algorithm to optimize performance while tracking trajectory setpoints. See Tuning Servos for information on setting up a servomotor system. The following polarity values determine how inputs are interpreted and how outputs are applied. They can usually be set via trial-and-error since there are only two possibilities. The EMCMOT utility program USRMOT can be used to set these interactively and verify their results so that the proper values can be put in the INI file with a minimum of trouble. The following entries are used to set the parameters for the DC servomotor simulations. These are only used when running the EMC in simulation. The following entry is used to set the parameters for the amplifier simulations. These are only used when running the EMC in simulation. The following entry is used to set the parameters for the encoder simulations. These are only used when running the EMC in simulation.

[EMCIO] Section

The [EMCIO] section contains control values and setup parameters for the digital and analog I/O points in EMCIO.

The following entries set general parameters for the I/O controller.

The following entries set parameters for spindle control. The following entries set the bit indices for the digital I/O so that the controller knows the mapping to I/O point wiring. The indices start at 0 for the least significant bit in the digital I/O map. See Setting up the External Interfaces for information on interfacing I/O boards to the software. The following entries set the polarities for the digital I/O points. These can be set by trial-and-error, or by noting the levels and any inverting done by the electronics between the sensors and actuators and the electronics.

Using the USRMOT Motion Utility

USRMOT is an interactive text-based utility that is used to set and test motion parameters for the EMCMOT motion controller. To use USRMOT, first run EMCMOT standalone (yourprompt> represents whatever your system prompt is):
yourprompt> emcmot
In another window, run the USRMOT utility:
yourprompt> usrmot
motion>
The motion> prompt is displayed by USRMOT when it runs. Entering a blank line lets you see the status:
motion> 
mode:           free
cmd echo:       0
split:          0
heartbeat:      605
compute time:   0.014992
traj time:      0.200000
servo time:     0.020000
interp rate:    10
axes enabled:   0               0               0
cmd pos:        0.000000        0.000000        0.000000
act pos:        0.000000        0.000000        0.000000
velocity:       10.000000
accel:          100.000000
id:             0
depth:          0
active depth:   0
inpos:          1
vscales:        Q: 1.00 X: 1.00 Y: 1.00 Z: 1.00
logging:        closed and stopped, size 0, skipping 0, type 0
homing:         ---
enabled:        DISABLED

Tuning Servos

For a detailed description of tuning servos, see the following references:
  1. Benjamin C. Kuo, Automatic Control Systems, Fourth Edition.

Defining Complex Kinematics

By default the EMC assumes trivial Cartesian kinematics in which X, Y, and Z coordinates map directly to motors 0, 1, and 2. You can define more complex kinematics, for example for a robot, by replacing the default kinematics functions with your own.

The C language declaration for the kinematics, found in emcmot.h, is

#include "posemath.h" /* PmPose */ extern int forwardKinematics(double * joints, PmPose * pos); extern int inverseKinematics(PmPose pos, double * joints);
You can replace these with any kinematics you like, provided they conform to these declarations. Replace the file trivkins.o from the link line that builds emcmot with your own, and rerun the compiler.

Setting up the External Interfaces

The interface between motion control and discrete I/O control points and the software is declared in the C language header file extintf.h.

For example, one of the external APIs is

/*
  extDacWrite(int dac, double volts)

  writes the value to the DAC at indicated dac, 0 .. max DAC - 1. 
  Value is in volts. Returns 0 if OK, -1 if dac is out of range.
  */
extern int extDacWrite(int axis, double voltage);
which is called by the motion controller to output a voltage to the motor velocity amplifiers. For a particular digital-to-analog converter board, the function would be implemented as something like:
/* specific function to output voltage for my board */
int myBoardDacWrite(int axis, double voltage)
{
  short int vout;

  vout = (short int) (voltage / 10.0 * 0xFFFF);

  _outw(0x280 + axis, vout);

  return 0;
}

/* mapping of my function to API */
int extDacWrite(int axis, double voltage)
{
  return myboardDacWrite(axis, voltage);
}
Another external API is
/* reads value of digital input at index, stores in value */
extern int extDioRead(int index, int *value);
which is called by the discrete I/O controller to read a digital input into the 'value' variable, from the I/O point at the specified 'index'. For a particular digital I/O board, the function would be implemented as something like:
/* specific function to input value from myboard */
int myBoardDioRead(int index, int *value)
{
  unsigned char mask;

  mask = 1 << index % 8;

  *value = (_inb(0x380 + index / 8) & mask) ? 1 : 0;

  return 0;
}

/* mapping of my function to API */
int extDioRead(int index, int *value)
{
  return myboardDioRead(index, value);
}
The code above is referred to as a "wrapper" for myboard. NIST has written wrappers for some specific boards. See Wrapped Hardware for more information.

Starting Up

The EMC can be started up by scripts, which take command line arguments for the various files if their names are to be overriden. The scripts should be run in the directory in which the configuration file are located, unless they are overriden with paths to alternate files. The conventional practice is to create a script file called run.emc based on one of the example run scripts, and run it in the top-level emc directory where the configuration files emc.ini and emc.nml are located. The syntax is:
./run.sunos5

Control Platforms

From the point of view of technology transfer, the EMC has strived to provide software which is of high performance yet can be run on inexpensive computing platforms. The target platform for control is a PC-compatible desktop computer, 386-compatible or higher, with a minimum of additional hardware. We have ported our software to the Linux operating system, since it is free and has free real-time support from New Mexico Tech. We also run in simulation on most Unixes, and Microsoft Windows NT. The following are some links to related Web sites.

No approval or endorsement of any commercial product by the National Institute of Standards and Technology is intended or implied. Certain commercial equipment, instruments, or materials are identified in this report in order to facilitate understanding. Such identification does not imply recommendation or endorsement by the National Institute of Standards and Technology, nor does it imply that the materials or equipment identified are necessarily the best available for the purpose.

PC Hardware

These links provide information on PC-compatible hardware in general. Go here for technical specs, pinouts, I/O addresses and register bitmaps, etc.

Linux Documentation

There is a world of free information on Linux, the free Unix-like operating system for 'most any platform. You can get it for PCs, Macintoshes, Sparc workstations, notebook computers, and more.

Linux Software

Third parties provide shrink-wrapped Linux packages which save you the trouble of ftp-ing 20 megabytes of code from Finland over your 28.8 kbps modem overnight. You can also find lots of free software for Linux.

Real-time Linux

Michael Barabanov and Victor Yodaiken of New Mexico Tech modified the Linux source slightly, inserting a real-time scheduler between Linux and the hardware interrupts it used to receive. Now, your code can run in the scheduler, with Linux running when you're done. Tasks can run at cycle times down to about 50 microseconds or so. That's 20 kilohertz in real-time on your desktop PC.

Programming Linux

Information on accessing hardware or operating system resources not covered in general C language textbooks.

Wrapped Hardware

We have written APIs to some hardware for our installations, giving them the functional interface we program to in our EMC code. Here are some of them.