예제 #1
0
 private void DownstreamThreadProc()
 {
     while (!_disposed)
     {
         // Fetch a Telegram and Signal any waiting threads
         // (Note: this will always be a Scan-Data telegram because the thread will be suspended for all other communications.)
         _lastTelegram = _client.ReceiveTelegram();
         _downstreamTurnstile.Set();
     }
 }
예제 #2
0
        protected override void UpdateImpl()
        {
            if ((null == _client) || (!_client.IsConnected) || (null == _downstreamTurnstile))
            {
                throw new InvalidOperationException($"{Name} disconnected");
            }

            try
            {
                // Wait for the next Scan-Data Telegram
                _downstreamTurnstile.WaitOne();
                CoLaBTelegram       scanDataTelegram = _lastTelegram;
                NetworkBinaryReader scanData         = new NetworkBinaryReader(scanDataTelegram);

                // Miscellaneous Metadata
                UInt16 versionNumber = scanData.ReadUInt16();
                if (1 != versionNumber)
                {
                    log.Warn($"{Name}: unexpected version number in telegram: {versionNumber}");
                }
                scanData.Skip(2);

                UInt32 serialNumber = scanData.ReadUInt32();
                if (_serialNumber != serialNumber)
                {
                    _serialNumber     = serialNumber;
                    base.serialNumber = serialNumber.ToString();
                }

                scanData.Skip(1);
                byte deviceStatus = scanData.ReadByte();
                if (0 != deviceStatus)
                {
                    log.Error($"{Name}: unexpected device status: {deviceStatus}");
                }

                scanData.Skip(2);
                _scanCounter = scanData.ReadUInt16();

                scanData.Skip(4);
                _timeStamp = scanData.ReadUInt32();

                // Skip: input states, output states, reserved bytes, frequency information, encoders
                scanData.Skip(2 + 2 + 2 + 4 + 4 + 2);

                // 16-bit Channels
                UInt16 channelCount16 = scanData.ReadUInt16();
                if (1 != channelCount16)
                {
                    log.Error($"{Name}: unexpected number of 16-bit channels: {channelCount16}");
                }

                _channelName = scanData.ReadString(5);

                _scalingFactor = scanData.ReadSingle() * 0.001f;
                float scalingOffset = scanData.ReadSingle();

                int startingAngle    = scanData.ReadInt32();
                int angularStepWidth = (int)scanData.ReadUInt16();
                if ((_startingAngle != startingAngle) || (_angularStepWidth != angularStepWidth))
                {
                    _startingAngle    = startingAngle;
                    _angularStepWidth = angularStepWidth;
                    _directions       = null;
                }

                int dataCount = (int)scanData.ReadUInt16();

                // Initialize or Reinitialize array of Polar Radii
                if (null == _radii)
                {
                    _radii      = new UInt16[dataCount];
                    _directions = null;
                }
                else if (_radii.Length != dataCount)
                {
                    Array.Resize(ref _radii, dataCount);
                    _directions = null;
                }

                // Read 16-bit unsigned pixels (reversed)
                for (int i = (dataCount - 1); i >= 0; --i)
                {
                    _radii[i] = scanData.ReadUInt16();
                }
            }
            catch (MetriCam2Exception)
            {
                // Pass MetriCam API Exceptions without alteration
                throw;
            }
            catch (Exception foreignException)
            {
                // Wrap and Throw other exceptions encountered during Connection
                throw ExceptionBuilder.Build(typeof(ImageAcquisitionFailedException), Name, foreignException.Message, foreignException);
            }
        }
예제 #3
0
        protected override void ConnectImpl()
        {
            try
            {
                // Reinitialize a Disconnected Client
                if ((null != _client) && (!_client.IsConnected))
                {
                    _client.Dispose();
                    _client = null;
                }

                // Connect when necessary
                if (null == _client)
                {
                    _client = CoLaBClient.Connect(_remoteEndPoint);
                    log.Debug($"{Name}: connected to {_remoteEndPoint}");

                    try
                    {
                        // Request Scan-Data Telegrams
                        CoLaBTelegram acknowledgement = _client.SendTelegram(CoLaCommandType.Event, "LMDscandata", (telegramWriter) =>
                        {
                            telegramWriter.Write(0x01);
                        }, acknowledgeTimeout: _timeoutMilliseconds);

                        if (acknowledgement.Data[acknowledgement.Offset] != 0)
                        {
                            log.Debug($"{Name}: CoLa (binary) telegram subscription established");
                        }
                        else
                        {
                            throw ExceptionBuilder.Build(typeof(ConnectionFailedException), Name, "error_connectionFailed", "CoLa (binary) telegram subscription failed");
                        }
                    }
                    catch
                    {
                        // Dispose the TCP/IP Client immediately
                        try
                        {
                            _client.Dispose();
                            _client = null;
                        }
                        catch
                        {
                            // Suppress secondary exceptions
                        }

                        // Rethrow the original exception
                        throw;
                    }

                    // Begin receiving telegrams in a background thread
                    _downstreamThread              = new Thread(DownstreamThreadProc);
                    _downstreamThread.Name         = Name;
                    _downstreamThread.IsBackground = true;
                    _downstreamThread.Start();
                }
            }
            catch (MetriCam2Exception)
            {
                // Pass MetriCam API Exceptions without alteration
                throw;
            }
            catch (Exception foreignException)
            {
                // Wrap and Throw other exceptions encountered during Connection
                throw ExceptionBuilder.Build(typeof(ConnectionFailedException), Name, foreignException.Message, foreignException);
            }
        }