Examples

Controller Addresses

Use Gclib.addresses() to see the different addresses that are available.

package examples;
import com.galil.Gclib;

public class Addresses {
    public static void main(String[] args) {
        System.out.println(Gclib.addresses());
    }
}
> mvn exec:java -Dexec.mainClass=examples.Addresses --quiet
192.168.0.40, DMC4040 Rev 1.3i, 10601
COM5, DMC-41x3
GALILPCI0

If using an ethernet controller that doesn't have an IP address yet, it will show up in Gclib.ipRequests(). Use Gclib.assignIp() to give the controller an IP. If successful, the controller will begin showing up in Gclib.addresses() under the new address.

package examples;
import com.galil.Gclib;

public class IpRequests {
    public static void main(String[] args) {
        System.out.println(Gclib.ipRequests());
        Gclib.assignIp("00:50:4C:20:29:69", "192.168.0.40");
    }
}
> mvn exec:java -Dexec.mainClass=examples.IpRequests --quiet
DMC4000, 10601, 00:50:4C:20:29:69, Ethernet, 192.168.0.1, 0.0.0.0

Connection Management

To use a controller with gclib, pass the address and an optional baud rate (for serial connections) to Gclib.Controller() to receive a controller object. After you are done, close the connection with Gclib.Controller.close().

package examples;
import com.galil.Gclib.Controller;

public class Connection {
    public static void main(String[] args) {
        try (var dmc = new Controller(args[0])) {
            System.out.println(dmc.revisionInformation());
        }
    }
}
> mvn exec:java -Dexec.args="192.168.0.40" -Dexec.mainClass=examples.Connection --quiet
192.168.0.40, DMC4040 Rev 1.3i, 10601

Commands

To issue commands, use Gclib.Controller.command() with an open connection. The following example uses Gclib.Controller.command() to implement a basic terminal.

package examples;
import com.galil.Gclib.Controller;

import java.util.NoSuchElementException;
import java.util.Scanner;

public class Commands {
    public static void main(String[] args) {
        try (var dmc = new Controller(args[0])) {
            System.out.println(dmc.revisionInformation());
            System.out.print(":");
            try (var scanner = new Scanner(System.in)) {
                while (true) {
                    String result = dmc.command(scanner.nextLine());
                    System.out.print(result.isEmpty() ? ":" : result + "\r\n:");
                }
            } catch (NoSuchElementException e) {}
        }
    }
}
> mvn exec:java -Dexec.args="192.168.0.40" -Dexec.mainClass=examples.Commands --quiet
Connected to DMC4040 Rev 1.3i
Use Ctrl+C to exit.
:MG "Hello World"
Hello World
:^C

Errors

If a gclib call is unsuccessful, a RuntimeError will be thrown with a description of the error code and a more detailed error string, if available.

package examples;
import com.galil.Gclib.Controller;

public class Errors {
    public static void main(String[] args) {
        try (var dmc = new Controller(args[0])) {
            dmc.command("invalid");
        } catch (RuntimeException e) {
            System.out.println(e);
        }
    }
}
> mvn exec:java -Dexec.args="192.168.0.40" -Dexec.mainClass=examples.Errors --quiet
java.lang.RuntimeException: Command "invalid" caused error code 1: The controller returned a question mark

Program & Arrays

Use Gclib.Controller.program() to get the controller's program, and use Gclib.Controller.setProgram() to set it.

package examples;
import com.galil.Gclib;

public class Program {
    public static void main(String[] args) {
        try (var dmc = new Gclib.Controller(args[0])) {
            dmc.setProgram("MG \"Hello World\"");
            System.out.println(dmc.program());
        }
    }
}
> mvn exec:java -Dexec.args="192.168.0.40" -Dexec.mainClass=examples.Program --quiet
MG "Hello World"

Use Gclib.Controller.array() to get an array from the controller, and use Gclib.Controller.setArray() to set it.

package examples;
import com.galil.Gclib.Controller;

public class Arrays {
    public static void main(String[] args) {
        try (var dmc = new Controller(args[0])) {
            dmc.command("DM test[5]");
            dmc.setArray("test", "1.0, 2.0, 3.0, 4.0, 5.0");
            System.out.println(dmc.array("test"));
        }
    }
}
> java Arrays 192.168.0.40
2.0000, 3.0000, 4.0000

Unsolicited Data

Blocking

For synchronous usage, subscribe without providing a callback or user data pointer.

dmc.subscribeMessages();

Once subscribed, you can then wait a specified amount of time for unsolicited data to arrive.

// Time out if message doesn't arrive within one second
dmc.message(1000);
<div class="tabbed">
- <b class="tab-title">Code</b>
<!-- MACRO{snippet|file=../../examples/java/src/main/java/examples/Unsolicited.java} -->
- <b class="tab-title">Output</b>
> mvn exec:java -Dexec.args="192.168.0.40" -Dexec.mainClass=examples.Unsolicited --quiet
Got message Hello World
Got data record, sample 39306
Got interrupt 240

Callback

For asynchronous usage, subscribe with a callback function. Each time unsolicited data arrives, your callback will be invoked.

dmc.subscribeMessages((message) => System.out.println("Got message: " + message));

CAUTION: The callback will be invoked on a separate thread. Be sure to protect any shared data!

package examples;
import com.galil.Gclib;
import java.util.concurrent.TimeUnit;

