write_path / write_path.pyon commit binary grating code (3ae49cb)
   1import nidaqmx
   2import pipython
   3import sys
   4import time
   5import numpy as np
   6import matplotlib.pyplot as plt
   7import threading
   8
   9from pipython import datarectools, pitools
  10
  11def setup():
  12
  13    # Set up stage
  14    pidevice = pipython.GCSDevice('E-727')
  15
  16    usb_devices = pidevice.EnumerateUSB()
  17    if len(usb_devices) < 1:
  18        print("No PI stages found - exiting")
  19        sys.exit()
  20
  21    pidevice.ConnectUSB(usb_devices[0].split(' ')[-1])
  22    pitools.startup(pidevice, servostates=True)
  23    pitools.waitontarget(pidevice, [1, 2, 3])
  24    tstart = time.time_ns()
  25    print(pidevice.qPOS([1, 2, 3]))
  26    print(time.time_ns() - tstart)
  27
  28    task = nidaqmx.Task()
  29    task.do_channels.add_do_chan("cDAQ1Mod3/port0/line2",
  30                                    line_grouping=nidaqmx.constants.LineGrouping.CHAN_PER_LINE)
  31    task.start()
  32
  33    return (task, pidevice)
  34
  35
  36class BufferTimer(threading.Thread):
  37    def __init__(self, event, fn, interval):
  38        threading.Thread.__init__(self)
  39        self.stopped = event
  40        self.fn = fn
  41        self.interval = interval
  42    def run(self):
  43        while not self.stopped.wait(self.interval):
  44            self.fn()
  45
  46class Recorder:
  47    """
  48    Wrapper for the PiPython GCS 2.0 data recorder
  49    """
  50
  51    def __init__(self, pidevice, sample_rate=500, sources=None, options=None):
  52        self.sample_rate = sample_rate
  53        self._drec = datarectools.Datarecorder(pidevice)
  54        if options is None:
  55            # Default: actual position
  56            options = datarectools.RecordOptions.ACTUAL_POSITION_2
  57        if sources is None:
  58            # Default: all axes
  59            sources = pidevice.axes
  60
  61        self._drec.samplefrequ = sample_rate
  62        self._drec.options = options
  63        self._drec.sources = sources
  64        self._drec.trigsources = datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4
  65        self.maxsamples = int(datarectools.getmaxnumvalues(pidevice) / len(sources))
  66
  67        self.interval = self.maxsamples * self._drec.sampletime / 1.5
  68        print(self.interval)
  69        self._stop_flag = threading.Event()
  70        self._refresh_thread = BufferTimer(self._stop_flag, self.get_data, self.interval)
  71        self.read_in_progress = False
  72        
  73        self.data = np.zeros((0, len(self._drec.sources)+1))
  74        self.headers = []
  75        self._time_start = []
  76        self._time_end = []
  77
  78    def start(self):
  79        self._drec.arm()
  80        self._time_start.append(time.time_ns())
  81        print("Starting recording at {}".format((self._time_start[-1] - self._time_start[0])/1e9))
  82        self._refresh_thread.start()
  83    
  84    def refresh(self):
  85        self._drec._gcs.DRT(0, datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4)
  86        self._time_start.append(time.time_ns())
  87
  88    def get_data(self, refresh=True):
  89        self.read_in_progress = True
  90        time_start = self._time_start[-1]
  91        time_current = time.time_ns()
  92        print("Starting reading at {}".format((time_current - self._time_start[0])/1e9))
  93        elapsed_time = (time_current - time_start) / 1e9
  94        
  95        read_no_samples = int(elapsed_time / self._drec.sampletime)
  96        extra_samples = int(0.5*read_no_samples)
  97        read_no_samples += extra_samples
  98        data = np.zeros((read_no_samples, len(self._drec.sources)+1))
  99        print("Data: {}".format(data.shape))
 100        start_timeval = (self._time_start[-1] - self._time_start[0])/1e9
 101        print("Start timeval: {}".format(start_timeval))
 102        print("Predicted elapsed time: {}, Actual elapsed time: {}".format(read_no_samples*self._drec.sampletime, elapsed_time))
 103        times = np.arange(start_timeval, start_timeval+elapsed_time-self._drec.sampletime + extra_samples*self._drec.sampletime, step=self._drec.sampletime)
 104        print("Times: {}".format(times.shape))
 105        data[:,0] = times
 106        tables = list(range(1, len(self._drec.sources)+1))
 107        header = pidevice.qDRR(tables, 1, read_no_samples)
 108        while pidevice.bufstate is not True:
 109            time.sleep(0.01)
 110        if refresh:
 111            self.refresh()
 112        d = np.array(pidevice.bufdata).transpose()
 113        data[:,1:] = d
 114        print(d[0,1:3])
 115        print(d[-1,1:3])
 116        
 117        self.data = np.vstack((self.data, data))
 118        self.read_in_progress = False
 119
 120    def _plot_data(self, data):
 121        fig, ax = plt.subplots()
 122        ax.plot(data[:,0], data[:,1], label='x', marker='.')
 123        ax.plot(data[:,0], data[:,2], label='y', marker='.')
 124        ax.plot(data[:,0], data[:,3], label='z', marker='.')
 125        plt.legend()
 126        plt.show()     
 127
 128    def stop(self, plot=False):
 129        print("Saving")
 130        self._stop_flag.set()
 131        while self.read_in_progress is True:
 132            time.sleep(0.1)
 133        self.get_data(refresh=False)
 134        diffs = np.diff(self.data[:,0])
 135        max_diff = np.max(diffs)
 136        print("Max gap: {}".format(max_diff))
 137        np.savetxt("data.txt", self.data, delimiter=',')
 138        if plot:
 139            self._plot_data(self.data)
 140
 141
 142
 143def lines(task, pidevice):
 144
 145    focus_top = 9
 146    focus_bottom = 9
 147    focus_range = 50
 148    start_x = 116
 149    start_y = 100
 150    pitch = 3
 151    line_length = 20
 152
 153    # Go to origin
 154    pidevice.MOV({1: start_x, 2: start_y, 3: focus_top})
 155
 156    # set velocity
 157    velocities = [0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000]
 158    #velocities = [1]
 159    pidevice.VCO({2: True})
 160
 161    for i, vel in enumerate(velocities):
 162
 163        # Calculate x coordinate for this line
 164        x = i * pitch
 165        z = focus_top + (focus_bottom - focus_top) / focus_range * x
 166
 167        # Go to start position
 168        pidevice.VEL({2: 100})
 169        pidevice.MOV({1: start_x + x, 2: start_y, 3: z})
 170        pitools.waitontarget(pidevice, [1, 2, 3])
 171        time.sleep(0.2)
 172
 173        # Turn on laser
 174        task.write(True)
 175        time.sleep(0.006)
 176
 177        # Start line
 178        pidevice.VEL({2: vel})
 179        pidevice.MOV({2: start_y + line_length})
 180        pitools.waitontarget(pidevice, [1, 2, 3])
 181
 182        # Turn off laser
 183        task.write(False)
 184        time.sleep(0.2)
 185        
 186    # Go to origin
 187    pidevice.VEL({2: 100})
 188    pidevice.MOV({1: start_x, 2: start_y, 3: focus_top})
 189    pitools.waitontarget(pidevice, [1, 2, 3])
 190
 191def dots(task, pidevice):
 192
 193    # Focusing procedure:
 194    # Get two z values where the beam is in focus at two points: the left 
 195    # and right sides of the writing area. Put these values in focus_*,
 196    # and the distance between the two sample points in focus_range.
 197    focus_left = 8.5
 198    focus_right = 8.5
 199    focus_range = 10
 200
 201    # Positioning parameters
 202    start_x = 25
 203    start_y = 0
 204    pitch = 5
 205
 206    # Go to origin
 207    #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left})
 208    pidevice.MOV({1: start_x, 2: start_y})
 209
 210    # Set exposure times in ms
 211    #times = np.array([10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000])
 212    times = np.array([10, 20, 50, 100, 200, 500, 1000])
 213    for i, t in enumerate(times):
 214
 215        # Go to dot position
 216        y = start_y + i * pitch
 217        z = focus_left + (focus_right - focus_left) / focus_range * y
 218        #pidevice.MOV({2: y, 3: z})
 219        pidevice.MOV({2: y})
 220        #pitools.waitontarget(pidevice, [1, 2, 3])
 221        pitools.waitontarget(pidevice, [1, 2])
 222        time.sleep(0.1)
 223
 224        # Write dot
 225        print("{} of {}: {} ms".format(i+1, len(times), t))
 226        task.write(True)
 227        time.sleep(t/1e3)
 228        task.write(False)
 229
 230        time.sleep(0.5)
 231
 232    # Go to origin
 233    #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left})
 234    #pitools.waitontarget(pidevice, [1, 2, 3])
 235    pidevice.MOV({1: start_x, 2: start_y})
 236    pitools.waitontarget(pidevice, [1, 2])
 237
 238def test_rec(pidevice):
 239    pidevice.VCO({1: True, 2: True})
 240    pidevice.VEL({1: 1000, 2: 1000})
 241    pidevice.MOV({1: 0, 2: 0})
 242    pitools.waitontarget(pidevice, [1, 2])
 243    pidevice.VEL({1: 20, 2: 20})
 244    rec = Recorder(pidevice)
 245    rec.start()
 246    pidevice.MOV({1: 100, 2: 100})
 247    #pitools.waitontarget(pidevice, [1, 2, 2])
 248    time.sleep(15)
 249    #rec.get_data()
 250    #pitools.waitontarget(pidevice, [1, 2, 3])
 251    #rec.get_data()
 252    # time.sleep(5)
 253    # rec.get_data()
 254    rec.stop(plot=True)
 255
 256
 257if __name__ == "__main__":
 258    task, pidevice = setup()
 259    try:
 260        #lines(task, pidevice)
 261        dots(task, pidevice)
 262        #test_rec(pidevice)
 263    finally:
 264        pitools.stopall(pidevice)
 265        task.close()