|
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. |
| 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. |
|
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.
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.
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 12Stepper 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.
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.
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.
[SECTION] ; COMMENT SYMBOL = VALUEEverything 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.
The version number for the INI file. This is automatically updated when using the Revision Control System, which looks for the $Revision: 1.13 $ string and appends the revision number. If you want to edit this manually just change the number and leave the other tags alone.
This is the name of the controller, which is printed out when it runs. You can put whatever you want here.
The period, in seconds, at which EMCTASK will run. You can make this as small as you want to increase the throughput. Making it 0.0 or a negative number will tell EMCTASK not to sleep at all. Ultimately the system loading will limit the effective throughput.
The number of controlled axes in the system.
The number of linear units per millimeter. For systems executing in native English (inch) units, this value is as shown above. For systems executing in native millimeter units, this value is 1. This does not affect the ability to program in English or metric units in NC code. It is used to determine how to interpret the numbers reported in the controller status by external programs.
The number of angular units per degree. For systems executing in native degree units, this value is as shown above. For systems executing in radians, this value is 0.01745329252167, or PI/180.
The period in seconds at which trajectory calculations are performed. This is a multiple of the period at which servo calculations are performed, as set in the [AXIS_#] CYCLE_TIME entry. Trajectory calculations are called at multiples of the servo period to plan linear or circular motion in Cartesian space. These values are interpolated at the servo period and run through the inverse kinematics.
The initial velocity used for axis or coordinated axis motion, in user units per second.
The initial acceleration used for axis or coordinated acis motion, in user units per second per second.
The maximum velocity for any axis or coordinated move, in user units per second.
The maximum acceleration for any axis or coordinated axis move, in user units per second per second.
The type of axes, either LINEAR or ANGULAR. Values for the position of LINEAR axes are in the units (per millimeter) specified in the [AXIS_#] UNITS entry. Values for the position of ANGULAR axes are in the units (per degree) specified in the same entry.
Units per millimeter for a LINEAR axis, as defined in the [AXIS_#] TYPE section, or units per degree for an ANGULAR axis as defined in the same section.
The proportional gain for the axis servo. This value multiplies the error between commanded and actual position in user units, resulting in a contribution to the computed voltage for the motor amplifier. The units on the P gain are volts per user unit.
The integral gain for the axis servo. The value multiplies the cumulative error between commanded and actual position in user units, resulting in a contribution to the computed voltage for the motor amplifier. The units on the I gain are volts per user unit-seconds.
The derivative gain for the axis servo. The value multiplies the difference between the current and previous errors, resulting in a contribution to the computed voltage for the motor amplifier. The units on the D gain are volts per user unit per second.
The 0-th order feedforward gain. This number is multiplied by the commanded position, resulting in a contribution to the computed voltage for the motor amplifier. The units on the FF0 gain are volts per user unit.
The 1st order feedforward gain. This number is multiplied by the change in commanded position per second, resulting in a contribution to the computed voltage for the motor amplifier. The units on the FF1 gain are volts per user unit per second.
The 2nd order feedforward gain. This number is multiplied by the change in commanded position per second per second, resulting in a contribution to the computed voltage for the motor amplifier. The units on the FF2 gain are volts per user unit per second per second.
This is the period in seconds at which servo calculations will run. The values can be different between different axes, and the lowest will be used for all. This ensures that the calculations will occur at least as fast as they are specified here. The value should be an integer submultiple of the trajectory cycle time specified in the [TRAJ] CYCLE_TIME entry, so that an integer number of interpolations will occur. If this is not the case the times will be forced so that the interpolation interval is the next highest integer.
These two values are the scale and offset factors for the axis input from the raw feedback device, e.g., an incremental encoder. The second value (offset) is subtracted from raw input (e.g., encoder counts), and divided by the first value (scale factor), before being used as feedback. The units on the scale value are in raw units (e.g., counts) per user units (e.g., inch). The units on the offset value are in raw units (e.g., counts).Specifically, when reading inputs, the EMC first reads the raw sensor values. The units on these values are the sensor units, typically A/D counts, or encoder ticks. These units, and the location of their 0 value, will not in general correspond to the quasi-SI units used in the EMC. Hence a scaling is done immediately upon sampling:
input = (raw - offset) / scaleThe value for scale can be obtained analytically by doing a unit analysis, i.e., units are [sensor units]/[desired input SI units]. For example, on a 2000 counts per rev encoder, and 10 revs/inch gearing, and desired units of mm, we have[scale units] = 2000 [counts/rev] * 10 [rev/inch] * 1/25.4 [inch/mm] = 787.4 counts/mmand, as a result,input [mm] = (encoder [counts] - offset [counts]) / 787.4 [counts/mm]Note that the units of the offset are in sensor units, e.g., counts, and they are pre-subtracted from the sensor readings. The value for this offset is obtained by finding the value of counts for which you want your user units to read 0.0. This is normally accomplished automatically during a homing procedure.
These two values are the scale and offset factors for the axis output to the motor amplifiers. The second value (offset) is subtracted from the computed output (in volts), and divided by the first value (scale factor), before being written to the D/A converters. The units on the scale value are in true volts per DAC output volts. The units on the offset value are in volts. These can be used to linearize a DAC.Specifically, when writing outputs, the EMC first converts the desired output in quasi-SI units to raw actuator values, e.g., volts for an amplifier DAC. This scaling looks like:
raw = (output - offset) / scaleThe value for scale can be obtained analytically by doing a unit analysis, i.e., units are [output SI units]/[actuator units]. For example, on a machine with a velocity mode amplifier such that 1 volt results in 250 mm/sec velocity, we have:[scale units] = 250 [mm/sec] / 1 [volts] = 250 mm/sec/voltand, as a result,amplifier [volts] = (output [mm/sec] - offset [mm/sec]) / 250 [mm/sec/volt]Note that the units of the offset are in user units, e.g., mm/sec, and they are pre-subtracted from the sensor readings. The value for this offset is obtained by finding the value of your output which yields 0.0 for the actuator output. If the DAC is linearized, this offset is normally 0.0.The scale and offset can be used to linearize the DACs as well, resulting in values that reflect the combined effects of amplifier gain, DAC non-linearity, DAC units, etc. To do this, follow this procedure:
a. Build a calibration table for the output, driving the DACs with a desired voltage and measuring the result, e.g.,
RAW MEAS --- ---- -10 -9.93 -9 -8.83 0 -0.03 1 0.96 9 9.87 10 10.87b. Do a least-squares linear fit to get coefficients a, b such thatmeas = a * raw + bc. Note that we want raw output such that our measured result is identical to the commanded output. This meanscmd = a * raw + b raw = (cmd - b) / aAs a result, the a and b coefficients from the linear fit can be used as the scale and offset for the controller directly.
The minimum limit (soft limit) for axis motion, in user units. When this limit is exceeded, the controller aborts axis motion.
The maximum limit (soft limit) for axis motion, in user units. When this limit is exceeded, the controller aborts axis motion.
The minimum value for the output of the PID compensation that is written to the motor amplifier, in volts. The computed output value is clamped to this limit. The limit is applied before scaling to raw output units.
The maximum value for the output of the PID compensation that is written to the motor amplifier, in volts. The computed output value is clamped to this limit. The limit is applied before scaling to raw output units.
The maximum allowable following error, in user units. If the difference between commanded and sensed position exceeds this amount, the controller disables servo calculations, sets all the outputs to 0.0, and disables the amplifiers.
The polarity for enabling the amplifiers. Set this to 0 or 1 for the proper polarity. This value can be determined by following all the electronics back from the amplifier, through any driver circuitry, etc. or it can be set through a simple trial-and-error. Normally, for amplifiers which are enabled active-low (0 volts enables), this is a 0.
The polarity for detecting minimum-travel hardware limit switch trips. Set this depending on how your switches are wired up to the digital inputs on the I/O board.
The polarity for detecting maximum-travel hardware limit switch trips. Set this depending on how your switches are wired up to the digital inputs on the I/O board.
The polarity for detecting homing switch trips. Set this depending on how your switches are wired up to the digital inputs on the I/O board.
The direction in which homing moves are initiated. 0 means in the negative direction, 1 means in the positive direction.
The polarity for detecting amplifier faults. Set this to 0 or 1 depending upon how the amplifier sets the logic level for its fault condition.
The units used to interpret subsequent values for ROTOR_INERTIA and DAMPING_FRICTION_COEFFICIENT. This can be OZ_IN for ounce-inches, LB_FT for pound-feet, or N_M for newton-meters.
The resistance, in ohms, of the motor.
The inductance, in henries, of the motor.
The back EMF constant, or torque constant, in volts per radian per second.
The rotor inertia, in torque units * seconds2.
The damping coefficient, in torque units per radian per second.
The angular offset, in radians, between the the motor initial position and the encoder initial position. Normally this is 0, but can be made any arbitrary value if the simulated motor shaft position is interpreted as the actual axis position and should be something other than 0 when the encoder reports 0.
The amount of motor shaft revolutions per user unit of position. For example, for a 1/10 inch lead screw, where 10 rotations equals 1 inch, this would be 10.
The gain of the amplifier, which multiplies the input voltage to generate an output voltage which drives the motor.
The maximum output current of the amplifier, in amps.
The resistance, in ohms, of the load on the amplifier. This is normally the same as the motor armature resistance, but it may not be, for example, if there is additional resistive load between the amplifier and the motor itself.
The number of encoder counts per motor shaft revolution. If there is gearing between the encoder shaft and the motor shaft, this value should include this.
The following entries set general parameters for the I/O controller.
The period, in seconds, at which EMCIO will run. You can make this as small as you want to increase the throughput. Making it 0.0 or a negative number will tell EMCIO not to sleep at all. Ultimately the system loading will limit the effective throughput.
The file which contains tool information. The format of the file isPOC FMS LEN DIAM COMMENT 1 1 0 0 2 2 0 0where the first line is a comment (in this case the name of the columns), and the subsequent lines contain the pocket number in which the tool is located, the tool ID of the tool itself, the length, the diameter, and an optional comment. The length and diameter are in user units.
How long, in seconds, to wait after the spindle has been turned off before applying the brake.
How long, in seconds, to wait after the spindle brake has been released before turning the spindle on.
The location of the input bit which is used to detect whether the system is in ESTOP.
The location of the input bit which is used to detect whether the lubrication level is OK or low.
The location of the output bit which is used to drive the spindle forward. Only applicable to manual spindles.
The location of the output bit which is used to drive the spindle in reverse. Only applicable to manual spindles.
The location of the output bit which is used to turn mist coolant on or off.
The location of the output bit which is used to turn flood coolant on or off.
The location of the output bit which is used to decrease the spindle speed. Only applicable to manual spindles.
The location of the output bit which is used to increase the spindle speed. Only applicable to manual spindles.
The location of the output bit which is used to cause an ESTOP.
The location of the output bit which is used to engage or release the spindle brake.
The polarity of the sensed estop input bit.
The polarity of the sensed lube level bit.
The polarity of the sensed spindle forward bit.
The polarity of the sensed spindle reverse bit.
The polarity of the sensed mist coolant bit.
The polarity of the sensed flood coolant bit.
The polarity of the sensed spindle decrease bit.
The polarity of the sensed spindle increase bit.
The polarity of the sensed estop activation bit.
The polarity of the sensed spindle brake bit.
yourprompt> emcmotIn 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
The C language declaration for the kinematics, found in emcmot.h, is
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.#include "posemath.h" /* PmPose */ extern int forwardKinematics(double * joints, PmPose * pos); extern int inverseKinematics(PmPose pos, double * joints);
For example, one of the external APIs is
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:/* 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);
/* 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
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:/* reads value of digital input at index, stores in value */ extern int extDioRead(int index, int *value);
/* 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.
./run.sunos5
|
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. |
Frequently-asked questions about the PC, including lots of technical information.
Davin McCall's collection of very useful technical information on the PC.
The PC parallel port provides for 12 digital outputs and 5 digital inputs. If you have a minimum of I/O, you can use this port and save some money.
Instructions for installing Linux and Real-Time Linux, tailored for potential EMC users.
Where to start for Linux. Includes links to lots of other Linux resources.
Sunsite's Linux Documentation Project (LDP) has lots of documentation on Linux in general.
The Linux Journal folks at SSC have a Linux page with useful links.
How to use the PC parallel port with Linux. Useful if you have a printer and a ZIP drive.
Commercial versions of Linux, with manuals, graphical installation and configuration tools, etc. on a CD.
New Mexico Tech's Linux tour de force, giving Linux real-time determinism. RT-Linux is not a real-time operating system, but a real-time subsystem, in which code that requires limited operating system resources can run without being bothered.
Here's something on programming Intel X86 I/O ports in Linux, via the usual inb() and outb() functions.
Linux and RT-Linux processes communicate between themselves using FIFOs, but shared memory has some advantages. Here's information on how to set it up and use it.
The C language header file for API used by the EMC software when reading and writing to I/O boards for A/D, D/A, digital I/O, encoders, et cetera. Implementations of these functions need to be written by EMC integrators. In the body of these functions should be calls to the specific boards used in the implementation. extintf.h
Servo To Go 4- and 8-axis electronic interface card, with D/A converters, encoder quadrature counters, digital I/O, optional analog input. EMC supports the Model 1 board. We don't yet have a driver for the Model 2 board. If you're going to use this board, here are the pin assignments. stg.h
stg.c
extstgmot.c
The PC parallel port can be used for 12 general-purpose digital outputs and 5 digital inputs. parport.h
parport.c
extppt.c