Digital Thread
Dave Loffredo
2017-10-24

Case Study: Drive a CNC Machine from the Digital Thread

Over the past several years, we have interfaced many machines to the digital thread: three and five axis, Siemens, Fanuc, Heidenhain, Okuma, Hyundai, Haas, and other controls. A simple interface is easy to create, and can expand to reflect your shop's policies and unique values, or even use feedback from the machine to close the loop and respond to conditions during machining.

Let's make a simple interface. We will use C#, but we could also use Javascript and Node.js, or Visual Basic. First we read a digital thread model and prepare to iterate over the process. [Download the whole program]

// Print all tool moves in a machining program.  This C# project
// calls the STEP-NC API using the .NET interface. 
//
Finder finder = new Finder();
Adaptive ctl = new Adaptive();

// Read a model and traversing the process
finder.OpenProject("digital_thread_model.stpnc");
ctl.StartProject();

The simplest way to walk the process is using an event-based API. We identify things that we are interested in: individual tool moves, tool changes, and the beginning and ending of operations. There are many options for walking through the process in great detail, but this is sufficient for now.

// Select some process events to respond to.  We will emit
// codes for individual tool moves and tool changes.  We
// will also note begin/end of operations.

ctl.SetWanted(Adaptive.CtlEvent.MOVE);
ctl.SetWanted(Adaptive.CtlEvent.TOOL_CHANGE);
ctl.SetWanted(Adaptive.CtlEvent.OPERATION_START);
ctl.SetWanted(Adaptive.CtlEvent.OPERATION_END);
// other process event are available, some include:
// ctl.SetWanted(Adaptive.CtlEvent.EXEC_WORKPLAN_START);
// ctl.SetWanted(Adaptive.CtlEvent.EXEC_WORKPLAN_END);
// ctl.SetWanted(Adaptive.CtlEvent.TOOLPATH_START);

Then the main loop of our interface advances through the process until the next event that we have requested. Simply print a comment for the start and end of an operation. Your tool change logic will certainly be more involved, but here we just issue an M6 for a tool move.

When a tool movement is seen, we examine the type of move and call different functions depending on whether we see a linear move, an arc, or a helix move. These are discussed below.

while (ctl.Next() != Adaptive.CtlEvent.DONE)
{
    long id = ctl.GetActiveExec();  // can ask for active tool, exec, etc

    switch (ctl.Event())
    {
	case Adaptive.CtlEvent.OPERATION_START:
	    Console.WriteLine("(START OPERATION #{0}, workstep #{1} {2})",
		ctl.GetActiveOperation(), id, finder.GetExecutableName(id));
	    break;

	case Adaptive.CtlEvent.OPERATION_END:
	    Console.WriteLine("(ENDING OPERATION #{0}, workstep #{1} {2})",
		ctl.GetActiveOperation(), id, finder.GetExecutableName(id));
	    break;

	case Adaptive.CtlEvent.TOOL_CHANGE:
	    long tool_id = ctl.GetActiveTool();
	    bool dummy;
	    Console.WriteLine("T{0}M6", finder.GetToolNumber (tool_id, out dummy));
	    break;

	case Adaptive.CtlEvent.MOVE:
	    switch (ctl.GetActiveType())
	    {
		case Adaptive.CtlType.MOVE:
		    printend(ctl, ctl.GetMoveEnd());
		    break;
		case Adaptive.CtlType.MOVE_ARC:
		    printarc(ctl, ctl.GetMoveArc());
		    break;
		case Adaptive.CtlType.MOVE_HELIX:
		    Console.WriteLine("HELIX MOVE");
		    printarc(ctl, ctl.GetMoveArc());
		    printend(ctl, ctl.GetMoveEnd());
		    break;
	    }
	    break;

	default:
	    Console.WriteLine("UNEXPECTED EVENT");
	    break;
    }
}

In the example below, we generate simple rapids and linear moves with feeds. The process in the thread is described in part coordinates, so tool paths are usable with any style machine — AC, BC, AB, or even parallel kinemantic machines. The API also has easy access to the position in part coordinates, setup coordinates, and other options.

static double old_feed = 0;
static double x = 9999.99;
static double y = 9999.99;
static double z = 9999.99;
static void printend(Adaptive ctl, uint p)
{
    double a, b, c;
    ctl.GetPosXYZ(out a, out b, out c, p);
    if (a == x && b == y && c == z)
	return;

    if (ctl.GetMoveIsRapid())
    {
	Console.Write("G0");
	if (x != a) Console.Write(" X{0:0.0####}", a);
	if (y != b) Console.Write(" Y{0:0.0####}", b);
	if (z != c) Console.Write(" Z{0:0.0####}", c);
    }
    else
    {
	double feed = ctl.GetMoveFeed();
	if (feed != old_feed)
	{
	    Console.WriteLine("F{0:0.0####}", feed);
	    old_feed = feed;
	}
	Console.Write("G1");
	if (x != a) Console.Write(" X{0:0.0####}", a);
	if (y != b) Console.Write(" Y{0:0.0####}", b);
	if (z != c) Console.Write(" Z{0:0.0####}", c);
    }

    if (ctl.GetPosDirZ(out a, out b, out c, p))
    {
	// Tool tilt is stored as IJK in part space.  Some controls can use
	// directly, like Siemens TRAORI A3/B3/C3=, or FANUC G43.5 TCP mode.
	// For others, we can calculate AC/BC/AB angles.
	Console.Write("  I{0:0.0####} J{1:0.0####} K{2:0.0####}", a, b, c);
    }
    Console.WriteLine();
    x = a;
    y = b;
    z = c;
}

A second function handles circular motion. The API provides simple queries for the arc center, radius, and direction.

static void printarc(Adaptive ctl, uint p)
{
    double a, b, c;
    ctl.GetPosXYZ(out a, out b, out c, p);
    if (ctl.GetArcIsCW(p))
	Console.Write("G2");
    else
	Console.Write("G3");
    Console.Write(" X{0:0.0####} Y{1:0.0####} Z{2:0.0####}", a, b, c);
    Console.Write(" R{0:0.0####}", ctl.GetArcRadius(p));
    // can also get angle, helix height, test for 180+, full circle etc
    Console.WriteLine();
}

Stable ISO Standards mean APIs that everyone can use to access process data, machine state, and report measurement results. Stable APIs mean that your machines will no longer be chained to your CAM system or obscure codes.

The data is associative so that you can understand the tolerances that are being machined, the part faces impacted, as well as any other high-level cam parameters.

Finally, the open character of the data means that you can add new capabilities over time with feedback from the machine, probed flexible setup, tool management, speed and feed monitoring, and other digital thread advances.