import pipython
import sys
import time
+import numpy as np
+import matplotlib.pyplot as plt
+import threading
+from pipython import datarectools, pitools
-# Set up stage
-pidevice = pipython.GCSDevice('E-727')
+def setup():
-usb_devices = pidevice.EnumerateUSB()
-if len(usb_devices) < 1:
- print("No PI stages found - exiting")
- sys.exit()
+ # Set up stage
+ pidevice = pipython.GCSDevice('E-727')
-pidevice.ConnectUSB(usb_devices[0].split(' ')[-1])
+ usb_devices = pidevice.EnumerateUSB()
+ if len(usb_devices) < 1:
+ print("No PI stages found - exiting")
+ sys.exit()
-with nidaqmx.Task() as task:
+ pidevice.ConnectUSB(usb_devices[0].split(' ')[-1])
+ pitools.startup(pidevice, servostates=True)
+ pitools.waitontarget(pidevice, [1, 2, 3])
+ tstart = time.time_ns()
+ print(pidevice.qPOS([1, 2, 3]))
+ print(time.time_ns() - tstart)
+
+ task = nidaqmx.Task()
task.do_channels.add_do_chan("cDAQ1Mod3/port0/line2",
- line_grouping=nidaqmx.constants.LineGrouping.CHAN_PER_LINE)
+ line_grouping=nidaqmx.constants.LineGrouping.CHAN_PER_LINE)
task.start()
- while True:
+
+ return (task, pidevice)
+
+
+class BufferTimer(threading.Thread):
+ def __init__(self, event, fn, interval):
+ threading.Thread.__init__(self)
+ self.stopped = event
+ self.fn = fn
+ self.interval = interval
+ def run(self):
+ while not self.stopped.wait(self.interval):
+ self.fn()
+
+class Recorder:
+ """
+ Wrapper for the PiPython GCS 2.0 data recorder
+ """
+
+ def __init__(self, pidevice, sample_rate=500, sources=None, options=None):
+ self.sample_rate = sample_rate
+ self._drec = datarectools.Datarecorder(pidevice)
+ if options is None:
+ # Default: actual position
+ options = datarectools.RecordOptions.ACTUAL_POSITION_2
+ if sources is None:
+ # Default: all axes
+ sources = pidevice.axes
+
+ self._drec.samplefrequ = sample_rate
+ self._drec.options = options
+ self._drec.sources = sources
+ self._drec.trigsources = datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4
+ self.maxsamples = int(datarectools.getmaxnumvalues(pidevice) / len(sources))
+
+ self.interval = self.maxsamples * self._drec.sampletime / 1.5
+ print(self.interval)
+ self._stop_flag = threading.Event()
+ self._refresh_thread = BufferTimer(self._stop_flag, self.get_data, self.interval)
+ self.read_in_progress = False
+
+ self.data = np.zeros((0, len(self._drec.sources)+1))
+ self.headers = []
+ self._time_start = []
+ self._time_end = []
+
+ def start(self):
+ self._drec.arm()
+ self._time_start.append(time.time_ns())
+ print("Starting recording at {}".format((self._time_start[-1] - self._time_start[0])/1e9))
+ self._refresh_thread.start()
+
+ def refresh(self):
+ self._drec._gcs.DRT(0, datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4)
+ self._time_start.append(time.time_ns())
+
+ def get_data(self, refresh=True):
+ self.read_in_progress = True
+ time_start = self._time_start[-1]
+ time_current = time.time_ns()
+ print("Starting reading at {}".format((time_current - self._time_start[0])/1e9))
+ elapsed_time = (time_current - time_start) / 1e9
+
+ read_no_samples = int(elapsed_time / self._drec.sampletime)
+ extra_samples = int(0.5*read_no_samples)
+ read_no_samples += extra_samples
+ data = np.zeros((read_no_samples, len(self._drec.sources)+1))
+ print("Data: {}".format(data.shape))
+ start_timeval = (self._time_start[-1] - self._time_start[0])/1e9
+ print("Start timeval: {}".format(start_timeval))
+ print("Predicted elapsed time: {}, Actual elapsed time: {}".format(read_no_samples*self._drec.sampletime, elapsed_time))
+ times = np.arange(start_timeval, start_timeval+elapsed_time-self._drec.sampletime + extra_samples*self._drec.sampletime, step=self._drec.sampletime)
+ print("Times: {}".format(times.shape))
+ data[:,0] = times
+ tables = list(range(1, len(self._drec.sources)+1))
+ header = pidevice.qDRR(tables, 1, read_no_samples)
+ while pidevice.bufstate is not True:
+ time.sleep(0.01)
+ if refresh:
+ self.refresh()
+ d = np.array(pidevice.bufdata).transpose()
+ data[:,1:] = d
+ print(d[0,1:3])
+ print(d[-1,1:3])
+
+ self.data = np.vstack((self.data, data))
+ self.read_in_progress = False
+
+ def _plot_data(self, data):
+ fig, ax = plt.subplots()
+ ax.plot(data[:,0], data[:,1], label='x', marker='.')
+ ax.plot(data[:,0], data[:,2], label='y', marker='.')
+ ax.plot(data[:,0], data[:,3], label='z', marker='.')
+ plt.legend()
+ plt.show()
+
+ def stop(self, plot=False):
+ print("Saving")
+ self._stop_flag.set()
+ while self.read_in_progress is True:
+ time.sleep(0.1)
+ self.get_data(refresh=False)
+ diffs = np.diff(self.data[:,0])
+ max_diff = np.max(diffs)
+ print("Max gap: {}".format(max_diff))
+ np.savetxt("data.txt", self.data, delimiter=',')
+ if plot:
+ self._plot_data(self.data)
+
+
+
+def lines(task, pidevice):
+
+ focus_top = 9
+ focus_bottom = 9
+ focus_range = 50
+ start_x = 116
+ start_y = 100
+ pitch = 3
+ line_length = 20
+
+ # Go to origin
+ pidevice.MOV({1: start_x, 2: start_y, 3: focus_top})
+
+ # set velocity
+ velocities = [0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000]
+ #velocities = [1]
+ pidevice.VCO({2: True})
+
+ for i, vel in enumerate(velocities):
+
+ # Calculate x coordinate for this line
+ x = i * pitch
+ z = focus_top + (focus_bottom - focus_top) / focus_range * x
+
+ # Go to start position
+ pidevice.VEL({2: 100})
+ pidevice.MOV({1: start_x + x, 2: start_y, 3: z})
+ pitools.waitontarget(pidevice, [1, 2, 3])
+ time.sleep(0.2)
+
+ # Turn on laser
+ task.write(True)
+ time.sleep(0.006)
+
+ # Start line
+ pidevice.VEL({2: vel})
+ pidevice.MOV({2: start_y + line_length})
+ pitools.waitontarget(pidevice, [1, 2, 3])
+
+ # Turn off laser
+ task.write(False)
+ time.sleep(0.2)
+
+ # Go to origin
+ pidevice.VEL({2: 100})
+ pidevice.MOV({1: start_x, 2: start_y, 3: focus_top})
+ pitools.waitontarget(pidevice, [1, 2, 3])
+
+def dots(task, pidevice):
+
+ # Focusing procedure:
+ # Get two z values where the beam is in focus at two points: the left
+ # and right sides of the writing area. Put these values in focus_*,
+ # and the distance between the two sample points in focus_range.
+ focus_left = 8.5
+ focus_right = 8.5
+ focus_range = 10
+
+ # Positioning parameters
+ start_x = 25
+ start_y = 0
+ pitch = 5
+
+ # Go to origin
+ #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left})
+ pidevice.MOV({1: start_x, 2: start_y})
+
+ # Set exposure times in ms
+ #times = np.array([10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000])
+ times = np.array([10, 20, 50, 100, 200, 500, 1000])
+ for i, t in enumerate(times):
+
+ # Go to dot position
+ y = start_y + i * pitch
+ z = focus_left + (focus_right - focus_left) / focus_range * y
+ #pidevice.MOV({2: y, 3: z})
+ pidevice.MOV({2: y})
+ #pitools.waitontarget(pidevice, [1, 2, 3])
+ pitools.waitontarget(pidevice, [1, 2])
+ time.sleep(0.1)
+
+ # Write dot
+ print("{} of {}: {} ms".format(i+1, len(times), t))
task.write(True)
- time.sleep(1)
+ time.sleep(t/1e3)
task.write(False)
- time.sleep(1)
+ time.sleep(0.5)
+
+ # Go to origin
+ #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left})
+ #pitools.waitontarget(pidevice, [1, 2, 3])
+ pidevice.MOV({1: start_x, 2: start_y})
+ pitools.waitontarget(pidevice, [1, 2])
+
+def test_rec(pidevice):
+ pidevice.VCO({1: True, 2: True})
+ pidevice.VEL({1: 1000, 2: 1000})
+ pidevice.MOV({1: 0, 2: 0})
+ pitools.waitontarget(pidevice, [1, 2])
+ pidevice.VEL({1: 20, 2: 20})
+ rec = Recorder(pidevice)
+ rec.start()
+ pidevice.MOV({1: 100, 2: 100})
+ #pitools.waitontarget(pidevice, [1, 2, 2])
+ time.sleep(15)
+ #rec.get_data()
+ #pitools.waitontarget(pidevice, [1, 2, 3])
+ #rec.get_data()
+ # time.sleep(5)
+ # rec.get_data()
+ rec.stop(plot=True)
+
+
+if __name__ == "__main__":
+ task, pidevice = setup()
+ try:
+ #lines(task, pidevice)
+ dots(task, pidevice)
+ #test_rec(pidevice)
+ finally:
+ pitools.stopall(pidevice)
+ task.close()
\ No newline at end of file