private void ConvertApdSamplesHandler() { int xSampleCountPerLine = m_config.GetScanXPoints(); int imageSampleCountPerFrame = m_config.GetScanXPoints() * m_config.GetScanYPoints(); int scanRows = m_config.GetScanStrategy() == SCAN_STRATEGY.Z_BIDIRECTION ? m_params.ScanRows * 2 : m_params.ScanRows; SCAN_STRATEGY scanStrategy = m_config.GetScanStrategy(); int sourceIndex; int[] data = new int[xSampleCountPerLine]; while (m_scanning) { if (!m_scanData.DequeueApdSample(out ApdSampleData sample)) { continue; } // 采集数据转换 // 去背景噪声 sample.Convert(); // 如果是双向扫描,且当前是奇数行,则该行的数据需要反转 // 根据错位补偿参数,完成相应的截断 if (scanStrategy == SCAN_STRATEGY.Z_BIDIRECTION) { if ((sample.Line & 0x01) == 0x01) // 奇数行,需要反转 { sourceIndex = m_config.GetScanPixelCompensation() / 2 + m_config.GetScanPixelCalibration(); Array.Reverse(sample.NSamples); Array.Copy(sample.NSamples, sourceIndex, data, 0, xSampleCountPerLine); } else { sourceIndex = m_config.GetScanPixelCompensation() / 2 + m_config.GetScanPixelOffset(); Array.Copy(sample.NSamples, sourceIndex, data, 0, xSampleCountPerLine); } } else { sourceIndex = m_config.GetScanPixelCompensation() / 2 + m_config.GetScanPixelOffset(); Array.Copy(sample.NSamples, sourceIndex, data, 0, xSampleCountPerLine); } ApdSampleData convertData = new ApdSampleData(data, sample.Frame, sample.Line, sample.ChannelIndex); m_scanData.EnqueueApdConvertData(convertData); if (convertData.Line + 1 == scanRows) { Logger.Info(string.Format("channel[{0}] convert info: frame[{1}], line[{2}].", convertData.ChannelIndex, convertData.Frame, convertData.Line)); } data = new int[xSampleCountPerLine]; } Logger.Info(string.Format("scan task[{0}|{1}] stop, finish convert samples.", m_taskId, m_taskName)); }
private void UpdateVariables() { // 扫描模式 SCAN_MODE mode = rbtnGalv.Checked ? SCAN_MODE.GALVANOMETER : SCAN_MODE.RESONANT; m_config.SetScanMode(mode); // 扫描策略 SCAN_STRATEGY strategy = ((KeyValuePair <SCAN_STRATEGY, string>)cbxScanStrategy.SelectedItem).Key; m_config.SetScanStartegy(strategy); // 振镜系统 SCAN_MIRROR_NUM mirrorNum = rbtnThree.Checked ? SCAN_MIRROR_NUM.THREEE : SCAN_MIRROR_NUM.TWO; m_config.SetScanMirrorNum(mirrorNum); // 采集模式 & 采集数量 SCAN_ACQUISITION_MODE acquisitionMode = ((KeyValuePair <SCAN_ACQUISITION_MODE, string>)cbxAcquisitionMode.SelectedItem).Key; m_config.SetScanAcquisitionMode(acquisitionMode); // 采集模式数量 int acquisitionModeNum = (int)cbxAcquisitionModeNum.SelectedItem; m_config.SetScanAcquisitionModeNum(acquisitionModeNum); // Dwell Time m_config.SetScanDwellTime(double.Parse(cbxDwellTime.SelectedItem.ToString())); // 扫描像素 int scanPixels = ((KeyValuePair <int, string>)cbxScanPixels.SelectedItem).Key; m_config.SetScanXPoints(scanPixels); m_config.SetScanYPoints(scanPixels); // 激光[通道]开关状态 LASER_CHAN_SWITCH status = chbx405.Checked ? LASER_CHAN_SWITCH.ON : LASER_CHAN_SWITCH.OFF; m_config.SetLaserSwitch(CHAN_ID.WAVELENGTH_405_NM, status); status = chbx488.Checked ? LASER_CHAN_SWITCH.ON : LASER_CHAN_SWITCH.OFF; m_config.SetLaserSwitch(CHAN_ID.WAVELENGTH_488_NM, status); status = chbx561.Checked ? LASER_CHAN_SWITCH.ON : LASER_CHAN_SWITCH.OFF; m_config.SetLaserSwitch(CHAN_ID.WAVELENGTH_561_NM, status); status = chbx640.Checked ? LASER_CHAN_SWITCH.ON : LASER_CHAN_SWITCH.OFF; m_config.SetLaserSwitch(CHAN_ID.WAVELENGTH_640_NM, status); m_params.Calculate(); }
private void cbxScanStrategy_SelectedIndexChanged(object sender, EventArgs e) { SCAN_STRATEGY strategy = ((KeyValuePair <SCAN_STRATEGY, string>)cbxScanStrategy.SelectedItem).Key; if (m_config.GetScanStrategy() == strategy) { return; } this.Cursor = System.Windows.Forms.Cursors.WaitCursor; // if task is not running, just update config if (m_scheduler.TaskScanning() == false) { m_config.SetScanStartegy(strategy); m_scheduler.ConfigScanTask(m_scheduler.GetScanningTask()); this.Cursor = System.Windows.Forms.Cursors.Default; return; } // if task is already running, stop first m_scheduler.StopScanTask(m_scheduler.GetScanningTask()); // update config m_config.SetScanStartegy(strategy); // create & start task m_scheduler.CreateScanTask(0, "实时扫描", out ScanTask scanTask); API_RETURN_CODE code = m_scheduler.StartScanTask(scanTask); this.Cursor = System.Windows.Forms.Cursors.Default; if (code != API_RETURN_CODE.API_SUCCESS) { MessageBox.Show(string.Format("启动扫描任务失败,失败码: [0x{0}][{1}].", ((int)code).ToString("X"), code)); } }
public API_RETURN_CODE SetScanStartegy(SCAN_STRATEGY strategy) { Logger.Info(string.Format("set scan strategy: [{0}].", strategy)); m_scan.Strategy = strategy; return(API_RETURN_CODE.API_SUCCESS); }
private void UpdateChart() { chart.Series[0].Points.Clear(); chart.Series[1].Points.Clear(); chart.Series[2].Points.Clear(); chart.Series[3].Points.Clear(); Params m_params = Params.GetParams(); SCAN_STRATEGY strategy = Config.GetConfig().GetScanStrategy(); SCAN_MIRROR_NUM mirror = Config.GetConfig().GetScanMirrorNum(); int aoPointCount = m_params.AoSampleCountPerLine * 2; double aoSampleTime = 1e3 / m_params.AoSampleRate; double[] aoXValues = new double[aoPointCount]; double[] xGalvSamples = new double[aoPointCount]; double[] y1GalvSamples, y2GalvSamples; if (m_config.GetScanStrategy() == SCAN_STRATEGY.Z_UNIDIRECTION) { y1GalvSamples = Enumerable.Concat( Enumerable.Repeat <double>(m_params.AoY1SamplesPerRow[0], m_params.AoSampleCountPerLine), Enumerable.Repeat <double>(m_params.AoY1SamplesPerRow[1], m_params.AoSampleCountPerLine)).ToArray(); y2GalvSamples = Enumerable.Concat( Enumerable.Repeat <double>(m_params.AoY2SamplesPerRow[0], m_params.AoSampleCountPerLine), Enumerable.Repeat <double>(m_params.AoY2SamplesPerRow[1], m_params.AoSampleCountPerLine)).ToArray(); } else { y1GalvSamples = Enumerable.Concat( Enumerable.Concat( Enumerable.Repeat <double>(m_params.AoY1SamplesPerRow[0], m_params.AoSampleCountPerLine / 2), Enumerable.Repeat <double>(m_params.AoY1SamplesPerRow[1], m_params.AoSampleCountPerLine / 2)), Enumerable.Concat( Enumerable.Repeat <double>(m_params.AoY1SamplesPerRow[2], m_params.AoSampleCountPerLine / 2), Enumerable.Repeat <double>(m_params.AoY1SamplesPerRow[3], m_params.AoSampleCountPerLine / 2)) ).ToArray(); y2GalvSamples = Enumerable.Concat( Enumerable.Concat( Enumerable.Repeat <double>(m_params.AoY2SamplesPerRow[0], m_params.AoSampleCountPerLine / 2), Enumerable.Repeat <double>(m_params.AoY2SamplesPerRow[1], m_params.AoSampleCountPerLine / 2)), Enumerable.Concat( Enumerable.Repeat <double>(m_params.AoY2SamplesPerRow[2], m_params.AoSampleCountPerLine / 2), Enumerable.Repeat <double>(m_params.AoY2SamplesPerRow[3], m_params.AoSampleCountPerLine / 2)) ).ToArray(); } aoXValues[0] = 0; for (int i = 1; i < aoPointCount; i++) { aoXValues[i] = aoXValues[i - 1] + aoSampleTime; } Array.Copy(m_params.AoXSamplesPerLine, 0, xGalvSamples, 0, m_params.AoSampleCountPerLine); Array.Copy(m_params.AoXSamplesPerLine, 0, xGalvSamples, m_params.AoSampleCountPerLine, m_params.AoSampleCountPerLine); chart.Series[0].Points.DataBindXY(aoXValues, xGalvSamples); chart.Series[1].Points.DataBindXY(aoXValues, y1GalvSamples); chart.Series[2].Points.DataBindXY(aoXValues, y2GalvSamples); chart.Series[2].IsVisibleInLegend = Config.GetConfig().GetScanMirrorNum() == SCAN_MIRROR_NUM.THREEE ? true : false; int doPointCount = m_params.DoSampleCountPerLine * 2; double doSampleTime = 1e3 / m_params.DoSampleRate; double[] doXValues = new double[doPointCount]; double[] doSamples = new double[doPointCount]; doXValues[0] = 0; for (int i = 1; i < doPointCount; i++) { doXValues[i] = doXValues[i - 1] + doSampleTime; } Array.Copy(m_params.DigitalTriggerSamplesPerLine, 0, doSamples, 0, m_params.DoSampleCountPerLine); Array.Copy(m_params.DigitalTriggerSamplesPerLine, 0, doSamples, m_params.DoSampleCountPerLine, m_params.DoSampleCountPerLine); chart.Series[3].Points.DataBindXY(doXValues, doSamples); //double xValue; //int index, line; //for (int i = 0; i < pointCount; i++) //{ // line = i / m_params.AoSampleCountPerLine; // index = i % m_params.AoSampleCountPerLine; // xValue = aoSampleTime * i; // chart.Series[0].Points.AddXY(xValue, m_params.AoXSamplesPerLine[index]); // if (strategy == SCAN_STRATEGY.Z_UNIDIRECTION) // { // chart.Series[1].Points.AddXY(xValue, m_params.AoY1SamplesPerRow[line]); // chart.Series[2].Points.AddXY(xValue, m_params.AoY2SamplesPerRow[line]); // } // else // { // if (index < m_params.AoPreviousSampleCountPerLine + m_params.AoValidSampleCountPerLine) // { // chart.Series[1].Points.AddXY(xValue, m_params.AoY1SamplesPerRow[line]); // chart.Series[2].Points.AddXY(xValue, m_params.AoY2SamplesPerRow[line]); // } // else // { // chart.Series[1].Points.AddXY(xValue, m_params.AoY1SamplesPerRow[line] + m_params.AoVoltagePerPixel); // chart.Series[2].Points.AddXY(xValue, m_params.AoY2SamplesPerRow[line] + m_params.AoVoltagePerPixel * 2); // } // } // chart.Series[3].Points.AddXY(xValue, m_params.DigitalTriggerSamplesPerLine[index*2]); // chart.Series[3].Points.AddXY(xValue + aoSampleTime, m_params.DigitalTriggerSamplesPerLine[index*2+1]); //} //chart.Series[2].IsVisibleInLegend = Config.GetConfig().GetScanMirrorNum() == SCAN_MIRROR_NUM.THREEE ? true : false; }
/// <summary> /// 将行数据转换成帧数据存储 /// 对于单向扫描,将行数据逐行存储,直到完成一帧数据的存储后,加入到帧数据存储队列 /// 对于双向扫描: /// (a)对偶数行数据截取中间段数据存储到帧数据中 /// (b)奇数行数据先做反转操作,再根据数据错位值截取相应的中间段数据,并存储到帧数据中 /// (c)一帧数据存储完成后,加入到帧数据存储队列 /// </summary> private void ConvertPmtSamplesHandler() { int activatedChannelNum = m_config.GetChannelNum(); int xSampleCountPerLine = m_config.GetScanXPoints(); int imageSampleCountPerFrame = m_config.GetScanXPoints() * m_config.GetScanYPoints(); int scanRows = m_config.GetScanStrategy() == SCAN_STRATEGY.Z_BIDIRECTION ? m_params.ScanRows * 2 : m_params.ScanRows; SCAN_STRATEGY scanStrategy = m_config.GetScanStrategy(); int i, sourceIndex; bool[] channelSwitch = new bool[activatedChannelNum]; for (i = 0; i < activatedChannelNum; i++) { channelSwitch[i] = m_config.GetLaserSwitch((CHAN_ID)i) == LASER_CHAN_SWITCH.ON ? true : false; } short[][] data = new short[activatedChannelNum][]; for (i = 0; i < activatedChannelNum; i++) { data[i] = channelSwitch[i] ? new short[xSampleCountPerLine] : null; } while (m_scanning) { if (!m_scanData.DequeuePmtSample(out PmtSampleData sample)) { continue; } // 采集数据转换 // 去背景噪声 sample.Convert(); // 如果是双向扫描,且当前是奇数行,则该行的数据需要反转 // 根据错位补偿参数,完成相应的截断 if (scanStrategy == SCAN_STRATEGY.Z_BIDIRECTION) { if ((sample.Line & 0x01) == 0x01) // 奇数行,需要反转 { sourceIndex = m_config.GetScanPixelCompensation() / 2 + m_config.GetScanPixelCalibration(); for (i = 0; i < activatedChannelNum; i++) { if (sample.NSamples[i] != null) { Array.Reverse(sample.NSamples[i]); Array.Copy(sample.NSamples[i], sourceIndex, data[i], 0, xSampleCountPerLine); } } } else { sourceIndex = m_config.GetScanPixelCompensation() / 2 + m_config.GetScanPixelOffset(); for (i = 0; i < activatedChannelNum; i++) { if (sample.NSamples[i] != null) { Array.Copy(sample.NSamples[i], sourceIndex, data[i], 0, xSampleCountPerLine); } } } } else { sourceIndex = m_config.GetScanPixelCompensation() / 2 + m_config.GetScanPixelOffset(); for (i = 0; i < activatedChannelNum; i++) { if (sample.NSamples[i] != null) { Array.Copy(sample.NSamples[i], sourceIndex, data[i], 0, xSampleCountPerLine); } } } PmtSampleData convertData = new PmtSampleData(data, sample.Frame, sample.Line); m_scanData.EnqueuePmtConvertData(convertData); // Logger.Info(string.Format("convert info: frame[{0}], line[{1}].", convertData.Frame, convertData.Line)); if (convertData.Line + 1 == scanRows) { Logger.Info(string.Format("convert info: frame[{0}], line[{1}].", convertData.Frame, convertData.Line)); } data = new short[activatedChannelNum][]; for (i = 0; i < activatedChannelNum; i++) { data[i] = channelSwitch[i] ? new short[xSampleCountPerLine] : null; } } Logger.Info(string.Format("scan task[{0}|{1}] stop, finish convert samples.", m_taskId, m_taskName)); }