public class Callback {
    public static void main(String[] args) throws InterruptedException {
        try (var dmc = new Gclib.Controller(args[0])) {
            dmc.subscribeMessages((message) -> System.out.println("Got message: " + message));
            dmc.subscribeInterrupts((interrupt) -> System.out.println("Got interrupt: " + interrupt.type()));
            dmc.subscribeDataRecords((dataRecord) -> System.out.println("Got data record, sample " + dataRecord.sample()));

            dmc.setInterrupts(Gclib.Interrupt.Type.ProgramStopped);
            dmc.setDataRecords(200);

            dmc.setProgram("WT 100; MG \"Hello World\"; EN");
            dmc.command("XQ");

            TimeUnit.MILLISECONDS.sleep(300);

            dmc.setInterrupts(Gclib.Interrupt.Type.NoInterrupts);
            dmc.setDataRecords(0);
        }
    }
}
> mvn exec:java -Dexec.args="192.168.0.40" -Dexec.mainClass=examples.Callback --quiet
Got message Hello World
Got data record, sample 39306
Got interrupt 240

For a full list of data record fields, see the Gclib.DataRecord API.

NOTE: Controllers with default settings will not generate interrupts or data records. Use Gclib.Controller.setInterrupts() and Gclib.Controller.setDataRecords() to configure your controller if needed.

Galil Connect

On the device hosting the remote gcaps server, use Gclib.setPublished().

package examples;
import com.galil.Gclib;

public class Server {
    public static void main(String[] args) {
        Gclib.setPublished(args[0]);
        System.out.println("Published remote gcaps server " + args[0]);
    }
}
> mvn exec:java -Dexec.args="pi" -Dexec.mainClass=examples.Callback --quiet
Published gcaps server "pi"

On the client, use Gclib.listServers() to view all available gcaps servers. Pass a server name to Gclib.setServer() for future gclib calls to be routed through that gcaps server. When done, call Gclib.setServer() with no arguments to disconnect from the remote gcaps server.

package examples;
import com.galil.Gclib;

public class Client {
    public static void main(String[] args) {
        System.out.println(Gclib.listServers());
        Gclib.setServer(args[0]);

        System.out.println("Addresses reported by pi: " + Gclib.addresses());
        try (var dmc = new Gclib.Controller(args[1])) {
            System.out.println(dmc.revisionInformation());
        }

        Gclib.setServer();
    }
}
Available servers:
pi

Addresses reported by pi:
COM5

Connected to COM5, DMC31010 Rev 1.4f, 12345

Example Project: Record and Replay

The ‘Record’ example uses RA in continuous mode along with Gclib.Controller.array() to allow recording movement for an arbitrary amount of time. It produces a file with the recorded positions of Axis A.

package examples;
import com.galil.Gclib;

import java.io.FileWriter;
import java.io.IOException;

public class Record {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 2) {
            System.out.println("Usage: Record ADDRESS SECONDS");
            return;
        }
        try (var dmc = new Gclib.Controller(args[0])) {
            dmc.command("MO");
            dmc.command("DM posA[1000]");
            dmc.command("RA posA[]");
            dmc.command("RD _TPA");
            dmc.command("RC 1,-1000"); // Assuming TM1000, record at 2ms intervals (1ms on DMC30010 / EDD37010 / RIO47000)

            long startTime = System.currentTimeMillis();
            short start = 0, end;

            try(var fileWriter = new FileWriter("positions.txt")) {
                while (System.currentTimeMillis() - startTime < Float.parseFloat(args[1]) * 1000) {
                    Thread.sleep(500);
                    end = (short)Float.parseFloat(dmc.command("MG_RD"));
                    var array = dmc.array("posA", start, end < start ? 0 : end);
                    if (end < start) {
                        array += ", " + dmc.array("posA", 0, end);
                    }
                    fileWriter.write(array.replace(", ", "\n") + '\n');
                    start = end;
                }
            }
            dmc.command("RC 0");
        }
    }
}
> mvn exec:java -Dexec.args="192.168.0.40 5" -Dexec.mainClass=examples.Record --quiet

The ‘Replay’ example uses the file produced by ‘Record’ along with CM to accurately reproduce the recorded movement. Note that axis A must be properly set up for motion.

package examples;
import com.galil.Gclib;

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileNotFoundException;

public class Replay {
    public static void main(String[] args) throws IOException, InterruptedException {
        if (args.length != 1) {
            System.out.println("Usage: Replay ADDRESS");
            System.exit(1);
        }
        try (var dmc = new Gclib.Controller(args[0])) {
            dmc.command("SH A");
            dmc.command("CM A");
            dmc.command("DT -1");

            int contourSpace = (int)Float.parseFloat(dmc.command("MG_CM"));

            try(BufferedReader bufferedReader = new BufferedReader(new FileReader("positions.txt"))) {
                String line = bufferedReader.readLine();
                Float position;
                Float lastPosition = null;
                String movement;
                while (line != null) {
                    position = Float.parseFloat(line);
                    if (lastPosition == null) {
                        lastPosition = position;
                        continue;
                    }
                    movement = String.valueOf((int)(position - lastPosition));
                    try {
                        dmc.command("CD " + movement);
                    } catch (RuntimeException e) {
                        if (!dmc.command("TC1").equals("32 Segment buffer full"))
                            throw e;
                        if ((int)Float.parseFloat(dmc.command("MG_DT")) == -1)
                            dmc.command("DT 1");
                        Thread.sleep(500);
                    }
                    lastPosition = position;
                    line = bufferedReader.readLine();
                }
            } catch (FileNotFoundException e) {
                System.out.println("Failed to open positions.txt");
                System.exit(1);
            }

            while ((int)Float.parseFloat(dmc.command("MG_CM")) < contourSpace)
                Thread.sleep(500);

            dmc.command("CD 0=0");
            dmc.command("MO");
        }
    }
}
> mvn exec:java -Dexec.args="192.168.0.40" -Dexec.mainClass=examples.Replay --quiet