def samplesToFLP(dtxypower, xymmToDac=None): clock_Hz = 60e3 xytickspmm = float(0xffff) / 125 lastPower = None xyticks = [] import numpy as np dtxypower = np.asarray(dtxypower) from OpenFL import FLP result = FLP.Packets() result.append(FLP.TimeRemaining(int(sum(dtxypower[:, 0])))) import numpy as np if xymmToDac is None: tickspmm = float(0xffff) / 125.0 midticks = float(0xffff) / 2 xyToTicks = np.array([[tickspmm, 0, midticks], [0, tickspmm, midticks], [0, 0, 1]]) def xymmToDac(x_mm, y_mm): xy_ticks = xyToTicks.dot((x_mm, y_mm, 1)) x_ticks, y_ticks = xy_ticks[:2] / xy_ticks[-1] return x_ticks, y_ticks for dt_s, x_mm, y_mm, power in dtxypower: #power = mWToNumber(power) if power != lastPower: if xyticks: result.append(FLP.XYMove(xyticks)) xyticks = [] result.append(FLP.LaserPowerLevel(power)) lastPower = power xy_ticks = xymmToDac(x_mm, y_mm) dt_ticks = dt_s * clock_Hz # Deal with potential that the move takes too long to fit in one step: for i in range(int(dt_ticks // 0xffff)): alpha = (i + 1) * 0xffff / dt_ticks x = np.interp(alpha, [0.0, 1.0], [lastxy_ticks[0], xy_ticks[0]]) y = np.interp(alpha, [0.0, 1.0], [lastxy_ticks[1], xy_ticks[1]]) xyticks.append((x, y, 0xffff)) dt_ticks %= 0xffff # Now we just have to do the last little bit. xyticks.append(tuple(xy_ticks) + (dt_ticks, )) lastxy_ticks = xy_ticks if xyticks: result.append(FLP.XYMove(xyticks)) return result
def samples_to_FLP(self, xy_mm_dts_s_mW, max_mm=5.0): import FLP clock_Hz = FLP.XYMoveClockRate.moverate_Hz() xyticks = [] import numpy as np xy_mm_dts_s_mW = np.asarray(xy_mm_dts_s_mW) result = FLP.Packets() xydtmW = self.sample_line_segments_mm_s( start_xy_mm=xy_mm_dts_s_mW[0, :2], xys_mm=xy_mm_dts_s_mW[1:, :2], dts_s=xy_mm_dts_s_mW[1:, 2], mWs=xy_mm_dts_s_mW[1:, 3], max_mm=5.0) # Use the starting row, then interpolate elsewhere. xydtmW = np.vstack([ xy_mm_dts_s_mW[:1], np.hstack([xydtmW[:, :2], xydtmW[:, 2:3], xydtmW[:, 3:4]]) ]) last_mW = None lastxy_ticks = self.mm_to_galvo(xydtmW[0][0], xydtmW[0][1]) for x_mm, y_mm, dt_s, mW in xydtmW: if mW != last_mW: if xyticks: result.append(FLP.XYMove(xyticks)) xyticks = [] result.append(FLP.LaserPowerLevel(self.mW_to_ticks(mW))) last_mW = mW xy_ticks = self.mm_to_galvo(x_mm, y_mm) dt_ticks = dt_s * clock_Hz # Deal with potential that the move takes too long to fit in one step: for i in range(int(dt_ticks // 0xffff)): alpha = (i + 1) * 0xffff / dt_ticks x = np.interp(alpha, [0.0, 1.0], [lastxy_ticks[0], xy_ticks[0]]) y = np.interp(alpha, [0.0, 1.0], [lastxy_ticks[1], xy_ticks[1]]) xyticks.append((x, y, 0xffff)) dt_ticks %= 0xffff # Now we just have to do the last little bit. xyticks.append(tuple(xy_ticks) + (dt_ticks, )) lastxy_ticks = xy_ticks if xyticks: result.append(FLP.XYMove(xyticks)) return result
def to_flp(stipples, dpi=300, x_mm=0, y_mm=0, laser_pwr=35000, ticks=500, base=100): """" Converts a set of stipples into a list of FLP packets dpi is the image's DPI x_mm and y_mm are the corner location of the image (default 0,0) (where 0,0 is the center of the build platform) laser_power is the laser's power level in ticks ticks is the number of frames the laser spends a black point base is the number of frames the laser spends on a white point """ # Accumulated list of FLP packets packets = F.Packets() # Sort by X to reduce the amount of laser moves necessary stipples = sorted(stipples, key=lambda s: s[0]) # Draw stuff for every point for x, y, i in stipples: # Center position in mm x = mm_to_pos(x / float(dpi) * 25.4 + x_mm) y = mm_to_pos(y / float(dpi) * 25.4 + y_mm) # Decide how long to stay on this point (longer time = darker point) t = int(ceil((ticks - base) * (1 - i)) + base) if t == 0: continue # Move to this stipple's location with the laser off, then pause # briefly to let the controller stabilize packets.append(F.LaserPowerLevel(0)) packets.append(F.XYMove([[x, y, 200], [x, y, 100]])) # Draw the spot with the laser on packets.append(F.LaserPowerLevel(laser_pwr)) packets.append(F.XYMove([[x, y, t]])) return packets